]> git.kernelconcepts.de Git - karo-tx-redboot.git/commitdiff
Initial revision
authorlothar <lothar>
Fri, 13 Feb 2009 17:04:23 +0000 (17:04 +0000)
committerlothar <lothar>
Fri, 13 Feb 2009 17:04:23 +0000 (17:04 +0000)
319 files changed:
packages/devs/can/arm/at91/at91sam7/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/can/arm/at91/at91sam7/v2_0/cdl/can_at91sam7.cdl [new file with mode: 0644]
packages/devs/can/arm/at91/at91sam7/v2_0/include/can_at91sam7.inl [new file with mode: 0644]
packages/devs/can/arm/at91/at91sam7/v2_0/src/can_at91sam7.c [new file with mode: 0644]
packages/devs/can/arm/at91/at91sam7/v2_0/tests/can_test_aux.inl [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/cdl/can_lpc2xxx.cdl [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/include/can_lpc2xxx.h [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/include/can_lpc2xxx_baudrates.h [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/src/can_accfilt_lpc2xxx.c [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/src/can_lpc2xxx.c [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/tests/can_baudrates.c [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/tests/can_busload.c [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/tests/can_extended_cfg.c [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/tests/can_multichan_rx.c [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/tests/can_multichan_tx.c [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/tests/can_rx_tx.c [new file with mode: 0644]
packages/devs/can/arm/lpc2xxx/v2_0/tests/can_test_aux.inl [new file with mode: 0644]
packages/devs/can/loop/v2_0/doc/README [new file with mode: 0644]
packages/devs/can/loop/v2_0/doc/synth_test.ecm [new file with mode: 0644]
packages/devs/can/loop/v2_0/tests/can_callback.c [new file with mode: 0644]
packages/devs/can/m68k/mcf52xx/v2_0/tests/flexcan_wake.c [new file with mode: 0644]
packages/devs/disk/generic/mmc/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/disk/generic/mmc/v2_0/cdl/devs_disk_mmc.cdl [new file with mode: 0644]
packages/devs/disk/generic/mmc/v2_0/doc/disk_mmc.sgml [new file with mode: 0644]
packages/devs/disk/generic/mmc/v2_0/include/mmc_protocol.h [new file with mode: 0644]
packages/devs/disk/generic/mmc/v2_0/src/mmc_spi.c [new file with mode: 0644]
packages/devs/eth/arm/at91/v2_0/ChangeLog [new file with mode: 0755]
packages/devs/eth/arm/at91/v2_0/cdl/at91_eth.cdl [new file with mode: 0755]
packages/devs/eth/arm/at91/v2_0/src/if_at91.c [new file with mode: 0755]
packages/devs/eth/arm/phycore229x/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/eth/arm/phycore229x/v2_0/cdl/phycore229x_eth_drivers.cdl [new file with mode: 0755]
packages/devs/eth/arm/phycore229x/v2_0/include/devs_eth_phycore229x.inl [new file with mode: 0755]
packages/devs/eth/phy/v2_0/src/DM9161A.c [new file with mode: 0644]
packages/devs/eth/phy/v2_0/src/KS8721.c [new file with mode: 0644]
packages/devs/eth/phy/v2_0/src/ics189x.c [new file with mode: 0644]
packages/devs/flash/arm/ea2468/v2_0/ChangeLog [new file with mode: 0755]
packages/devs/flash/arm/ea2468/v2_0/cdl/flash_ea2468.cdl [new file with mode: 0755]
packages/devs/flash/arm/ea2468/v2_0/src/flash_ea2468.c [new file with mode: 0755]
packages/devs/flash/arm/lpc2xxx/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/flash/arm/lpc2xxx/v2_0/cdl/flash_arm_lpc2xxx.cdl [new file with mode: 0644]
packages/devs/flash/arm/lpc2xxx/v2_0/include/flash_arm_lpc2xxx.h [new file with mode: 0644]
packages/devs/flash/arm/lpc2xxx/v2_0/src/flash_arm_lpc2xxx.c [new file with mode: 0644]
packages/devs/flash/arm/phycore229x/v2_0/ChangeLog [new file with mode: 0755]
packages/devs/flash/arm/phycore229x/v2_0/cdl/flash_phycore229x.cdl [new file with mode: 0755]
packages/devs/flash/arm/phycore229x/v2_0/src/flash_phycore229x.c [new file with mode: 0755]
packages/devs/flash/fr30/skmb91302/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/flash/fr30/skmb91302/v2_0/cdl/flash_skmb91302.cdl [new file with mode: 0644]
packages/devs/flash/fr30/skmb91302/v2_0/src/skmb91302_flash.c [new file with mode: 0644]
packages/devs/i2c/arm/lpc2xxx/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/i2c/arm/lpc2xxx/v2_0/cdl/i2c_lpc2xxx.cdl [new file with mode: 0644]
packages/devs/i2c/arm/lpc2xxx/v2_0/src/i2c_lpc2xxx.c [new file with mode: 0644]
packages/devs/i2c/m68k/mcf52xx/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/i2c/m68k/mcf52xx/v2_0/cdl/i2c_mcf52xx.cdl [new file with mode: 0644]
packages/devs/i2c/m68k/mcf52xx/v2_0/doc/mcf52xx_i2c.sgml [new file with mode: 0644]
packages/devs/i2c/m68k/mcf52xx/v2_0/include/i2c_mcf52xx.h [new file with mode: 0644]
packages/devs/i2c/m68k/mcf52xx/v2_0/src/i2c_mcf52xx.c [new file with mode: 0644]
packages/devs/serial/arm/lpc24xx/v2_0/ChangeLog [new file with mode: 0755]
packages/devs/serial/arm/lpc24xx/v2_0/cdl/ser_arm_lpc24xx.cdl [new file with mode: 0755]
packages/devs/serial/arm/lpc24xx/v2_0/include/arm_lpc24xx_ser.inl [new file with mode: 0755]
packages/devs/serial/arm/pxa2x0/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/serial/arm/pxa2x0/v2_0/cdl/ser_arm_xscale_pxa2x0.cdl [new file with mode: 0644]
packages/devs/serial/arm/pxa2x0/v2_0/include/arm_xscale_pxa2x0_ser.inl [new file with mode: 0644]
packages/devs/serial/coldfire/mcf5272/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/serial/coldfire/mcf5272/v2_0/cdl/mcf5272_serial.cdl [new file with mode: 0644]
packages/devs/serial/coldfire/mcf5272/v2_0/src/mcf5272_serial.c [new file with mode: 0644]
packages/devs/serial/coldfire/mcf5272/v2_0/src/mcf5272_serial.h [new file with mode: 0644]
packages/devs/serial/freescale/esci/drv/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/serial/freescale/esci/drv/v2_0/cdl/ser_freescale_esci.cdl [new file with mode: 0644]
packages/devs/serial/freescale/esci/drv/v2_0/src/ser_esci.c [new file with mode: 0644]
packages/devs/serial/freescale/esci/hdr/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/serial/freescale/esci/hdr/v2_0/cdl/ser_freescale_esci_h.cdl [new file with mode: 0644]
packages/devs/serial/freescale/esci/hdr/v2_0/include/ser_esci.h [new file with mode: 0644]
packages/devs/serial/powerpc/mpc555/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/serial/powerpc/mpc555/v2_0/cdl/ser_powerpc_mpc555.cdl [new file with mode: 0644]
packages/devs/serial/powerpc/mpc555/v2_0/src/mpc555_serial.h [new file with mode: 0644]
packages/devs/serial/powerpc/mpc555/v2_0/src/mpc555_serial_with_ints.c [new file with mode: 0644]
packages/devs/spi/arm/lpc2xxx/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/spi/arm/lpc2xxx/v2_0/cdl/spi_lpc2xxx.cdl [new file with mode: 0644]
packages/devs/spi/arm/lpc2xxx/v2_0/include/spi_lpc2xxx.h [new file with mode: 0644]
packages/devs/spi/arm/lpc2xxx/v2_0/src/spi_lpc2xxx.cxx [new file with mode: 0644]
packages/devs/usb/at91/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/usb/at91/v2_0/cdl/usbs_at91.cdl [new file with mode: 0644]
packages/devs/usb/at91/v2_0/include/usbs_at91.h [new file with mode: 0644]
packages/devs/usb/at91/v2_0/src/bitops.h [new file with mode: 0644]
packages/devs/usb/at91/v2_0/src/usbs_at91.c [new file with mode: 0644]
packages/devs/usb/at91/v2_0/src/usbs_at91_data.cxx [new file with mode: 0644]
packages/devs/usb/d12/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/usb/d12/v2_0/cdl/usbs_d12.cdl [new file with mode: 0644]
packages/devs/usb/d12/v2_0/include/usbs_d12.h [new file with mode: 0644]
packages/devs/usb/d12/v2_0/src/usbs_d12.c [new file with mode: 0644]
packages/devs/usb/d12/v2_0/src/usbs_d12_data.cxx [new file with mode: 0644]
packages/devs/usb/i386/SoRoD12/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/usb/i386/SoRoD12/v2_0/cdl/usbs_i386_sorod12.cdl [new file with mode: 0644]
packages/devs/usb/i386/SoRoD12/v2_0/include/usbs_i386_sorod12.inl [new file with mode: 0644]
packages/devs/wallclock/arm/lpc2xxx/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/wallclock/arm/lpc2xxx/v2_0/cdl/lpc2xxx_wallclock.cdl [new file with mode: 0644]
packages/devs/wallclock/arm/lpc2xxx/v2_0/src/lpc2xxx_wallclock.cxx [new file with mode: 0644]
packages/devs/watchdog/arm/at91wdtc/v2_0/ChangeLog [new file with mode: 0644]
packages/devs/watchdog/arm/at91wdtc/v2_0/cdl/watchdog_at91wdtc.cdl [new file with mode: 0644]
packages/devs/watchdog/arm/at91wdtc/v2_0/src/watchdog_at91wdtc.cxx [new file with mode: 0644]
packages/fs/ram/v2_0/tests/ramfs3.c [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/cdl/hal_arm_at91sam7s.cdl [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/hal_platform_ints.h [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/hal_platform_setup.h [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s128_rom.h [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s128_rom.ldi [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s256_rom.h [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s256_rom.ldi [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s32_rom.h [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s32_rom.ldi [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s64_rom.h [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s64_rom.ldi [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x128_rom.h [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x128_rom.ldi [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x256_rom.h [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x256_rom.ldi [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x512_rom.h [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x512_rom.ldi [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/include/plf_io.h [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/misc/redboot_RAM.ecm [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/misc/redboot_ROM.ecm [new file with mode: 0644]
packages/hal/arm/at91/at91sam7s/v2_0/src/at91sam7s_misc.c [new file with mode: 0644]
packages/hal/arm/at91/at91sam7sek/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/arm/at91/at91sam7sek/v2_0/cdl/hal_arm_at91sam7sek.cdl [new file with mode: 0644]
packages/hal/arm/at91/at91sam7sek/v2_0/src/at91sam7sek_misc.c [new file with mode: 0644]
packages/hal/arm/at91/at91sam7xek/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/arm/at91/at91sam7xek/v2_0/cdl/hal_arm_at91sam7xek.cdl [new file with mode: 0644]
packages/hal/arm/at91/at91sam7xek/v2_0/src/at91sam7xek_misc.c [new file with mode: 0644]
packages/hal/arm/at91/sam7ex256/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/arm/at91/sam7ex256/v2_0/cdl/hal_arm_sam7ex256.cdl [new file with mode: 0644]
packages/hal/arm/at91/sam7ex256/v2_0/src/sam7ex256_misc.c [new file with mode: 0644]
packages/hal/arm/at91/var/v2_0/src/hal_diag_dbg.c [new file with mode: 0644]
packages/hal/arm/at91/var/v2_0/src/hal_diag_dcc.c [new file with mode: 0644]
packages/hal/arm/at91/var/v2_0/src/hal_diag_dcc.h [new file with mode: 0644]
packages/hal/arm/at91/var/v2_0/src/timer_pit.c [new file with mode: 0644]
packages/hal/arm/at91/var/v2_0/src/timer_tc.c [new file with mode: 0644]
packages/hal/arm/lpc24xx/ea2468/v2_0/ChangeLog [new file with mode: 0755]
packages/hal/arm/lpc24xx/ea2468/v2_0/cdl/hal_arm_lpc24xx_ea2468.cdl [new file with mode: 0755]
packages/hal/arm/lpc24xx/ea2468/v2_0/include/hal_platform_setup.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_ram.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_ram.ldi [new file with mode: 0755]
packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_rom.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_rom.ldi [new file with mode: 0755]
packages/hal/arm/lpc24xx/ea2468/v2_0/include/plf_io.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/ea2468/v2_0/src/ea2468_misc.c [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/ChangeLog [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/cdl/hal_arm_lpc24xx.cdl [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/include/hal_cache.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/include/hal_diag.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/include/hal_var_ints.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/include/lpc24xx_misc.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/include/plf_stub.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/include/var_arch.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/include/var_io.h [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/src/hal_diag.c [new file with mode: 0755]
packages/hal/arm/lpc24xx/var/v2_0/src/lpc24xx_misc.c [new file with mode: 0755]
packages/hal/arm/lpc2xxx/phycore229x/v2_0/ChangeLog [new file with mode: 0755]
packages/hal/arm/lpc2xxx/phycore229x/v2_0/cdl/hal_arm_lpc2xxx_phycore229x.cdl [new file with mode: 0755]
packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/hal_platform_setup.h [new file with mode: 0755]
packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_ram.h [new file with mode: 0755]
packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_ram.ldi [new file with mode: 0755]
packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_rom.h [new file with mode: 0755]
packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_rom.ldi [new file with mode: 0755]
packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/plf_io.h [new file with mode: 0755]
packages/hal/arm/lpc2xxx/phycore229x/v2_0/src/phycore229x_misc.c [new file with mode: 0755]
packages/hal/arm/lpc2xxx/var/v2_0/include/lpc2xxx_misc.h [new file with mode: 0644]
packages/hal/arm/mac7100/mac7100evb/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/arm/mac7100/mac7100evb/v2_0/cdl/hal_arm_mac7100_mac7100evb.cdl [new file with mode: 0644]
packages/hal/arm/mac7100/mac7100evb/v2_0/include/hal_platform_ints.h [new file with mode: 0644]
packages/hal/arm/mac7100/mac7100evb/v2_0/include/hal_platform_setup.h [new file with mode: 0644]
packages/hal/arm/mac7100/mac7100evb/v2_0/include/mac7100evb_misc.h [new file with mode: 0644]
packages/hal/arm/mac7100/mac7100evb/v2_0/include/pkgconf/mlt_arm_mac7100_mac7100evb_rom.h [new file with mode: 0644]
packages/hal/arm/mac7100/mac7100evb/v2_0/include/pkgconf/mlt_arm_mac7100_mac7100evb_rom.ldi [new file with mode: 0644]
packages/hal/arm/mac7100/mac7100evb/v2_0/include/plf_io.h [new file with mode: 0644]
packages/hal/arm/mac7100/mac7100evb/v2_0/src/mac7100evb_misc.c [new file with mode: 0644]
packages/hal/arm/mac7100/mace1/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/arm/mac7100/mace1/v2_0/cdl/hal_arm_mac7100_mace1.cdl [new file with mode: 0644]
packages/hal/arm/mac7100/mace1/v2_0/include/hal_platform_ints.h [new file with mode: 0644]
packages/hal/arm/mac7100/mace1/v2_0/include/hal_platform_setup.h [new file with mode: 0644]
packages/hal/arm/mac7100/mace1/v2_0/include/mace1_misc.h [new file with mode: 0644]
packages/hal/arm/mac7100/mace1/v2_0/include/pkgconf/mlt_arm_mac7100_mace1_rom.h [new file with mode: 0644]
packages/hal/arm/mac7100/mace1/v2_0/include/pkgconf/mlt_arm_mac7100_mace1_rom.ldi [new file with mode: 0644]
packages/hal/arm/mac7100/mace1/v2_0/include/plf_io.h [new file with mode: 0644]
packages/hal/arm/mac7100/mace1/v2_0/src/mace1_misc.c [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/cdl/hal_arm_mac7100.cdl [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/include/hal_cache.h [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/include/hal_diag.h [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/include/hal_var_setup.h [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/include/mac7100_misc.h [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/include/plf_stub.h [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/include/var_arch.h [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/include/var_io.h [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/src/flash_security.S [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/src/hal_diag.c [new file with mode: 0644]
packages/hal/arm/mac7100/var/v2_0/src/mac7100_misc.c [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/cdl/hal_coldfire.cdl [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/doc/readme.txt [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/include/arch.inc [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/include/basetype.h [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/include/coldfire_regs.h [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/include/coldfire_stub.h [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/include/hal_arch.h [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/include/hal_cache.h [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/include/hal_intr.h [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/include/hal_io.h [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/include/hal_startup.h [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/src/coldfire.ld [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/src/coldfire_stub.c [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/src/context.S [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/src/hal_misc.c [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/src/hal_mk_defs.c [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/src/hal_startup.c [new file with mode: 0644]
packages/hal/coldfire/arch/v2_0/src/vectors.S [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/cdl/hal_coldfire_m5272c3.cdl [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/hal_memmap.h [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_ram.h [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_ram.ldi [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_rom.h [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_rom.ldi [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_romram.h [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_romram.ldi [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/platform.inc [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/plf_intr.h [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/plf_serial.h [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/plf_startup.h [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/include/plf_stub.h [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/src/plf_mk_defs.c [new file with mode: 0644]
packages/hal/coldfire/m5272c3/v2_0/src/plf_startup.c [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/cdl/hal_coldfire_mcf5272.cdl [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/include/hal_diag.h [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/include/mcf5272_devs.h [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/include/var_arch.h [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/include/var_basetype.h [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/include/var_cache.h [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/include/var_intr.h [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/include/var_regs.h [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/include/var_startup.h [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/include/variant.inc [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/src/hal_diag.c [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/src/var_misc.c [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/src/var_startup.c [new file with mode: 0644]
packages/hal/coldfire/mcf5272/v2_0/src/variant.S [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/cdl/hal_fr30.cdl [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/include/arch.inc [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/include/basetype.h [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/include/fr30.inc [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/include/fr30_stub.h [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/include/hal_arch.h [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/include/hal_cache.h [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/include/hal_intr.h [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/include/hal_io.h [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/src/context.S [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/src/fr30_stub.c [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/src/hal_misc.c [new file with mode: 0644]
packages/hal/fr30/arch/v2_0/src/vectors.S [new file with mode: 0644]
packages/hal/fr30/mb91301/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/fr30/mb91301/v2_0/cdl/hal_fr30_mb91301.cdl [new file with mode: 0644]
packages/hal/fr30/mb91301/v2_0/include/hal_diag.h [new file with mode: 0644]
packages/hal/fr30/mb91301/v2_0/include/var_arch.h [new file with mode: 0644]
packages/hal/fr30/mb91301/v2_0/include/var_intr.h [new file with mode: 0644]
packages/hal/fr30/mb91301/v2_0/include/variant.inc [new file with mode: 0644]
packages/hal/fr30/mb91301/v2_0/src/fr30_mb91301.ld [new file with mode: 0644]
packages/hal/fr30/mb91301/v2_0/src/hal_diag.c [new file with mode: 0644]
packages/hal/fr30/mb91301/v2_0/src/var_misc.c [new file with mode: 0644]
packages/hal/fr30/mb91301/v2_0/src/variant.S [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/ChangeLog [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/cdl/hal_fr30_skmb91302.cdl [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_ram.h [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_ram.ldi [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_rom.h [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_rom.ldi [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/include/platform.inc [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/include/plf_cache.h [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/include/plf_intr.h [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/include/plf_io.h [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/include/plf_stub.h [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/misc/redboot_RAM.ecm [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/misc/redboot_ROM.ecm [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/src/platform.S [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/src/plf_misc.c [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/src/plf_stub.c [new file with mode: 0644]
packages/hal/fr30/skmb91302/v2_0/src/ser.c [new file with mode: 0644]
packages/hal/synth/arch/v2_0/tests/ftok.c [new file with mode: 0644]
packages/io/can/v2_0/doc/can.sgml [new file with mode: 0644]
packages/io/can/v2_0/tests/can_filter.c [new file with mode: 0644]
packages/io/can/v2_0/tests/can_hdi.c [new file with mode: 0644]
packages/io/can/v2_0/tests/can_load.c [new file with mode: 0644]
packages/io/can/v2_0/tests/can_remote.c [new file with mode: 0644]
packages/io/can/v2_0/tests/can_test_aux.inl [new file with mode: 0644]
packages/io/can/v2_0/tests/can_tx.c [new file with mode: 0644]
packages/io/fileio/v2_0/include/fnmatch.h [new file with mode: 0644]
packages/io/fileio/v2_0/src/fnmatch.c [new file with mode: 0644]
packages/io/fileio/v2_0/tests/fnmatch.c [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/ChangeLog [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/cdl/usbs_serial.cdl [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/doc/usbs_serial.sgml [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/host/linux/.cvsignore [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/host/linux/Makefile [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/host/linux/ecos_usbserial.c [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/host/windows/eCosUsbSerial.inf [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/include/usbs_serial.h [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/src/usbs_serial.c [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/tests/usb2serial.c [new file with mode: 0644]
packages/io/usb/serial/slave/v2_0/tests/usbserial_echo.c [new file with mode: 0644]
packages/io/usb/slave/v2_0/host/bulk-boundaries.tcl [new file with mode: 0644]
packages/isoinfra/v2_0/include/fnmatch.h [new file with mode: 0644]
packages/isoinfra/v2_0/include/sys/time.h [new file with mode: 0644]
packages/kernel/v2_0/tests/timeslice2.c [new file with mode: 0644]
packages/redboot/v2_0/doc/.cvsignore [new file with mode: 0644]
packages/redboot/v2_0/src/flash_load.c [new file with mode: 0644]
packages/redboot/v2_0/src/flash_load.h [new file with mode: 0644]
packages/redboot/v2_0/src/gunzip.c [new file with mode: 0644]

diff --git a/packages/devs/can/arm/at91/at91sam7/v2_0/ChangeLog b/packages/devs/can/arm/at91/at91sam7/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..5448c26
--- /dev/null
@@ -0,0 +1,41 @@
+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
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/can/arm/at91/at91sam7/v2_0/cdl/can_at91sam7.cdl b/packages/devs/can/arm/at91/at91sam7/v2_0/cdl/can_at91sam7.cdl
new file mode 100644 (file)
index 0000000..6b1f029
--- /dev/null
@@ -0,0 +1,214 @@
+# ====================================================================
+#
+#      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 eCosCentric Limited
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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/packages/devs/can/arm/at91/at91sam7/v2_0/include/can_at91sam7.inl b/packages/devs/can/arm/at91/at91sam7/v2_0/include/can_at91sam7.inl
new file mode 100644 (file)
index 0000000..d0a4df7
--- /dev/null
@@ -0,0 +1,187 @@
+#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 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/can/arm/at91/at91sam7/v2_0/src/can_at91sam7.c b/packages/devs/can/arm/at91/at91sam7/v2_0/src/can_at91sam7.c
new file mode 100644 (file)
index 0000000..2f8d4ba
--- /dev/null
@@ -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 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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;
+                }
+             }
+             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;
+            }
+            
+            //
+            // 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/packages/devs/can/arm/at91/at91sam7/v2_0/tests/can_test_aux.inl b/packages/devs/can/arm/at91/at91sam7/v2_0/tests/can_test_aux.inl
new file mode 100644 (file)
index 0000000..2946b8f
--- /dev/null
@@ -0,0 +1,148 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/can/arm/lpc2xxx/v2_0/ChangeLog b/packages/devs/can/arm/lpc2xxx/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..ec01cff
--- /dev/null
@@ -0,0 +1,111 @@
+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
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/can/arm/lpc2xxx/v2_0/cdl/can_lpc2xxx.cdl b/packages/devs/can/arm/lpc2xxx/v2_0/cdl/can_lpc2xxx.cdl
new file mode 100644 (file)
index 0000000..ba8ebdb
--- /dev/null
@@ -0,0 +1,405 @@
+# ====================================================================
+#
+#      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 eCosCentric Limited
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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_LPC2XXX_EXTENDED_CFG_KEYS {
+                display       "Extended acceptance 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 groups.  A message group 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
+                    groups for each CAN channel. The support of
+                    message filter groups is not conform to the
+                    standard API of the CAN I/O layer and should only
+                    be used for application where portability is not
+                    important."
+             }
+             
+         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."
+    }
+    
+    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/packages/devs/can/arm/lpc2xxx/v2_0/include/can_lpc2xxx.h b/packages/devs/can/arm/lpc2xxx/v2_0/include/can_lpc2xxx.h
new file mode 100644 (file)
index 0000000..7e4d773
--- /dev/null
@@ -0,0 +1,93 @@
+#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 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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
+//
+#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/packages/devs/can/arm/lpc2xxx/v2_0/include/can_lpc2xxx_baudrates.h b/packages/devs/can/arm/lpc2xxx/v2_0/include/can_lpc2xxx_baudrates.h
new file mode 100644 (file)
index 0000000..9569d06
--- /dev/null
@@ -0,0 +1,214 @@
+#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 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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
+
+
+//==========================================================================
+//                          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/packages/devs/can/arm/lpc2xxx/v2_0/src/can_accfilt_lpc2xxx.c b/packages/devs/can/arm/lpc2xxx/v2_0/src/can_accfilt_lpc2xxx.c
new file mode 100644 (file)
index 0000000..e708931
--- /dev/null
@@ -0,0 +1,1011 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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_global_can_info.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/packages/devs/can/arm/lpc2xxx/v2_0/src/can_lpc2xxx.c b/packages/devs/can/arm/lpc2xxx/v2_0/src/can_lpc2xxx.c
new file mode 100644 (file)
index 0000000..e1bb926
--- /dev/null
@@ -0,0 +1,2204 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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.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_])
+#else
+#define LPC2XXX_GET_CAN_CHANNEL(_can_info_, _chan_no_) ((can_channel*)(_can_info_).active_channels[0])
+#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 -EPERM;
+                 }
+             }
+             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;
+}
+
+
+//===========================================================================
+// Start CAN module - set CANMOD operational and enable all interrupts
+//===========================================================================
+static void lpc2xxx_start_module(can_channel *chan)
+{
+    cyg_uint32          regval;
+    lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+    
+    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_LPC2XXX_EXTENDED_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_filtergroup_cfg *filter_grp = (cyg_can_filtergroup_cfg *)buf;
+    lpc2xxx_can_info_t      *info = (lpc2xxx_can_info_t *)chan->dev_priv; 
+    
+    
+    if (*len != sizeof(cyg_can_filtergroup_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 : -EPERM;
+}
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_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_LPC2XXX_EXTENDED_CFG_KEYS
+        //
+        // Add message filter group to acceptance filter
+        //
+        case CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP :
+             {
+                 return lpc2xxx_can_config_accfilt_group(chan, buf, len);
+             }
+             break;
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_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;
+                }
+             }
+             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 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;
+             }
+             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;
+}
+
+
+//===========================================================================
+// 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;
+            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;
+            }
+            else if (data.bytes[3] >= 96)
+            {
+                pevent->flags |= CYGNUM_CAN_EVENT_WARNING_TX;
+                info->state = CYGNUM_CAN_STATE_BUS_WARN;
+            }
+            else
+            {
+                info->state = CYGNUM_CAN_STATE_ACTIVE;
+            }
+            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;
+            }
+            else
+            {
+                info->state = CYGNUM_CAN_STATE_ACTIVE;    
+            }
+            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 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;
+    lpc2xxx_can_info_t       *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+    
+    //
+    // 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
+    //
+#if CYGINT_IO_CAN_CHANNELS > 1 
+    cyg_uint8 i = 0;     
+    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/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_baudrates.c b/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_baudrates.c
new file mode 100644 (file)
index 0000000..2dc8d2e
--- /dev/null
@@ -0,0 +1,231 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_busload.c b/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_busload.c
new file mode 100644 (file)
index 0000000..37c8198
--- /dev/null
@@ -0,0 +1,253 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_extended_cfg.c b/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_extended_cfg.c
new file mode 100644 (file)
index 0000000..8ff3d9c
--- /dev/null
@@ -0,0 +1,252 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_multichan_rx.c b/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_multichan_rx.c
new file mode 100644 (file)
index 0000000..b7a16da
--- /dev/null
@@ -0,0 +1,339 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_multichan_tx.c b/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_multichan_tx.c
new file mode 100644 (file)
index 0000000..4aa2f52
--- /dev/null
@@ -0,0 +1,292 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_rx_tx.c b/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_rx_tx.c
new file mode 100644 (file)
index 0000000..ffab4a5
--- /dev/null
@@ -0,0 +1,349 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_test_aux.inl b/packages/devs/can/arm/lpc2xxx/v2_0/tests/can_test_aux.inl
new file mode 100644 (file)
index 0000000..2946b8f
--- /dev/null
@@ -0,0 +1,148 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/can/loop/v2_0/doc/README b/packages/devs/can/loop/v2_0/doc/README
new file mode 100644 (file)
index 0000000..78195b6
--- /dev/null
@@ -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/packages/devs/can/loop/v2_0/doc/synth_test.ecm b/packages/devs/can/loop/v2_0/doc/synth_test.ecm
new file mode 100644 (file)
index 0000000..634924a
--- /dev/null
@@ -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/packages/devs/can/loop/v2_0/tests/can_callback.c b/packages/devs/can/loop/v2_0/tests/can_callback.c
new file mode 100644 (file)
index 0000000..afdf322
--- /dev/null
@@ -0,0 +1,241 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/can/m68k/mcf52xx/v2_0/tests/flexcan_wake.c b/packages/devs/can/m68k/mcf52xx/v2_0/tests/flexcan_wake.c
new file mode 100644 (file)
index 0000000..92400a2
--- /dev/null
@@ -0,0 +1,247 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/disk/generic/mmc/v2_0/ChangeLog b/packages/devs/disk/generic/mmc/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..981767d
--- /dev/null
@@ -0,0 +1,110 @@
+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
+  
+  //===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2005, 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/disk/generic/mmc/v2_0/cdl/devs_disk_mmc.cdl b/packages/devs/disk/generic/mmc/v2_0/cdl/devs_disk_mmc.cdl
new file mode 100644 (file)
index 0000000..cf813c3
--- /dev/null
@@ -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 eCosCentric Limited
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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/hd0/\"" }
+           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."
+
+           # Testing support. For now just hard-code some values for partition 0
+           # on the card.
+           define_proc {
+               puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_DEVICE CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME \"1\""
+               puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_MOUNTPOINT \"/dosfs\""
+               puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_DIRECTORY  \"/test\""
+           }
+       }
+       
+       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/packages/devs/disk/generic/mmc/v2_0/doc/disk_mmc.sgml b/packages/devs/disk/generic/mmc/v2_0/doc/disk_mmc.sgml
new file mode 100644 (file)
index 0000000..f1afe05
--- /dev/null
@@ -0,0 +1,214 @@
+<!-- DOCTYPE refentry  PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner                         -->
+
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!--     disk_mmc.sgml                                               -->
+<!--                                                                 -->
+<!--     Documentation for the MMC disk device driver                -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN####                                          -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004 eCosCentric Limited                          -->
+<!-- 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                   -->
+<!-- =============================================================== -->
+<!--                                                                 -->      
+<!-- ####COPYRIGHTEND####                                            -->
+<!-- =============================================================== -->
+<!-- =============================================================== -->
+<!-- #####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/packages/devs/disk/generic/mmc/v2_0/include/mmc_protocol.h b/packages/devs/disk/generic/mmc/v2_0/include/mmc_protocol.h
new file mode 100644 (file)
index 0000000..b59b8b3
--- /dev/null
@@ -0,0 +1,175 @@
+#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 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does 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
+
+// Response formats are different for MMC vs. SPI mode, so are defined
+// in the appropriate source files.
+
+// 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)
+
+
+#endif //  ifdef CYGONCE_DEVS_DISK_MMC_PROTOCOL_H
+
+/* EOF mmc_protocol.h */
diff --git a/packages/devs/disk/generic/mmc/v2_0/src/mmc_spi.c b/packages/devs/disk/generic/mmc/v2_0/src/mmc_spi.c
new file mode 100644 (file)
index 0000000..6ee0d40
--- /dev/null
@@ -0,0 +1,1194 @@
+//==========================================================================
+//
+//      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 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does 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.
+//
+// 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
+
+// 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;
+} 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)
+{
+    cyg_spi_bus     *bus;
+    cyg_spi_device  *dev;
+
+    DEBUG2("mmc_spi_send_init(): dev pointer 0x%p, %d\n", disk->mmc_spi_dev, cyg_mmc_spi_polled );
+    dev = disk->mmc_spi_dev;
+    bus = dev->spi_bus;
+    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("mmc_spi_send_command_start(): polling for completion of previous write\n");
+        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. That CRC is
+    // well-known. Once in SPI mode the card will not use CRCs by
+    // default.
+    request[5]  = (command == 0x00) ? 0x0095 : 0x00ff;
+    // 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("mmc_spi_read_data(): got error response %02x after %d iterations\n", 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("mmc_spi_read_data(): got data and CRC %02x %02x\n", response[0], response[1]);
+    
+    return MMC_DATA_TOKEN_SUCCESS;
+}
+
+// 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("mmc_spi_read_register(): unexpected response to command %02x, reply code %02x\n", 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("mmc_spi_read_register(): unexpected response to command %02x, expected 0x00FE data token, got %02x\n", 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("mmc_spi_read_disk_block(%d): sending command\n", block);
+    reply = mmc_spi_send_command_start(disk, MMC_REQUEST_READ_SINGLE_BLOCK, block * MMC_SPI_BLOCK_SIZE);
+    if (MMC_REPLY_SUCCESS != reply) {
+        DEBUG1("mmc_spi_read_disk_block(%d): unexpected response to READ_SINGLE_BLOCK command, code %02x\n", 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("mmc_spi_read_disk_block(%d): reading data token/data/crc\n", 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("mmc_spi_read_disk_block(%d): failed to retrieve data, error token %02x\n", 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("mmc_spi_write_disk_block(), sending command\n");
+    reply = mmc_spi_send_command_start(disk, MMC_REQUEST_WRITE_BLOCK, block * MMC_SPI_BLOCK_SIZE);
+    if (MMC_REPLY_SUCCESS != reply) {
+        DEBUG1("mmc_spi_write_disk_block(): unexpected response to WRITE_BLOCK command, code %02x\n", 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("mmc_spi_write_disk_block(): sending data token/data/crc\n");
+    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("mmc_spi_write_disk_block(): got data response token %02x\n", 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("mmc_spi_write_disk_block(): invalid data response token %02x\n", 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("mmc_spi_write_disk_block(), polling for ! busy, got response %02x\n", 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("mmc_spi_check_for_disk(): loop %d, card did not enter idle state, code %02x\n", 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("mmc_spi_check_for_disk(): unable to get a response from the MMC card: code %02x\n", reply);
+        // A working card should be returning some data
+        return -ENODEV;
+    }
+    if (0x01 != reply) {
+        DEBUG1("mmc_spi_check_for_disk(): card did not enter idle state, code %02x\n", reply);
+        return -EIO;
+    }
+    
+    // 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
+        reply = mmc_spi_send_command(disk, MMC_REQUEST_SEND_OP_COND, 0);
+    }
+    if (MMC_REPLY_SUCCESS != reply) {
+        DEBUG1("mmc_spi_check_for_disk(): card has not entered operational state: reply code %02x\n", 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.
+    // 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]);
+    
+    // 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));
+    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);
+    }
+    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));
+    {
+        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);
+    }
+    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));
+    {
+        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)]);
+    }
+    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));
+    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                
+
+    // 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;
+    }
+
+    // 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.
+    // 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;
+    DEBUG1("Disk blockcount %d (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 sector %02x %02x %02x, file system %02x, last sector %02x %02x %02x\n", i,   \
+                   partition[0], 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("mmc_spi_disk_lookup(): target name=%s\n", 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("mmc_spi_disk_read(): first block %d, buf %p, len %lu blocks (%lu bytes)\n",
+           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("mmc_spi_disk_write(): first block %d, buf %p, len %lu blocks (%lu bytes)\n",
+           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/packages/devs/eth/arm/at91/v2_0/ChangeLog b/packages/devs/eth/arm/at91/v2_0/ChangeLog
new file mode 100755 (executable)
index 0000000..7adee0e
--- /dev/null
@@ -0,0 +1,53 @@
+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.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright 2006 Andrew Lunn
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/eth/arm/at91/v2_0/cdl/at91_eth.cdl b/packages/devs/eth/arm/at91/v2_0/cdl/at91_eth.cdl
new file mode 100755 (executable)
index 0000000..46cfb57
--- /dev/null
@@ -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 Red Hat, Inc.
+## Copyright (C) 2002 Jonathan Larmour
+## Copyright (C) 2006 Andrew Lunn
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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/packages/devs/eth/arm/at91/v2_0/src/if_at91.c b/packages/devs/eth/arm/at91/v2_0/src/if_at91.c
new file mode 100755 (executable)
index 0000000..587e42f
--- /dev/null
@@ -0,0 +1,1029 @@
+//==========================================================================
+//
+//      if_at91.c
+//
+//
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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 cleared */
+   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 cleared */
+   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/packages/devs/eth/arm/phycore229x/v2_0/ChangeLog b/packages/devs/eth/arm/phycore229x/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..55a205f
--- /dev/null
@@ -0,0 +1,38 @@
+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
+
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
diff --git a/packages/devs/eth/arm/phycore229x/v2_0/cdl/phycore229x_eth_drivers.cdl b/packages/devs/eth/arm/phycore229x/v2_0/cdl/phycore229x_eth_drivers.cdl
new file mode 100755 (executable)
index 0000000..b6c5e0a
--- /dev/null
@@ -0,0 +1,116 @@
+# ====================================================================
+#
+#      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 Red Hat, Inc.
+## Copyright (C) 2008 eCosCentric Limited 
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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/packages/devs/eth/arm/phycore229x/v2_0/include/devs_eth_phycore229x.inl b/packages/devs/eth/arm/phycore229x/v2_0/include/devs_eth_phycore229x.inl
new file mode 100755 (executable)
index 0000000..14d0a20
--- /dev/null
@@ -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 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/eth/phy/v2_0/src/DM9161A.c b/packages/devs/eth/phy/v2_0/src/DM9161A.c
new file mode 100644 (file)
index 0000000..af19dab
--- /dev/null
@@ -0,0 +1,134 @@
+//==========================================================================
+//
+//      dev/DM9161A.c
+//
+//      Ethernet transceiver (PHY) support 
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/eth/phy/v2_0/src/KS8721.c b/packages/devs/eth/phy/v2_0/src/KS8721.c
new file mode 100644 (file)
index 0000000..12c29c7
--- /dev/null
@@ -0,0 +1,115 @@
+//==========================================================================
+//
+//      dev/KS8721.c
+//
+//      Ethernet transceiver (PHY) support 
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/eth/phy/v2_0/src/ics189x.c b/packages/devs/eth/phy/v2_0/src/ics189x.c
new file mode 100644 (file)
index 0000000..5e13969
--- /dev/null
@@ -0,0 +1,119 @@
+//==========================================================================
+//
+//      ics189x.c
+//
+//      Ethernet transceiver (PHY) support 
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/flash/arm/ea2468/v2_0/ChangeLog b/packages/devs/flash/arm/ea2468/v2_0/ChangeLog
new file mode 100755 (executable)
index 0000000..4b61c1a
--- /dev/null
@@ -0,0 +1,39 @@
+2008-07-08  Uwe Kindler <uwe_kindler@web.de>
+
+       * src/flash_ea2468.c: 
+       * cdl/flash_ea2468.cdl: New package/file(s).
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/flash/arm/ea2468/v2_0/cdl/flash_ea2468.cdl b/packages/devs/flash/arm/ea2468/v2_0/cdl/flash_ea2468.cdl
new file mode 100755 (executable)
index 0000000..f200d9e
--- /dev/null
@@ -0,0 +1,71 @@
+# ====================================================================
+#
+#      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 Red Hat, Inc.
+## Copyright (C) 2003 Andrew Lunn
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-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
+}
+
+# EOF flash_ea2468.cdl
\ No newline at end of file
diff --git a/packages/devs/flash/arm/ea2468/v2_0/src/flash_ea2468.c b/packages/devs/flash/arm/ea2468/v2_0/src/flash_ea2468.c
new file mode 100755 (executable)
index 0000000..3fe230a
--- /dev/null
@@ -0,0 +1,72 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+// Copyright (C) 2003 Andrew Lunn
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/flash/arm/lpc2xxx/v2_0/ChangeLog b/packages/devs/flash/arm/lpc2xxx/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..5d0263d
--- /dev/null
@@ -0,0 +1,35 @@
+2007-07-12  Hans Rosenfeld  <rosenfeld@grumpf.hope-2000.org>
+
+       * lpc2xxx: driver for on-chip flash memory
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/flash/arm/lpc2xxx/v2_0/cdl/flash_arm_lpc2xxx.cdl b/packages/devs/flash/arm/lpc2xxx/v2_0/cdl/flash_arm_lpc2xxx.cdl
new file mode 100644 (file)
index 0000000..7eda995
--- /dev/null
@@ -0,0 +1,83 @@
+# ====================================================================
+#
+#      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 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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
+
+    # 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/packages/devs/flash/arm/lpc2xxx/v2_0/include/flash_arm_lpc2xxx.h b/packages/devs/flash/arm/lpc2xxx/v2_0/include/flash_arm_lpc2xxx.h
new file mode 100644 (file)
index 0000000..2ee0f42
--- /dev/null
@@ -0,0 +1,81 @@
+#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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/flash/arm/lpc2xxx/v2_0/src/flash_arm_lpc2xxx.c b/packages/devs/flash/arm/lpc2xxx/v2_0/src/flash_arm_lpc2xxx.c
new file mode 100644 (file)
index 0000000..d612dc8
--- /dev/null
@@ -0,0 +1,216 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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>
+
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.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/packages/devs/flash/arm/phycore229x/v2_0/ChangeLog b/packages/devs/flash/arm/phycore229x/v2_0/ChangeLog
new file mode 100755 (executable)
index 0000000..1aa4fa6
--- /dev/null
@@ -0,0 +1,41 @@
+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.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2008 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/flash/arm/phycore229x/v2_0/cdl/flash_phycore229x.cdl b/packages/devs/flash/arm/phycore229x/v2_0/cdl/flash_phycore229x.cdl
new file mode 100755 (executable)
index 0000000..61ebb86
--- /dev/null
@@ -0,0 +1,104 @@
+# ====================================================================
+#
+#      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 Red Hat, Inc.
+## Copyright (C) 2008 eCosCentric Limited 
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-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/packages/devs/flash/arm/phycore229x/v2_0/src/flash_phycore229x.c b/packages/devs/flash/arm/phycore229x/v2_0/src/flash_phycore229x.c
new file mode 100755 (executable)
index 0000000..2da552a
--- /dev/null
@@ -0,0 +1,69 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/flash/fr30/skmb91302/v2_0/ChangeLog b/packages/devs/flash/fr30/skmb91302/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..40bfde7
--- /dev/null
@@ -0,0 +1,44 @@
+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.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/flash/fr30/skmb91302/v2_0/cdl/flash_skmb91302.cdl b/packages/devs/flash/fr30/skmb91302/v2_0/cdl/flash_skmb91302.cdl
new file mode 100644 (file)
index 0000000..176a90f
--- /dev/null
@@ -0,0 +1,74 @@
+# ====================================================================
+#
+#      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 Red Hat, Inc.
+## Copyright (C) 2002 Gary Thomas
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-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
+
+    implements    CYGHWR_IO_FLASH_DEVICE
+
+    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/packages/devs/flash/fr30/skmb91302/v2_0/src/skmb91302_flash.c b/packages/devs/flash/fr30/skmb91302/v2_0/src/skmb91302_flash.c
new file mode 100644 (file)
index 0000000..f3f8db1
--- /dev/null
@@ -0,0 +1,73 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/devs/i2c/arm/lpc2xxx/v2_0/ChangeLog b/packages/devs/i2c/arm/lpc2xxx/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..68b6b70
--- /dev/null
@@ -0,0 +1,35 @@
+2007-07-12  Hans Rosenfeld  <rosenfeld@grumpf.hope-2000.org>
+
+       * lpc2xxx: driver for on-chip I2C unit
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/i2c/arm/lpc2xxx/v2_0/cdl/i2c_lpc2xxx.cdl b/packages/devs/i2c/arm/lpc2xxx/v2_0/cdl/i2c_lpc2xxx.cdl
new file mode 100644 (file)
index 0000000..ab8b21b
--- /dev/null
@@ -0,0 +1,59 @@
+# ====================================================================
+#
+#      i2c_lpc2xxx.cdl
+#
+#      I2C driver for LPC2xxx
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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_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
+
+    description "This package provides a driver for the I2C module found in
+                 Philips LPC2xxx controllers."
+
+    compile     i2c_lpc2xxx.c
+}
\ No newline at end of file
diff --git a/packages/devs/i2c/arm/lpc2xxx/v2_0/src/i2c_lpc2xxx.c b/packages/devs/i2c/arm/lpc2xxx/v2_0/src/i2c_lpc2xxx.c
new file mode 100644 (file)
index 0000000..54629d2
--- /dev/null
@@ -0,0 +1,414 @@
+//==========================================================================
+//
+//      i2c_lpc2xxx.c
+//
+//      I2C driver for LPC2xxx
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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_i2c_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/i2c.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.
+ */
+
+#define I2C_XFER        8
+#define I2C_INTR        CYGNUM_HAL_INTERRUPT_I2C
+#define I2C_FREQ        (CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / \
+                         CYGNUM_HAL_ARM_LPC2XXX_VPBDIV)
+#define I2C_BASE        CYGARC_HAL_LPC2XXX_REG_I2_BASE
+
+#define I2C_CONSET      CYGARC_HAL_LPC2XXX_REG_I2CONSET
+#define I2C_CONCLR      CYGARC_HAL_LPC2XXX_REG_I2CONCLR
+#define I2C_CON         I2C_CONSET
+#define I2C_STAT        CYGARC_HAL_LPC2XXX_REG_I2STAT
+#define I2C_DAT         CYGARC_HAL_LPC2XXX_REG_I2DAT
+#define I2C_ADR         CYGARC_HAL_LPC2XXX_REG_I2ADR
+#define I2C_SCLH        CYGARC_HAL_LPC2XXX_REG_I2SCLH
+#define I2C_SCLL        CYGARC_HAL_LPC2XXX_REG_I2SCLL
+
+#define I2C_R8(r, x)    HAL_READ_UINT8  (I2C_BASE + (r), (x))
+#define I2C_W8(r, x)    HAL_WRITE_UINT8 (I2C_BASE + (r), (x))
+#define I2C_R16(r, x)   HAL_READ_UINT16 (I2C_BASE + (r), (x))
+#define I2C_W16(r, x)   HAL_WRITE_UINT16(I2C_BASE + (r), (x))
+
+/* Special case for setting/clearing bits in I2C_CON */
+#define SET_CON(x)      I2C_W8(I2C_CONSET, (x))
+#define CLR_CON(x)      I2C_W8(I2C_CONCLR, (x))
+
+#define CON_EN          CYGARC_HAL_LPC2XXX_REG_I2CONSET_I2EN
+#define CON_STA         CYGARC_HAL_LPC2XXX_REG_I2CONSET_STA
+#define CON_STO         CYGARC_HAL_LPC2XXX_REG_I2CONSET_STO
+#define CON_SI          CYGARC_HAL_LPC2XXX_REG_I2CONSET_SI
+#define CON_AA          CYGARC_HAL_LPC2XXX_REG_I2CONSET_AA
+
+static cyg_uint8        i2c_addr;
+static cyg_uint32       i2c_count = 0;
+static const cyg_uint8* i2c_txbuf = NULL;
+static cyg_uint8*       i2c_rxbuf = NULL;
+static cyg_bool         i2c_rxnak;
+
+volatile
+static cyg_uint32       i2c_flag = 0;
+static cyg_uint32       i2c_delay;
+
+static cyg_drv_mutex_t  i2c_lock;
+static cyg_drv_cond_t   i2c_wait;
+static cyg_handle_t     i2c_hand;
+static cyg_interrupt    i2c_data;
+
+#define I2C_FLAG_FINISH 1       /* transfer finished                        */
+#define I2C_FLAG_ACT    2       /* bus still active, no STOP condition sent */
+#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                     */
+
+/*
+ * set up I2C bus timing
+ * I2C clock period is in PCLK ticks
+ */
+static void
+i2c_lpc2xxx_delay(cyg_uint32 delay)
+{
+  cyg_uint32 period;
+  
+  if(delay == i2c_delay)
+    return;
+  
+  period = I2C_FREQ / (1000000000 / delay);
+  period /= 2;
+  
+  I2C_W16(I2C_SCLL, period);
+  I2C_W16(I2C_SCLH, period);
+  i2c_delay = delay;
+}
+
+/*
+ * 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
+i2c_lpc2xxx_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+  cyg_uint8 status;
+  I2C_R8(I2C_STAT, status);
+  
+  switch(status) {
+    case 0x08: /* START sent, send Addr+R/W   */
+    case 0x10: /* ReSTART sent, send Addr+R/W */
+      CLR_CON(CON_STA);
+      I2C_W8(I2C_DAT, i2c_addr);
+      break;
+      
+    case 0x18: /* Addr ACKed, send data       */
+    case 0x28: /* Data ACKed, send more       */
+      if(i2c_count == 0) {
+        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(i2c_txbuf == NULL) {
+        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, *i2c_txbuf);
+      i2c_txbuf++;
+      i2c_count--;
+      break;
+      
+    case 0x50: /* Data ACKed, receive more    */
+    case 0x58: /* Data not ACKed, end reception */
+      if(i2c_rxbuf == NULL) {
+        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, *i2c_rxbuf);
+      i2c_rxbuf++;
+      i2c_count--;
+    case 0x40: /* Addr ACKed, receive data    */
+      if(status == 0x58 || i2c_count == 0) {
+        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(i2c_count == 1 && i2c_rxnak)
+        CLR_CON(CON_AA);
+      else    
+        SET_CON(CON_AA);
+      break;
+      
+    case 0x20: /* Addr not ACKed */
+    case 0x48:
+      i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_ADDR;
+      cyg_drv_interrupt_mask_intunsafe(vec);
+      cyg_drv_interrupt_acknowledge(vec);
+      return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+      break;
+    case 0x30: /* Data not ACKed */
+      i2c_count++;
+      i2c_txbuf--;
+      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 */
+      i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_LOST;
+      break;
+    default: /* lots of unused states... */
+      i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_UNK;
+      break;
+  }
+  
+  CLR_CON(CON_SI);
+  cyg_drv_interrupt_acknowledge(vec);
+  return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+
+static void
+i2c_lpc2xxx_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+  if(i2c_flag)
+    cyg_drv_cond_signal(&i2c_wait);
+}
+
+/*
+ * Initialize driver & hardware state
+ */
+static void
+i2c_lpc2xxx_init(struct cyg_i2c_bus *bus)
+{
+  cyg_uint32 addr, tmp;
+  
+  /* enable I2C pins */
+  addr = CYGARC_HAL_LPC2XXX_REG_PIN_BASE + CYGARC_HAL_LPC2XXX_REG_PINSEL0;
+  HAL_READ_UINT32(addr, tmp);
+  tmp |= 0x50;
+  HAL_WRITE_UINT32(addr, tmp);
+  
+  cyg_drv_mutex_init(&i2c_lock);
+  cyg_drv_cond_init(&i2c_wait, &i2c_lock);
+  cyg_drv_interrupt_create(I2C_INTR, 0, (cyg_addrword_t) 0, &i2c_lpc2xxx_isr,
+                           &i2c_lpc2xxx_dsr, &i2c_hand, &i2c_data);
+  cyg_drv_interrupt_attach(i2c_hand);
+  
+  CLR_CON(CON_EN | CON_STA | CON_SI | CON_AA);
+  I2C_W8(I2C_ADR, 0);
+  SET_CON(CON_EN);
+}
+
+/*
+ * transmit a buffer to a device
+ */
+static cyg_uint32
+i2c_lpc2xxx_tx(const cyg_i2c_device *dev, 
+               cyg_bool send_start, 
+               const cyg_uint8 *tx_data, 
+               cyg_uint32 count, 
+               cyg_bool send_stop)
+{
+  i2c_lpc2xxx_delay(dev->i2c_delay);
+  
+  i2c_addr  = dev->i2c_address << 1;
+  i2c_count = count;
+  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 && i2c_flag == I2C_FLAG_ACT) {
+    SET_CON(CON_STA);
+    CLR_CON(CON_SI);
+  } else if(send_start) {
+    SET_CON(CON_STA);
+  } else {
+    I2C_W8(I2C_DAT, *i2c_txbuf);
+    i2c_txbuf++;
+    i2c_count--;
+    CLR_CON(CON_SI);
+  }
+  
+  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(&i2c_lock);
+  cyg_drv_dsr_lock();
+  cyg_drv_interrupt_unmask(I2C_INTR);
+  while(!(i2c_flag & (I2C_FLAG_FINISH|I2C_FLAG_ERROR)))
+    cyg_drv_cond_wait(&i2c_wait);
+  cyg_drv_interrupt_mask(I2C_INTR);
+  cyg_drv_dsr_unlock();
+  cyg_drv_mutex_unlock(&i2c_lock);
+  
+  /* too bad we have no way to tell the caller */
+  if(i2c_flag & I2C_FLAG_ERROR)
+    diag_printf("I2C TX error flag: %x\n", i2c_flag);
+  
+  if(send_stop) {
+    SET_CON(CON_STO);
+    CLR_CON(CON_SI | CON_STA);
+  } else  i2c_flag = I2C_FLAG_ACT;
+  
+  count -= i2c_count;
+  
+  i2c_addr  = 0;
+  i2c_count = 0;
+  i2c_txbuf = NULL;
+  
+  return count;
+}
+
+/*
+ * receive into a buffer from a device
+ */
+static cyg_uint32
+i2c_lpc2xxx_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)
+{
+  i2c_lpc2xxx_delay(dev->i2c_delay);
+  
+  i2c_addr  = dev->i2c_address << 1 | 1;
+  i2c_count = count;
+  i2c_rxbuf = rx_data;
+  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 && i2c_flag == I2C_FLAG_ACT) {
+    SET_CON(CON_STA);
+    CLR_CON(CON_SI);
+  } else if(send_start)
+    SET_CON(CON_STA);
+  
+  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(&i2c_lock);
+  cyg_drv_dsr_lock();
+  cyg_drv_interrupt_unmask(I2C_INTR);
+  while(!(i2c_flag & (I2C_FLAG_FINISH|I2C_FLAG_ERROR)))
+    cyg_drv_cond_wait(&i2c_wait);
+  cyg_drv_interrupt_mask(I2C_INTR);
+  cyg_drv_dsr_unlock();
+  cyg_drv_mutex_unlock(&i2c_lock);
+  
+  /* too bad we have no way to tell the caller */
+  if(i2c_flag & I2C_FLAG_ERROR)
+    diag_printf("I2C RX error flag: %x\n", i2c_flag);
+  
+  if(send_stop) {
+    SET_CON(CON_STO);
+    CLR_CON(CON_SI | CON_STA);
+  } else  i2c_flag = I2C_FLAG_ACT;
+  
+  count -= i2c_count;
+  
+  i2c_addr  = 0;
+  i2c_count = 0;
+  i2c_rxbuf = NULL;
+  
+  return count;
+  
+}
+
+
+/*
+ * generate a STOP
+ */
+static void
+i2c_lpc2xxx_stop(const cyg_i2c_device *dev)
+{
+  SET_CON(CON_STO);
+}
+
+CYG_I2C_BUS(cyg_i2c_lpc2xxx_bus,
+            &i2c_lpc2xxx_init,
+            &i2c_lpc2xxx_tx,
+            &i2c_lpc2xxx_rx,
+            &i2c_lpc2xxx_stop,
+            (void *) 0);
diff --git a/packages/devs/i2c/m68k/mcf52xx/v2_0/ChangeLog b/packages/devs/i2c/m68k/mcf52xx/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..415b7bc
--- /dev/null
@@ -0,0 +1,41 @@
+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
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/i2c/m68k/mcf52xx/v2_0/cdl/i2c_mcf52xx.cdl b/packages/devs/i2c/m68k/mcf52xx/v2_0/cdl/i2c_mcf52xx.cdl
new file mode 100644 (file)
index 0000000..3421520
--- /dev/null
@@ -0,0 +1,105 @@
+# ====================================================================
+#
+#      i2c_mcf52xx.cdl
+#
+#      eCos MCF52xx I2C configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2005, 2006 eCosCentric Limited
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of 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"
+
+    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/packages/devs/i2c/m68k/mcf52xx/v2_0/doc/mcf52xx_i2c.sgml b/packages/devs/i2c/m68k/mcf52xx/v2_0/doc/mcf52xx_i2c.sgml
new file mode 100644 (file)
index 0000000..a0ae383
--- /dev/null
@@ -0,0 +1,279 @@
+<!-- DOCTYPE refentry  PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner                         -->
+
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!--     mcf52xx_i2c.sgml                                            -->
+<!--                                                                 -->
+<!--     Documentation for the mcf52xx I2C bus driver                -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN####                                          -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2006 eCosCentric Limited                          -->
+<!-- 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                   -->
+<!-- =============================================================== -->
+<!--                                                                 -->      
+<!-- ####COPYRIGHTEND####                                            -->
+<!-- =============================================================== -->
+<!-- #####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/packages/devs/i2c/m68k/mcf52xx/v2_0/include/i2c_mcf52xx.h b/packages/devs/i2c/m68k/mcf52xx/v2_0/include/i2c_mcf52xx.h
new file mode 100644 (file)
index 0000000..219721c
--- /dev/null
@@ -0,0 +1,117 @@
+//==========================================================================
+//
+//      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 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/i2c/m68k/mcf52xx/v2_0/src/i2c_mcf52xx.c b/packages/devs/i2c/m68k/mcf52xx/v2_0/src/i2c_mcf52xx.c
new file mode 100644 (file)
index 0000000..235abdb
--- /dev/null
@@ -0,0 +1,451 @@
+//==========================================================================
+//
+//      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 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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) {
+            // 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)) {
+                diag_printf("send_start failed\n");
+                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/packages/devs/serial/arm/lpc24xx/v2_0/ChangeLog b/packages/devs/serial/arm/lpc24xx/v2_0/ChangeLog
new file mode 100755 (executable)
index 0000000..5b5c2c1
--- /dev/null
@@ -0,0 +1,37 @@
+2008-07-07 Uwe Kindler <uwe_kindler@web.de>
+
+       * include/arm_lpc24xx_ser.inl: 
+       Serial driver for ARM LPC24XX, using generic 16X5X driver. 
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/serial/arm/lpc24xx/v2_0/cdl/ser_arm_lpc24xx.cdl b/packages/devs/serial/arm/lpc24xx/v2_0/cdl/ser_arm_lpc24xx.cdl
new file mode 100755 (executable)
index 0000000..a4c15ba
--- /dev/null
@@ -0,0 +1,179 @@
+# ====================================================================
+#
+#      ser_arm_lpc24xx.cdl
+#
+#      eCos serial ARM/LPC24XX configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2004 eCosCentric Limited 
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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:
+# Date:           2008-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_ARM_LPC24XX {
+    display       "ARM LPC24xx serial device drivers"
+
+    parent        CYGPKG_IO_SERIAL_DEVICES
+    active_if     CYGPKG_IO_SERIAL
+    active_if     CYGPKG_HAL_ARM_LPC24XX
+    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."
+
+    # 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_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  *****/"
+    }
+    
+    # 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
+                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 LPC24cxx 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 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 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 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 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 15
+                default_value 15
+                description   "
+                    This option selects the interupt priority for the
+                    UART [set ::channel] 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 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/packages/devs/serial/arm/lpc24xx/v2_0/include/arm_lpc24xx_ser.inl b/packages/devs/serial/arm/lpc24xx/v2_0/include/arm_lpc24xx_ser.inl
new file mode 100755 (executable)
index 0000000..e23e125
--- /dev/null
@@ -0,0 +1,345 @@
+//==========================================================================
+//
+//      io/serial/arm/arm_lpc24xx_ser.inl
+//
+//      ARM LPC24XX Serial I/O definitions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Date:         2008-06-07
+// Purpose:      LPC24XX Serial I/O module (interrupt driven version)
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+//                               INCLUDES
+//==========================================================================
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/lpc24xx_misc.h>
+
+
+//==========================================================================
+//                              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/packages/devs/serial/arm/pxa2x0/v2_0/ChangeLog b/packages/devs/serial/arm/pxa2x0/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..8f0c2c7
--- /dev/null
@@ -0,0 +1,48 @@
+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.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/serial/arm/pxa2x0/v2_0/cdl/ser_arm_xscale_pxa2x0.cdl b/packages/devs/serial/arm/pxa2x0/v2_0/cdl/ser_arm_xscale_pxa2x0.cdl
new file mode 100644 (file)
index 0000000..4cb41c5
--- /dev/null
@@ -0,0 +1,155 @@
+# ====================================================================
+#
+#      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 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-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/packages/devs/serial/arm/pxa2x0/v2_0/include/arm_xscale_pxa2x0_ser.inl b/packages/devs/serial/arm/pxa2x0/v2_0/include/arm_xscale_pxa2x0_ser.inl
new file mode 100644 (file)
index 0000000..ca0908a
--- /dev/null
@@ -0,0 +1,123 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+//##
+//## eCos is free software; you can redistribute it and/or modify it under
+//## the terms of the GNU General Public License as published by the Free
+//## Software Foundation; either version 2 or (at your option) any later version.
+//##
+//## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+//## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//## for more details.
+//##
+//## You should have received a copy of the GNU General Public License along
+//## with eCos; if not, write to the Free Software Foundation, Inc.,
+//## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//##
+//## As a special exception, if other files instantiate templates or use macros
+//## or inline functions from this file, or you compile this file and link it
+//## with other works to produce a work based on this file, this file does not
+//## by itself cause the resulting work to be covered by the GNU General Public
+//## License. However the source code for this file must still be made available
+//## in accordance with section (3) of the GNU General Public License.
+//##
+//## This exception does not invalidate any other reasons why a work based on
+//## this file might be covered by the GNU General Public License.
+//##
+//## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+//## at http://sources.redhat.com/ecos/ecos-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/packages/devs/serial/coldfire/mcf5272/v2_0/ChangeLog b/packages/devs/serial/coldfire/mcf5272/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..65ecb6a
--- /dev/null
@@ -0,0 +1,47 @@
+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.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/serial/coldfire/mcf5272/v2_0/cdl/mcf5272_serial.cdl b/packages/devs/serial/coldfire/mcf5272/v2_0/cdl/mcf5272_serial.cdl
new file mode 100644 (file)
index 0000000..9740dc4
--- /dev/null
@@ -0,0 +1,191 @@
+# ====================================================================
+#
+#      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 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This 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/packages/devs/serial/coldfire/mcf5272/v2_0/src/mcf5272_serial.c b/packages/devs/serial/coldfire/mcf5272/v2_0/src/mcf5272_serial.c
new file mode 100644 (file)
index 0000000..ab4300b
--- /dev/null
@@ -0,0 +1,1137 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/serial/coldfire/mcf5272/v2_0/src/mcf5272_serial.h b/packages/devs/serial/coldfire/mcf5272/v2_0/src/mcf5272_serial.h
new file mode 100644 (file)
index 0000000..790dafc
--- /dev/null
@@ -0,0 +1,140 @@
+#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 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/serial/freescale/esci/drv/v2_0/ChangeLog b/packages/devs/serial/freescale/esci/drv/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..a91f280
--- /dev/null
@@ -0,0 +1,55 @@
+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
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//     
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/serial/freescale/esci/drv/v2_0/cdl/ser_freescale_esci.cdl b/packages/devs/serial/freescale/esci/drv/v2_0/cdl/ser_freescale_esci.cdl
new file mode 100644 (file)
index 0000000..d7e5ad4
--- /dev/null
@@ -0,0 +1,304 @@
+# ====================================================================
+#
+#      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 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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/packages/devs/serial/freescale/esci/drv/v2_0/src/ser_esci.c b/packages/devs/serial/freescale/esci/drv/v2_0/src/ser_esci.c
new file mode 100644 (file)
index 0000000..1093027
--- /dev/null
@@ -0,0 +1,547 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+// Copyright (C) 2996 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/serial/freescale/esci/hdr/v2_0/ChangeLog b/packages/devs/serial/freescale/esci/hdr/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..bdc339a
--- /dev/null
@@ -0,0 +1,56 @@
+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
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//     
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/serial/freescale/esci/hdr/v2_0/cdl/ser_freescale_esci_h.cdl b/packages/devs/serial/freescale/esci/hdr/v2_0/cdl/ser_freescale_esci_h.cdl
new file mode 100644 (file)
index 0000000..98bac8e
--- /dev/null
@@ -0,0 +1,66 @@
+# ====================================================================
+#
+#      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 eCosCentric Ltd
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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/packages/devs/serial/freescale/esci/hdr/v2_0/include/ser_esci.h b/packages/devs/serial/freescale/esci/hdr/v2_0/include/ser_esci.h
new file mode 100644 (file)
index 0000000..bb568c2
--- /dev/null
@@ -0,0 +1,161 @@
+#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 Red Hat, Inc.
+// Copyright (C) eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/serial/powerpc/mpc555/v2_0/ChangeLog b/packages/devs/serial/powerpc/mpc555/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..647f7a5
--- /dev/null
@@ -0,0 +1,48 @@
+2008-04-06  Steven Clugston <steven.clugston@ncl.ac.uk>
+
+       * Refactored cme555 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.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/serial/powerpc/mpc555/v2_0/cdl/ser_powerpc_mpc555.cdl b/packages/devs/serial/powerpc/mpc555/v2_0/cdl/ser_powerpc_mpc555.cdl
new file mode 100644 (file)
index 0000000..f324339
--- /dev/null
@@ -0,0 +1,181 @@
+# ====================================================================
+#
+#      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 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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
+    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_component CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B {
+    display       "mpc555 PowerPC serial port B driver"
+    flavor        bool
+    default_value 1
+    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/packages/devs/serial/powerpc/mpc555/v2_0/src/mpc555_serial.h b/packages/devs/serial/powerpc/mpc555/v2_0/src/mpc555_serial.h
new file mode 100644 (file)
index 0000000..72141a4
--- /dev/null
@@ -0,0 +1,154 @@
+#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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/serial/powerpc/mpc555/v2_0/src/mpc555_serial_with_ints.c b/packages/devs/serial/powerpc/mpc555/v2_0/src/mpc555_serial_with_ints.c
new file mode 100644 (file)
index 0000000..a2c94b6
--- /dev/null
@@ -0,0 +1,631 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555
+
+#include "mpc555_serial.h"
+
+//-----------------
+// Type definitions
+//-----------------
+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;   // tells if the transmit interrupt may be re-enabled
+  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
+} mpc555_serial_info;
+
+//--------------------
+// Function prototypes
+//--------------------
+static bool mpc555_serial_init(struct cyg_devtab_entry * tab);
+static bool mpc555_serial_putc(serial_channel * chan, unsigned char c);
+static Cyg_ErrNo mpc555_serial_lookup(struct cyg_devtab_entry ** tab, 
+                                      struct cyg_devtab_entry * sub_tab,
+                                      const char * name);
+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);
+
+// 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);
+
+//-------------------------------------------
+// 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
+static mpc555_serial_info mpc555_serial_info0 = {MPC555_SERIAL_BASE_A,
+                                                 CYGNUM_HAL_INTERRUPT_IMB3_SCI0_TX,
+                                                 CYGNUM_HAL_INTERRUPT_IMB3_SCI0_RX,
+                                                 CYGNUM_HAL_INTERRUPT_IMB3_SCI0_TX_PRIORITY,
+                                                 CYGNUM_HAL_INTERRUPT_IMB3_SCI0_RX_PRIORITY,
+                                                 false};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE > 0
+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 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
+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};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BUFSIZE > 0
+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 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_SCI0_RX);
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A // Do not waist time on unused hardware
+  if((status & CYGARC_REG_IMM_SCxSR_TDRE) && (control & CYGARC_REG_IMM_SCCxR1_TIE))
+    return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI0_TX);
+// Don't waist time on unused interrupts
+//  if((status & CYGARC_REG_IMM_SCxSR_TC) && (control & CYGARC_REG_IMM_SCCxR1_TCIE))
+//    return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI0_TXC);
+// Don't waist time on unused interrupts
+//  if((status & CYGARC_REG_IMM_SCxSR_IDLE) && (control & CYGARC_REG_IMM_SCCxR1_ILIE))
+//    return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI0_IDLE);
+#endif
+
+  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_SCI1_RX);
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B // Do not waist time on unused hardware
+  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
+//  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
+//  if((status & CYGARC_REG_IMM_SCxSR_IDLE) && (control & CYGARC_REG_IMM_SCCxR1_ILIE))
+//    return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_IDLE);
+
+#if 0
+  // The driver doesn't use the queue operation of the hardware (It would need different code for serial 1 and 2
+  // since oly one port supports queue mode). So the following is not needed.
+  // Leave it there. It is easyer for later implementations to remove the comments than finding
+  // out how the hardware works again.
+  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);
+
+  cyg_uint16 status;
+  cyg_uint16 control;
+
+  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
+  
+#endif
+
+  return 0;
+}
+
+//--------------------------------------------------------------------------------
+// Internal function to actually 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);
+
+  // 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) 
+  { // 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);
+  } 
+  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;
+
+   (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
+   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); 
+
+     // 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 interrupt handler
+                              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);
+    }
+
+    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;
+  (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 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;
+
+  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.
+}
+
+//--------------------------------------
+// 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;
+
+  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);
+
+  return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+//------------------------------------------
+// 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;
+
+  // Allways read out the received character, in order to clear receiver flags
+  HAL_READ_UINT16(port + MPC555_SERIAL_SCxDR, scdr);
+
+  HAL_READ_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+  if(scsr & (cyg_uint16)MPC555_SERIAL_SCxSR_ERRORS)
+  {
+    scsr &= ~((cyg_uint16)MPC555_SERIAL_SCxSR_ERRORS);
+    HAL_WRITE_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+  }
+  else
+  {
+    (chan->callbacks->rcv_char)(chan, (cyg_uint8)scdr);
+  }
+
+  cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_num);
+}
+
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC555
+
+// EOF mpc555_serial_with_ints.c
diff --git a/packages/devs/spi/arm/lpc2xxx/v2_0/ChangeLog b/packages/devs/spi/arm/lpc2xxx/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..723c8bd
--- /dev/null
@@ -0,0 +1,35 @@
+2007-07-12  Hans Rosenfeld  <rosenfeld@grumpf.hope-2000.org>
+
+       * lpc2xxx: driver for on-chip SPI units
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/spi/arm/lpc2xxx/v2_0/cdl/spi_lpc2xxx.cdl b/packages/devs/spi/arm/lpc2xxx/v2_0/cdl/spi_lpc2xxx.cdl
new file mode 100644 (file)
index 0000000..80487e6
--- /dev/null
@@ -0,0 +1,73 @@
+# ====================================================================
+#
+#      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 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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_option 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 option to get support for SPI interface 0."
+    }
+
+    cdl_option 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 option to get support for SPI interface 1."
+    }
+}
\ No newline at end of file
diff --git a/packages/devs/spi/arm/lpc2xxx/v2_0/include/spi_lpc2xxx.h b/packages/devs/spi/arm/lpc2xxx/v2_0/include/spi_lpc2xxx.h
new file mode 100644 (file)
index 0000000..c1507e7
--- /dev/null
@@ -0,0 +1,105 @@
+#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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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_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/packages/devs/spi/arm/lpc2xxx/v2_0/src/spi_lpc2xxx.cxx b/packages/devs/spi/arm/lpc2xxx/v2_0/src/spi_lpc2xxx.cxx
new file mode 100644 (file)
index 0000000..4c5c2d3
--- /dev/null
@@ -0,0 +1,364 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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_GET_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)
+{
+  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;
+  cyg_drv_interrupt_create(
+                           vec, 0, (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);
+#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);
+#endif
+  }
+};
+
+static cyg_spi_lpc2xxx_init_class spi_lpc2xxx_init 
+    CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);
+
diff --git a/packages/devs/usb/at91/v2_0/ChangeLog b/packages/devs/usb/at91/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..cd70aba
--- /dev/null
@@ -0,0 +1,120 @@
+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...
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/usb/at91/v2_0/cdl/usbs_at91.cdl b/packages/devs/usb/at91/v2_0/cdl/usbs_at91.cdl
new file mode 100644 (file)
index 0000000..040a2b1
--- /dev/null
@@ -0,0 +1,210 @@
+# ====================================================================
+#
+#      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 eCosCentric
+## Copyright (C) 2006 Andrew Lunn
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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:
+# 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_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?"
+            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_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 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/packages/devs/usb/at91/v2_0/include/usbs_at91.h b/packages/devs/usb/at91/v2_0/include/usbs_at91.h
new file mode 100644 (file)
index 0000000..3554c43
--- /dev/null
@@ -0,0 +1,63 @@
+#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 eCosCentric Ltd
+// Copyright (C) 2007 Andrew Lunn
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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>
+
+#define AT91_USB_ENDPOINTS 4
+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;
+
+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/packages/devs/usb/at91/v2_0/src/bitops.h b/packages/devs/usb/at91/v2_0/src/bitops.h
new file mode 100644 (file)
index 0000000..e23482a
--- /dev/null
@@ -0,0 +1,97 @@
+#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) 2002 Bart Veer
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/usb/at91/v2_0/src/usbs_at91.c b/packages/devs/usb/at91/v2_0/src/usbs_at91.c
new file mode 100644 (file)
index 0000000..1cb7741
--- /dev/null
@@ -0,0 +1,1408 @@
+//==========================================================================
+//
+//      usbs_at91.c
+//
+//      Driver for the AT91 USB device
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric
+// Copyright (C) 2006 Andrew Lunn
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// 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/devs_usb_at91.h>
+#include <cyg/io/usb/usb.h>
+#include <cyg/io/usb/usbs.h>
+#include <cyg/io/usb/usbs_at91.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))
+
+#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)
+
+#define THERE_IS_A_NEW_PACKET_IN_THE_UDP 0xffff
+
+// Fifo size for each end point.
+static const cyg_uint16 usbs_at91_endpoint_fifo_size[AT91_USB_ENDPOINTS] = {
+  8,
+  64,
+  64,
+  64,
+};
+
+// Does an endpoint support ping pong buffering?
+static const bool usbs_at91_endpoint_pingpong[AT91_USB_ENDPOINTS] = {
+  false,
+  true,
+  true,
+  false
+};
+
+static cyg_uint8 *usbs_at91_endpoint_pbegin[AT91_USB_ENDPOINTS] = 
+  { 0, 0, 0, 0 };
+static cyg_uint8 *usbs_at91_endpoint_pend[AT91_USB_ENDPOINTS] = 
+  { 0, 0 ,0, 0 };
+static bool usbs_at91_endpoint_bank1[AT91_USB_ENDPOINTS] = 
+  { false, false, false, false };
+static cyg_uint16 usbs_at91_endpoint_bytes_in_fifo[AT91_USB_ENDPOINTS] =
+  { 0, 0, 0, 0 };
+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,
+    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,
+};
+
+// 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
+};
+
+// 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)
+{                
+
+#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, 0, 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_drv_dsr_lock ();
+  
+  if (pep->halted != new_value) {       
+    /* There is something is to do */
+    pep->halted = new_value;
+    
+    if (new_value && BITS_ARE_SET (pIMR, 1 << epn)) {   
+      /* Ready to transmit */
+      if (pep->complete_fn) {
+        (*pep->complete_fn) (pep->complete_data, -EAGAIN);
+      }
+      usbs_at91_endpoint_interrupt_enable (epn, false);
+      SET_BITS (pCSR, AT91_UDP_CSR_FORCESTALL);
+    } else {
+      CLEAR_BITS (pCSR, AT91_UDP_CSR_FORCESTALL);
+    }
+  }
+  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_handle_reset (void)
+{
+  int epn;
+  const usb_endpoint_descriptor *usb_endpoints;
+  cyg_uint8 endpoint_type;
+  
+   cyg_uint8 endpoint_number;
+
+  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);
+  }
+
+  // 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);
+}
+
+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;
+  }
+  
+  if (pep->halted) {            
+    /* Halted means nothing to do */
+    cyg_drv_dsr_unlock ();
+
+    if (pep->complete_fn) {
+      (*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;
+    if (space == endpoint_size) {
+      *ppend = *ppbegin;        /* Send zero-packet */
+    }
+    
+    *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;
+      if (space == endpoint_size) {
+        *ppend = *ppbegin;            /* Send zero-packet */
+      }
+      
+      *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 {
+      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 */
+      }
+    }
+  }
+  
+  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");
+  
+  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->buffer_size && pep->complete_fn) {
+      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_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) && 
+          (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) {
+          /* TODO */
+        }
+      } else {
+        status = EP0_LL_STALL;
+      }
+    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_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) && 
+          (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) {
+          /* TODO */
+        }
+      } else {
+        status = EP0_LL_STALL;
+      }
+    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_handle_reset ();
+  
+  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);
+  
+  HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_TXVC, 0);
+  
+  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/packages/devs/usb/at91/v2_0/src/usbs_at91_data.cxx b/packages/devs/usb/at91/v2_0/src/usbs_at91_data.cxx
new file mode 100644 (file)
index 0000000..6c0da3c
--- /dev/null
@@ -0,0 +1,183 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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)
+
+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
diff --git a/packages/devs/usb/d12/v2_0/ChangeLog b/packages/devs/usb/d12/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..7d98fec
--- /dev/null
@@ -0,0 +1,35 @@
+2006-06-06  Frank Pagliughi <fpagliughi@mindspring.com>
+
+       * First version of the USB device driver for the philips D12
+       
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/usb/d12/v2_0/cdl/usbs_d12.cdl b/packages/devs/usb/d12/v2_0/cdl/usbs_d12.cdl
new file mode 100644 (file)
index 0000000..6628289
--- /dev/null
@@ -0,0 +1,317 @@
+# ====================================================================
+#
+#       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 eCosCentric Limited
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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/packages/devs/usb/d12/v2_0/include/usbs_d12.h b/packages/devs/usb/d12/v2_0/include/usbs_d12.h
new file mode 100644 (file)
index 0000000..e66e55b
--- /dev/null
@@ -0,0 +1,73 @@
+#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 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/usb/d12/v2_0/src/usbs_d12.c b/packages/devs/usb/d12/v2_0/src/usbs_d12.c
new file mode 100644 (file)
index 0000000..955f196
--- /dev/null
@@ -0,0 +1,2322 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/usb/d12/v2_0/src/usbs_d12_data.cxx b/packages/devs/usb/d12/v2_0/src/usbs_d12_data.cxx
new file mode 100644 (file)
index 0000000..391e3cb
--- /dev/null
@@ -0,0 +1,230 @@
+//==========================================================================
+//
+//      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 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/usb/i386/SoRoD12/v2_0/ChangeLog b/packages/devs/usb/i386/SoRoD12/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..e5bd83a
--- /dev/null
@@ -0,0 +1,36 @@
+2006-06-06  Frank Pagliughi <fpagliughi@mindspring.com>
+
+       * First version of the USB device driver using the philips D12
+       for i386 targets.
+       
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/usb/i386/SoRoD12/v2_0/cdl/usbs_i386_sorod12.cdl b/packages/devs/usb/i386/SoRoD12/v2_0/cdl/usbs_i386_sorod12.cdl
new file mode 100644 (file)
index 0000000..6fdff51
--- /dev/null
@@ -0,0 +1,91 @@
+# ====================================================================
+#
+#   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 eCosCentric Limited
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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/packages/devs/usb/i386/SoRoD12/v2_0/include/usbs_i386_sorod12.inl b/packages/devs/usb/i386/SoRoD12/v2_0/include/usbs_i386_sorod12.inl
new file mode 100644 (file)
index 0000000..dd8e93d
--- /dev/null
@@ -0,0 +1,128 @@
+#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, eCosCentric
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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/packages/devs/wallclock/arm/lpc2xxx/v2_0/ChangeLog b/packages/devs/wallclock/arm/lpc2xxx/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..ed005d1
--- /dev/null
@@ -0,0 +1,37 @@
+2007-07-12  Hans Rosenfeld  <rosenfeld@grumpf.hope-2000.org>
+
+       * lpc2xxx: driver for on-chip RTC unit
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+
+
diff --git a/packages/devs/wallclock/arm/lpc2xxx/v2_0/cdl/lpc2xxx_wallclock.cdl b/packages/devs/wallclock/arm/lpc2xxx/v2_0/cdl/lpc2xxx_wallclock.cdl
new file mode 100644 (file)
index 0000000..ff7dfba
--- /dev/null
@@ -0,0 +1,86 @@
+# ====================================================================
+#
+#      lpc2xxx_wallclock.cdl
+#
+#      eCos configuration data for LPC2xxx internal RTC
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Gary Thomas
+## Copyright (C) 2004 eCosCentric Ltd
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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
+# Date:           2007-06-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_ARM_LPC2XXX {
+    display       "LPC2xxx Real-time clock"
+    description   "RTC driver for the LPC2xxx controller"
+
+    parent        CYGPKG_IO_WALLCLOCK
+    active_if     CYGPKG_IO_WALLCLOCK
+    active_if     CYGPKG_HAL_ARM_LPC2XXX
+
+    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
+    }
+
+    cdl_option CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT {
+        display    "RTC prescaler integer portion"
+        flavor     data
+        calculated { ((CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 
+                       CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) / 32768) - 1 }
+    }
+
+    cdl_option CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREFRAC {
+        display    "RTC prescaler fractional portion"
+        flavor     data
+        calculated { ((CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 
+                       CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) -
+                      ((CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT + 1) * 32768)) }
+    }
+}
diff --git a/packages/devs/wallclock/arm/lpc2xxx/v2_0/src/lpc2xxx_wallclock.cxx b/packages/devs/wallclock/arm/lpc2xxx/v2_0/src/lpc2xxx_wallclock.cxx
new file mode 100644 (file)
index 0000000..fee9747
--- /dev/null
@@ -0,0 +1,161 @@
+//==========================================================================
+//
+//      lpc2xxx_wallclock.cxx
+//
+//      Wallclock implementation for LPC2xxx
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+// Copyright (C) 2004 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-06-19
+// Purpose:       Wallclock driver for LPC2xxx
+//
+//####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>
+
+/*
+ * 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;
+  volatile cyg_uint32 preint;
+  volatile cyg_uint32 prefrac;
+};
+
+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 */
+  rtc->preint  = CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT;
+  rtc->prefrac = CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREFRAC;
+  
+#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
diff --git a/packages/devs/watchdog/arm/at91wdtc/v2_0/ChangeLog b/packages/devs/watchdog/arm/at91wdtc/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..9b8a505
--- /dev/null
@@ -0,0 +1,39 @@
+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. 
+
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
diff --git a/packages/devs/watchdog/arm/at91wdtc/v2_0/cdl/watchdog_at91wdtc.cdl b/packages/devs/watchdog/arm/at91wdtc/v2_0/cdl/watchdog_at91wdtc.cdl
new file mode 100644 (file)
index 0000000..d5edb7f
--- /dev/null
@@ -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 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2006 Andrew Lunn (andrew.lunn@ascom.ch>
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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"
+        calculated    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/packages/devs/watchdog/arm/at91wdtc/v2_0/src/watchdog_at91wdtc.cxx b/packages/devs/watchdog/arm/at91wdtc/v2_0/src/watchdog_at91wdtc.cxx
new file mode 100644 (file)
index 0000000..21cf62d
--- /dev/null
@@ -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 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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_DRIVERS)
+  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/packages/fs/ram/v2_0/tests/ramfs3.c b/packages/fs/ram/v2_0/tests/ramfs3.c
new file mode 100644 (file)
index 0000000..ca8a6ef
--- /dev/null
@@ -0,0 +1,185 @@
+//==========================================================================
+//
+//      ramfs3.c
+//
+//      Test fileio system, especially lseek calls.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           nickg, asl, Paluch Sebastian
+// Contributors:        nickg
+// Date:                2006-10-05
+// Purpose:             Test fileio system
+// Description:         This test uses the testfs to check out the initialization
+//                      and basic operation of the fileio system
+//                      
+//                      
+//                      
+//                      
+//                      
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include <cyg/fileio/fileio.h>
+
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>            // HAL polled output
+//==========================================================================
+
+#define SHOW_RESULT( _fn, _res ) \
+diag_printf("FAIL: " #_fn "() returned %ld %s\n", \
+           (unsigned long)_res, _res<0?strerror(errno):"");
+
+//==========================================================================
+
+cyg_uint8 buf[256];
+cyg_uint8 buf1[256];
+
+//==========================================================================
+// main
+
+int main( int argc, char **argv )
+{
+    int err;
+    FILE *stream;
+    long pos;
+    unsigned int i;
+    char header[3];
+
+    CYG_TEST_INIT();
+
+    // --------------------------------------------------------------
+
+    CYG_TEST_INFO("mount /");    
+    err = mount( "", "/", "ramfs" );
+
+    if( err < 0 ) SHOW_RESULT( mount, err );    
+    
+    CYG_TEST_INFO("creating /fseek");
+    stream = fopen("/fseek","w+");
+    if (!stream) {
+      SHOW_RESULT( fopen, NULL);
+      CYG_TEST_FAIL_FINISH("done");\
+    }
+
+    for (i = 0; i < sizeof(buf); i++) {
+      buf[i] = i % 256;
+    }
+    
+    CYG_TEST_INFO("writing test pattern");    
+    err=fwrite(buf,sizeof(buf), 1, stream);
+    if ( err < 0 ) SHOW_RESULT( fwrite, err );
+    
+    pos = ftell(stream);
+    if (pos < 0) SHOW_RESULT( ftell, pos );
+    if (pos != sizeof(buf))
+      diag_printf("<FAIL>: ftell is not telling the truth.");
+    
+    CYG_TEST_INFO("fseek()ing to 85");
+    err = fseek(stream, 85, SEEK_SET);
+    if ( err < 0 ) SHOW_RESULT( fseek, err );
+
+    pos = ftell(stream);
+    if (pos < 0) SHOW_RESULT( ftell, pos );
+    if (pos != 85) CYG_TEST_FAIL("ftell is not telling the truth");
+
+    err = fread(header,3,1,stream);
+    if ( err < 0 ) SHOW_RESULT( fwrite, err );
+    if ((header[0] != 85) ||
+        (header[1] != 86) ||
+        (header[2] != 87))
+      CYG_TEST_FAIL("Read returned false data");
+    
+    pos = ftell(stream);
+    if (pos < 0) SHOW_RESULT( ftell, pos );
+    if (pos != 88)  CYG_TEST_FAIL("ftell is not telling the truth");
+
+    for (i = 88; i < 161; i++) {
+      buf[i] = 0x42;
+    }
+    
+    CYG_TEST_INFO("writing");
+    err = fwrite(buf+88, 73, 1, stream);
+    if ( err < 0 ) SHOW_RESULT( fwrite, err );
+
+    pos = ftell(stream);
+    if (pos < 0) SHOW_RESULT( ftell, pos );
+    if (pos != 161)  CYG_TEST_FAIL("ftell is not telling the truth");
+
+    CYG_TEST_INFO("closing file");
+    err = fclose(stream);
+    if (err != 0) SHOW_RESULT( fclose, err );
+
+    CYG_TEST_INFO("open file /fseek");
+    stream = fopen("/fseek", "r+");
+    if (!stream) {
+      SHOW_RESULT( fopen, NULL);
+      CYG_TEST_FAIL_FINISH("done");\
+    }
+
+    CYG_TEST_INFO("Seeking to beginning of file");
+    err = fseek(stream, 0, SEEK_SET);
+    if ( err < 0 ) SHOW_RESULT( fseek, err );
+
+    CYG_TEST_INFO("Reading buf1");
+    err = fread(buf1,sizeof(buf1),1, stream);
+    if (err != 1) SHOW_RESULT( fread, err );
+
+    CYG_TEST_INFO("Comparing contents");
+    if (memcmp(buf, buf1, sizeof(buf1))) 
+      CYG_TEST_FAIL("File contents inconsistent");
+
+    CYG_TEST_INFO("closing file");
+    err = fclose(stream);
+    if (err != 0) SHOW_RESULT( fclose, err );
+    
+    CYG_TEST_INFO("umount /");    
+    err = umount( "/" );
+    if( err < 0 ) SHOW_RESULT( umount, err );    
+    
+    CYG_TEST_PASS_FINISH("ramfs3");
+}
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/ChangeLog b/packages/hal/arm/at91/at91sam7s/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..e210a34
--- /dev/null
@@ -0,0 +1,160 @@
+2008-05-11  James G. Smith <jsmith@rallysmith.co.uk
+            Andrew Lunn  <andrew@lunn.ch>
+
+       * cdl/hal_arm_at91sam7s.cdl: CDL for crystal vs clock signal.
+       * include/hal_platform_setup.h: Rework flash wait states to remove
+       redundant code when running at > 60MHz. Support clock signal input
+       when starting the main clock.
+
+2008-04-30  John Eigelaar  <jeigelaar@mweb.co.za>
+
+       * include/pkgconf/mlt_arm_at91sam7x512_rom.{h|ldi}: Added the 
+       memory layout files to support the at91sam7x512  
+       * cdl/hal_arm_at91s.cdl: Added the configuration options to 
+       support the at91sam7x512
+       
+2008-04-23  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * include/hal_platform_setup.h: Fix setting the flash wait states
+       when the clock is running faster than 60MHz. r0 was undefined 
+       causing a data abort.
+       
+2007-03-26  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * cdl/hal_arm_at91sam7s.cdl: SAM7X and SAM7XC have a CAN bus
+       controller.
+
+2007-01-17  John Eigelaar <jeigelaar@mweb.co.za>
+
+       * include/plf_io.h
+       * src/at91sam7s_misc.c
+       Added code to initialise the platform ethernet hardware if need be
+        
+2007-01-02  Uwe Kindler <uwe_kindler@web.de>
+
+       * cdl/hal_arm_at91sam7s.cdl Moved HAL_PLATFORM_XXX defines and
+       definition of platform header file (CYGBLD_HAL_PLATFORM_H) from
+       package CYGPKG_HAL_ARM_AT91SAM7 into board specific packages.
+       
+2006-06-01  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * cdl/hal_arm_at91sam7s.cdl: Implement the SPI bus 1 interface for
+       the SAM7X and SAM7XC.
+
+2006-06-01  John Eigelaar <jeigelaar@mweb.co.za>
+
+       * include/plf_io.h: Add SPI DMA registers.
+
+2006-05-20  John Eigelaar <jeigelaar@mweb.co.za>
+
+       include/pkgconf/mlt_arm_at91sam7x128_rom.{h|ldi}
+       include/pkgconf/mlt_arm_at91sam7x256_rom.{h|ldi}: Linker files
+       for AT91SAM7X processor.
+       
+2006-05-17  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * src/at91sam7s_misc.c: Use the AT91 generic PIO manipulation
+       macros. Move the LED function out into the board specific HAL
+       package.
+
+2006-04-07  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * cdl/hal_arm_at91sam7s.cdl: 
+       * include/pkgconf/mlt_arm_at91sam7s32_rom.ldi: 
+       * include/pkgconf/mlt_arm_at91sam7s64_rom.ldi: 
+       * include/pkgconf/mlt_arm_at91sam7s128_rom.ldi: 
+       * include/pkgconf/mlt_arm_at91sam7s267_rom.ldi: 
+       Allow CDL to control where in flash the image is placed.
+
+2006-03-23  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * cdl/hal_arm_at91sam7s.cdl: Implement the USB interface when chip
+       has the device.
+       
+2006-03-10  Oliver Munz  <oli@snr.ch>
+
+       * hal_arm_at91sam7s.cdl: Change the PLL-defaults so that 96MHz is
+       generated so that the USB does work.
+       
+2006-03-10  Andrew Lunn  <andrew.lunn@ascom.ch>
+            Oliver Munz  <munz@speag.ch>
+       
+       * cdl/hal_arm_at91sam7s.cdl: Set the debug UART as the default
+       channel and fix some dodge spelling.
+       * src/at91sam7s_misc.c (hal_plf_hardware_init): Enable the Debug UART
+       pins for output and control by the device.
+       * include/plf_io.h: Define USART2 to be the debug UART.
+       
+2006-03-01  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * cdl/hal_arm_at91sam7s.cdl: Change the crystal frequency.  The
+       numbers printed on top of the crystal are misleading. It has a
+       18.432MHz crystal, not 20MHz. This error when combined with the
+       previous fix to the PLL made the serial baud rate wrong.  Change
+       the multiplier and divisor to achieve about the same CPU clock,
+       which should be USB compatible.
+       * src/at91sam7s_misc.c (hal_at91_us_baud): Need the same PLL fix
+       when calculating the baud rate dynamically.
+       * include/plf_io.h: Add the Programmable Clock Output registers.
+       
+2006-02-28  Oliver Munz <munz@speag.ch>
+
+       * include/hal_platform_setup.h: Fix the PLL multiplier settings
+       
+2006-02-25  Andrew Lunn <andrew.lunn@ascom.ch>
+
+       * misc/redboot_R[AO]M.ecm: Disable FIS and fconfig, enable
+       loading directly into flash with the load command.
+       
+2006-01-01  Oliver Munz <munz@speag.ch>
+           Andrew Lunn <andrew.lunn@ascom.ch>
+
+       * cdl/hal_arm_at91sam7s.cdl:
+       * include/hal_platform_ints.h:
+       * include/hal_platform_setup.h:
+       * include/plf_io.h:
+       * include/pkgconf/mlt_arm_at91sam7s256_rom.h:
+       * include/pkgconf/mlt_arm_at91sam7s256_rom.ldi:
+       * include/pkgconf/mlt_arm_at91sam7s128_rom.h:
+       * include/pkgconf/mlt_arm_at91sam7s128_rom.ldi:
+       * include/pkgconf/mlt_arm_at91sam7s64_rom.h:
+       * include/pkgconf/mlt_arm_at91sam7s64_rom.ldi:
+       * include/pkgconf/mlt_arm_at91sam7s32_rom.h:
+       * include/pkgconf/mlt_arm_at91sam7s32_rom.ldi:
+       * src/at91sam7s_misc.c:
+       * misc/redboot_ROM.ecm:
+       * misc/redboot_RAM.ecm:
+       * ChangeLog: First import of a hal for the AT91SAM7S family.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/cdl/hal_arm_at91sam7s.cdl b/packages/hal/arm/at91/at91sam7s/v2_0/cdl/hal_arm_at91sam7s.cdl
new file mode 100644 (file)
index 0000000..6a46d1b
--- /dev/null
@@ -0,0 +1,465 @@
+# ====================================================================
+#
+#      hal_arm_at91_sam7s.cdl
+#
+#      ARM AT91 SAM7 HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2005 eCosCentric Ltd
+## Copyright (C) 2005 Andrew Lunn
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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, nickg, Oliver Munz, asl
+# Date:           2005-06-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_AT91SAM7 {
+    display       "Atmel AT91SAM7 HAL"
+    parent        CYGPKG_HAL_ARM
+    define_header hal_arm_at91sam7.h
+    include_dir   cyg/hal
+    hardware
+    description   "
+        The AT91SAM7 HAL package provides the support needed to run
+        eCos on an Atmel AT91SAM7 based board."
+
+    compile       at91sam7s_misc.c
+    
+    requires      { CYGHWR_HAL_ARM_AT91_FIQ     }
+    requires      { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s32" implies
+                    CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0 == 0 }
+
+    implements    CYGINT_HAL_ARM_AT91_SERIAL_DBG_HW
+    implements    CYGINT_HAL_ARM_AT91_PIT_HW
+    implements    CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
+
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_arm.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H  <pkgconf/hal_arm_at91.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_IO_H"
+    }
+
+    cdl_option CYGHWR_HAL_ARM_AT91SAM7 {
+        display        "AT91SAM7 variant used"
+        flavor         data
+        default_value  {"at91sam7s256"}
+        legal_values   {"at91sam7s32" "at91sam7s321" "at91sam7s64" 
+                        "at91sam7s128" "at91sam7s256" 
+                        "at91sam7x128" "at91sam7x256" "at91sam7x512" 
+                        "at91sam7xc128" "at91sam7xc256" }
+        description    "
+           The AT91SAM7 microcontroller family has several variants,
+           the main differences being the amount of on-chip SRAM,
+           FLASH, peripherals and their layout. This option allows the
+           platform HALs to select the specific microcontroller
+           being used."
+    }
+
+    cdl_option CYGHWR_HAL_ARM_AT91SAM7S {
+        display     "SAM7S device" 
+        calculated  { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s256" ||
+                      CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s128" ||        
+                      CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s64"  ||        
+                      CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s32"  ||
+                      CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s321" }
+        description "
+            Is the AT91SAM7 device a member of the AT91SAM7S family?"
+    }
+
+    cdl_option CYGHWR_HAL_ARM_AT91SAM7X {
+        display     "SAM7X device" 
+        calculated  { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x512" ||
+                     CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x256" ||
+                      CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x128" }        
+        description "
+            Is the AT91SAM7 device a member of the AT91SAM7X family?"
+    }
+
+    cdl_option CYGHWR_HAL_ARM_AT91SAM7XC {
+        display     "SAM7XC device" 
+        calculated  { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7xc256" ||
+                      CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7xc128" }        
+        description "
+            Is the AT91SAM7 device a member of the AT91SAM7XC family?"
+    }
+
+    cdl_option CYGBLD_HAL_ARM_AT91SAM7_USB {
+        display       "USB device"
+        active_if     {!( "at91sam7s32" == CYGHWR_HAL_ARM_AT91SAM7S) ||
+                        CYGHWR_HAL_ARM_AT91SAM7X                     ||
+                        CYGHWR_HAL_ARM_AT91SAM7XC }
+        implements    CYGINT_DEVS_USB_AT91_HAS_USB
+        default_value 1
+        no_define
+        description   "
+            All but the AT91SAM7S32 has the USB device"
+    }
+
+    cdl_option CYGBLD_HAL_ARM_AT91SAM7_SPI1 {
+        display       "Second SPI bus controller"
+        active_if     { CYGHWR_HAL_ARM_AT91SAM7X ||
+                        CYGHWR_HAL_ARM_AT91SAM7XC }
+        implements    CYGINT_DEVS_SPI_ARM_AT91_HAS_BUS1
+        default_value 1
+        no_define
+        description   "
+            The SAM7X and SAM7XC have the second SPI bus controller"
+    }
+
+    cdl_option CYGBLD_HAL_ARM_AT91SAM7_CAN0 {
+        display       "CAN bus controller"
+        active_if     { CYGHWR_HAL_ARM_AT91SAM7X ||
+                        CYGHWR_HAL_ARM_AT91SAM7XC }
+        implements    CYGINT_DEVS_CAN_AT91SAM7_CAN0
+        default_value 1
+        no_define
+        description   "
+            The SAM7X and SAM7XC have the CAN controller"
+    }
+
+    cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+        display       "Real-time clock constants"
+        flavor        none
+
+        cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+            display       "Real-time clock numerator"
+            flavor        data
+            default_value 1000000000
+        }
+        cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+            display       "Real-time clock denominator"
+            flavor        data
+            default_value 100
+        }
+        cdl_option CYGNUM_HAL_RTC_PERIOD {
+            display       "Real-time clock period"
+            flavor        data
+            legal_values  1 to 0xffff 
+            calculated    ((CYGNUM_HAL_RTC_NUMERATOR * CYGNUM_HAL_ARM_AT91_CLOCK_SPEED/16) / CYGNUM_HAL_RTC_DENOMINATOR / 1000000000)
+            description   "
+                CYGNUM_HAL_RTC_PERIOD : (CYGNUM_HAL_RTC_NUMERATOR * CYGNUM_HAL_ARM_AT91_CLOCK_SPEED/16) / CYGNUM_HAL_RTC_DENOMINATOR / 1000000000 "
+        }
+    }
+    
+    cdl_component CYG_HAL_STARTUP {
+        display       "Startup type"
+        flavor        data
+        default_value {"ROM"}
+        legal_values  {"RAM" "ROM"}
+        no_define
+        define -file system.h CYG_HAL_STARTUP
+        description   "
+            When targeting the AT91SAM7 eval boards it is possible to build
+            the system for either RAM bootstrap or ROM bootstrap(s). Select
+            'ram' when building programs to load into RAM using on board
+            debug software such as Angel or eCos GDB stubs.  Select 'rom'
+            when building a stand-alone application which will be put
+            into ROM"
+    }
+
+    cdl_option CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS {
+        display       "Address in flash the image should live"
+        active_if     { CYG_HAL_STARTUP == "ROM" }
+        flavor        data        
+        default_value 0x00100000
+        description   "
+            This optionspecifies where in flash the image
+            lives. By default it is at the bottom of the flash,
+            but for example redboot may be at the bottom and an
+            application lives higher up, which is acheived by 
+            setting the address here."
+    }
+
+    # Real-time clock/counter specifics
+    cdl_option CYGNUM_HAL_ARM_AT91_CLOCK_SPEED {
+        display       "CPU clock speed"
+        flavor        data
+        calculated    { CYGNUM_HAL_ARM_AT91_CLOCK_OSC_MAIN *
+                        CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER /
+                        CYGNUM_HAL_ARM_AT91_PLL_DIVIDER / 2}
+        legal_values  { 0 to 220000000 }
+        description   "
+            The master clock-frequency has to be 48MHz, 96MHz or
+            192MHz for the USB to work correctly. The clock setup uses
+            PLL clock divided by two"
+    }
+
+    cdl_option CYGNUM_HAL_ARM_AT91_CLOCK_OSC_MAIN {
+        display       "Main oscillator frequency"
+        flavor        data
+        legal_values  { 3000000 to 20000000} 
+        default_value { 18432000 }
+        description   "
+            The frequency of the clock input, be it a crystal or a clock 
+            signal"
+    }
+
+    cdl_option CYGNUM_HAL_ARM_AT91_CLOCK_TYPE {
+        display       "Type of main frequency input"
+        flavor        data
+        default_value { "CRYSTAL" }
+        legal_values  { "CRYSTAL" "EXTCLOCK" } 
+        description   "
+            Whether a crystal or a XIN input clock is clocking the device."
+    }
+
+    cdl_option CYGNUM_HAL_ARM_AT91_PLL_DIVIDER {
+        display       "Divider for PLL clock"
+        flavor        data
+        legal_values  { 0 to 255 }
+        default_value 24
+        description   "
+            The X-tal clock is divided by this value when generating the
+            PLL clock"
+    }       
+        
+    cdl_option CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER {
+        display       "Multiplier for PLL clock"
+        flavor        data
+        legal_values  { 0 to 2047 }
+        default_value 125
+        description   "
+           The X-tal clock is multiplied by this value when generating
+           the PLL clock."
+    }
+
+    cdl_option CYGNUM_HAL_ARM_AT91_SLOW_CLOCK {
+        display       "Slow clock frequency"
+        flavor        data
+        default_value { 32768 }
+        description   "
+            The slow clock is an LC oscillator which runs all the
+            time. The accuracy of this clock is not very high and 
+            is temperature dependent."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+        display       "Number of communication channels on the board"
+        flavor        data
+        default_value 3
+        description   "
+            The AT91SAM7S development boards has two Serial port connectors.
+            these correspond to USART0 and the Debug Serial port. The chip
+            has a third serial port which does not have a 9pin D
+            connector, but is accessible via the patch panel pins."
+    }
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+        display          "Debug serial port"
+        active_if        CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+        flavor data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    2
+        description      "
+            The AT91SAM7S has three serial ports. This option
+            chooses which port will be used to connect to a host
+            running GDB."
+     }
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+         display          "Diagnostic serial port"
+         active_if        CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+         flavor data
+         legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+         default_value    2
+         description      "
+            The AT91SAM7S board has three USART serial ports. This option
+            chooses which port will be used for diagnostic output."
+     }
+     
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+        display       "Diagnostic serial port baud rate"
+        flavor        data
+        legal_values  9600 19200 38400 57600 115200
+        default_value 38400
+        description   "
+            This option selects the baud rate used for the diagnostic port."
+    }
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+         display       "GDB serial port baud rate"
+         flavor        data
+         legal_values  9600 19200 38400 57600 115200
+         default_value 38400
+         description   "
+            This option controls the baud rate used for the GDB connection."
+     }
+    cdl_option CYGBLD_HAL_ARM_AT91_BAUD_DYNAMIC {
+        display       "Dynamic calculation of baud rate"
+        default_value 0
+        description   "
+             The AT91SAM7S has a flexible clock generation mechanism 
+             where the main clock used to drive peripherals can be
+             changed during run time. Such changes affect the serial port
+             baud rate generators. Enabling this option includes code 
+             which calculates the baud rate setting dynamically from the
+             current clock settings. Without this option a static
+             calculation is performed which assumes the clock frequency
+             has not been changed."
+    }
+
+    cdl_option CYGSEM_HAL_ROM_MONITOR {
+        display       "Behave as a ROM monitor"
+        flavor        bool
+        default_value 0
+        parent        CYGPKG_HAL_ROM_MONITOR
+        requires      { CYG_HAL_STARTUP == "ROM" } 
+        description   "
+            Enable this option if this program is to be used as a ROM monitor,
+            i.e. applications will be loaded into RAM on the board, and this
+            ROM monitor may process exceptions or interrupts generated from the
+            application. This enables features such as utilizing a separate
+            interrupt stack when exceptions are generated."
+    }
+
+    cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+         display       "Work with a ROM monitor"
+         flavor        booldata
+         legal_values  { "Generic" "GDB_stubs" }
+         default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+         parent        CYGPKG_HAL_ROM_MONITOR
+         requires      { CYG_HAL_STARTUP == "RAM" }
+         description   "
+             Support can be enabled for different varieties of ROM monitor.
+             This support changes various eCos semantics such as the encoding
+             of diagnostic output, or the overriding of hardware interrupt
+             vectors.
+             Firstly there is \"Generic\" support which prevents the HAL
+             from overriding the hardware vectors that it does not use, to
+             instead allow an installed ROM monitor to handle them. This is
+             the most basic support which is likely to be common to most
+             implementations of ROM monitor.
+             \"GDB_stubs\" provides support when GDB stubs are included in
+             the ROM monitor or boot ROM."
+    }
+
+    cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+        display       "Redboot HAL options"
+        flavor        none
+        no_define
+        parent        CYGPKG_REDBOOT
+        active_if     CYGPKG_REDBOOT
+        description   "
+            This option lists the target's requirements for a valid Redboot
+            configuration."
+
+        cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+            display       "Build Redboot ROM binary image"
+            active_if     CYGBLD_BUILD_REDBOOT
+            default_value 1
+            no_define
+            description "This option enables the conversion of the Redboot ELF
+                         image to a binary image suitable for ROM programming."
+    
+            make -priority 325 {
+                <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+                $(OBJCOPY) --strip-debug $< $(@:.bin=.img) 
+                $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+                $(OBJCOPY) -O binary $< $@
+            }
+        }
+    }
+
+    cdl_component CYGBLD_GLOBAL_OPTIONS {
+        display "Global build options"
+        flavor  none
+        parent  CYGPKG_NONE
+        description   "
+            Global build options including control over
+            compiler flags, linker flags and choice of toolchain."
+
+        cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+            display "Global command prefix"
+            flavor  data
+            no_define
+            default_value { "arm-elf" }
+            description "
+                This option specifies the command prefix used when
+                invoking the build tools."
+        }
+
+        cdl_option CYGBLD_GLOBAL_CFLAGS {
+            display "Global compiler flags"
+            flavor  data
+            no_define
+            default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+            description   "
+                This option controls the global compiler flags which are used to
+                compile all packages by default. Individual packages may define
+                options which override these global flags."
+        }
+
+        cdl_option CYGBLD_GLOBAL_LDFLAGS {
+            display "Global linker flags"
+            flavor  data
+            no_define
+            default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -Wl,--gc-sections -Wl,-static -g -nostdlib" }
+            description   "
+                This option controls the global linker flags. Individual
+                packages may define options which override these global flags."
+        }
+    }
+
+    cdl_component CYGHWR_MEMORY_LAYOUT {
+        display "Memory layout"
+        flavor data
+        no_define
+        calculated { (CYG_HAL_STARTUP == "RAM") ? \
+                     "arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_ram" :
+                     "arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_rom" }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+            display "Memory layout linker script fragment"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+            calculated { (CYG_HAL_STARTUP == "RAM") ? \
+                 "<pkgconf/mlt_arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_ram.ldi>" :
+                 "<pkgconf/mlt_arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_rom.ldi>" }
+        }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_H {
+            display "Memory layout header file"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_H
+            calculated { (CYG_HAL_STARTUP == "RAM") ? \
+                 "<pkgconf/mlt_arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_ram.h>" :
+                 "<pkgconf/mlt_arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_rom.h>" }
+        }
+    }
+}
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/hal_platform_ints.h b/packages/hal/arm/at91/at91sam7s/v2_0/include/hal_platform_ints.h
new file mode 100644 (file)
index 0000000..e16fb13
--- /dev/null
@@ -0,0 +1,123 @@
+#ifndef CYGONCE_HAL_PLATFORM_INTS_H
+#define CYGONCE_HAL_PLATFORM_INTS_H
+//==========================================================================
+//
+//      hal_platform_ints.h
+//
+//      HAL Interrupt and clock assignments for AT91SAM7
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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, Oliver Munz, Andrew Lunn, John Eigelaar
+// Date:         2001-07-12
+// Purpose:      Define Interrupt support
+// Description:  The interrupt specifics for the AT91SAM7 platform are
+//               defined here.
+//              
+// Usage:        #include <cyg/hal/hal_platform_ints.h>
+//               ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal_arm_at91sam7.h>
+
+#define CYGNUM_HAL_INTERRUPT_FIQ               0
+
+#define CYGNUM_HAL_INTERRUPT_SYS               1
+#define CYGNUM_HAL_INTERRUPT_PIOA              2
+
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+#define CYGNUM_HAL_INTERRUPT_PIOB              3
+#define CYGNUM_HAL_INTERRUPT_SPI               4
+#define CYGNUM_HAL_INTERRUPT_SPI1              5
+#endif
+#ifdef CYGHWR_HAL_ARM_AT91SAM7S
+#define CYGNUM_HAL_INTERRUPT_ADC               4
+#define CYGNUM_HAL_INTERRUPT_SPI               5
+#endif
+
+#define CYGNUM_HAL_INTERRUPT_USART0            6
+#define CYGNUM_HAL_INTERRUPT_USART1            7
+#define CYGNUM_HAL_INTERRUPT_SSC               8
+#define CYGNUM_HAL_INTERRUPT_TWI               9
+#define CYGNUM_HAL_INTERRUPT_PWMC              10
+#define CYGNUM_HAL_INTERRUPT_UDP               11
+#define CYGNUM_HAL_INTERRUPT_TC0               12
+#define CYGNUM_HAL_INTERRUPT_TC1               13
+#define CYGNUM_HAL_INTERRUPT_TC2               14
+
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+#define CYGNUM_HAL_INTERRUPT_CAN               15
+#define CYGNUM_HAL_INTERRUPT_EMAC              16
+#define CYGNUM_HAL_INTERRUPT_ADC               17
+#endif
+
+#define CYGNUM_HAL_INTERRUPT_IRQ0              30
+#define CYGNUM_HAL_INTERRUPT_IRQ1              31
+
+// Interrupts which are multiplexed on to the System Interrupt
+#define CYGNUM_HAL_INTERRUPT_PITC               32
+#define CYGNUM_HAL_INTERRUPT_RTTC               33
+#define CYGNUM_HAL_INTERRUPT_PMC                34
+#define CYGNUM_HAL_INTERRUPT_MC                 35
+#define CYGNUM_HAL_INTERRUPT_WDTC               36
+#define CYGNUM_HAL_INTERRUPT_RSTC               37
+#define CYGNUM_HAL_INTERRUPT_DBG                38
+
+#define CYGNUM_HAL_ISR_MIN                      0
+#define CYGNUM_HAL_ISR_MAX                     38
+
+#define CYGNUM_HAL_ISR_COUNT                   (CYGNUM_HAL_ISR_MAX + 1)
+
+// The vector used by the Real time clock
+#ifdef CYGBLD_HAL_ARM_AT91_TIMER_TC
+#define CYGNUM_HAL_INTERRUPT_RTC               CYGNUM_HAL_INTERRUPT_TC0
+#endif
+#ifdef CYGBLD_HAL_ARM_AT91_TIMER_PIT
+#define CYGNUM_HAL_INTERRUPT_RTC               CYGNUM_HAL_INTERRUPT_PITC
+#endif
+
+//----------------------------------------------------------------------------
+// Reset.
+__externC void hal_at91_reset_cpu(void);
+#define HAL_PLATFORM_RESET() hal_at91_reset_cpu()
+
+#define HAL_PLATFORM_RESET_ENTRY 0x0000000
+
+#endif // CYGONCE_HAL_PLATFORM_INTS_H
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/hal_platform_setup.h b/packages/hal/arm/at91/at91sam7s/v2_0/include/hal_platform_setup.h
new file mode 100644 (file)
index 0000000..9ca7751
--- /dev/null
@@ -0,0 +1,155 @@
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+
+/*=============================================================================
+//
+//      hal_platform_setup.h
+//
+//      Platform specific support for HAL
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+// Copy
+
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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, asl
+// Date:        2006-02-18
+// Purpose:     AT91SAM7S platform specific support routines
+// Description: 
+// Usage:       #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <cyg/hal/var_io.h>
+#include <cyg/hal/plf_io.h>
+        
+// Macro to initialise the Memory Controller
+        .macro _flash_init
+__flash_init__:
+        ldr     r0,=AT91_MC
+#if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 60000000
+        // When the clock is running faster than 60MHz we need two wait states
+        ldr     r1,=(AT91_MC_FMR_2FWS)
+#else 
+# if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 30000000
+        // When the clock is running faster than 30MHz we need a wait state
+        ldr     r1,=(AT91_MC_FMR_1FWS)
+# else
+        // We have a slow clock, no extra wait states are needed
+        ldr     r1,=AT91_MC_FMR_0FWS
+# endif
+#endif
+        str     r1,[r0,#AT91_MC_FMR]
+        .endm
+
+// Macro to start the main clock.
+        .macro  _main_clock_init
+__main_clock_init__:
+        ldr     r0,=AT91_PMC
+          // Swap to the slow clock, just to be sure.
+        ldr     r1,=(AT91_PMC_MCKR_PRES_CLK|AT91_PMC_MCKR_SLOW_CLK)
+        str     r1,[r0,#AT91_PMC_MCKR]
+       // startup time
+#if defined(CYGNUM_HAL_ARM_AT91_CLOCK_TYPE_EXTCLOCK)
+        ldr     r1,=(AT91_PMC_MOR_OSCBYPASS)
+#else
+        ldr     r1,=(AT91_PMC_MOR_OSCCOUNT(6)|AT91_PMC_MOR_MOSCEN)
+#endif
+        str     r1,[r0,#AT91_PMC_MOR]
+
+        // Wait for oscilator start timeout
+wait_pmc_sr_1:  
+        ldr     r1,[r0,#AT91_PMC_SR]
+        ands    r1,r1,#AT91_PMC_SR_MOSCS
+        beq     wait_pmc_sr_1
+
+        // Set the PLL multiplier and divider. 16 slow clocks go by
+       // before the LOCK bit is set. */
+        ldr     r1,=((AT91_PMC_PLLR_DIV(CYGNUM_HAL_ARM_AT91_PLL_DIVIDER))|(AT91_PMC_PLLR_PLLCOUNT(16))|(AT91_PMC_PLLR_MUL(CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER-1)))
+        str     r1,[r0,#AT91_PMC_PLLR]
+
+        // Wait for PLL locked indication
+wait_pmc_sr_2:
+        ldr     r1,[r0,#AT91_PMC_SR]
+        ands    r1,r1,#AT91_PMC_SR_LOCK
+        beq     wait_pmc_sr_2
+
+        // Enable the PLL clock and set the prescale to 2 */
+        ldr     r1,=(AT91_PMC_MCKR_PRES_CLK_2|AT91_PMC_MCKR_PLL_CLK)
+        str     r1,[r0,#AT91_PMC_MCKR]
+
+        // Wait for the MCLK ready indication
+wait_pmc_sr_3:
+        ldr     r1,[r0,#AT91_PMC_SR]
+        ands    r1,r1,#AT91_PMC_SR_MCKRDY
+        beq     wait_pmc_sr_3
+        .endm
+
+// Remap the flash from address 0x0 and place RAM there instead.
+        .macro  _remap_flash
+__remap_flash:
+        ldr     r0,=0x000004 // Use the underfined instruction exception
+        ldr     r1,=0x200004
+        ldr     r2,[r0]      // Save away copies so we can restore them
+        ldr     r3,[r1]
+        ldr     r4,=0xffffff
+        eor     r4,r3,r4     // XOR the contents of 0x20004 
+        str     r4,[r1]      // and write it
+        ldr     r5,[r0]      // Read from low memory
+        cmp     r5,r4
+        beq     remap_done
+        ldr     r0,=AT91_MC  // Need to do a remap
+        ldr     r5,=1
+        str     r5,[r0,#AT91_MC_RCR]
+remap_done:
+        str     r3,[r1]      // restore the value we changed
+        .endm
+        
+#if defined(CYG_HAL_STARTUP_ROM)
+        .macro  _setup
+        _flash_init
+        _main_clock_init
+        _remap_flash
+        .endm
+
+#define PLATFORM_SETUP1     _setup
+#else
+#define PLATFORM_SETUP1
+#endif
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s128_rom.h b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s128_rom.h
new file mode 100644 (file)
index 0000000..54893cd
--- /dev/null
@@ -0,0 +1,25 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x08000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x20000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00204000 - (size_t) CYG_LABEL_NAME (__heap1))
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s128_rom.ldi b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s128_rom.ldi
new file mode 100644 (file)
index 0000000..788ffce
--- /dev/null
@@ -0,0 +1,30 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+    ram : ORIGIN = 0x00200000, LENGTH = 0x08000
+    rom : ORIGIN = 0x00100000, LENGTH = 0x20000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+    SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+    SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s256_rom.h b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s256_rom.h
new file mode 100644 (file)
index 0000000..9d43fb6
--- /dev/null
@@ -0,0 +1,25 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x10000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x40000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00210000 - (size_t) CYG_LABEL_NAME (__heap1))
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s256_rom.ldi b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s256_rom.ldi
new file mode 100644 (file)
index 0000000..84c790c
--- /dev/null
@@ -0,0 +1,30 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+    ram : ORIGIN = 0x00200000, LENGTH = 0x10000
+    rom : ORIGIN = 0x00100000, LENGTH = 0x40000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+    SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+    SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s32_rom.h b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s32_rom.h
new file mode 100644 (file)
index 0000000..61ffc48
--- /dev/null
@@ -0,0 +1,25 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x02000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x08000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00202000 - (size_t) CYG_LABEL_NAME (__heap1))
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s32_rom.ldi b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s32_rom.ldi
new file mode 100644 (file)
index 0000000..4724f59
--- /dev/null
@@ -0,0 +1,30 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+    ram : ORIGIN = 0x00200000, LENGTH = 0x02000
+    rom : ORIGIN = 0x00100000, LENGTH = 0x08000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+    SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+    SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s64_rom.h b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s64_rom.h
new file mode 100644 (file)
index 0000000..9e3d25c
--- /dev/null
@@ -0,0 +1,25 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x04000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x10000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00204000 - (size_t) CYG_LABEL_NAME (__heap1))
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s64_rom.ldi b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7s64_rom.ldi
new file mode 100644 (file)
index 0000000..ab34564
--- /dev/null
@@ -0,0 +1,30 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+    ram : ORIGIN = 0x00200000, LENGTH = 0x04000
+    rom : ORIGIN = 0x00100000, LENGTH = 0x10000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+    SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+    SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x128_rom.h b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x128_rom.h
new file mode 100644 (file)
index 0000000..54893cd
--- /dev/null
@@ -0,0 +1,25 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x08000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x20000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00204000 - (size_t) CYG_LABEL_NAME (__heap1))
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x128_rom.ldi b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x128_rom.ldi
new file mode 100644 (file)
index 0000000..788ffce
--- /dev/null
@@ -0,0 +1,30 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+    ram : ORIGIN = 0x00200000, LENGTH = 0x08000
+    rom : ORIGIN = 0x00100000, LENGTH = 0x20000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+    SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+    SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x256_rom.h b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x256_rom.h
new file mode 100644 (file)
index 0000000..9d43fb6
--- /dev/null
@@ -0,0 +1,25 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x10000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x40000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00210000 - (size_t) CYG_LABEL_NAME (__heap1))
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x256_rom.ldi b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x256_rom.ldi
new file mode 100644 (file)
index 0000000..84c790c
--- /dev/null
@@ -0,0 +1,30 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+    ram : ORIGIN = 0x00200000, LENGTH = 0x10000
+    rom : ORIGIN = 0x00100000, LENGTH = 0x40000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+    SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+    SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x512_rom.h b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x512_rom.h
new file mode 100644 (file)
index 0000000..8ef949e
--- /dev/null
@@ -0,0 +1,25 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x20000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x80000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00220000 - (size_t) CYG_LABEL_NAME (__heap1))
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x512_rom.ldi b/packages/hal/arm/at91/at91sam7s/v2_0/include/pkgconf/mlt_arm_at91sam7x512_rom.ldi
new file mode 100644 (file)
index 0000000..2ac2c00
--- /dev/null
@@ -0,0 +1,30 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+    ram : ORIGIN = 0x00200000, LENGTH = 0x20000
+    rom : ORIGIN = 0x00100000, LENGTH = 0x80000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+    SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+    SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/include/plf_io.h b/packages/hal/arm/at91/at91sam7s/v2_0/include/plf_io.h
new file mode 100644 (file)
index 0000000..48f3c07
--- /dev/null
@@ -0,0 +1,205 @@
+#ifndef CYGONCE_HAL_PLF_IO_H
+#define CYGONCE_HAL_PLF_IO_H
+//=============================================================================
+//
+//      plf_io.h
+//
+//      AT91SAM7S board specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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: andrew lunn, Oliver Munz
+// Date:        2005-12-31
+// Purpose:     Atmel AT91SAM7S board specific registers
+// Description: 
+// Usage:       #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+#include <pkgconf/hal_arm_at91sam7.h>
+
+#define CYGARC_PHYSICAL_ADDRESS(_x_)
+
+//SPI - Serial Peripheral Interface
+#define AT91_SPI0   0xFFFE0000
+
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+#define AT91_SPI1   0xFFFE4000
+#endif
+
+#define AT91_SPI AT91_SPI0
+
+//Extra SPI control bits
+#define AT91_SPI_MR_MODFDIS (1<<4)
+
+// DMA registers 
+#define AT91_SPI_RPR  0x100 // Receive Pointer Register
+#define AT91_SPI_RCR  0x104 // Receive Counter Register
+#define AT91_SPI_TPR  0x108 // Transmit Pointer Register
+#define AT91_SPI_TCR  0x10C // Transmit Counter Register
+#define AT91_SPI_NRPR 0x110 // Next Receive Pointer Register
+#define AT91_SPI_NRCR 0x114 // Next Receive Counter Register
+#define AT91_SPI_NTPR 0x118 // Next Transmit Pointer Register
+#define AT91_SPI_NTCR 0x11C // Next Trsnsmit Counter Register
+#define AT91_SPI_PTCR 0x120 // PDC Transfer Control Register
+#define AT91_SPI_PTSR 0x124 // PDC Transfer Status Register
+
+// Peripheral Input/Output Controllers
+#define AT91_PIOA   0xFFFFF400
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+#define AT91_PIOB   0xFFFFF600
+#endif
+
+#define AT91_WSTC   0xFFFFFD40
+
+// USART
+
+#define AT91_USART0 0xFFFC0000
+#define AT91_USART1 0xFFFC4000
+
+// Define USART2 to be the debug UART. It is similar enough to a USART
+// that both the hal_diag and interrupt driven driver will work.
+// However trying to change parity, start/stop bits etc will not work.
+#define CYGNUM_HAL_INTERRUPT_USART2 CYGNUM_HAL_INTERRUPT_DBG 
+#define AT91_USART2 AT91_DBG 
+
+#ifndef __ASSEMBLER__
+#ifdef CYGBLD_HAL_ARM_AT91_BAUD_DYNAMIC
+extern cyg_uint32 hal_at91_us_baud(cyg_uint32 baud);
+#define AT91_US_BAUD(baud) hal_at91_us_baud(baud)
+#endif
+#endif // __ASSEMBLER__
+
+#define AT91_US_RPR  0x100 // Receive Pointer Register
+#define AT91_US_RCR  0x104 // Receive Counter Register
+#define AT91_US_TPR  0x108 // Transmit Pointer Register
+#define AT91_US_TCR  0x10C // Transmit Counter Register
+#define AT91_US_NRPR 0x110 // Next Receive Pointer Register
+#define AT91_US_NRCR 0x114 // Next Receive Counter Register
+#define AT91_US_NTPR 0x118 // Next Transmit Pointer Register 
+#define AT91_US_NTCR 0x11C // Next Trsnsmit Counter Register
+#define AT91_US_PTCR 0x120 // PDC Transfer Control Register
+#define AT91_US_PTSR 0x124 // PDC Transfer Status Register
+
+// PIO - Programmable I/O
+
+#define AT91_PIO    AT91_PIOA
+
+// AIC - Advanced Interrupt Controller
+
+#define AT91_AIC    0xFFFFF000
+
+// TC - Timer Counter
+
+#define AT91_TC     0xFFFA0000
+
+// Power Management Controller
+
+#define AT91_PMC    0xFFFFFC00
+
+#define AT91_PMC_MOR  0x20 // Main Oscillator Register
+#define AT91_PMC_MOR_MOSCEN    (1 << 0) // Main Oscillator Enable
+#define AT91_PMC_MOR_OSCBYPASS (1 << 1) // Main Oscillator Bypass
+#define AT91_PMC_MOR_OSCCOUNT(x) (x << 8) // Slow clocks ticks
+#define AT91_PMC_MCFR 0x24 // Main Clock Frequency Register
+#define AT91_PMC_PLLR 0x2c // PLL Register
+#define AT91_PMC_PLLR_DIV(x)      ((x) <<  0)  // PLL Devide
+#define AT91_PMC_PLLR_PLLCOUNT(x) ((x) <<  8)  // PLL Count
+#define AT91_PMC_PLLR_MUL(x)      ((x) << 16)  // PLL Devide
+#define AT91_PMC_PLLR_OUT_0 (0 << 14)
+#define AT91_PMC_PLLR_OUT_1 (1 << 14)
+#define AT91_PMC_PLLR_OUT_2 (2 << 14)
+#define AT91_PMC_PLLR_OUT_3 (3 << 14)
+#define AT91_PMC_PLLR_USBDIV_0 (0 << 28) // USB clock is PLL clock / 1
+#define AT91_PMC_PLLR_USBDIV_1 (1 << 28) // USB clock is PLL clock / 2
+#define AT91_PMC_PLLR_USBDIV_2 (2 << 28) // USB clock is PLL clock / 4
+#define AT91_PMC_MCKR 0x30 // Master Clock Register
+#define AT91_PMC_MCKR_SLOW_CLK (0 << 0) // Slow clock selected
+#define AT91_PMC_MCKR_MAIN_CLK (1 << 0) // Main clock selected
+#define AT91_PMC_MCKR_PLL_CLK  (3 << 0) // PLL clock selected
+#define AT91_PMC_MCKR_PRES_CLK    (0 << 2) // divide by 1
+#define AT91_PMC_MCKR_PRES_CLK_2  (1 << 2) // divide by 2
+#define AT91_PMC_MCKR_PRES_CLK_4  (2 << 2) // divide by 4
+#define AT91_PMC_MCKR_PRES_CLK_8  (3 << 2) // divide by 8
+#define AT91_PMC_MCKR_PRES_CLK_16 (4 << 2) // divide by 16
+#define AT91_PMC_MCKR_PRES_CLK_32 (5 << 2) // divide by 32
+#define AT91_PMC_MCKR_PRES_CLK_64 (6 << 2) // divide by 64
+#define AT91_PMC_PCKR0 0x40  // Programmable Clock Register 0
+#define AT91_PMC_PCKR1 0x44  // Programmable Clock Register 1
+#define AT91_PMC_PCKR2 0x48  // Programmable Clock Register 2
+#define AT91_PMC_IER  0x60 // Interrupt Enable Register
+#define AT91_PMC_IDR  0x64 // Interrupt Disable Register
+#define AT91_PMC_SR   0x68 // Status Register
+#define AT91_PMC_SR_MOSCS   (1 << 0) // Main oscillator stable
+#define AT91_PMC_SR_LOCK    (1 << 2) // PLL Locked
+#define AT91_PMC_SR_MCKRDY  (1 << 3) // MCK is ready to be enabled
+#define AT91_PMC_SR_PCK0RDY (1 << 8) // Pad clock 0 is ready to be enabled
+#define AT91_PMC_SR_PCK1RDY (1 << 9) // Pad clock 1 is ready to be enabled
+#define AT91_PMC_SR_PCK2RDY (1 << 10) // Pad clock 2 is ready to be enabled
+#define AT91_PMC_SR_PCK3RDY (1 << 11) // Pad clock 3 is ready to be enabled
+#define AT91_PMC_IMR  0x6c // Interrupt Mask Register
+
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+
+// EMAC - Ethernet Medium Access Controller
+
+#define AT91_EMAC 0xFFFDC000
+
+// CAN - Controller Area Network
+
+#define AT91_CAN 0xFFFD0000 
+
+#endif
+
+//----------------------------------------------------------------------
+// The platform needs this initialization during the
+// hal_hardware_init() function in the varient HAL.
+#ifndef __ASSEMBLER__
+extern void hal_plf_hardware_init(void);
+#define HAL_PLF_HARDWARE_INIT() \
+    hal_plf_hardware_init()
+
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+extern void hal_plf_eth_init(void);
+#define HAL_PLF_ETH_INIT() \
+    hal_plf_eth_init()
+#endif          
+
+#endif  //__ASSEMBLER__         
+
+
+#endif //CYGONCE_HAL_PLF_IO_H
+
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/misc/redboot_RAM.ecm b/packages/hal/arm/at91/at91sam7s/v2_0/misc/redboot_RAM.ecm
new file mode 100644 (file)
index 0000000..b7f956e
--- /dev/null
@@ -0,0 +1,82 @@
+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    at91sam7s ;
+    template    redboot ;
+    package -hardware CYGPKG_HAL_ARM current ;
+    package -hardware CYGPKG_HAL_ARM_AT91 current ;
+    package -hardware CYGPKG_DEVS_FLASH_AT91 current ;
+    package -template CYGPKG_HAL current ;
+    package -template CYGPKG_INFRA current ;
+    package -template CYGPKG_REDBOOT current ;
+    package CYGPKG_IO_FLASH current ;
+};
+
+cdl_option CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE {
+    user_value 6144
+};
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+    user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+    inferred_value 0
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+    inferred_value 1
+};
+
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+    inferred_value 0 0
+};
+
+cdl_component CYGBLD_BUILD_REDBOOT {
+    user_value 1
+};
+
+cdl_option CYGOPT_REDBOOT_FIS {
+    user_value 0
+};
+
+cdl_component CYGSEM_REDBOOT_FLASH_CONFIG {
+    user_value 0
+};
+
+cdl_option CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG {
+    user_value 0
+};
+
+cdl_option CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK {
+    user_value -16
+};
+
+
+cdl_option CYGBLD_BUILD_REDBOOT_WITH_EXEC {
+    user_value 0
+};
+
+cdl_option CYGBLD_DEV_FLASH_AT91_LOCKING {
+    user_value 0
+};
+
+cdl_option CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK {
+    user_value -24
+};
+
+cdl_option CYGBLD_REDBOOT_MIN_IMAGE_SIZE {
+    user_value 0x15000
+};
+
+cdl_option CYGBLD_REDBOOT_LOAD_INTO_FLASH {
+    user_value 1
+};
\ No newline at end of file
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/misc/redboot_ROM.ecm b/packages/hal/arm/at91/at91sam7s/v2_0/misc/redboot_ROM.ecm
new file mode 100644 (file)
index 0000000..e18ee4b
--- /dev/null
@@ -0,0 +1,90 @@
+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    at91sam7s ;
+    template    redboot ;
+    package -hardware CYGPKG_HAL_ARM current ;
+    package -hardware CYGPKG_HAL_ARM_AT91 current ;
+    package -hardware CYGPKG_DEVS_FLASH_AT91 current ;
+    package -template CYGPKG_HAL current ;
+    package -template CYGPKG_INFRA current ;
+    package -template CYGPKG_REDBOOT current ;
+    package CYGPKG_IO_FLASH current ;
+};
+
+cdl_option CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE {
+    user_value 6144
+};
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+    user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+    inferred_value 0
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+    inferred_value 1
+};
+
+cdl_option CYGSEM_HAL_ROM_MONITOR {
+    inferred_value 1
+};
+
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+    inferred_value 0 0
+};
+
+cdl_component CYG_HAL_STARTUP {
+    user_value ROM
+};
+
+cdl_component CYGBLD_BUILD_REDBOOT {
+    user_value 1
+};
+
+cdl_option CYGOPT_REDBOOT_FIS {
+    user_value 0
+};
+
+cdl_component CYGSEM_REDBOOT_FLASH_CONFIG {
+    user_value 0
+};
+
+cdl_option CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG {
+    user_value 0
+};
+
+cdl_option CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK {
+    user_value -16
+};
+
+
+cdl_option CYGBLD_BUILD_REDBOOT_WITH_EXEC {
+    user_value 0
+};
+
+cdl_option CYGBLD_DEV_FLASH_AT91_LOCKING {
+    user_value 0
+};
+
+cdl_option CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK {
+    user_value -24
+};
+
+cdl_option CYGBLD_REDBOOT_MIN_IMAGE_SIZE {
+    user_value 0x15000
+};
+
+cdl_option CYGBLD_REDBOOT_LOAD_INTO_FLASH {
+    user_value 1
+};
\ No newline at end of file
diff --git a/packages/hal/arm/at91/at91sam7s/v2_0/src/at91sam7s_misc.c b/packages/hal/arm/at91/at91sam7s/v2_0/src/at91sam7s_misc.c
new file mode 100644 (file)
index 0000000..89596f3
--- /dev/null
@@ -0,0 +1,177 @@
+/*==========================================================================
+//
+//      at91sam7s_misc.c
+//
+//      HAL misc board support code for Atmel AT91sam7s
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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, nickg, tkoeller, Oliver Munz, Andrew Lunn
+// Date:         2001-07-12
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_trac.h>         // tracing macros
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#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>           // necessary?
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h>             // calling interface
+#include <cyg/hal/hal_misc.h>           // helper functions
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+#include <cyg/hal/drv_api.h>            // HAL ISR support
+#endif
+
+extern void hal_at91_led(int val);
+
+void
+hal_at91_set_leds (int val)
+{
+    hal_at91_led(val);
+}
+
+// -------------------------------------------------------------------------
+// Hardware init
+
+void hal_plf_hardware_init (void) 
+{
+  /* Enable the Serial devices to driver the serial port pins */
+  HAL_ARM_AT91_PIO_CFG(AT91_USART_RXD0);
+  HAL_ARM_AT91_PIO_CFG(AT91_USART_TXD0);
+  HAL_ARM_AT91_PIO_CFG(AT91_DBG_DTXD);
+  HAL_ARM_AT91_PIO_CFG(AT91_DBG_DRXD);
+
+#if !defined(CYGHWR_HAL_ARM_AT91SAM7S_at91sam7s32)
+  /* Enable the Serial devices to driver the serial port pins */
+  HAL_ARM_AT91_PIO_CFG(AT91_USART_RXD1);
+  HAL_ARM_AT91_PIO_CFG(AT91_USART_TXD1);
+#endif
+
+  /* Setup the Reset controller. Allow user resets */
+  HAL_WRITE_UINT32(AT91_RST+AT91_RST_RMR, 
+                   AT91_RST_RMR_URSTEN | 
+                   10 << 8 | 
+                   AT91_RST_RMR_KEY);
+
+#ifdef CYGBLD_HAL_ARM_AT91_SERIAL_UART
+  /* Enable peripheral clocks for USART 0 and 1 if they are to be used */
+  HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, 
+                   AT91_PMC_PCER_US0 |
+                   AT91_PMC_PCER_US1);
+#endif
+
+#ifdef CYGBLD_HAL_ARM_AT91_TIMER_TC
+  /* Enable peripheral clocks for TC 0 and 1 if they are to be used */
+  HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, 
+                   AT91_PMC_PCER_TC0 |
+                   AT91_PMC_PCER_TC2); 
+#endif
+
+#ifndef CYGPKG_IO_WATCHDOG
+  /* Disable the watchdog. The eCos philosophy is that the watchdog is
+     disabled unless the watchdog driver is used to enable it.
+     Whoever if we disable it here we cannot re-enable it in the
+     watchdog driver, hence the conditional compilation. */
+  HAL_WRITE_UINT32(AT91_WDTC + AT91_WDTC_WDMR, AT91_WDTC_WDMR_DIS); 
+#endif
+
+/* Perform some platform specific bits to get the Ethernet hardware
+   setup. Specifically if a specific phy is used and does not start in
+   the correct mode a function needs to be supplied as part of the plf
+   to do the necessary initializations.
+*/
+#ifdef CYGPKG_DEVS_ETH_ARM_AT91
+#ifdef HAL_PLF_ETH_INIT
+       HAL_PLF_ETH_INIT();
+#endif
+#endif
+}
+
+// Calculate the baud value to be programmed into the serial port baud
+// rate generators. This function will determine what the clock speed
+// is that is driving the generator so it can be used in situations
+// when the application dynamically changes the clock speed. 
+cyg_uint32 
+hal_at91_us_baud(cyg_uint32 baud_rate)
+{
+  cyg_uint32 val, pll;
+  cyg_uint32 main_clock = 0;
+  cyg_uint32 baud_value = 0;
+
+  HAL_READ_UINT32((AT91_PMC+AT91_PMC_MCKR), val);
+  switch (val & 0x03) {
+    /* Slow clock */
+    case AT91_PMC_MCKR_SLOW_CLK:
+      main_clock = CYGNUM_HAL_ARM_AT91_SLOW_CLOCK;
+      break;
+      
+      /* Main clock */
+    case AT91_PMC_MCKR_MAIN_CLK:
+      main_clock = CYGNUM_HAL_ARM_AT91_CLOCK_OSC_MAIN;
+      break;
+      /* PLL */
+    case AT91_PMC_MCKR_PLL_CLK:
+      HAL_READ_UINT32((AT91_PMC+AT91_PMC_PLLR), pll);
+      main_clock = CYGNUM_HAL_ARM_AT91_CLOCK_OSC_MAIN * 
+        (((pll & 0x7FF0000) >> 16) + 1) / (pll & 0xFF);
+      break;
+  }
+  
+  // Process prescale
+  val = (val & 0x1C) >> 2;
+  main_clock = main_clock >> val;
+
+  /* Define the baud rate divisor register, (round) */
+  baud_value = (main_clock/(8*baud_rate)+1)/2;
+  
+  return baud_value;
+}
+
+//--------------------------------------------------------------------------
+// EOF at91sam7s_misc.c
diff --git a/packages/hal/arm/at91/at91sam7sek/v2_0/ChangeLog b/packages/hal/arm/at91/at91sam7sek/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..174ab05
--- /dev/null
@@ -0,0 +1,47 @@
+2007-10-16  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * src/at91sam7sek_misc.c (hal_at91_led): Fix off by one error on
+       GPIO lines for LEDs. Reported by Rasmus Stougaard
+       <rasmus.stougaard@gmail.com>
+
+2007-01-02  Uwe Kindler <uwe_kindler@web.de>
+
+       * cdl/hal_arm_at91sam7s.cdl Moved HAL_PLATFORM_XXX defines and
+       definition of platform header file (CYGBLD_HAL_PLATFORM_H) from
+       package CYGPKG_HAL_ARM_AT91SAM7 into board specific packages.
+       
+2006-05-20  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * AT91SAM7X-EK development board package
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/arm/at91/at91sam7sek/v2_0/cdl/hal_arm_at91sam7sek.cdl b/packages/hal/arm/at91/at91sam7sek/v2_0/cdl/hal_arm_at91sam7sek.cdl
new file mode 100644 (file)
index 0000000..3e1469c
--- /dev/null
@@ -0,0 +1,74 @@
+# ====================================================================
+#
+#      hal_arm_at91_sam7sek.cdl
+#
+#      ARM AT91 SAM7S EK development board package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 2006 Andrew Lunn
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_AT91SAM7SEK {
+    display       "Atmel AT91SAM7S EK development board"
+    parent        CYGPKG_HAL_ARM_AT91SAM7
+    define_header hal_arm_at91sam7sek.h
+    include_dir   cyg/hal
+    hardware
+    description   "
+        The AT91SAM7SEK HAL package provides the support needed to run
+        eCos on an Atmel AT91SAM7S-EK development board."
+
+    compile       at91sam7sek_misc.c
+    
+    requires      { CYGHWR_HAL_ARM_AT91 == "AT91SAM7S" }
+    requires      { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s256" ||
+                    CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s128" ||
+                    CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s64"  ||
+                    CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s32"  ||
+                    CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s321" }
+    
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_at91sam7sek.h>"
+        puts $::cdl_header "/***** proc output start *****/"
+        puts $::cdl_header "#include <pkgconf/hal_arm_at91sam7.h>"
+        puts $::cdl_header "#define HAL_PLATFORM_CPU    \"ARM7TDMI\""
+        puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"Atmel (AT91SAM7S-EK)\""
+        puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+        puts $::cdl_header "/****** proc output end ******/"
+    }
+}
diff --git a/packages/hal/arm/at91/at91sam7sek/v2_0/src/at91sam7sek_misc.c b/packages/hal/arm/at91/at91sam7sek/v2_0/src/at91sam7sek_misc.c
new file mode 100644 (file)
index 0000000..dcd42a0
--- /dev/null
@@ -0,0 +1,77 @@
+/*==========================================================================
+//
+//      at91sam7sek_misc.c
+//
+//      HAL misc board support code for Atmel AT91sam7s EK board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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: Oliver Munz, Andrew Lunn
+// Date:         2006-06-20
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_io.h>             // IO macros
+
+// The development board has four LEDs
+void 
+hal_at91_led (int val)
+{
+  HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PA0, AT91_PIN_OUT);
+  HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PA1, AT91_PIN_OUT);
+  HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PA2, AT91_PIN_OUT);
+  HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PA3, AT91_PIN_OUT);
+  
+  HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PA0, AT91_PIN_PULLUP_DISABLE);
+  HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PA1, AT91_PIN_PULLUP_DISABLE);
+  HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PA2, AT91_PIN_PULLUP_DISABLE);
+  HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PA3, AT91_PIN_PULLUP_DISABLE);
+
+  // Set the bits. The logic is inverted 
+  HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PA0, !(val & 1));
+  HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PA1, !(val & 2));
+  HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PA2, !(val & 4));
+  HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PA3, !(val & 8));
+}
+
+//--------------------------------------------------------------------------
+// EOF at91sam7sek_misc.c
diff --git a/packages/hal/arm/at91/at91sam7xek/v2_0/ChangeLog b/packages/hal/arm/at91/at91sam7xek/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..4bc1e01
--- /dev/null
@@ -0,0 +1,54 @@
+2008-04-30  John Eigelaar <jeigelaar@mweb.co.za>
+
+        * cdl/hal_arm_at91sam7xek.cdl: Added configuration options in 
+       order to support the at91sam7x512
+       * src/at91sam7xek_misc.c: Fix a typo in the phy initialisation code.
+       Pin 18 was being setup to drive the powerdown pin of the phy but 
+       pin 19 was driven low instead.
+
+2007-01-17  John Eigelaar <jeigelaar@mweb.co.za>
+
+        * Added hal_plf_eth_init() in order to initialise the Davicom
+         9161A PHY properly on the Evaluation board
+         
+2007-01-02  Uwe Kindler <uwe_kindler@web.de>
+
+       * cdl/hal_arm_at91sam7s.cdl Moved HAL_PLATFORM_XXX defines and
+       definition of platform header file (CYGBLD_HAL_PLATFORM_H) from
+       package CYGPKG_HAL_ARM_AT91SAM7 into board specific packages.
+       
+2006-05-20  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * AT91SAM7X-EK development board package
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/arm/at91/at91sam7xek/v2_0/cdl/hal_arm_at91sam7xek.cdl b/packages/hal/arm/at91/at91sam7xek/v2_0/cdl/hal_arm_at91sam7xek.cdl
new file mode 100644 (file)
index 0000000..d25f167
--- /dev/null
@@ -0,0 +1,75 @@
+# ====================================================================
+#
+#      hal_arm_at91_sam7xek.cdl
+#
+#      ARM AT91 SAM7X EK development board package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 2006 Andrew Lunn
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_AT91SAM7XEK {
+    display       "Atmel AT91SAM7X EK development board"
+    parent        CYGPKG_HAL_ARM_AT91SAM7
+    define_header hal_arm_at91sam7xek.h
+    include_dir   cyg/hal
+    hardware
+    description   "
+        The AT91SAM7XEK HAL package provides the support needed to run
+        eCos on an Atmel AT91SAM7X-EK development board."
+
+    compile       at91sam7xek_misc.c
+    
+    requires      { CYGHWR_HAL_ARM_AT91 == "AT91SAM7S" }
+    requires      { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x256"  || 
+                    CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x128" ||
+                    CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x512" }
+                   
+    requires      { is_active(CYGPKG_DEVS_ETH_PHY) implies
+                    (1 == CYGHWR_DEVS_ETH_PHY_DM9161A) }
+                                           
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_at91sam7xek.h>"
+        puts $::cdl_header "/***** proc output start *****/"
+        puts $::cdl_header "#include <pkgconf/hal_arm_at91sam7.h>"
+        puts $::cdl_header "#define HAL_PLATFORM_CPU    \"ARM7TDMI\""
+        puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"Atmel (AT91SAM7X-EK)\""
+        puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+        puts $::cdl_header "/****** proc output end ******/"
+    }
+}
diff --git a/packages/hal/arm/at91/at91sam7xek/v2_0/src/at91sam7xek_misc.c b/packages/hal/arm/at91/at91sam7xek/v2_0/src/at91sam7xek_misc.c
new file mode 100644 (file)
index 0000000..ba5b276
--- /dev/null
@@ -0,0 +1,113 @@
+/*==========================================================================
+//
+//      at91sam7xek_misc.c
+//
+//      HAL misc board support code for Atmel AT91SAM7X EK board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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, John Eigelaar
+// Date:         2006-06-20
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_io.h>             // IO macros
+
+// The development board has four LEDs
+void 
+hal_at91_led (int val)
+{
+  HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB19, AT91_PIN_OUT);
+  HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB20, AT91_PIN_OUT);
+  HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB21, AT91_PIN_OUT);
+  HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB22, AT91_PIN_OUT);
+  
+  HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB19, AT91_PIN_PULLUP_DISABLE);
+  HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB20, AT91_PIN_PULLUP_DISABLE);
+  HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB21, AT91_PIN_PULLUP_DISABLE);
+  HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB22, AT91_PIN_PULLUP_DISABLE);
+
+  // Set the bits. The logic is inverted 
+  HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB19, !(val & 1));
+  HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB20, !(val & 2));
+  HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB21, !(val & 4));
+  HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB22, !(val & 8));
+}
+
+void hal_plf_eth_init(void)
+{
+   cyg_uint32 stat;
+
+   /* Enable the PIOB Clock */
+   HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_PIOB);
+  
+   /* RXDV / Testmode select */
+   HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB15, AT91_PIN_IN);
+   HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB15, AT91_PIN_PULLUP_DISABLE);
+
+   //TODO: The errata reports that the RMII mode for the SAM7X does not work.
+   //      It would probably still be a good idea to use the RMII/MII CDL 
+   //      configuration to select the appropriate mode here
+   /* COL / !MII select */
+   HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB16, AT91_PIN_IN);
+   HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB16, AT91_PIN_PULLUP_DISABLE);
+
+   /* TXCLK / ISOLATE */
+   HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB0, AT91_PIN_IN);
+   HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB0, AT91_PIN_PULLUP_DISABLE);
+
+   /* Power Down Mode */
+   HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB18, AT91_PIN_OUT);
+   HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB18,0);
+
+   /* All the lines setup correctly. Now do a external reset and let the phy 
+      start up in the correct mode */
+   HAL_WRITE_UINT32(AT91_RST+AT91_RST_RMR,AT91_RST_RMR_KEY|(1<<0x8));
+   HAL_WRITE_UINT32(AT91_RST+AT91_RST_RCR,AT91_RST_RCR_KEY|AT91_RST_RCR_EXTRST);
+
+   do {
+     HAL_READ_UINT32(AT91_RST+AT91_RST_RSR,stat);
+   } while (!(stat&AT91_RST_RSR_NRST_SET));
+}
+
+//--------------------------------------------------------------------------
+// EOF at91sam7sek_misc.c
diff --git a/packages/hal/arm/at91/sam7ex256/v2_0/ChangeLog b/packages/hal/arm/at91/sam7ex256/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..77cf90f
--- /dev/null
@@ -0,0 +1,50 @@
+2007-04-10  Uwe Kindler  <uwe_kindler@web.de>
+
+       * cdl/hal_arm_sam7ex256.cdl Removed "implements 
+         CYGINT_DEVS_CAN_AT91SAM7_CAN0" because this interface is already
+         implemented by package CYGPKG_HAL_ARM_AT91SAM7
+         
+2007-04-06  Uwe Kindler  <uwe_kindler@web.de>
+
+       * src/sam7ex256_misc.c Added hal_plf_eth_init() in order to initialise 
+         the Micrel KS8721 PHY properly on the Olimex board
+
+2007-08-01  Uwe Kindler  <uwe_kindler@web.de>
+
+       * src/sam7ex256_misc.c Use the backlight of the lcd as a simple 1-bit LED
+
+2006-12-30  Uwe Kindler  <uwe_kindler@web.de>
+
+       * SAM7-EX256 development board package
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/arm/at91/sam7ex256/v2_0/cdl/hal_arm_sam7ex256.cdl b/packages/hal/arm/at91/sam7ex256/v2_0/cdl/hal_arm_sam7ex256.cdl
new file mode 100644 (file)
index 0000000..4717f55
--- /dev/null
@@ -0,0 +1,74 @@
+# ====================================================================
+#
+#      hal_arm_sam7ex256.cdl
+#
+#      Olimex SAM7-EX256 development board package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 2006 Andrew Lunn
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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:           2006-12-30
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_SAM7EX256 {
+    display       "Olimex SAM7-EX256 development board"
+    parent        CYGPKG_HAL_ARM_AT91SAM7
+    define_header hal_arm_sam7ex256.h
+    include_dir   cyg/hal
+    hardware
+    description   "
+        The SAM7EX256 HAL package provides the support needed to run
+        eCos on an Olimex SAM7-EX256 development board."
+
+    compile       sam7ex256_misc.c
+    
+    requires      { CYGHWR_HAL_ARM_AT91 == "AT91SAM7S" }
+    requires      { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x256" }
+    
+    requires      { is_active(CYGPKG_DEVS_ETH_PHY) implies
+                    (1 == CYGHWR_DEVS_ETH_PHY_KS8721) }
+
+    
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_sam7ex256.h>"
+        puts $::cdl_header "/***** proc output start *****/"
+        puts $::cdl_header "#include <pkgconf/hal_arm_at91sam7.h>"
+        puts $::cdl_header "#define HAL_PLATFORM_CPU    \"ARM7TDMI\""
+        puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"Olimex SAM7-EX256\""
+        puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+        puts $::cdl_header "/****** proc output end ******/"
+    }
+}
diff --git a/packages/hal/arm/at91/sam7ex256/v2_0/src/sam7ex256_misc.c b/packages/hal/arm/at91/sam7ex256/v2_0/src/sam7ex256_misc.c
new file mode 100644 (file)
index 0000000..27f8889
--- /dev/null
@@ -0,0 +1,111 @@
+/*==========================================================================
+//
+//      sam7ex256_misc.c
+//
+//      HAL misc board support code for Olimex SAM7-EX256 board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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: Andrew Lunn, John Eigelaar
+// Date:         2006-12-30
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_io.h>             // IO macros
+
+//
+// The development board does not contain any leds but a nokia 320 x 320 
+// pixel lcd. We use the backlight of the lcd as a simple 1-bit LED
+//
+void hal_at91_led (int val)
+{
+    HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB20, AT91_PIN_OUT);
+    HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB20, (val & 1));
+}
+
+//
+// Initialisation of Micrel KS8721 ethernet phy
+//
+void hal_plf_eth_init(void)
+{
+   cyg_uint32 stat;
+
+   // Enable the PIOB Clock
+   HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_PIOB);
+    
+   // PU = Enables PCS_LPBK mode at power-up / reset.
+   HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB15, AT91_PIN_IN);
+   HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB15, AT91_PIN_PULLUP_DISABLE);
+   
+   // PU = Enables ISOLATE mode at power-up /reset.
+   HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB7, AT91_PIN_IN);
+   HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB7, AT91_PIN_PULLUP_DISABLE);
+   
+   // PU = Enables RMII mode at power-up / reset
+   // TODO: The errata reports that the RMII mode for the SAM7X does not work.
+   //      It would probably still be a good idea to use the RMII/MII CDL 
+   //      configuration to select the appropriate mode here
+   HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB16, AT91_PIN_IN);
+   HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB16, AT91_PIN_PULLUP_DISABLE);
+   
+   // PU = Enable RMII_BTB mode at power-up / reset.
+   HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB4, AT91_PIN_IN);
+   HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB4, AT91_PIN_PULLUP_DISABLE);
+
+   // Power Down Mode = 1 = normal operation
+   HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB18, AT91_PIN_OUT);
+   HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB18, 1);
+
+   // All the lines setup correctly. Now do a external reset and let the phy 
+   // start up in the correct mode
+   HAL_WRITE_UINT32(AT91_RST+AT91_RST_RMR,AT91_RST_RMR_KEY|(1<<0x8));
+   HAL_WRITE_UINT32(AT91_RST+AT91_RST_RCR,AT91_RST_RCR_KEY|AT91_RST_RCR_EXTRST);
+
+   do 
+   {
+     HAL_READ_UINT32(AT91_RST+AT91_RST_RSR,stat);
+   } while (!(stat & AT91_RST_RSR_NRST_SET));
+}
+
+
+//--------------------------------------------------------------------------
+// EOF sam7ex256_misc.c
diff --git a/packages/hal/arm/at91/var/v2_0/src/hal_diag_dbg.c b/packages/hal/arm/at91/var/v2_0/src/hal_diag_dbg.c
new file mode 100644 (file)
index 0000000..831a5f6
--- /dev/null
@@ -0,0 +1,348 @@
+/*=============================================================================
+//
+//      hal_diag_dbg.c
+//
+//      HAL diagnostic output code using the debug serial port
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-07-12
+// Purpose:     HAL diagnostic output
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_at91.h>
+
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/infra/cyg_type.h>         // base types
+
+#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_if.h>             // interface API
+#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h>           // Helper functions
+#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/hal/var_io.h>             // Device registers
+
+#include "hal_diag_dcc.h"               // DCC initialization file
+//-----------------------------------------------------------------------------
+typedef struct {
+    cyg_uint8* base;
+    cyg_int32 msec_timeout;
+    int isr_vector;
+    cyg_uint32 baud_rate;
+} channel_data_t;
+
+//-----------------------------------------------------------------------------
+
+static void
+cyg_hal_plf_serial_dbg_init_channel(void* __ch_data)
+{
+    cyg_uint8 *base = ((channel_data_t*)__ch_data)->base;
+
+    cyg_uint32 baud_value = 0;
+    cyg_uint32 baud_rate  = ((channel_data_t*)__ch_data)->baud_rate;
+    
+    /* Enable pins to be driven by peripheral, using peripheral A. */
+    HAL_WRITE_UINT32((AT91_PIO+AT91_PIO_ASR),
+                     (AT91_PIO_PSR_DRXD | 
+                      AT91_PIO_PSR_DTXD));
+
+    /* Disables the PIO from controlling the corresponding pin
+      (enables peripheral control of the pin). */
+    HAL_WRITE_UINT32((AT91_PIO+AT91_PIO_PDR),
+                     (AT91_PIO_PSR_DRXD | 
+                      AT91_PIO_PSR_DTXD));
+
+    /* Disable interrupt */
+    HAL_WRITE_UINT32((base+AT91_DBG_IDR), 0xFFFFFFFF);
+
+    /* Reset receiver and transmitter */
+    HAL_WRITE_UINT32((base+AT91_DBG_CR),
+                     (AT91_DBG_CR_RSTRX | AT91_DBG_CR_RSTTX | 
+                      AT91_DBG_CR_RXDIS | AT91_DBG_CR_TXDIS));
+
+    baud_value = AT91_US_BAUD(baud_rate);
+
+    HAL_WRITE_UINT32((base+AT91_DBG_BRGR), baud_value);
+
+    /* Define the USART mode */
+    /* (USART) Normal, 1 stop bit, No Parity, Character Length: 8 bits, Clock */
+    HAL_WRITE_UINT32(base+AT91_DBG_MR, 
+                     (AT91_DBG_MR_CHMODE_NORMAL |
+                      AT91_DBG_MR_PAR_NONE));
+    
+    /* Enable Transmitter */
+    HAL_WRITE_UINT32((base+AT91_DBG_CR), AT91_DBG_CR_TXEN);
+
+    /* Enable Receiver */
+    HAL_WRITE_UINT32((base+AT91_DBG_CR), AT91_DBG_CR_RXEN);
+}
+
+void
+cyg_hal_plf_serial_dbg_putc(void* __ch_data, char c)
+{
+    cyg_uint8 * base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint32 status;
+    CYGARC_HAL_SAVE_GP();
+
+    // Wait for Tx FIFO not full
+    do
+    {
+        HAL_READ_UINT32((base+AT91_DBG_CSR), status);
+    }
+    while (!(status & AT91_DBG_CSR_TXRDY)) ;
+
+    //UART TX data register
+    HAL_WRITE_UINT8((base+AT91_DBG_THR), c);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_serial_dbg_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    cyg_uint8 * base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint32 status;
+
+    HAL_READ_UINT32((base+AT91_DBG_CSR), status);
+    if (status & AT91_DBG_CSR_RXRDY)
+      {
+        HAL_READ_UINT8((base+AT91_DBG_RHR), *ch);
+        return true;
+    }
+    return false;
+}
+
+cyg_uint8
+cyg_hal_plf_serial_dbg_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    while (!cyg_hal_plf_serial_dbg_getc_nonblock(__ch_data, &ch));
+
+    CYGARC_HAL_RESTORE_GP();
+    return ch;
+}
+
+static void
+cyg_hal_plf_serial_dbg_write(void* __ch_data, const cyg_uint8* __buf,
+                             cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while (__len-- > 0)
+        cyg_hal_plf_serial_dbg_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_serial_dbg_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while (__len-- > 0)
+        *__buf++ = cyg_hal_plf_serial_dbg_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+cyg_bool
+cyg_hal_plf_serial_dbg_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    int delay_count;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
+
+    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
+
+    for (;;) {
+        res = cyg_hal_plf_serial_dbg_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+
+        CYGACC_CALL_IF_DELAY_US(100);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static int
+cyg_hal_plf_serial_dbg_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    int ret = 0;
+    va_list ap;
+
+    CYGARC_HAL_SAVE_GP();
+    va_start(ap, __func);
+
+    switch (__func) {
+      case __COMMCTL_GETBAUD:
+        ret = chan->baud_rate;
+        break;
+      case __COMMCTL_SETBAUD:
+        chan->baud_rate = va_arg(ap, cyg_int32);
+        // Should we verify this value here?
+        cyg_hal_plf_serial_dbg_init_channel(chan);
+        ret = 0;
+        break;
+      case __COMMCTL_IRQ_ENABLE:
+        irq_state = 1;
+        HAL_INTERRUPT_UNMASK(chan->isr_vector);
+        HAL_WRITE_UINT32((chan->base+AT91_DBG_IER), AT91_DBG_CSR_RXRDY);
+        break;
+      case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+        HAL_WRITE_UINT32((chan->base+AT91_DBG_IDR), AT91_DBG_CSR_RXRDY);
+        HAL_INTERRUPT_MASK(chan->isr_vector);
+        break;
+      case __COMMCTL_DBG_ISR_VECTOR:
+        ret = chan->isr_vector;
+        break;
+      case __COMMCTL_SET_TIMEOUT:
+        ret = chan->msec_timeout;
+        chan->msec_timeout = va_arg(ap, cyg_uint32);
+      default:
+        break;
+    }
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
+}
+
+static int
+cyg_hal_plf_serial_dbg_isr(void *__ch_data, int* __ctrlc,
+                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    int res = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint32 status;
+    cyg_uint32 c;
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    *__ctrlc = 0;
+    HAL_READ_UINT32(chan->base+AT91_DBG_CSR, status);
+    if ( (status & AT91_DBG_CSR_RXRDY) != 0 ) {
+
+      HAL_READ_UINT32(chan->base+AT91_DBG_RHR, c);
+      ch = (cyg_uint8)(c & 0xff);
+      if( cyg_hal_is_break( &ch , 1 ) )
+        *__ctrlc = 1;
+      
+      res = CYG_ISR_HANDLED;
+    }
+
+    HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static channel_data_t at91_ser_channels[1] = {
+    { (cyg_uint8*)AT91_DBG, 1000, CYGNUM_HAL_INTERRUPT_DBG, 
+      CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD}
+};
+
+static void
+cyg_hal_plf_serial_init(void)
+{
+    hal_virtual_comm_table_t* comm;
+    int cur;
+
+    cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+    // Init channels
+    cyg_hal_plf_serial_dbg_init_channel(&at91_ser_channels[0]);
+
+    // Setup procs in the vector table
+
+    // Set channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &at91_ser_channels[0]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_dbg_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_dbg_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_dbg_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_dbg_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_dbg_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_dbg_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_dbg_getc_timeout);
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+
+    initialized = 1;
+
+    cyg_hal_plf_serial_init();
+
+#ifdef CYGBLD_HAL_ARM_AT91_DCC
+    cyg_hal_plf_dcc_init(CYGBLD_HAL_ARM_AT91_DCC_CHANNEL);
+#endif
+}
+
+void
+hal_diag_led(int mask)
+{
+    hal_at91_set_leds(mask);
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_diag_dbg.c
diff --git a/packages/hal/arm/at91/var/v2_0/src/hal_diag_dcc.c b/packages/hal/arm/at91/var/v2_0/src/hal_diag_dcc.c
new file mode 100644 (file)
index 0000000..a3a021e
--- /dev/null
@@ -0,0 +1,211 @@
+/*=============================================================================
+//
+//      hal_diag_dcc.c
+//
+//      HAL diagnostic output via the DCC interface.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 FSF
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   Andrew Lunn
+// Contributors:jskov, gthomas
+// Date:        2008-06-15
+// Purpose:     HAL diagnostic output via DCC.
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/infra/cyg_type.h>         // base types
+
+#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_if.h>             // interface API
+#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h>           // Helper functions
+#include <cyg/hal/hal_diag.h>
+
+#define DCC_TX_BUSY 2
+#define DCC_RX_READY 1
+
+//-----------------------------------------------------------------------------
+
+static void
+cyg_hal_plf_dcc_putc(void * __ch_data, char ch)
+{
+  unsigned int status;
+  CYG_UNUSED_PARAM(void *, __ch_data);
+
+  CYGARC_HAL_SAVE_GP();
+  
+  do {
+    __asm__ volatile ( "mrc p14,0, %0, c0, c0\n" : "=r" (status));
+  } while ( status & DCC_TX_BUSY );
+  __asm__( "mcr p14,0, %0, c1, c0\n" : : "r" (ch));
+  
+  CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_dcc_getc_nonblock(cyg_uint8* ch)
+{
+  cyg_uint32 status;
+  cyg_uint32 c;
+  
+  __asm__( "mrc p14,0, %0, c0, c0\n" : "=r" (status));
+  
+  if (status & DCC_RX_READY) {
+    __asm__( "mrc p14,0, %0, c1, c0\n" : "=r" (c));
+    *ch = (char )c;
+    return true;
+  } else 
+    return false;
+}
+
+static cyg_uint8
+cyg_hal_plf_dcc_getc(void* __ch_data)
+{
+  cyg_uint8 ch;
+  CYG_UNUSED_PARAM(void *, __ch_data);
+  CYGARC_HAL_SAVE_GP();
+  
+  while(!cyg_hal_plf_dcc_getc_nonblock(&ch));
+  
+  CYGARC_HAL_RESTORE_GP();
+  return ch;
+}
+
+static void
+cyg_hal_plf_dcc_write(void* __ch_data, const cyg_uint8* __buf, 
+                      cyg_uint32 __len)
+{
+  CYG_UNUSED_PARAM(void *, __ch_data);
+  CYGARC_HAL_SAVE_GP();
+  
+  while(__len-- > 0)
+    cyg_hal_plf_dcc_putc(NULL, *__buf++);
+  
+  CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_dcc_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+  CYG_UNUSED_PARAM(void *, __ch_data);
+  CYGARC_HAL_SAVE_GP();
+  
+  while(__len-- > 0)
+    *__buf++ = cyg_hal_plf_dcc_getc(NULL);
+  
+  CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_dcc_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+  int delay_count;
+  cyg_bool res;
+  CYG_UNUSED_PARAM(void *, __ch_data);
+
+  CYGARC_HAL_SAVE_GP();
+
+  delay_count = 100010; // delay in .1 ms steps
+
+  for(;;) {
+    res = cyg_hal_plf_dcc_getc_nonblock(ch);
+    if (res || 0 == delay_count--)
+      break;
+    
+    CYGACC_CALL_IF_DELAY_US(100);
+  }
+  
+  CYGARC_HAL_RESTORE_GP();
+  return res;
+}
+
+static int
+cyg_hal_plf_dcc_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+  CYG_UNUSED_PARAM(void *, __ch_data);
+  CYG_UNUSED_PARAM(__comm_control_cmd_t, __func);
+  
+  return 0;
+}
+
+static void
+cyg_hal_plf_dcc_register(const int channel)
+{
+  hal_virtual_comm_table_t* comm;
+  int cur;
+  
+  cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+  // Setup procs in the vector table
+  
+  CYGACC_CALL_IF_SET_CONSOLE_COMM(channel);
+  comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+  CYGACC_COMM_IF_CH_DATA_SET(*comm, NULL);
+  CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_dcc_write);
+  CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_dcc_read);
+  CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_dcc_putc);
+  CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_dcc_getc);
+  CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_dcc_control);
+  CYGACC_COMM_IF_DBG_ISR_SET(*comm, NULL);
+  CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_dcc_getc_timeout);
+
+  // Restore to original console.
+  CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_dcc_init(const int channel)
+{
+  static int initialized = 0;
+  
+  if (initialized)
+    return;
+  
+  initialized = 1;
+  
+  cyg_hal_plf_dcc_register(channel);
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_diag_dcc.c
diff --git a/packages/hal/arm/at91/var/v2_0/src/hal_diag_dcc.h b/packages/hal/arm/at91/var/v2_0/src/hal_diag_dcc.h
new file mode 100644 (file)
index 0000000..ecffd10
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef CYGONCE_HAL_DIAG_DCC_H
+#define CYGONCE_HAL_DIAG_DCC_H
+
+//=============================================================================
+//
+//      hal_diag_dcc.h
+//
+//      HAL Support for Kernel Diagnostic Routines via DCC
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 FSF.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   asl
+// Contributors:
+// Date:        2008-06-15
+// Purpose:     HAL Support for Kernel Diagnostic Routines via DCC.
+// Description: Diagnostic routines for use during kernel development.
+// Usage:       #include "hal_diag_dcc.h"
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+externC void cyg_hal_plf_dcc_init(const int channel);
+
+#endif
+
diff --git a/packages/hal/arm/at91/var/v2_0/src/timer_pit.c b/packages/hal/arm/at91/var/v2_0/src/timer_pit.c
new file mode 100644 (file)
index 0000000..1de14df
--- /dev/null
@@ -0,0 +1,151 @@
+/*==========================================================================
+//
+//      timer_pit.c
+//
+//      HAL timer code using the Periodic Interval Timer
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    asl, Oliver Munz
+// Contributors: asl, Oliver Munz
+// Date:         2006-02-12
+// Purpose:      Clock support using the PIT
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_platform_ints.h>
+// -------------------------------------------------------------------------
+// Use system clock
+void
+hal_clock_initialize(cyg_uint32 period)
+{
+  cyg_uint32 sr;
+  
+  CYG_ASSERT(CYGNUM_HAL_INTERRUPT_RTC == CYGNUM_HAL_INTERRUPT_PITC,
+             "Invalid timer interrupt");
+  
+  /* Set Period Interval timer and enable interrupt */
+  HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), 
+                   (period - 1) |  
+                   AT91_PITC_PIMR_PITEN |
+                   AT91_PITC_PIMR_PITIEN);
+  
+  // Read the status register to clear any pending interrupt
+  HAL_READ_UINT32(AT91_PITC + AT91_PITC_PISR, sr);
+}
+
+// This routine is called during a clock interrupt.
+void
+hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+  cyg_uint32 reg;
+  cyg_uint32 pimr;
+  
+  CYG_ASSERT(period < AT91_PITC_VALUE_MASK, "Invalid HAL clock configuration");
+  
+  // Check that the PIT has the right period.
+  HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR), pimr);
+  if ((pimr & AT91_PITC_VALUE_MASK) != (period - 1)) {
+    HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), 
+                     (period - 1) |  
+                     AT91_PITC_PIMR_PITEN |
+                     AT91_PITC_PIMR_PITIEN);
+  }
+
+  /* Read the value register so that we clear the interrupt */
+  HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIVR, reg);
+}
+
+// Read the current value of the clock, returning the number of hardware
+// "ticks" that have occurred (i.e. how far away the current value is from
+// the start)
+void
+hal_clock_read(cyg_uint32 *pvalue)
+{
+  cyg_uint32 ir;
+  cyg_uint32 pimr;
+  
+  // Check that the PIT is running. If not start it.
+  HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR),pimr);
+  if (!(pimr & AT91_PITC_PIMR_PITEN)) {
+    HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), 
+                     AT91_PITC_VALUE_MASK | AT91_PITC_PIMR_PITEN);
+  }
+  
+  HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir);
+  *pvalue = ir & AT91_PITC_VALUE_MASK;
+}
+
+// -------------------------------------------------------------------------
+//
+// Delay for some number of micro-seconds
+// PIT is clocked at MCLK / 16
+//
+void hal_delay_us(cyg_int32 usecs)
+{
+  cyg_int64 ticks;
+  cyg_uint32 val1, val2;
+  cyg_uint32 piv;
+  
+  // Calculate how many PIT ticks the required number of microseconds
+  // equate to. We do this calculation in 64 bit arithmetic to avoid
+  // overflow.
+  ticks = (((cyg_uint64)usecs) * 
+           ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/16/1000000LL;
+  
+  // Calculate the wrap around period. 
+  HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIMR, piv);
+  piv = (piv & AT91_PITC_VALUE_MASK) - 1; 
+  
+  hal_clock_read(&val1);
+  while (ticks > 0) {
+    hal_clock_read(&val2);
+    if (val2 < val1)
+      ticks -= ((piv + val2) - val1); //overflow occurred
+    else 
+      ticks -= (val2 - val1);
+    val1 = val2;
+  }
+}
+
+// timer_pit.c
diff --git a/packages/hal/arm/at91/var/v2_0/src/timer_tc.c b/packages/hal/arm/at91/var/v2_0/src/timer_tc.c
new file mode 100644 (file)
index 0000000..ecd29be
--- /dev/null
@@ -0,0 +1,160 @@
+/*==========================================================================
+//
+//      timer_tc.c
+//
+//      HAL timer code using the Timer Counter
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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, nickg, tkoeller
+// Date:         2001-07-12
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_arch.h>           // Register state info
+#include <cyg/hal/hal_intr.h>           // necessary?
+
+// -------------------------------------------------------------------------
+// Clock support
+
+static cyg_uint32 _period;
+
+void hal_clock_initialize(cyg_uint32 period)
+{
+    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
+
+    CYG_ASSERT(period < 0x10000, "Invalid clock period");
+
+    // Disable counter
+    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+
+    // Set registers
+    HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CPCTRG |        // Reset counter on CPC
+                                        AT91_TC_CMR_CLKS_MCK32);    // 1 MHz
+    HAL_WRITE_UINT32(timer+AT91_TC_RC, period);
+
+    // Start timer
+    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
+
+    // Enable timer 0 interrupt    
+    HAL_WRITE_UINT32(timer+AT91_TC_IER, AT91_TC_IER_CPC);
+}
+
+void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
+    cyg_uint32 sr;
+
+    CYG_ASSERT(period < 0x10000, "Invalid clock period");
+
+    HAL_READ_UINT32(timer+AT91_TC_SR, sr);  // Clear interrupt
+
+    if (period != _period) {
+        hal_clock_initialize(period);
+    }
+    _period = period;
+
+}
+
+void hal_clock_read(cyg_uint32 *pvalue)
+{
+    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
+    cyg_uint32 val;
+
+    HAL_READ_UINT32(timer+AT91_TC_CV, val);
+    *pvalue = val;
+}
+
+// -------------------------------------------------------------------------
+//
+// Delay for some number of micro-seconds
+//   Use timer #2 in MCLOCK/32 mode.
+//
+void hal_delay_us(cyg_int32 usecs)
+{
+    cyg_uint32 stat;
+    cyg_uint64 ticks;
+#if defined(CYGHWR_HAL_ARM_AT91_JTST)
+    // TC2 is reserved for AD/DA. Use TC1 instead. 
+    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC1;
+#else
+    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC2;
+#endif
+    // Calculate how many timer ticks the required number of
+    // microseconds equate to. We do this calculation in 64 bit
+    // arithmetic to avoid overflow.
+    ticks = (((cyg_uint64)usecs) * 
+             ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/32000000LL;
+    
+    //    CYG_ASSERT(ticks < (1 << 16), "Timer overflow");
+    
+    if (ticks > (1 << 16))
+      ticks = (1 << 16) - 1;
+    
+    if (ticks == 0)
+      return;
+    
+    // Disable counter
+    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+
+    // Set registers
+    HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CLKS_MCK32);  // 1MHz
+    HAL_WRITE_UINT32(timer+AT91_TC_RA, 0);
+    HAL_WRITE_UINT32(timer+AT91_TC_RC, ticks);
+
+    // Clear status flags
+    HAL_READ_UINT32(timer+AT91_TC_SR, stat);
+    
+    // Start timer
+    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
+    
+    // Wait for the compare
+    do {
+      HAL_READ_UINT32(timer+AT91_TC_SR, stat);
+    } while ((stat & AT91_TC_SR_CPC) == 0);
+}
+
+// timer_tc.c
diff --git a/packages/hal/arm/lpc24xx/ea2468/v2_0/ChangeLog b/packages/hal/arm/lpc24xx/ea2468/v2_0/ChangeLog
new file mode 100755 (executable)
index 0000000..f195cc6
--- /dev/null
@@ -0,0 +1,48 @@
+2008-07-21  Uwe Kindler  <uwe_kindler@web.de>
+
+       * src/ea2468_misc.c: Added hal_lpc_can_init() to initialize CAN
+       channels
+       * include/plf_io.h: Added HAL_LPC2XXX_INIT_CAN() macro for CAN channel
+       initialisation
+       
+2008-07-06  Uwe Kindler  <uwe_kindler@web.de>
+
+       * Initial release of Embedded Artists LPC2468 OEM board package
+       * cdl/hal_arm_lpc2xxx_ea2468.cdl
+       * include/plf_io.h
+       * include/hal_platform_setup.h
+       * src/ea2468_misc
+
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+
diff --git a/packages/hal/arm/lpc24xx/ea2468/v2_0/cdl/hal_arm_lpc24xx_ea2468.cdl b/packages/hal/arm/lpc24xx/ea2468/v2_0/cdl/hal_arm_lpc24xx_ea2468.cdl
new file mode 100755 (executable)
index 0000000..97e28c3
--- /dev/null
@@ -0,0 +1,317 @@
+# ====================================================================
+#
+#      hal_arm_lpc24xx_ea2468.cdl
+#
+#      Embedded Artists LPC2468 OEM Board HAL package configuration data 
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2008 eCosCentric Limited
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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:           2008-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_LPC24XX_EA2468 {
+    display       "Embedded Artists LPC2468 OEM Board board HAL"
+    parent        CYGPKG_HAL_ARM_LPC24XX
+    define_header hal_arm_lpc24xx_ea2468.h
+    include_dir   cyg/hal
+    hardware
+    implements    CYGINT_DEVS_CAN_LPC2XXX_CAN0
+    implements    CYGINT_DEVS_CAN_LPC2XXX_CAN1
+    implements    CYGINT_IO_SERIAL_LPC24XX_UART0
+    implements    CYGINT_IO_SERIAL_LPC24XX_UART1
+    description   "
+        The LPC2468 OEM HAL package provides the support needed to run
+        eCos on Embedded Artists LPC2468 OEM 16/32 boards."
+
+    compile       ea2468_misc.c
+
+    requires      { CYGHWR_HAL_ARM_LPC24XX == "LPC2468" }
+
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_arm.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H  <pkgconf/hal_arm_lpc24xx.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_lpc24xx_ea2468.h>"
+        puts $::cdl_header "#define HAL_PLATFORM_CPU    \"ARM7TDMI-S\""
+        puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"Embedded Artists LPC2468 OEM Board\""
+        puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+    }
+    
+    cdl_option CYGNUM_HAL_ARM_LPC24XX_XTAL_FREQ {
+            display       "CPU xtal frequency"
+            parent        CYGNUM_HAL_ARM_LPC24XX_CLOCKING
+            flavor        data
+            default_value {12000000}
+    }
+    
+    cdl_option CYGNUM_HAL_ARM_LPC24XX_MAX_CLOCK_SPEED {
+            display       "Max. CPU clock speed"
+            parent        CYGNUM_HAL_ARM_LPC24XX_CLOCKING
+            flavor        data
+            calculated    {57600000}
+            requires      CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED <= 57600000
+            description   "
+                Due to a silicon errata, the highest internal core
+                clock frequency (at the time of writing this document)
+                is 57.6 MHz. This corresponds to an internal PLL
+                frequency of 288 MHz that is divided by 6 to get a 48
+                MHz clock for the core and the USB interface."
+    }
+      
+    cdl_component CYG_HAL_STARTUP {
+        display       "Startup type"
+        flavor        data
+        default_value {"ROM"}
+        legal_values  {"RAM" "ROM"}
+        no_define
+        define -file system.h CYG_HAL_STARTUP
+        description   "
+            Choose RAM or ROM startup type. Typically ROM startup is used for
+            building RedBoot. RedBoot runs from internal on chip flash of
+            LPC24xx. Use RAM startup for building eCos applications.
+            RedBoot manages the external on board flash devices. It copies
+            the eCos application image from FLASH to on board SDRAM 
+            and then starts the eCos application."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+        display      "Number of communication channels on the board"
+        flavor       data
+        calculated   2
+        description "
+            Channel 0: UART0, Channel 1: UART1"
+    }    
+    
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT {
+        display      "Default console channel."
+        active_if    CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+        flavor       data
+        calculated   0
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+        display          "Debug serial port"
+        active_if        CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+        flavor           data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    0
+        description      "
+            The LPC2468 OEM board has two serial channels. The first
+            channel, UART0, ist routed to an USB-to-serial bridge and
+            the second channel, UART1, is available on the Sub-D9
+            RS232 connector. This option chooses which channel will be
+            used to connect to a host running GDB."  
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+         display       "GDB serial port baud rate"
+         flavor        data
+         legal_values  9600 19200 38400 57600 115200
+         default_value 38400
+         description   "
+             This option controls the baud rate used for the GDB
+             connection."
+    }
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+         display          "Diagnostic serial port"
+         active_if        CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+         flavor data
+         legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+         default_value    0
+         description "
+             The LPC2468 OEM board has two serial ports. This option
+             chooses which port will be used for diagnostic output."
+     }
+
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+        display       "Diagnostic serial port baud rate"
+        flavor        data
+        legal_values  9600 19200 38400 57600 115200
+        default_value 38400
+        description   "
+            This option selects the baud rate used for the diagnostic port."
+    }
+   
+    cdl_option CYGHWR_HAL_ARM_LPC24XX_EA2468_DATA_BUS_WIDTH {
+        display "Data bus width"
+        flavor  data
+        default_value { 16 }
+        legal_values  { 16 32 }
+        description "
+            The LPC2468 OEM board is sold in two different data bus 
+            versions - a 16-bit version and a 32-bit version."
+    }
+
+   
+    cdl_component CYGBLD_GLOBAL_OPTIONS {
+        display "Global build options"
+        flavor  none
+        parent  CYGPKG_NONE
+        description   "
+            Global build options including control over compiler flags,
+            linker flags and choice of toolchain."
+
+        cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+            display "Global command prefix"
+            flavor  data
+            no_define
+            default_value { "arm-elf" }
+            description "
+                This option specifies the command prefix used when
+                invoking the build tools."
+        }
+
+        cdl_option CYGBLD_GLOBAL_CFLAGS {
+            display "Global compiler flags"
+            flavor  data
+            no_define
+            default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mno-short-load-words -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+            description   "
+                This option controls the global compiler flags which
+                are used to compile all packages by default. Individual
+                packages may define options which override these global
+                flags."
+        }
+
+        cdl_option CYGBLD_GLOBAL_LDFLAGS {
+            display "Global linker flags"
+            flavor  data
+            no_define
+            default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mno-short-load-words -Wl,--gc-sections -Wl,-static -g -nostdlib" }
+            description   "
+                This option controls the global linker flags. Individual
+                packages may define options which override these global
+                flags."
+        }
+    }
+
+    cdl_option CYGSEM_HAL_ROM_MONITOR {
+        display       "Behave as a ROM monitor"
+        flavor        bool
+        default_value 0
+        parent        CYGPKG_HAL_ROM_MONITOR
+        requires      { CYG_HAL_STARTUP == "ROM"}
+        description   "
+            Enable this option if this program is to be used as a
+            ROM monitor, i.e. applications will be loaded into RAM on
+            the board, and this ROM monitor may process exceptions or
+            interrupts generated from the application. This enables
+            features such as utilizing a separate interrupt stack when
+            exceptions are generated."
+    }
+
+    cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+         display       "Work with a ROM monitor"
+         flavor        booldata
+         legal_values  { "Generic" "GDB_stubs" }
+         default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+         parent        CYGPKG_HAL_ROM_MONITOR
+         requires      { CYG_HAL_STARTUP == "RAM" }
+         description   "
+             Support can be enabled for different varieties of ROM
+             monitor.  This support changes various eCos semantics such
+             as the encoding of diagnostic output, or the overriding of
+             hardware interrupt vectors.
+             Firstly there is \"Generic\" support which prevents the
+             HAL from overriding the hardware vectors that it does not
+             use, to instead allow an installed ROM monitor to handle
+             them. This is the most basic support which is likely to be
+             common to most implementations of ROM monitor.
+             \"GDB_stubs\" provides support when GDB stubs are included
+             in the ROM monitor or boot ROM."
+    }
+
+    cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+        display       "Redboot HAL options"
+        flavor        none
+        no_define
+        parent        CYGPKG_REDBOOT
+        active_if     CYGPKG_REDBOOT
+        description   "
+            This option lists the target's requirements for a valid
+            Redboot configuration."
+
+        cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+            display       "Build Redboot ROM binary image"
+            active_if     CYGBLD_BUILD_REDBOOT
+            requires      { !CYGBLD_BUILD_REDBOOT_WITH_EXEC }
+            default_value 1
+            no_define
+            description "
+                This option enables the conversion of the Redboot ELF
+                image to a binary image suitable for ROM programming."
+
+            make -priority 325 {
+                <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+                $(OBJCOPY) --strip-debug $< $(@:.bin=.img)
+                $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+                $(OBJCOPY) -O ihex $< $(@:.bin=.hex)
+                $(OBJCOPY) -O binary $< $@
+            }
+
+        }
+    }
+
+    cdl_component CYGHWR_MEMORY_LAYOUT {
+        display "Memory layout"
+        flavor data
+        no_define
+        calculated { (CYG_HAL_STARTUP == "RAM") ? "arm_lpc24xx_ea2468_ram" :
+                                                  "arm_lpc24xx_ea2468_rom" }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+            display "Memory layout linker script fragment"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+            calculated { (CYG_HAL_STARTUP == "RAM") ? 
+                             "<pkgconf/mlt_arm_lpc24xx_ea2468_ram.ldi>" :
+                             "<pkgconf/mlt_arm_lpc24xx_ea2468_rom.ldi>" }
+        }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_H {
+            display "Memory layout header file"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_H
+            calculated { (CYG_HAL_STARTUP == "RAM") ? 
+                             "<pkgconf/mlt_arm_lpc24xx_ea2468_ram.h>" :
+                             "<pkgconf/mlt_arm_lpc24xx_ea2468_rom.h>" }
+        }
+    }
+}
diff --git a/packages/hal/arm/lpc24xx/ea2468/v2_0/include/hal_platform_setup.h b/packages/hal/arm/lpc24xx/ea2468/v2_0/include/hal_platform_setup.h
new file mode 100755 (executable)
index 0000000..0e773ec
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+/*=============================================================================
+//
+//      hal_platform_setup.h
+//
+//      Platform specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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:         2008-06-05
+// Purpose:      EA LPC2468 OEM platform specific support routines
+// Description:
+// Usage:        #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+#include <pkgconf/system.h>
+#include <cyg/hal/var_io.h>
+
+
+//
+// The minimum initialisation code - we simply setup a valid C stack in 
+// internal SRAM and do any further initialisation in C code
+//
+#if defined(CYG_HAL_STARTUP_ROM)
+.macro _setup
+    //
+    // While setting the stack pointer please note that the 
+    // Flash programming routines use a
+    // section of the on-chip SRAM. In-System Programming (ISP) uses 
+    // the top 256 bytes and In-Application Programming (IAP) uses the 
+    // top 128 bytes of the on-chip SRAM. The application stack should 
+    // not overlap this area.
+    //
+    ldr r2,=0x4000ffff // ram end
+    sub sp,r2,#0xff
+        
+    //
+    // now map the vector table to internal flash - normally this should be
+    // the default value after boot - but we go the save way here and force
+    // the mapping to internal flash (the value for 
+    // CYGARC_HAL_LPC24XX_REG_MEMMAP is 1)
+    //
+    ldr r0,=CYGARC_HAL_LPC24XX_REG_SCB_BASE
+    mov r1,#1
+    str r1, [r0,#CYGARC_HAL_LPC24XX_REG_MEMMAP]        
+    
+    //    
+    // Now its is save to copy the first 64 bytes of flash to RAM
+    //
+    mov r0,#0                                  
+    mov r1,#0x40000000
+    mov r2,#0x40
+1:
+    ldr r3,[r0,#4]!
+    str r3,[r1,#4]!
+    cmps r0,r2
+    bne 1b
+        
+    // 
+    // Now we can map the vector table to internal SRAM        because the SRAM no
+    // contains a copy of the vector table from flash (the value for 
+    // CYGARC_HAL_LPC24XX_REG_MEMMAP is 2 = SRAM)
+    //
+    ldr r0,=CYGARC_HAL_LPC24XX_REG_SCB_BASE
+    mov r1,#2                                   // User RAM Mode. Interrupt 
+                                     // vectors are re-mapped to Static RAM.
+    str r1, [r0,#CYGARC_HAL_LPC24XX_REG_MEMMAP]
+    
+    //
+    // now we have a valid stack and we can jump into the beautiful
+    // world of C and do any further initialisation in C code
+    //
+    bl hal_plf_startup
+.endm
+#define CYGSEM_HAL_ROM_RESET_USES_JUMP
+#else
+.macro  _setup
+.endm    
+#endif
+
+#define PLATFORM_SETUP1 _setup
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H
diff --git a/packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_ram.h b/packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_ram.h
new file mode 100755 (executable)
index 0000000..59ec54e
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+
+#define CYGMEM_REGION_sram (0x40000000)
+#define CYGMEM_REGION_sram_SIZE (0x00010000)
+#define CYGMEM_REGION_sram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_ram (0xA0000000)
+#define CYGMEM_REGION_ram_SIZE (0x02000000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0xA2000000 - (size_t) CYG_LABEL_NAME (__heap1))
+
diff --git a/packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_ram.ldi b/packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_ram.ldi
new file mode 100755 (executable)
index 0000000..13074de
--- /dev/null
@@ -0,0 +1,26 @@
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_lpc24xx_ea2468.h>
+
+MEMORY
+{
+    sram   : ORIGIN = 0x40000000, LENGTH = 0x10000
+    ram    : ORIGIN = 0xA0000000, LENGTH = 0x2000000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    SECTION_fixed_vectors (sram, 0x40000400, LMA_EQ_VMA)
+    SECTION_rom_vectors (ram, 0xA0010000, LMA_EQ_VMA)
+    SECTION_text (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fini (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
+
diff --git a/packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_rom.h b/packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_rom.h
new file mode 100755 (executable)
index 0000000..b087b73
--- /dev/null
@@ -0,0 +1,28 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_sram (0x40000000)
+#define CYGMEM_REGION_sram_SIZE (0x00010000)
+#define CYGMEM_REGION_sram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_ram (0xA0000000)
+#define CYGMEM_REGION_ram_SIZE (0x02000000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_rom (0x00000000)
+#define CYGMEM_REGION_rom_SIZE (0x00080000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+
+
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0xA2000000 - (size_t) CYG_LABEL_NAME (__heap1))
+
diff --git a/packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_rom.ldi b/packages/hal/arm/lpc24xx/ea2468/v2_0/include/pkgconf/mlt_arm_lpc24xx_ea2468_rom.ldi
new file mode 100755 (executable)
index 0000000..ce376fd
--- /dev/null
@@ -0,0 +1,27 @@
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_lpc24xx_ea2468.h>
+
+MEMORY
+{
+    rom    : ORIGIN = 0x00000000, LENGTH = 0x80000
+    sram   : ORIGIN = 0x40000000, LENGTH = 0x10000
+    ram    : ORIGIN = 0xA0000000, LENGTH = 0x2000000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    SECTION_rom_vectors (rom, 0x00000000, LMA_EQ_VMA)
+    SECTION_text (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixed_vectors (sram, 0x40000400, LMA_EQ_VMA)
+    SECTION_data (ram, 0xA0000000, FOLLOWING (.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
+
diff --git a/packages/hal/arm/lpc24xx/ea2468/v2_0/include/plf_io.h b/packages/hal/arm/lpc24xx/ea2468/v2_0/include/plf_io.h
new file mode 100755 (executable)
index 0000000..635ef5a
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef CYGONCE_HAL_PLF_IO_H
+#define CYGONCE_HAL_PLF_IO_H
+//=============================================================================
+//
+//      plf_io.h
+//
+//      Embedded Artists LPC2468 OEM board specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-06
+// Purpose:      EA LPC2468 oem board specific registers
+// Description:
+// Usage:        #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+// On-chip device base addresses
+
+
+//----------------------------------------------------------------------
+// The platform needs this initialization during the
+// hal_hardware_init() function in the varient HAL.
+#ifndef __ASSEMBLER__
+extern void hal_plf_hardware_init(void);
+#define HAL_PLF_HARDWARE_INIT() \
+    hal_plf_hardware_init()
+
+//-----------------------------------------------------------------------------
+// LPX24xx variant specific initialisation of CAN channels
+// This function configures the pin functions for CAN use
+//-----------------------------------------------------------------------------            
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX
+externC void hal_lpc_can_init(cyg_uint8 can_chan_no);            
+#define HAL_LPC2XXX_INIT_CAN(_can_chan_no_) hal_lpc_can_init(_can_chan_no_)
+#endif // CYGPKG_DEVS_CAN_LPC2XXX   
+
+#endif  //__ASSEMBLER__ 
+
+//-----------------------------------------------------------------------------
+// end of plf_io.h
+#endif // CYGONCE_HAL_PLF_IO_H
+
diff --git a/packages/hal/arm/lpc24xx/ea2468/v2_0/src/ea2468_misc.c b/packages/hal/arm/lpc24xx/ea2468/v2_0/src/ea2468_misc.c
new file mode 100755 (executable)
index 0000000..bdfbc4c
--- /dev/null
@@ -0,0 +1,465 @@
+/*==========================================================================
+//
+//      ea2468_misc.c
+//
+//      HAL misc board support code for EA LPC2468 OEM board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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:         2008-06-15
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+
+//===========================================================================
+//                               INCLUDES
+//===========================================================================
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_lpc24xx_ea2468.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_io.h>             // IO macros
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+#include <cyg/hal/var_io.h>
+#include <cyg/hal/plf_io.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGPKG_REDBOOT
+#include <redboot.h>
+#endif
+
+
+//===========================================================================
+//                               DEFINES
+//===========================================================================
+#define SCB_BASE   CYGARC_HAL_LPC24XX_REG_SCB_BASE
+#define EMC_BASE   CYGARC_HAL_LPC24XX_REG_EMC_BASE
+#define PIN_BASE   CYGARC_HAL_LPC24XX_REG_PIN_BASE
+#define IO_BASE    CYGARC_HAL_LPC24XX_REG_IO_BASE
+#define FIO_BASE   CYGARC_HAL_LPC24XX_REG_FIO_BASE
+#define SDRAM_BASE 0xA0000000
+extern void cyg_hal_plf_serial_init(void);
+
+
+//===========================================================================
+// Initialize communication channels
+//===========================================================================
+void cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+       
+    if (initialized)
+        return;
+    initialized = 1;
+
+    cyg_hal_plf_serial_init();
+}
+
+
+//===========================================================================
+// Finalize hardware initialisation of platform
+//===========================================================================
+void hal_plf_hardware_init(void)
+{
+
+}
+
+
+//===========================================================================
+// hal_gpio_init 
+//===========================================================================
+void hal_gpio_init(void)
+{
+    //
+    // Enable UART0 pins
+    //
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL0, 0x00000050);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL1, 0); 
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL2, 0);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL3, 0);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL4, 0);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL5, 0);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL6, 0);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL7, 0x30003fff);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL8, 0);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL9, 0);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL10,0);
+
+    HAL_WRITE_UINT32(IO_BASE + CYGARC_HAL_LPC24XX_REG_IO0DIR, 0);
+    HAL_WRITE_UINT32(IO_BASE + CYGARC_HAL_LPC24XX_REG_IO1DIR, 0);
+    HAL_WRITE_UINT32(IO_BASE + CYGARC_HAL_LPC24XX_REG_IO0SET, 0xffffffff);
+    HAL_WRITE_UINT32(IO_BASE + CYGARC_HAL_LPC24XX_REG_IO1SET, 0xffffffff);
+
+    HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO0DIR, 0);
+    HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO1DIR, 0);
+    HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO2DIR, 0);
+    HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO3DIR, 0);
+    HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO4DIR, 0);
+    
+    HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO0SET, 0xffffffff);
+    HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO1SET, 0xffffffff);
+    HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO2SET, 0xffffffff);
+    HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO3SET, 0xffffffff);
+    HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO4SET, 0xffffffff);
+}
+
+
+//===========================================================================
+// hal_pll_init - initialize pll and all clocks
+//===========================================================================
+void hal_pll_init(void)
+{
+    cyg_uint32 regval;
+    
+    HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLSTAT, regval);
+    if (regval & CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLLC)
+    {
+       //
+       // Enable PLL, disconnected
+       //
+       HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLCON,  
+                         CYGARC_HAL_LPC24XX_REG_PLLCON_PLLE);
+       HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0xaa);
+       HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0x55); 
+    }
+    
+    //
+    // Disable PLL, disconnected
+       //
+       HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLCON,  0x00);
+       HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0xaa);
+       HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0x55); 
+                        
+    //
+    // Enables main oscillator and wait until it is usable
+    //
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_SCS, 
+                     CYGARC_HAL_LPC24XX_REG_SCS_OSCEN);
+    do
+    {
+        HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_SCS, regval);    
+    } while (!(regval & CYGARC_HAL_LPC24XX_REG_SCS_OSCSTAT));
+    
+    //
+    // select main OSC, 12MHz, as the PLL clock source 
+    //
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_CLKSRCSEL, 
+                     CYGARC_HAL_LPC24XX_REG_CLKSRCSEL_MAIN);
+    
+    //
+    // Configure PLL multiplier and pre divider according to
+    // configuration values
+    //                 
+    regval = ((CYGNUM_HAL_ARM_LPC24XX_PLL_MUL - 1) | 
+              (CYGNUM_HAL_ARM_LPC24XX_PLL_DIV - 1) << 16);
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLCFG,  regval);
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0xaa);
+       HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0x55); 
+                        
+    //
+    // Enable PLL, disconnected
+    //
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLCON,  
+                     CYGARC_HAL_LPC24XX_REG_PLLCON_PLLE);
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0xaa);
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0x55); 
+                     
+    //
+    // Set CPU clock divider
+    //
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_CCLKCFG, 
+                     CYGNUM_HAL_ARM_LPC24XX_CPU_CLK_DIV - 1);
+                     
+    //
+    // Set USB clock divider
+    //
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_CCLKCFG, 
+                     CYGNUM_HAL_ARM_LPC24XX_USB_CLK_DIV - 1);
+                     
+    //
+    // Check lock bit status
+    //
+    do
+    {
+        HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLSTAT, regval);   
+    } while(!(regval & CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLOCK));
+    
+    //
+    // Enable PLL and connect
+    //
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLCON, 
+                     CYGARC_HAL_LPC24XX_REG_PLLCON_PLLE | 
+                     CYGARC_HAL_LPC24XX_REG_PLLCON_PLLC);
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0xaa);
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0x55);  
+                     
+    //
+    // Check connect bit status
+    //
+    do
+    {
+        HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLSTAT, regval);   
+    } while(!(regval & CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLLC));  
+    
+    //
+    // entry for JTAG debugger- enable this while loop as a stop for
+    // the JTAG debugger - the JTAG debugger only works after the PLL is
+    // initialized properly
+    //
+    /*while (1)
+    {
+    }*/
+}
+
+
+//===========================================================================
+// hal_mem_init - initialize external memory interface
+//===========================================================================
+void hal_mem_init(void)
+{
+    volatile unsigned int i;
+    volatile unsigned int dummy;
+    volatile cyg_uint32   regval;
+    
+    //
+    // Enable external memory interface
+    //
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMC_CTRL, 
+                     CYGARC_HAL_LPC24XX_REG_EMC_CTRL_EN);
+    HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCONP, regval);
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCONP,
+                     regval | CYGARC_HAL_LPC24XX_REG_PCONP_EMC);  
+                    
+    //
+    // Setup pin functions
+    //
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL4, 0x50000000);
+#if defined(CYGHWR_HAL_ARM_LPC24XX_EA2468_DATA_BUS_WIDTH_32)
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL5, 0x55010115);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL7, 0x55555555);
+#else
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL5, 0x05050555);
+#endif
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL6, 0x55555555);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL8, 0x55555555);
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL9, 0x50555555);
+
+#if defined(CYGHWR_HAL_ARM_LPC24XX_EA2468_DATA_BUS_WIDTH_32)  
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RP,    1);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RAS,   3);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_SREX,  5);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_APR,   1);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_DAL,   5);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_WR,    1);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RC,    5);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RFC,   5);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_XSR,   5);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RRD,   1);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_MRD,   1);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RDCFG, 1);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS0, 
+                     0x00000202);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG0, 
+                     0x00005480);
+#else
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RP,    2);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RAS,   3);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_SREX,  7);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_APR,   2);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_DAL,   5);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_WR,    1);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RC,    5);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RFC,   5);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_XSR,   7);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RRD,   1);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_MRD,   2);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RDCFG, 1);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS0, 
+                     0x00000303);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG0, 
+                     0x00000680);
+#endif
+    
+    //  
+    // Wait 100 ms and then send command: NOP
+    //
+    HAL_DELAY_US(100000);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONTROL, 
+                     0x00000183);
+
+    //
+    // wait 200 ms and then send command: PRECHARGE-ALL, shortest
+    // possible refresh period
+    //
+    HAL_DELAY_US(200000);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONTROL, 
+                     0x00000103);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_REFRESH, 
+                     0x00000002);
+    
+    //
+    // wait 128 ABH clock cycles
+    //
+    for(i = 0; i < 64; i++)
+    {
+        asm volatile(" nop");
+    }  
+    
+    //  
+    // Set correct refresh period and the send command MODE
+    //
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_REFRESH, 28);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONTROL, 
+                     0x00000083);
+
+    //
+    // Set mode register in SDRAM
+    //
+#if defined(CYGHWR_HAL_ARM_LPC24XX_EA2468_DATA_BUS_WIDTH_32)
+    dummy = *((volatile unsigned int*)(SDRAM_BASE | (0x22 << 11)));
+#else
+    dummy = *((volatile unsigned int*)(SDRAM_BASE | (0x33 << 12)));
+#endif
+    
+    //
+    //Send command: NORMAL, enable buffer and wait for 1 second
+    //
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONTROL, 
+                     0x00000000);
+    HAL_READ_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG0, regval);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG0, 
+                     regval | 0x00080000);
+    HAL_DELAY_US(1000);
+
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN0, 0x2);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN0, 0x2);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD0,   0x1f);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE0, 0x1f);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR0,   0x1f);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN0, 0xf);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG0,   
+                     0x00000081);
+  
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN1, 0x2);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN1, 0x2);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD1,   0x8);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE1, 0x1f);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR1,   0x8);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN1, 0xf);
+    HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG1,   
+                     0x00000080);   
+}
+
+
+//===========================================================================
+// hal_plf_startup
+//===========================================================================
+void hal_plf_startup(void)
+{
+    hal_pll_init();
+    
+    //
+    // Set clock speed of all peripherals to reset value (CPU speed / 4)
+    //
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCLKSEL0, 0x00000000);
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCLKSEL1, 0x00000000);
+    
+    //
+    // Setup memory acceleration module
+    //
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_MAMCR, 0);
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_MAMTIM, 4);
+    
+    hal_gpio_init();
+    HAL_DELAY_US(20000);
+    hal_mem_init();
+}
+
+
+//===========================================================================
+// hal_lpc2xxx_set_leds
+//===========================================================================
+void hal_lpc24xx_set_leds (int mask)
+{
+    //
+    // implement function for setting diagnostic leds
+    //
+}
+
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX
+//===========================================================================
+// Configure CAN pins
+//===========================================================================
+void hal_lpc_can_init(cyg_uint8 can_chan_no)
+{
+    CYG_ASSERT(can_chan_no < 2, "CAN channel number out of bounds");
+    
+    cyg_uint32 pinsel0_val;
+    cyg_uint32 pconp_val;
+    HAL_READ_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL0, pinsel0_val);
+    HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCONP, pconp_val);
+    switch (can_chan_no)
+    {
+        case 0:
+             CYGARC_HAL_LPC24XX_SET_PIN_FUN(pinsel0_val, 0, 1);
+             CYGARC_HAL_LPC24XX_SET_PIN_FUN(pinsel0_val, 1, 1);
+             pconp_val |= CYGARC_HAL_LPC24XX_REG_PCONP_CAN1;
+             break;
+        
+        case 1:
+             CYGARC_HAL_LPC24XX_SET_PIN_FUN(pinsel0_val, 4, 2);
+             CYGARC_HAL_LPC24XX_SET_PIN_FUN(pinsel0_val, 5, 2); 
+             pconp_val |= CYGARC_HAL_LPC24XX_REG_PCONP_CAN2;
+             break;
+    }
+    HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL0, pinsel0_val);
+    HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCONP, pconp_val);
+}
+#endif // #ifdef CYGPKG_DEVS_CAN_LPC2XXX
+
+//--------------------------------------------------------------------------
+// EOF ea2468_misc.c
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/ChangeLog b/packages/hal/arm/lpc24xx/var/v2_0/ChangeLog
new file mode 100755 (executable)
index 0000000..7e2d817
--- /dev/null
@@ -0,0 +1,60 @@
+2008-07-21  Uwe Kindler  <uwe_kindler@web.de>
+
+       * src/lpc2xxx_misc.c: Added hal_lpc_can_init() to initialize CAN
+       channels
+       * cdl/hal_arm_lpc24xx.cdl: Added a number of CYGHWR_HAL_ARM_LPC2XXX_xxx
+       options for device driver compatibility reasons. Some LPC2xxx device
+       drivers rely on these definitions. Moved some configuration options
+       to make configuration more intuitive in configuration tool. Added
+       CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK option for configuration of CAN 
+       peripheral clock.
+       * include/var_io.h: Added macro CYGARC_HAL_LPC24XX_SET_PIN_FUN()
+       * src/lpc2xxx_misc.c: Added function hal_lpc_set_pclk() to set
+       peripheral clocks easily. Initialize peripheral clocks in
+       hal_hardware_init() according to configuration.
+       
+2008-07-06  Uwe Kindler  <uwe_kindler@web.de>
+
+       * Initial release of LPC24xx variant support (based on LPX2xxx variant)
+       * src/hal_diag.c: 
+       * src/lpc2xxx_misc.c: 
+       * include/plf_stub.h: 
+       * include/var_io.h: 
+       * include/var_arch.h: 
+       * include/hal_var_ints.h: 
+       * include/hal_diag.h: 
+       * include/hal_cache.h: 
+       * cdl/hal_arm_lpc24xx.cdl: New port - based on LPX2xxx variant.
+       
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/cdl/hal_arm_lpc24xx.cdl b/packages/hal/arm/lpc24xx/var/v2_0/cdl/hal_arm_lpc24xx.cdl
new file mode 100755 (executable)
index 0000000..297027f
--- /dev/null
@@ -0,0 +1,326 @@
+# ====================================================================
+#
+#      hal_arm_lpc24xx.cdl
+#
+#      NXP LPC24XX HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2004 eCosCentric Limited 
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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, tkoeller, tdrury, nickg
+# Date:           2008-07-05
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_LPC24XX {
+    display       "NXP LPC24XX variant HAL"
+    parent        CYGPKG_HAL_ARM
+    define_header hal_arm_lpc24xx.h
+    include_dir   cyg/hal
+    hardware
+    description   "
+        The LPC24XX HAL package provides the support needed to run
+        eCos on NXP LPC24XX based targets."
+
+    compile       hal_diag.c lpc24xx_misc.c
+
+    implements    CYGINT_HAL_DEBUG_GDB_STUBS
+    implements    CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
+    implements    CYGINT_HAL_ARM_ARCH_ARM7
+    implements    CYGINT_HAL_ARM_THUMB_ARCH
+
+    # Let the architectural HAL see this variant's files
+    define_proc {
+        puts $::cdl_header "#define CYGBLD_HAL_VAR_INTS_H <cyg/hal/hal_var_ints.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_IO_H"
+        puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_ARCH_H"
+    }
+
+    cdl_component CYGHWR_HAL_ARM_LPC24XX {
+        display        "LPC24XX variant used"
+        flavor         data
+        default_value  { "LPC246x" }
+        legal_values   { "LPC246x" "LPC2458" "LPC2460" "LPC2468" "LPC2470" 
+                         "LPC2478"}
+        description    "
+             The LPC24XX microcontroller family has several variants,
+             the main differences being the amount of on-chip RAM,
+             flash and peripherals. This option allows the platform
+             HALs to select the specific microcontroller being used."
+
+        cdl_option CYGHWR_HAL_ARM_LPC24XX_FAMILY {
+            display       "LPC24XX variant family"
+            flavor        data
+            calculated    {
+                is_substr(CYGHWR_HAL_ARM_LPC24XX, "LPC246") ? 
+                   "LPC246X" : "LPC24XX"
+                          }
+            description   "
+                This specifies the family that the processor
+                belongs to. This is useful as it defines certain common
+                characteristics which affect which features should be
+                available in the HAL."
+        }
+    }
+    
+    # This is going to get really messy before long as the number of parts
+    # explodes. Its useful to know the actual part in use, but its just as
+    # useful to know which family it belongs to. LPC210x shouldn't really
+    # be in the list of devices, but will probably break something if removed.
+    cdl_component CYGHWR_HAL_ARM_LPC2XXX {
+        display        "LPC2XXX variant used"
+        flavor         data
+        calculated     CYGHWR_HAL_ARM_LPC24XX
+        description    "
+             This option is only here for compatibility reasons because some of
+             the LPC2XXX device drivers rely on these definitions. If this
+             is defined here, the LPC24XX variant can use the LPC2XXX device
+             drivers for on-chip peripherals."
+
+        cdl_option CYGHWR_HAL_ARM_LPC2XXX_FAMILY {
+            display       "LPC2XXX variant family"
+            flavor        data
+            calculated    CYGHWR_HAL_ARM_LPC24XX_FAMILY
+            description   "
+                 This option is only here for compatibility reasons
+                 because some of the LPC2XXX device drivers rely on
+                 these definitions. If this is defined here, the
+                 LPC24XX variant can use the LPC2XXX device drivers
+                 for on-chip peripherals."
+        }
+        
+        cdl_option CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION {
+            display       "LPC2XXX variant version"
+            flavor        data
+            calculated    {
+                is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC21") ? 1 :
+                is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC22") ? 2 :
+                is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC24") ? 4 : 0
+                          }
+            description   "
+                This specifies the variant version that the processor
+                belongs to. Some common characteristics may be 
+                different in newer LPC2xxx versions. I.e. the LPC24xx variants
+                are significant different from former LPC2xxx variants." 
+        }
+    }
+
+    # Important! Be very careful changing this value. That will always
+    # enter the LPC24XX bootloader after reset and consequently will
+    # never run your code. You must know what you are doing. Look at
+    # arch. vectors.S for details.
+    cdl_option CYGNUM_HAL_ARM_VECTOR_0x14 {
+        display       "ARM vector at 0x14"
+        flavor        data
+        default_value 0xB4405F62
+        legal_values  0 to 0xFFFFFFFF
+        description "
+           In order to detect if a valid program is present, every
+           user program must have a program signature. This signature
+           is a word-wide number that is stored in the unused
+           location in the ARM7 vector table at 0x00000014. The
+           program signature is the two's compliment of the checksum
+           of the ARM vector table."
+    }
+
+    cdl_component CYGNUM_HAL_ARM_LPC24XX_CLOCKING {
+        display       "Clocking"
+        flavor        none
+
+        cdl_option CYGNUM_HAL_ARM_LPC24XX_PLL_MUL {
+            display       "PLL multiplier"
+            flavor        data
+            legal_values  6 to 32767
+            default_value { 12 }
+        }
+    
+        cdl_option CYGNUM_HAL_ARM_LPC24XX_PLL_DIV {
+            display       "PLL divider"
+            flavor         data
+            legal_values  1 to 32 
+            default_value { 1 }
+        }
+
+        cdl_option CYGNUM_HAL_ARM_LPC24XX_PLL_OUTPUT {
+            display       "PLL output (MHz)"
+            flavor         data
+            legal_values   275000000 to 290000000
+            calculated {  2 * CYGNUM_HAL_ARM_LPC24XX_PLL_MUL * 
+                          CYGNUM_HAL_ARM_LPC24XX_XTAL_FREQ / 
+                          CYGNUM_HAL_ARM_LPC24XX_PLL_DIV}
+            description "
+                Normally the PLL output must be in the range of 275 MHz to 
+                550 MHz Because of a chip errata the maximum output of the CCO 
+                within the PLL block is limited to 290 MHz."
+        }
+       
+        cdl_component CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED {
+            display       "CPU clock speed"
+            flavor        data
+            calculated {  2 * CYGNUM_HAL_ARM_LPC24XX_PLL_MUL * 
+                          CYGNUM_HAL_ARM_LPC24XX_XTAL_FREQ / 
+                          CYGNUM_HAL_ARM_LPC24XX_PLL_DIV / 
+                          CYGNUM_HAL_ARM_LPC24XX_CPU_CLK_DIV}
+            description "
+                The core CPU clock speed is the PLL output divided by the 
+                CPU clock divider" 
+                
+            cdl_option CYGNUM_HAL_ARM_LPC24XX_CPU_CLK_DIV {
+                display       "CPU clock divider"
+                flavor        data
+                legal_values  6 to 256
+                default_value { 6 }
+                description "
+                    The CPU clock divider controls the division of the PLL 
+                    output before it is used by the CPU. When the PLL is 
+                    bypassed, the division may be by 1. When the PLL is 
+                    running, the output must be divided in order to bring the 
+                    CPU clock frequency (CCLK) within operating limits. An 8 
+                    bit divider allows a range of options, including slowing 
+                    CPU operation to a low rate for temporary power savings 
+                    without turning off the PLL. Only even values 
+                    (2, 4, 6, ..., 256) are supported and can be used. 
+                    Warning: Using an odd value (1, 3, 5, ..., 255) when 
+                    setting this option may result in incorrect operation of 
+                    the device."
+             }    
+        }
+    
+        
+        cdl_component CYGNUM_HAL_ARM_LPC24XX_USB_CLOCK_SPEED {
+            display       "USB clock speed"
+            flavor        data
+            calculated {  2 * CYGNUM_HAL_ARM_LPC24XX_PLL_MUL * 
+                          CYGNUM_HAL_ARM_LPC24XX_XTAL_FREQ / 
+                          CYGNUM_HAL_ARM_LPC24XX_PLL_DIV / 
+                          CYGNUM_HAL_ARM_LPC24XX_USB_CLK_DIV}
+            description "
+                The USB clock speed is the PLL output divided by the 
+                USB clock divider" 
+                
+            cdl_option CYGNUM_HAL_ARM_LPC24XX_USB_CLK_DIV {
+                display       "USB clock divider"
+                flavor        data
+                legal_values  1 to 8
+                default_value { 6 }
+                description "
+                    This divider controls the division of the PLL output before 
+                    it is used by the USB block. If the PLL is bypassed, the 
+                    division may be by 1. In that case, the PLL input frequency 
+                    must be 48 MHz, with a 500 ppm tolerance. When the PLL is 
+                    running, the output must be divided in order to bring the 
+                    USB clock frequency to 48 MHz with a 50% duty cycle. A 
+                    4-bit divider allows obtaining the correct USB clock from 
+                    any even multiple of 48 MHz (i.e. any mutliple of 96 MHz) 
+                    within the PLL operating range."
+            }
+        }
+        
+        cdl_component CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK {
+            display       "CAN clock speed"
+            flavor        data
+            calculated   {  CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED / 
+                            CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV}
+            description "
+                The CAN clock speed is the CPU clock output divided by the 
+                CAN clock divider" 
+                
+            cdl_option CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV {
+                display       "CAN clock divider"
+                flavor        data
+                legal_values  { 1 2 4 6 }
+                default_value { 1 }
+                description "
+                    This divider selects the peripheral clock for both CAN 
+                    channels. The divider divides the CPU clock to get the 
+                    clock for the CAN peripherals."
+            }
+        }      
+    }
+    
+    cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+        display       "Real-time clock constants"
+        flavor        none
+
+        cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+            display       "Real-time clock numerator"
+            flavor        data
+            default_value 1000000000
+        }
+        cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+            display       "Real-time clock denominator"
+            flavor        data
+            default_value 100
+        }
+        cdl_option CYGNUM_HAL_RTC_PERIOD {
+            display       "Real-time clock period"
+            flavor        data
+            default_value { ((CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED) / 
+                              CYGNUM_HAL_RTC_DENOMINATOR) }
+        }
+    }
+
+    cdl_option CYGHWR_HAL_ARM_LPC24XX_IDLE_PWRSAVE {
+        display       "Stop clock in idle loop to save power"
+        flavor        bool
+        default_value { is_active(CYGPKG_REDBOOT) ? 0 : 1 }
+        description   "
+           Select this option when it is desired to save power by
+           stopping the processor clock in the idle loop. This is
+           controlled by the PCON register. Generally this is a good
+           thing, but it may be necessary to disable this when
+           debugging via JTAG, as stopping the clock can prevent the
+           debugger getting control of the system."
+    }
+    
+    cdl_option CYGNUM_HAL_KERNEL_COUNTERS_CLOCK_ISR_DEFAULT_PRIORITY {
+           display             "Default priority for system clock interrupts"
+           flavor              data
+           legal_values  { 0 to 15 }
+        default_value 15
+           description "
+            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, allowing a single write to elevate the priority 
+            of an individual interrupt."
+    }
+
+}
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/include/hal_cache.h b/packages/hal/arm/lpc24xx/var/v2_0/include/hal_cache.h
new file mode 100755 (executable)
index 0000000..4d34161
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef CYGONCE_HAL_CACHE_H
+#define CYGONCE_HAL_CACHE_H
+
+//=============================================================================
+//
+//      hal_cache.h
+//
+//      HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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:
+// Date:        2004-09-08
+// Purpose:     Cache control API
+// Description: The macros defined here provide the HAL APIs for handling
+//              cache control operations.
+// Usage:
+//              #include <cyg/hal/hal_cache.h>
+//              ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//-----------------------------------------------------------------------------
+// Global control of data cache
+
+// Enable the data cache
+#define HAL_DCACHE_ENABLE()
+
+// Disable the data cache
+#define HAL_DCACHE_DISABLE()
+
+// Invalidate the entire cache
+#define HAL_DCACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_DCACHE_SYNC()
+
+// Purge contents of data cache
+#define HAL_DCACHE_PURGE_ALL()
+
+// Query the state of the data cache (does not affect the caching)
+#define HAL_DCACHE_IS_ENABLED(_state_)          \
+    CYG_MACRO_START                             \
+    (_state_) = 0;                              \
+    CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+// Global control of Instruction cache
+
+// Enable the instruction cache
+#define HAL_ICACHE_ENABLE()
+
+// Disable the instruction cache
+#define HAL_ICACHE_DISABLE()
+
+// Invalidate the entire cache
+#define HAL_ICACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_ICACHE_SYNC()
+
+// Query the state of the instruction cache (does not affect the caching)
+#define HAL_ICACHE_IS_ENABLED(_state_)          \
+    CYG_MACRO_START                             \
+    (_state_) = 0;                              \
+    CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_CACHE_H
+// End of hal_cache.h
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/include/hal_diag.h b/packages/hal/arm/lpc24xx/var/v2_0/include/hal_diag.h
new file mode 100755 (executable)
index 0000000..cd33054
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef CYGONCE_HAL_DIAG_H
+#define CYGONCE_HAL_DIAG_H
+//=============================================================================
+//
+//      hal_diag.h
+//
+//      HAL Support for Kernel Diagnostic Routines
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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, tkoeller
+// Date:        2001-07-12
+// Purpose:     HAL Support for Kernel Diagnostic Routines
+// Description: Diagnostic routines for use during kernel development.
+// Usage:       #include <cyg/hal/hal_diag.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+//-----------------------------------------------------------------------------
+// LED
+externC void hal_diag_led(int mask);
+externC void hal_lpc24xx_set_leds(int mask);
+
+//-----------------------------------------------------------------------------
+// delay
+
+externC void hal_delay_us(cyg_int32 usecs);
+#define HAL_DELAY_US(n) hal_delay_us(n);
+
+//-----------------------------------------------------------------------------
+// end of hal_diag.h
+#endif // CYGONCE_HAL_DIAG_H
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/include/hal_var_ints.h b/packages/hal/arm/lpc24xx/var/v2_0/include/hal_var_ints.h
new file mode 100755 (executable)
index 0000000..b9ded61
--- /dev/null
@@ -0,0 +1,116 @@
+#ifndef CYGONCE_HAL_VAR_INTS_H
+#define CYGONCE_HAL_VAR_INTS_H
+//==========================================================================
+//
+//      hal_var_ints.h
+//
+//      HAL Interrupt and clock support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-05
+// Purpose:      Define Interrupt support
+// Description:  The interrupt details for the LPC24XX are defined here.
+// Usage:
+//              #include <pkgconf/system.h>
+//              #include CYGBLD_HAL_VARIANT_H
+//               #include CYGBLD_HAL_VAR_INTS_H
+//
+//               ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#define CYGNUM_HAL_INTERRUPT_WD      0
+#define CYGNUM_HAL_INTERRUPT_SOFT    1
+#define CYGNUM_HAL_INTERRUPT_DCC_RX  2
+#define CYGNUM_HAL_INTERRUPT_DCC_TX  3
+#define CYGNUM_HAL_INTERRUPT_TIMER0  4
+#define CYGNUM_HAL_INTERRUPT_TIMER1  5
+#define CYGNUM_HAL_INTERRUPT_UART0   6
+#define CYGNUM_HAL_INTERRUPT_UART1   7
+#define CYGNUM_HAL_INTERRUPT_PWM0    8
+#define CYGNUM_HAL_INTERRUPT_I2C     9
+#define CYGNUM_HAL_INTERRUPT_SPI0    10
+#define CYGNUM_HAL_INTERRUPT_SPI1    11
+#define CYGNUM_HAL_INTERRUPT_PLL     12
+#define CYGNUM_HAL_INTERRUPT_RTCDEV  13        // actual RTC device not the
+                                        // eCos 'real time clock'
+                                        // interrupt. The latter is on
+                                        // TIMER0.
+#define CYGNUM_HAL_INTERRUPT_EINT0   14
+#define CYGNUM_HAL_INTERRUPT_EINT1   15
+#define CYGNUM_HAL_INTERRUPT_EINT2   16
+#define CYGNUM_HAL_INTERRUPT_EINT3   17
+#define CYGNUM_HAL_INTERRUPT_AD      18 
+#define CYGNUM_HAL_INTERRUPT_I2C1    19
+#define CYGNUM_HAL_INTERRUPT_BOD     20
+#define CYGNUM_HAL_INTERRUPT_ETH     21
+#define CYGNUM_HAL_INTERRUPT_USB     22
+#define CYGNUM_HAL_INTERRUPT_CAN     23
+#define CYGNUM_HAL_INTERRUPT_SD_MMC  24
+#define CYGNUM_HAL_INTERRUPT_DMA     25
+#define CYGNUM_HAL_INTERRUPT_TIMER2  26
+#define CYGNUM_HAL_INTERRUPT_TIMER3  27
+#define CYGNUM_HAL_INTERRUPT_UART2   28
+#define CYGNUM_HAL_INTERRUPT_UART3   29
+#define CYGNUM_HAL_INTERRUPT_I2C2    30
+#define CYGNUM_HAL_INTERRUPT_I2S     31
+
+
+#define CYGNUM_HAL_ISR_MIN           0
+#define CYGNUM_HAL_ISR_MAX           (31)
+
+#define CYGNUM_HAL_ISR_COUNT         (CYGNUM_HAL_ISR_MAX+1)
+
+/* use non-vectored interrupts in kernel tests intr0/kintr0 */
+#define HAL_INTR_TEST_PRIO_A 16
+#define HAL_INTR_TEST_PRIO_B 16
+#define HAL_INTR_TEST_PRIO_C 16
+
+//The vector used by the Real time clock
+#define CYGNUM_HAL_INTERRUPT_RTC     CYGNUM_HAL_INTERRUPT_TIMER0
+
+// Other entries here moved to variant specific include file
+// This is included here to avoid breaking anything
+#include <cyg/hal/lpc24xx_misc.h>
+
+//---------------------------------------------------------------------------
+#endif // CYGONCE_HAL_VAR_INTS_H
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/include/lpc24xx_misc.h b/packages/hal/arm/lpc24xx/var/v2_0/include/lpc24xx_misc.h
new file mode 100755 (executable)
index 0000000..ebd3f20
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef CYGONCE_HAL_ARM_LPC24XX_VAR_LPC24XX_MISC_H
+#define CYGONCE_HAL_ARM_LPC24XX_VAR_LPC24XX_MISC_H
+//=============================================================================
+//
+//      lpc24xx_misc.h
+//
+//      HAL misc variant support code for NCP LPC24xx header file
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    andyj 
+// Contributors: jani
+// Date:         2006-02-04
+// Purpose:      LPC2XXX specific miscellaneous support header file
+// Description: 
+// Usage:        #include <cyg/hal/lpc24xx_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Functions to obtain the current processor clock settings
+//-----------------------------------------------------------------------------
+externC cyg_uint32 hal_lpc_get_pclk(cyg_uint32 peripheral_id);
+
+//
+// Identifiers for peripheral clock. Use these identifiers with the function
+// hal_get_pclk()
+//
+#define CYNUM_HAL_LPC24XX_PCLK_WDT    0
+#define CYNUM_HAL_LPC24XX_PCLK_TIMER0 1
+#define CYNUM_HAL_LPC24XX_PCLK_TIMER1 2
+#define CYNUM_HAL_LPC24XX_PCLK_UART0  3
+#define CYNUM_HAL_LPC24XX_PCLK_UART1  4
+#define CYNUM_HAL_LPC24XX_PCLK_PWM0   5
+#define CYNUM_HAL_LPC24XX_PCLK_PWM1   6
+#define CYNUM_HAL_LPC24XX_PCLK_I2C0   7
+#define CYNUM_HAL_LPC24XX_PCLK_SPI    8
+#define CYNUM_HAL_LPC24XX_PCLK_RTC    9
+#define CYNUM_HAL_LPC24XX_PCLK_SSP1   10
+#define CYNUM_HAL_LPC24XX_PCLK_DAC    11
+#define CYNUM_HAL_LPC24XX_PCLK_ADC    12
+#define CYNUM_HAL_LPC24XX_PCLK_CAN1   13
+#define CYNUM_HAL_LPC24XX_PCLK_CAN2   14
+#define CYNUM_HAL_LPC24XX_PCLK_ACF    15
+#define CYNUM_HAL_LPC24XX_PCLK_BATRAM 16
+#define CYNUM_HAL_LPC24XX_PCLK_GPIO   17
+#define CYNUM_HAL_LPC24XX_PCLK_PCB    18
+#define CYNUM_HAL_LPC24XX_PCLK_I2C1   19
+#define CYNUM_HAL_LPC24XX_PCLK_SSP0   21
+#define CYNUM_HAL_LPC24XX_PCLK_TIMER2 22
+#define CYNUM_HAL_LPC24XX_PCLK_TIMER3 23
+#define CYNUM_HAL_LPC24XX_PCLK_UART2  24
+#define CYNUM_HAL_LPC24XX_PCLK_UART3  25
+#define CYNUM_HAL_LPC24XX_PCLK_I2C2   26
+#define CYNUM_HAL_LPC24XX_PCLK_I2S    27
+#define CYNUM_HAL_LPC24XX_PCLK_MCI    28
+#define CYNUM_HAL_LPC24XX_PCLK_SYSCON 30
+
+
+//-----------------------------------------------------------------------------
+// Macros to derive the baudrate divider values for the internal UARTs
+// The LPC24xx family supports differents baudrate clocks for each single
+// UART. So we need a way to calculate the baudrate for each single UART
+// Now we rely on the fact that we use the same baurate clock for all
+// UARTs and we query only UART0
+//-----------------------------------------------------------------------------
+#define CYG_HAL_ARM_LPC24XX_PCLK(_pclkid_) hal_lpc_get_pclk(_pclkid_) 
+#define CYG_HAL_ARM_LPC2XXX_BAUD_GENERATOR(baud) \
+            (CYG_HAL_ARM_LPC24XX_PCLK(CYNUM_HAL_LPC24XX_PCLK_UART0)/((baud)*16))
+#define CYG_HAL_ARM_LPC24XX_BAUD_GENERATOR(_pclkid_, baud) \
+            (CYG_HAL_ARM_LPC24XX_PCLK(_pclkid_)/((baud)*16))
+            
+
+//-----------------------------------------------------------------------------
+// LPX24xx platform reset (watchdog resets the board)
+//-----------------------------------------------------------------------------
+externC void hal_lpc_watchdog_reset(void);
+
+#define HAL_PLATFORM_RESET() hal_lpc_watchdog_reset()
+#define HAL_PLATFORM_RESET_ENTRY 0
+
+//-----------------------------------------------------------------------------
+// end of lpc24xx_misc.h
+#endif // CYGONCE_HAL_ARM_LPC24XX_VAR_LPC24XX_MISC_H
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/include/plf_stub.h b/packages/hal/arm/lpc24xx/var/v2_0/include/plf_stub.h
new file mode 100755 (executable)
index 0000000..328d6f3
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef CYGONCE_HAL_PLF_STUB_H
+#define CYGONCE_HAL_PLF_STUB_H
+
+//=============================================================================
+//
+//      plf_stub.h
+//
+//      Platform header for GDB stub support.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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:jskov, gthomas
+// Date:        2004-10-5
+// Purpose:     Platform HAL stub support for LPC2XXX based boards.
+// Usage:       #include <cyg/hal/plf_stub.h>
+//              
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h>         // CYG_UNUSED_PARAM
+
+#include <cyg/hal/arm_stub.h>           // architecture stub support
+
+//----------------------------------------------------------------------------
+// Define some platform specific communication details. This is mostly
+// handled by hal_if now, but we need to make sure the comms tables are
+// properly initialized.
+
+externC void cyg_hal_plf_comms_init(void);
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL()       cyg_hal_plf_comms_init()
+
+#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud))
+#define HAL_STUB_PLATFORM_INTERRUPTIBLE       0
+#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ()    CYG_EMPTY_STATEMENT
+
+//----------------------------------------------------------------------------
+// Stub initializer.
+#define HAL_STUB_PLATFORM_INIT()              CYG_EMPTY_STATEMENT
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_PLF_STUB_H
+// End of plf_stub.h
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/include/var_arch.h b/packages/hal/arm/lpc24xx/var/v2_0/include/var_arch.h
new file mode 100755 (executable)
index 0000000..efd02ef
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef CYGONCE_HAL_VAR_ARCH_H
+#define CYGONCE_HAL_VAR_ARCH_H
+//=============================================================================
+//
+//      var_arch.h
+//
+//      LPC24XX variant architecture overrides
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Jonathan Larmour <jifl@eCosCentric.com>
+// Copyright (C) 2004 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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: jlarmour,Daniel Neri
+// Date:         2008-07-06
+// Purpose:      LPC24XX variant architecture overrides
+// Description: 
+// Usage:        #include <cyg/hal/hal_arch.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Idle thread code.
+// This macro is called in the idle thread loop, and gives the HAL the
+// chance to insert code. Typical idle thread behaviour might be to halt the
+// processor. These implementations halt the system core clock.
+
+#ifdef CYGHWR_HAL_ARM_LPC24XX_IDLE_PWRSAVE
+#ifndef HAL_IDLE_THREAD_ACTION
+
+#define HAL_IDLE_THREAD_ACTION(_count_)                       \
+CYG_MACRO_START                                               \
+HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE +            \
+                 CYGARC_HAL_LPC24XX_REG_PCON,                 \
+                 CYGARC_HAL_LPC24XX_REG_PCON_IDL);            \
+CYG_MACRO_END
+
+#endif         // HAL_IDLE_THREAD_ACTION
+#endif         // CYGHWR_HAL_ARM_LPC24XX_IDLE_MODE
+
+//-----------------------------------------------------------------------------
+// end of var_arch.h
+#endif // CYGONCE_HAL_VAR_ARCH_H
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/include/var_io.h b/packages/hal/arm/lpc24xx/var/v2_0/include/var_io.h
new file mode 100755 (executable)
index 0000000..6654ba3
--- /dev/null
@@ -0,0 +1,840 @@
+#ifndef CYGONCE_HAL_VAR_IO_H
+#define CYGONCE_HAL_VAR_IO_H
+//=============================================================================
+//
+//      var_io.h
+//
+//      Variant specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-05
+// Purpose:     NXP LPC24xx variant specific registers
+// Description: 
+// Usage:       #include <cyg/hal/var_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal_arm_lpc24xx.h>  // variant chip model selection.
+#include <cyg/hal/plf_io.h>
+
+//=============================================================================
+// Watchdog (WD)
+#define CYGARC_HAL_LPC24XX_REG_WD_BASE                   0xE0000000
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_WDMOD                     0x0000
+#define CYGARC_HAL_LPC24XX_REG_WDMOD_WDEN                (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_WDMOD_WDRESET             (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_WDMOD_WDTOF               (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_WDMOD_WDINT               (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_WDTC                      0x0004
+#define CYGARC_HAL_LPC24XX_REG_WDFEED                    0x0008
+#define CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC1             0xAA
+#define CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC2             0x55
+#define CYGARC_HAL_LPC24XX_REG_WDTV                      0x000C
+
+
+//=============================================================================
+// Timers (Tx)
+
+#define CYGARC_HAL_LPC24XX_REG_TIMER0_BASE               0xE0004000
+#define CYGARC_HAL_LPC24XX_REG_TIMER1_BASE               0xE0008000
+#define CYGARC_HAL_LPC24XX_REG_TIMER2_BASE               0xE0070000
+#define CYGARC_HAL_LPC24XX_REG_TIMER3_BASE               0xE0074000
+
+// Registers are offsets from base for each timer
+#define CYGARC_HAL_LPC24XX_REG_TxIR                      0x0000
+#define CYGARC_HAL_LPC24XX_REG_TxIR_MR0                  (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_MR1                  (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_MR2                  (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_MR3                  (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_CR0                  (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_CR1                  (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_CR2                  (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_CR3                  (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_TxTCR                     0x0004
+#define CYGARC_HAL_LPC24XX_REG_TxTCR_CTR_ENABLE          (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_TxTCR_CTR_RESET           (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_TxTC                      0x0008
+#define CYGARC_HAL_LPC24XX_REG_TxPR                      0x000C
+#define CYGARC_HAL_LPC24XX_REG_TxPC                      0x0010
+#define CYGARC_HAL_LPC24XX_REG_TxMCR                     0x0014
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_INT             (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_RESET           (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_STOP            (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR1_INT             (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR1_RESET           (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR1_STOP            (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR2_INT             (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR2_RESET           (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR2_STOP            (1<<8)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR3_INT             (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR3_RESET           (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR3_STOP            (1<<11)
+#define CYGARC_HAL_LPC24XX_REG_TxMR0                     0x0018
+#define CYGARC_HAL_LPC24XX_REG_TxMR1                     0x001C
+#define CYGARC_HAL_LPC24XX_REG_TxMR2                     0x0020
+#define CYGARC_HAL_LPC24XX_REG_TxMR3                     0x0024
+#define CYGARC_HAL_LPC24XX_REG_TxCCR                     0x0028
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR0_RISE        (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR0_FALL        (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR0             (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR1_RISE        (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR1_FALL        (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR1             (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR2_RISE        (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR2_FALL        (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR2             (1<<8)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR3_RISE        (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR3_FALL        (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR3             (1<<11)
+#define CYGARC_HAL_LPC24XX_REG_TxCR0                     0x002C
+#define CYGARC_HAL_LPC24XX_REG_TxCR1                     0x0030
+#define CYGARC_HAL_LPC24XX_REG_TxCR2                     0x0034
+#define CYGARC_HAL_LPC24XX_REG_TxCR3                     0x0038
+#define CYGARC_HAL_LPC24XX_REG_TxEMR                     0x003C
+#define CYGARC_HAL_LPC24XX_REG_TxEMR_EM0                 (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_TxEMR_EM1                 (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_TxEMR_EM2                 (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_TxEMR_EM3                 (1<<3)
+
+//=============================================================================
+// UARTs (Ux)
+
+#define CYGARC_HAL_LPC24XX_REG_UART0_BASE                0xE000C000
+#define CYGARC_HAL_LPC24XX_REG_UART1_BASE                0xE0010000
+#define CYGARC_HAL_LPC24XX_REG_UART2_BASE                0xE0078000
+#define CYGARC_HAL_LPC24XX_REG_UART3_BASE                0xE007C000
+
+// Registers are offsets from base for each UART
+#define CYGARC_HAL_LPC24XX_REG_UxRBR                     0x0000 // DLAB=0 read
+#define CYGARC_HAL_LPC24XX_REG_UxTHR                     0x0000 // DLAB=0 write
+#define CYGARC_HAL_LPC24XX_REG_UxDLL                     0x0000 // DLAB=1 r/w
+#define CYGARC_HAL_LPC24XX_REG_UxIER                     0x0004 // DLAB=0
+#define CYGARC_HAL_LPC24XX_REG_UxIER_RXDATA_INT          (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_UxIER_THRE_INT            (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_UxIER_RXLS_INT            (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_U1IER_RXMS_INT            (1<<3) // U1 only
+#define CYGARC_HAL_LPC24XX_REG_UxDLM                     0x0004 // DLAB=1
+
+#define CYGARC_HAL_LPC24XX_REG_UxIIR                     0x0008 // read
+#define CYGARC_HAL_LPC24XX_REG_UxIIR_IIR0                (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_UxIIR_IIR1                (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_UxIIR_IIR2                (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_UxIIR_IIR3                (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_UxIIR_FIFOS               (0xB0)
+
+#define CYGARC_HAL_LPC24XX_REG_UxFCR                     0x0008 // write
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_FIFO_ENA            (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_RX_FIFO_RESET       (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_TX_FIFO_RESET       (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_RX_TRIGGER_0        (0x00)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_RX_TRIGGER_1        (0x40)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_RX_TRIGGER_2        (0x80)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_RX_TRIGGER_3        (0xB0)
+
+#define CYGARC_HAL_LPC24XX_REG_UxLCR                     0x000C
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_WORD_LENGTH_5       (0x00)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_WORD_LENGTH_6       (0x01)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_WORD_LENGTH_7       (0x02)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_WORD_LENGTH_8       (0x03)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_STOP_1              (0x00)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_STOP_2              (0x04)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_PARITY_ENA          (0x08)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_PARITY_ODD          (0x00)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_PARITY_EVEN         (0x10)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_PARITY_ONE          (0x20)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_PARITY_ZERO         (0x30)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_BREAK_ENA           (0x40)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_DLAB                (0x80)
+
+
+// Modem Control Register is UART1 only
+#define CYGARC_HAL_LPC24XX_REG_U1MCR                     0x0010
+#define CYGARC_HAL_LPC24XX_REG_U1MCR_DTR                 (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_U1MCR_RTS                 (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_U1MCR_LOOPBACK            (1<<4)
+
+#define CYGARC_HAL_LPC24XX_REG_UxLSR                     0x0014
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_RDR                 (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_OE                  (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_PE                  (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_FE                  (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_BI                  (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_THRE                (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_TEMT                (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_RX_FIFO_ERR         (1<<7)
+
+// Modem Status Register is UART1 only
+#define CYGARC_HAL_LPC24XX_REG_U1MSR                     0x0018
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_DCTS                (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_DDSR                (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_RI_FALL             (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_DDCD                (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_CTS                 (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_DSR                 (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_RI                  (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_DCD                 (1<<7)
+
+#define CYGARC_HAL_LPC24XX_REG_UxSCR                     0x001C
+#define CYGARC_HAL_LPC24XX_REG_UxACR                     0x0020
+#define CYGARC_HAL_LPC24XX_REG_U3ICR                     0x0024
+#define CYGARC_HAL_LPC24XX_REG_UxFDR                     0x0028
+#define CYCARC_HAL_LPC24XX_REG_UxTER                     0x0030
+
+
+//=============================================================================
+// Pulse Width Modulator (PWM)
+
+#define CYGARC_HAL_LPC24XX_REG_PWM0_BASE                 0xE0014000
+#define CYGARC_HAL_LPC24XX_REG_PWM1_BASE                 0xE0018000
+
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_PWMIR                     0x0000
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR0_INT             (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR1_INT             (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR2_INT             (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR3_INT             (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR4_INT             (1<<8)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR5_INT             (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR6_INT             (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_PWMTCR                    0x0004
+#define CYGARC_HAL_LPC24XX_REG_PWMTCR_CTR_ENA            (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PWMTCR_CTR_RESET          (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PWMTCR_PWM_ENA            (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PWMTC                     0x0008
+#define CYGARC_HAL_LPC24XX_REG_PWMPR                     0x000C
+#define CYGARC_HAL_LPC24XX_REG_PWMPC                     0x0010
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR                    0x0014
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR0_INT            (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR0_RESET          (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR0_STOP           (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR1_INT            (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR1_RESET          (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR1_STOP           (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR2_INT            (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR2_RESET          (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR2_STOP           (1<<8)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR3_INT            (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR3_RESET          (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR3_STOP           (1<<11)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR4_INT            (1<<12)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR4_RESET          (1<<13)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR4_STOP           (1<<14)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR5_INT            (1<<15)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR5_RESET          (1<<16)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR5_STOP           (1<<17)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR6_INT            (1<<18)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR6_RESET          (1<<19)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR6_STOP           (1<<20)
+#define CYGARC_HAL_LPC24XX_REG_PWMMR0                    0x0018
+#define CYGARC_HAL_LPC24XX_REG_PWMMR1                    0x001C
+#define CYGARC_HAL_LPC24XX_REG_PWMMR2                    0x0020
+#define CYGARC_HAL_LPC24XX_REG_PWMMR3                    0x0024
+#define CYGARC_HAL_LPC24XX_REG_PWMMR4                    0x0040
+#define CYGARC_HAL_LPC24XX_REG_PWMMR5                    0x0044
+#define CYGARC_HAL_LPC24XX_REG_PWMMR6                    0x0048
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR                   0x004C
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL1              (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL2              (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL3              (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL4              (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL5              (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL6              (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA1              (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA2              (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA3              (1<<11)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA4              (1<<12)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA5              (1<<13)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA6              (1<<14)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER                    0x0050
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M0_ENA             (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M1_ENA             (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M2_ENA             (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M3_ENA             (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M4_ENA             (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M5_ENA             (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M6_ENA             (1<<6)
+
+#define CYGARC_HAL_LPC24XX_REG_PWMCTCR                   0x0070
+
+//=============================================================================
+// I2C (I2)
+
+#define CYGARC_HAL_LPC24XX_REG_I2C0_BASE                 0xE001C000
+#define CYGARC_HAL_LPC24XX_REG_I2C1_BASE                 0xE005C000
+#define CYGARC_HAL_LPC24XX_REG_I2C2_BASE                 0xE0080000
+
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET                  0x0000
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET_AA               (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET_SI               (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET_STO              (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET_STA              (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET_I2EN             (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_I2STAT                    0x0004
+#define CYGARC_HAL_LPC24XX_REG_I2STAT_SHIFT              3
+#define CYGARC_HAL_LPC24XX_REG_I2DAT                     0x0008
+#define CYGARC_HAL_LPC24XX_REG_I2ADR                     0x000C
+#define CYGARC_HAL_LPC24XX_REG_I2ADR_GC                  (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_I2SCLH                    0x0010
+#define CYGARC_HAL_LPC24XX_REG_I2SCLL                    0x0014
+#define CYGARC_HAL_LPC24XX_REG_I2CONCLR                  0x0018
+#define CYGARC_HAL_LPC24XX_REG_I2CONCLR_AAC              (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_I2CONCLR_SIC              (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_I2CONCLR_STAC             (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_I2CONCLR_I2ENC            (1<<6)
+
+//=============================================================================
+// SPI (S)
+
+#define CYGARC_HAL_LPC24XX_REG_SPI0_BASE                  0xE0020000
+#define CYGARC_HAL_LPC24XX_REG_SPI1_BASE                  0xE0030000
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR                   0x0000
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR_CPHA              (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR_CPOL              (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR_MSTR              (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR_LSBF              (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR_SPIE              (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR                   0x0004
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR_ABRT              (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR_MODF              (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR_ROVR              (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR_WCOL              (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR_SPIF              (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPDR                   0x0008
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCCR                  0x000C
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPINT                  0x001C
+
+
+//=============================================================================
+// RTC
+
+#define CYGARC_HAL_LPC24XX_REG_RTC_BASE                   0xE0024000
+
+// Registers are offsets from base of this subsystem
+
+#define CYGARC_HAL_LPC24XX_REG_RTC_ILR                    0x0000
+#define CYGARC_HAL_LPC24XX_REG_RTC_ILR_CIF                (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_RTC_ILR_ALF                (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_RTC_CTC                    0x0004
+#define CYGARC_HAL_LPC24XX_REG_RTC_CCR                    0x0008
+#define CYGARC_HAL_LPC24XX_REG_RTC_CCR_CLKEN              (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_RTC_CCR_CTCRST             (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_RTC_CIIR                   0x000C
+#define CYGARC_HAL_LPC24XX_REG_RTC_AMR                    0x0010
+#define CYGARC_HAL_LPC24XX_REG_RTC_CTIME0                 0x0014
+#define CYGARC_HAL_LPC24XX_REG_RTC_CTIME1                 0x0018
+#define CYGARC_HAL_LPC24XX_REG_RTC_CTIME2                 0x001C
+#define CYGARC_HAL_LPC24XX_REG_RTC_SEC                    0x0020
+#define CYGARC_HAL_LPC24XX_REG_RTC_MIN                    0x0024
+#define CYGARC_HAL_LPC24XX_REG_RTC_HOUR                   0x0028
+#define CYGARC_HAL_LPC24XX_REG_RTC_DOM                    0x002C
+#define CYGARC_HAL_LPC24XX_REG_RTC_DOW                    0x0030
+#define CYGARC_HAL_LPC24XX_REG_RTC_DOY                    0x0034
+#define CYGARC_HAL_LPC24XX_REG_RTC_MONTH                  0x0038
+#define CYGARC_HAL_LPC24XX_REG_RTC_YEAR                   0x003C
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALSEC                  0x0060
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALMIN                  0x0064
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALHOUR                 0x0068
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALDOM                  0x006C
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALDOW                  0x0070
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALDOY                  0x0074
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALMON                  0x0078
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALYEAR                 0x007C
+#define CYGARC_HAL_LPC24XX_REG_RTC_PREINT                 0x0080
+#define CYGARC_HAL_LPC24XX_REG_RTC_PREFRAC                0x0084
+
+//=============================================================================
+// GPIO (IO)
+
+#define CYGARC_HAL_LPC24XX_REG_IO_BASE                   0xE0028000
+#define CYGARC_HAL_LPC24XX_REG_FIO_BASE                  0x3FFFC000
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_IO0PIN                    0x000
+#define CYGARC_HAL_LPC24XX_REG_IO0SET                    0x004
+#define CYGARC_HAL_LPC24XX_REG_IO0DIR                    0x008
+#define CYGARC_HAL_LPC24XX_REG_IO0CLR                    0x00C
+
+#define CYGARC_HAL_LPC24XX_REG_IO1PIN                    0x010
+#define CYGARC_HAL_LPC24XX_REG_IO1SET                    0x014
+#define CYGARC_HAL_LPC24XX_REG_IO1DIR                    0x018
+#define CYGARC_HAL_LPC24XX_REG_IO1CLR                    0x01C
+
+#define CYGARC_HAL_LPC24XX_REG_FIO0DIR                   0x0000
+#define CYGARC_HAL_LPC24XX_REG_FIO1DIR                   0x0020
+#define CYGARC_HAL_LPC24XX_REG_FIO2DIR                   0x0040
+#define CYGARC_HAL_LPC24XX_REG_FIO3DIR                   0x0050
+#define CYGARC_HAL_LPC24XX_REG_FIO4DIR                   0x0080
+
+#define CYGARC_HAL_LPC24XX_REG_FIO0SET                   0x0018
+#define CYGARC_HAL_LPC24XX_REG_FIO1SET                   0x0038
+#define CYGARC_HAL_LPC24XX_REG_FIO2SET                   0x0058
+#define CYGARC_HAL_LPC24XX_REG_FIO3SET                   0x0078
+#define CYGARC_HAL_LPC24XX_REG_FIO4SET                   0x0098
+
+#define CYGARC_HAL_LPC24XX_REG_FIO0CLR                   0x001C
+#define CYGARC_HAL_LPC24XX_REG_FIO1CLR                   0x003C
+#define CYGARC_HAL_LPC24XX_REG_FIO2CLR                   0x005C
+#define CYGARC_HAL_LPC24XX_REG_FIO3CLR                   0x007C
+#define CYGARC_HAL_LPC24XX_REG_FIO4CLR                   0x009C
+
+#define CYGARC_HAL_LPC24XX_REG_FIO0PIN                   0x0014
+#define CYGARC_HAL_LPC24XX_REG_FIO1PIN                   0x0034
+#define CYGARC_HAL_LPC24XX_REG_FIO2PIN                   0x0054
+#define CYGARC_HAL_LPC24XX_REG_FIO3PIN                   0x0074
+#define CYGARC_HAL_LPC24XX_REG_FIO4PIN                   0x0094
+
+#define CYGARC_HAL_LPC24XX_REG_FIO0MASK                  0x0010
+#define CYGARC_HAL_LPC24XX_REG_FIO1MASK                  0x0030
+#define CYGARC_HAL_LPC24XX_REG_FIO2MASK                  0x0050
+#define CYGARC_HAL_LPC24XX_REG_FIO3MASK                  0x0070
+#define CYGARC_HAL_LPC24XX_REG_FIO4MASK                  0x0090
+
+
+
+//=============================================================================
+// Pin Connect Block (PIN)
+
+#define CYGARC_HAL_LPC24XX_REG_PIN_BASE                  0xE002C000
+
+#define CYGARC_HAL_LPC24XX_REG_PINSEL0                   0x000
+#define CYGARC_HAL_LPC24XX_REG_PINSEL1                   0x004
+#define CYGARC_HAL_LPC24XX_REG_PINSEL2                   0x008
+#define CYGARC_HAL_LPC24XX_REG_PINSEL3                   0x00C
+#define CYGARC_HAL_LPC24XX_REG_PINSEL4                   0x010
+#define CYGARC_HAL_LPC24XX_REG_PINSEL5                   0x014
+#define CYGARC_HAL_LPC24XX_REG_PINSEL6                   0x018
+#define CYGARC_HAL_LPC24XX_REG_PINSEL7                   0x01C
+#define CYGARC_HAL_LPC24XX_REG_PINSEL8                   0x020
+#define CYGARC_HAL_LPC24XX_REG_PINSEL9                   0x024
+#define CYGARC_HAL_LPC24XX_REG_PINSEL10                  0x028
+#define CYGARC_HAL_LPC24XX_REG_PINSEL11                  0x02C
+
+#define CYGARC_HAL_LPC24XX_REG_PINMODE0                  0x040
+#define CYGARC_HAL_LPC24XX_REG_PINMODE1                  0x044
+#define CYGARC_HAL_LPC24XX_REG_PINMODE2                  0x048
+#define CYGARC_HAL_LPC24XX_REG_PINMODE3                  0x04C
+#define CYGARC_HAL_LPC24XX_REG_PINMODE4                  0x050
+#define CYGARC_HAL_LPC24XX_REG_PINMODE5                  0x054
+#define CYGARC_HAL_LPC24XX_REG_PINMODE6                  0x058
+#define CYGARC_HAL_LPC24XX_REG_PINMODE7                  0x05C
+#define CYGARC_HAL_LPC24XX_REG_PINMODE8                  0x060
+#define CYGARC_HAL_LPC24XX_REG_PINMODE9                  0x064
+
+#define CYGARC_HAL_LPC24XX_SET_PIN_FUN(_regval_, _pin_, _func_) \
+    (_regval_) = ((_regval_) & ~(0x3 << ((_pin_) << 1))) | ((_func_) << ((_pin_) << 1))
+
+
+//=============================================================================
+// SSP - Synchronous Serial Port
+#define CYGARC_HAL_LPC24XX_REG_SSP0_BASE                 0xE0068000
+#define CYGARC_HAL_LPC24XX_REG_SSP1_BASE                 0xE0030000
+
+#define CYGARC_HAL_LPC24XX_REG_SSP_CR0                   0x0000
+#define CYGARC_HAL_LPC24XX_REG_SSP_CR1                   0x0004
+#define CYGARC_HAL_LPC24XX_REG_SSP_DR                    0x0008
+#define CYGARC_HAL_LPC24XX_REG_SSP_SR                    0x000C
+#define CYGARC_HAL_LPC24XX_REG_SSP_CPSR                  0x0010
+#define CYGARC_HAL_LPC24XX_REG_SSP_IMSC                  0x0014
+#define CYGARC_HAL_LPC24XX_REG_SSP_RIS                   0x0018
+#define CYGARC_HAL_LPC24XX_REG_SSP_MIS                   0x001C
+#define CYGARC_HAL_LPC24XX_REG_SSP_ICR                   0x0020
+#define CYGARC_HAL_LPC24XX_REG_SSP_DMACR                 0x0024
+
+
+//=============================================================================
+// ADC (AD)
+
+#define CYGARC_HAL_LPC24XX_REG_AD_BASE                  0xE0034000
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_ADCR                     0x0000
+#define CYGARC_HAL_LPC24XX_REG_ADCR_BURST               (1<<16)
+#define CYGARC_HAL_LPC24XX_REG_ADCR_PDN                 (1<<21)
+#define CYGARC_HAL_LPC24XX_REG_ADCR_EDGE                (1<<27)
+#define CYGARC_HAL_LPC24XX_REG_ADGDR                    0x0004
+#define CYGARC_HAL_LPC24XX_REG_ADSTAT                   0x0030
+#define CYGARC_HAL_LPC24XX_REG_ADINTEN                  0x000C
+#define CYGARC_HAL_LPC24XX_REG_ADDR0                    0x0010
+#define CYGARC_HAL_LPC24XX_REG_ADDR1                    0x0018
+#define CYGARC_HAL_LPC24XX_REG_ADDR2                    0x0018
+#define CYGARC_HAL_LPC24XX_REG_ADDR3                    0x001C
+#define CYGARC_HAL_LPC24XX_REG_ADDR4                    0x0020
+#define CYGARC_HAL_LPC24XX_REG_ADDR5                    0x0024
+#define CYGARC_HAL_LPC24XX_REG_ADDR6                    0x0028
+#define CYGARC_HAL_LPC24XX_REG_ADDR7                    0x002C
+
+
+//=============================================================================
+// CAN
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_RAM         0xE0038000
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_BASE        0xE003C000
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_AFMR        0x0000
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_SFF_sa      0x0004
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_SFF_GRP_sa  0x0008
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_EFF_sa      0x000C
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_EFF_GRP_sa  0x0010
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_END         0x0014
+
+#define CYGARC_HAL_LPC24XX_REG_CAN_COMMON_BASE         0xE0040000
+#define CYGARC_HAL_LPC24XX_REG_CAN_TxSR                0x0000
+#define CYGARC_HAL_LPC24XX_REG_CAN_RxSR                0x0004
+#define CYGARC_HAL_LPC24XX_REG_CAN_MSR                 0x0008
+
+#define CYGARC_HAL_LPC24XX_REG_CAN0_BASE               0xE0044000
+#define CYGARC_HAL_LPC24XX_REG_CAN1_BASE               0xE0048000
+#define CYCARC_HAL_LPC24XX_REG_CANx_MOD                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_CMR                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_GSR                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_ICR                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_IER                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_BTR                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_EWL                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_SR                 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RFS                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RID                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RDA                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RDB                0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RFI1               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TID1               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDA1               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDB1               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RFI2               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TID2               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDA2               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDB2               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RFI3               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TID3               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDA3               0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDB3               0x0000
+
+
+//=============================================================================
+// DAC
+#define CYGARC_HAL_LPC24XX_REG_DAC_BASE                0xE006C000
+
+
+//=============================================================================
+// Battery RAM
+#define CYGARC_HAL_LPC24XX_REG_BATTERY_RAM             0xE0084000
+
+
+//=============================================================================
+// I2S
+#define CYGARC_HAL_LPC24XX_REG_I2S_BASE                0xE0088000
+
+#define CYGARC_HAL_LPC24XX_REG_I2S_DAO                 0x0000
+#define CYGARC_HAL_LPC24XX_REG_I2S_DAI                 0x0004
+#define CYGARC_HAL_LPC24XX_REG_I2S_TXFIFO              0x0008
+#define CYGARC_HAL_LPC24XX_REG_I2S_RXFIFO              0x000C
+#define CYGARC_HAL_LPC24XX_REG_I2S_STATE               0x0010
+#define CYGARC_HAL_LPC24XX_REG_I2S_DMA1                0x0014
+#define CYGARC_HAL_LPC24XX_REG_I2S_DMA2                0x0018
+#define CYGARC_HAL_LPC24XX_REG_I2S_IRQ                 0x001C
+#define CYGARC_HAL_LPC24XX_REG_I2S_TXRATE              0x0020
+#define CYGARC_HAL_LPC24XX_REG_I2S_RXRATE              0x0024
+
+
+
+//=============================================================================
+// SD/MMC Card Interface
+#define CYGARC_HAL_LPC24XX_REG_SD_MMC_BASE             0xE008C000
+
+
+//=============================================================================
+// System Control Block
+
+#define CYGARC_HAL_LPC24XX_REG_SCB_BASE                 0xE01FC000
+
+// Registers are offsets from base of this subsystem
+
+// Memory accelerator module
+#define CYGARC_HAL_LPC24XX_REG_MAMCR                    0x0000
+#define CYGARC_HAL_LPC24XX_REG_MAMCR_DISABLED           0x00
+#define CYGARC_HAL_LPC24XX_REG_MAMCR_PARTIAL            0x01
+#define CYGARC_HAL_LPC24XX_REG_MAMCR_FULL               0x02
+#define CYGARC_HAL_LPC24XX_REG_MAMTIM                   0x0004
+
+// Memory mapping control
+#define CYGARC_HAL_LPC24XX_REG_MEMMAP                   0x0040
+
+// PLL
+#define CYGARC_HAL_LPC24XX_REG_PLLCON                   0x0080
+#define CYGARC_HAL_LPC24XX_REG_PLLCON_PLLE              (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PLLCON_PLLC              (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PLLCFG                   0x0084
+#define CYGARC_HAL_LPC24XX_REG_PLLSTAT                  0x0088
+#define CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLLE             (1<<24)
+#define CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLLC             (1<<25)
+#define CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLOCK            (1<<26)
+#define CYGARC_HAL_LPC24XX_REG_PLLFEED                  0x008C
+
+// Power Control
+#define CYGARC_HAL_LPC24XX_REG_PCON                     0x00C0
+#define CYGARC_HAL_LPC24XX_REG_PCON_IDL                 (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PCON_PD                  (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PCONP                    0x00C4
+#define CYGARC_HAL_LPC24XX_REG_PCONP_TIM0               (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_TIM1               (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_URT0               (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_URT1               (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_PWM0               (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_PWM1               (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_I2C0               (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_SPI                (1<<8)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_RTC                (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_SSP1               (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_EMC                (1<<11)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_AD                 (1<<12)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_CAN1               (1<<13)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_CAN2               (1<<14)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_I2C1               (1<<19)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_LCD                (1<<20)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_SSP0               (1<<21)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_TIM2               (1<<22)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_TIM3               (1<<23)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_URT2               (1<<24)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_URT3               (1<<25)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_I2C2               (1<<26)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_I2S                (1<<27)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_SD                 (1<<28)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_DMA                (1<<29)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_ENET               (1<<30)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_USB                (1<<31)
+
+// External interrupt inputs
+#define CYGARC_HAL_LPC24XX_REG_EXTINT                   0x0140
+#define CYGARC_HAL_LPC24XX_REG_EXTMODE                  0x0148
+#define CYGARC_HAL_LPC24XX_REG_EXTPOLAR                 0x014C
+
+#define CYGARC_HAL_LPC24XX_REG_EXTxxx_INT0              (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_EXTxxx_INT1              (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_EXTxxx_INT2              (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_EXTxxx_INT3              (1<<3)
+
+// Reset source identification register
+#define CYGARC_HAL_LPC24XX_REG_RSID                     0x0180
+#define CYGARC_HAL_LPC24XX_REG_RSID_POR                 (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_RSID_EXTR                (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_RSID_WDTR                (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_RSID_BODR                (1<<3)
+
+// System control and status register
+#define CYGARC_HAL_LPC24XX_REG_SCS                      0x01A0
+#define CYGARC_HAL_LPC24XX_REG_SCS_OSCEN                0x20
+#define CYGARC_HAL_LPC24XX_REG_SCS_OSCSTAT              0x40
+
+// Clock source selection register
+#define CYGARC_HAL_LPC24XX_REG_CLKSRCSEL                0x010C
+#define CYGARC_HAL_LPC24XX_REG_CLKSRCSEL_IRC            0x00 
+#define CYGARC_HAL_LPC24XX_REG_CLKSRCSEL_MAIN           0x01
+#define CYGARC_HAL_LPC24XX_REG_CLKSRCSEL_RTC            0x10
+
+#define CYGARC_HAL_LPC24XX_REG_CCLKCFG                  0x0104
+#define CYGARC_HAL_LPC24XX_REG_USBCLKCFG                0x0108
+#define CYGARC_HAL_LPC24XX_REG_IRCTRIM                  0x01A4
+#define CYGARC_HAL_LPC24XX_REG_PCLKSEL0                 0x01A8 
+#define CYGARC_HAL_LPC24XX_REG_PCLKSEL1                 0x01AC
+#define CYGARC_HAL_LPC24XX_REG_INTWAKE                  0x0144
+
+
+//=============================================================================
+// External Memory Controller
+#define CYGARC_HAL_LPC24XX_REG_EMC_BASE                 0xFFE08000
+
+#define CYGARC_HAL_LPC24XX_REG_EMC_CTRL                  0x0000
+#define CYGARC_HAL_LPC24XX_REG_EMC_CTRL_EN              (1 << 0)
+#define CYGARC_HAL_LPC24XX_REG_EMC_CTRL_ADDRMIRR        (1 << 1)
+#define CYGARC_HAL_LPC24XX_REG_EMC_CTRL_LOWPOW          (1 << 2)
+#define CYGARC_HAL_LPC24XX_REG_EMC_STATUS               0x0004
+#define CYGARC_HAL_LPC24XX_REG_EMC_CONFIG               0x0008
+#define CYGARC_HAL_LPC24XX_REG_EMCD_CONTROL             0x0020
+#define CYGARC_HAL_LPC24XX_REG_EMCD_REFRESH             0x0024
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RDCFG               0x0028
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RP                  0x0030
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RAS                 0x0034
+#define CYGARC_HAL_LPC24XX_REG_EMCD_SREX                0x0038
+#define CYGARC_HAL_LPC24XX_REG_EMCD_APR                 0x003C
+#define CYGARC_HAL_LPC24XX_REG_EMCD_DAL                 0x0040
+#define CYGARC_HAL_LPC24XX_REG_EMCD_WR                  0x0044
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RC                  0x0048
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RFC                 0x004C
+#define CYGARC_HAL_LPC24XX_REG_EMCD_XSR                 0x0050
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RRD                 0x0054
+#define CYGARC_HAL_LPC24XX_REG_EMCD_MRD                 0x0058
+#define CYGARC_HAL_LPC24XX_REG_EMCS_EXT_WAIT            0x0080
+
+#define CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG0             0x0100
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS0             0x0104
+#define CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG1             0x0120
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS1             0x0124
+#define CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG2             0x0140
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS2             0x0144
+#define CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG3             0x0160
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS3             0x0164
+
+#define CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG0             0x0200
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN0           0x0204
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN0           0x0208
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD0             0x020C
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE0           0x0210
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR0             0x0214
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN0           0x0218
+
+#define CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG1             0x0220
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN1           0x0224
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN1           0x0228
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD1             0x022C
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE1           0x0230
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR1             0x0234
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN1           0x0238
+
+#define CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG2             0x0240
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN2           0x0244
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN2           0x0248
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD2             0x024C
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE2           0x0250
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR2             0x0254
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN2           0x0258
+
+#define CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG3             0x0260
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN3           0x0264
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN3           0x0268
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD3             0x026C
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE3           0x0270
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR3             0x0274
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN3           0x0278
+
+
+//=============================================================================
+// Vectored Interrupt Controller (VIC)
+
+#define CYGARC_HAL_LPC24XX_REG_VIC_BASE                 0xFFFFF000
+
+// Registers are offsets from base of this subsystem
+
+#define CYGARC_HAL_LPC24XX_REG_VICIRQSTAT               0x000
+#define CYGARC_HAL_LPC24XX_REG_VICFIQSTAT               0x004
+#define CYGARC_HAL_LPC24XX_REG_VICRAWINTR               0x008
+#define CYGARC_HAL_LPC24XX_REG_VICINTSELECT             0x00C
+#define CYGARC_HAL_LPC24XX_REG_VICINTENABLE             0x010
+#define CYGARC_HAL_LPC24XX_REG_VICINTENCLEAR            0x014
+#define CYGARC_HAL_LPC24XX_REG_VICSOFTINT               0x018
+#define CYGARC_HAL_LPC24XX_REG_VICSOFTINTCLEAR          0x01C
+#define CYGARC_HAL_LPC24XX_REG_VICPROTECTION            0x020
+#define CYGARC_HAL_LPC24XX_REG_VICSWPRIOMASK            0x020
+
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR0             0x100
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR1             0x104
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR2             0x108
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR3             0x10C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR4             0x110
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR5             0x114
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR6             0x118
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR7             0x11C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR8             0x120
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR9             0x124
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR10            0x128
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR11            0x12C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR12            0x130
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR13            0x134
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR14            0x138
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR15            0x13C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR16            0x140
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR17            0x144
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR18            0x148
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR19            0x14C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR20            0x150
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR21            0x154
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR22            0x158
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR23            0x15C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR24            0x160
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR25            0x164
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR26            0x168
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR27            0x16C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR28            0x170
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR29            0x174
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR30            0x178
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR31            0x17C
+
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO0             0x200
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO1             0x204
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO2             0x208
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO3             0x20C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO4             0x210
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO5             0x214
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO6             0x218
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO7             0x21C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO8             0x220
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO9             0x224
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO10            0x228
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO11            0x22C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO12            0x230
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO13            0x234
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO14            0x238
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO15            0x23C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO16            0x240
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO17            0x244
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO18            0x248
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO19            0x24C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO20            0x250
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO21            0x254
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO22            0x258
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO23            0x25C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO24            0x260
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO25            0x264
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO26            0x268
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO27            0x26C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO28            0x270
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO29            0x274
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO30            0x278
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO31            0x27C
+
+
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR              0xF00
+
+//-----------------------------------------------------------------------------
+// end of var_io.h
+#endif // CYGONCE_HAL_VAR_IO_H
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/src/hal_diag.c b/packages/hal/arm/lpc24xx/var/v2_0/src/hal_diag.c
new file mode 100755 (executable)
index 0000000..3ac5815
--- /dev/null
@@ -0,0 +1,390 @@
+/*=============================================================================
+//
+//      hal_diag.c
+//
+//      HAL diagnostic output code
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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:jskov, gthomas
+// Date:        2001-07-12
+// Purpose:     HAL diagnostic output
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+
+//===========================================================================
+//                                INCLUDES
+//===========================================================================
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/infra/cyg_type.h>         // base types
+
+#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_if.h>             // interface API
+#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h>           // Helper functions
+#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/hal/var_io.h>             // USART registers
+#include <cyg/hal/lpc24xx_misc.h>       // peripheral identifiers
+
+
+//===========================================================================
+//                                DATA TYPES
+//===========================================================================-
+typedef struct 
+{
+    cyg_uint8* base;     
+    cyg_int32  msec_timeout;     
+    int        isr_vector;
+    int        baud_rate;
+    cyg_uint8  periph_id;
+} channel_data_t;
+
+
+//
+// Diagnostic serial channel data
+//
+static channel_data_t lpc2xxx_ser_channels[2] = 
+{
+    { (cyg_uint8*)CYGARC_HAL_LPC24XX_REG_UART0_BASE, 
+       1000, 
+       CYGNUM_HAL_INTERRUPT_UART0, 
+       CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD,
+       CYNUM_HAL_LPC24XX_PCLK_UART0},
+      
+    { (cyg_uint8*)CYGARC_HAL_LPC24XX_REG_UART1_BASE, 
+       1000, 
+       CYGNUM_HAL_INTERRUPT_UART1, 
+       CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD,
+       CYNUM_HAL_LPC24XX_PCLK_UART1}
+};
+
+
+//===========================================================================
+// Initialize diagnostic serial channel
+//===========================================================================
+static void cyg_hal_plf_serial_init_channel(void* __ch_data)
+{
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint8* base = chan->base;
+    cyg_uint16 divider = CYG_HAL_ARM_LPC24XX_BAUD_GENERATOR(chan->periph_id, 
+                                                            chan->baud_rate);
+    // Set baudrate
+    HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxLCR, 
+                     CYGARC_HAL_LPC24XX_REG_UxLCR_DLAB);
+    HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxDLM, divider >> 8);
+    HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxDLL, divider & 0xFF);
+
+    // 8-1-no parity.
+    HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxLCR, 
+                     CYGARC_HAL_LPC24XX_REG_UxLCR_WORD_LENGTH_8 |
+                     CYGARC_HAL_LPC24XX_REG_UxLCR_STOP_1);
+
+    // Reset and enable FIFO
+    HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxFCR, 
+                     CYGARC_HAL_LPC24XX_REG_UxFCR_FIFO_ENA |
+                     CYGARC_HAL_LPC24XX_REG_UxFCR_RX_FIFO_RESET | 
+                     CYGARC_HAL_LPC24XX_REG_UxFCR_TX_FIFO_RESET);
+}
+
+
+//===========================================================================
+// Write single character
+//===========================================================================
+void cyg_hal_plf_serial_putc(void *__ch_data, char c)
+{
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint8 stat;
+    CYGARC_HAL_SAVE_GP();
+
+    do {
+        HAL_READ_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxLSR, stat);
+    } while ((stat & CYGARC_HAL_LPC24XX_REG_UxLSR_THRE) == 0);
+
+    HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxTHR, c);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+
+//===========================================================================
+// Read single character non blocking
+//===========================================================================
+static cyg_bool cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint8* base = chan->base;
+    cyg_uint8 stat;
+
+    HAL_READ_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxLSR, stat);
+    if ((stat & CYGARC_HAL_LPC24XX_REG_UxLSR_RDR) == 0)
+        return false;
+
+    HAL_READ_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxRBR, *ch);
+
+    return true;
+}
+
+
+//===========================================================================
+// Read single character blocking
+//===========================================================================
+cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+
+    CYGARC_HAL_RESTORE_GP();
+    return ch;
+}
+
+
+//===========================================================================
+// Write data buffer via serial line
+//===========================================================================
+static void cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+
+//===========================================================================
+// Read data buffer
+//===========================================================================
+static void cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, 
+                                    cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+
+//===========================================================================
+// Read single character with timeout
+//===========================================================================
+cyg_bool cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    int delay_count;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
+
+    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
+
+    for(;;) {
+        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+        
+        CYGACC_CALL_IF_DELAY_US(100);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+
+//===========================================================================
+// Control serial channel configuration
+//===========================================================================
+static int cyg_hal_plf_serial_control(void *__ch_data, 
+                                      __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+    int ret = 0;
+    va_list ap;
+
+    CYGARC_HAL_SAVE_GP();
+    va_start(ap, __func);
+
+    switch (__func) {
+    case __COMMCTL_GETBAUD:
+        ret = chan->baud_rate;
+        break;
+    case __COMMCTL_SETBAUD:
+        chan->baud_rate = va_arg(ap, cyg_int32);
+        // Should we verify this value here?
+        cyg_hal_plf_serial_init_channel(chan);
+        ret = 0;
+        break;
+    case __COMMCTL_IRQ_ENABLE:
+        irq_state = 1;
+        HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+        HAL_INTERRUPT_UNMASK(chan->isr_vector);
+        HAL_WRITE_UINT32(base+CYGARC_HAL_LPC24XX_REG_UxIER, 
+                         CYGARC_HAL_LPC24XX_REG_UxIER_RXDATA_INT);
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+        HAL_INTERRUPT_MASK(chan->isr_vector);
+        HAL_WRITE_UINT32(base+CYGARC_HAL_LPC24XX_REG_UxIER, 0);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = chan->isr_vector;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+        ret = chan->msec_timeout;
+        chan->msec_timeout = va_arg(ap, cyg_uint32);
+    default:
+        break;
+    }
+
+    va_end(ap);
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
+}
+
+
+//===========================================================================
+// Serial channel ISR
+//===========================================================================
+static int cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
+                                  CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    int res = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint8 c;
+    cyg_uint8 iir;
+    
+    CYGARC_HAL_SAVE_GP();
+
+    *__ctrlc = 0;
+
+    HAL_READ_UINT32(chan->base + CYGARC_HAL_LPC24XX_REG_UxIIR, iir);
+    
+    if((iir & (CYGARC_HAL_LPC24XX_REG_UxIIR_IIR0 | 
+               CYGARC_HAL_LPC24XX_REG_UxIIR_IIR1 | 
+               CYGARC_HAL_LPC24XX_REG_UxIIR_IIR2)) 
+       == CYGARC_HAL_LPC24XX_REG_UxIIR_IIR2)
+    {
+        // Rx data available or character timeout
+        // Read data in order to clear interrupt
+        HAL_READ_UINT32(chan->base + CYGARC_HAL_LPC24XX_REG_UxRBR, c);
+        if( cyg_hal_is_break( &c , 1 ) ) *__ctrlc = 1;
+
+        res = CYG_ISR_HANDLED;
+    }
+
+    HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+
+//===========================================================================
+// Initialize serial channel
+//===========================================================================
+void cyg_hal_plf_serial_init(void)
+{
+    hal_virtual_comm_table_t* comm;
+    int cur;
+
+    cur = 
+      CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+    // Init channels
+    cyg_hal_plf_serial_init_channel(&lpc2xxx_ser_channels[0]);
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
+    cyg_hal_plf_serial_init_channel(&lpc2xxx_ser_channels[1]);
+#endif
+
+    // Setup procs in the vector table
+
+    // Set channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &lpc2xxx_ser_channels[0]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
+    // Set channel 1
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &lpc2xxx_ser_channels[1]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+
+//===========================================================================
+// Set diagnostic led
+//===========================================================================
+void hal_diag_led(int mask)
+{
+    hal_lpc24xx_set_leds(mask);
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_diag.c
diff --git a/packages/hal/arm/lpc24xx/var/v2_0/src/lpc24xx_misc.c b/packages/hal/arm/lpc24xx/var/v2_0/src/lpc24xx_misc.c
new file mode 100755 (executable)
index 0000000..7b7d489
--- /dev/null
@@ -0,0 +1,440 @@
+/*==========================================================================
+//
+//      lpc24xx_misc.c
+//
+//      HAL misc variant support code for NXP LPC24xx
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2004 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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, jskov, nickg, tkoeller
+// Date:         2008-07-06
+// Purpose:      Prozessor support
+// Description:  Implementations of LPC24xx processor support
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+
+//===========================================================================
+//                                INCLUDES
+//===========================================================================
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_lpc24xx.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_trac.h>         // tracing macros
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#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>           // necessary?
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h>             // calling interface
+#include <cyg/hal/hal_misc.h>           // helper functions
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+#include <cyg/hal/drv_api.h>            // HAL ISR support
+#endif
+#include <cyg/hal/var_io.h>             // platform registers
+
+#include <cyg/infra/diag.h>     // For diagnostic printing
+
+
+//===========================================================================
+// Get peripheral clock for a certain peripheral
+//===========================================================================
+cyg_uint32 hal_lpc_get_pclk(cyg_uint32 peripheral_id)
+{
+    static const cyg_uint8 divider_tbl[4] =
+    {
+        4, 1, 2, 8
+    };
+    cyg_uint32 pclkselreg;
+    cyg_uint32 regval;
+    cyg_uint8  divider;
+
+    //
+    // decide if we need PCLKSEL0 or PCLKSEL1
+    //
+    pclkselreg = ((peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_ACF) ? 
+                   CYGARC_HAL_LPC24XX_REG_PCLKSEL0 : 
+                   CYGARC_HAL_LPC24XX_REG_PCLKSEL1); 
+    HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval);
+    regval  = (regval >> ((peripheral_id & 0xF) << 1)) & 0x03;
+    divider = divider_tbl[regval];    
+    if ((8 == divider) && (peripheral_id >= CYNUM_HAL_LPC24XX_PCLK_CAN1)
+        && (peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_ACF))
+    {
+        divider = 6;
+    }           
+    return CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED / divider;
+}
+
+
+//===========================================================================
+// Set peripheral clock
+//===========================================================================
+void hal_lpc_set_pclk(cyg_uint32 peripheral_id, cyg_uint8 divider)
+{
+    static const cyg_uint8 clock_tbl[4] =
+    {
+        0x01, 0x02, 0x00, 0x03
+    }; 
+    cyg_uint32 clock;
+    cyg_uint32 pclkselreg;
+    cyg_uint32 regval;
+     
+    CYG_ASSERT(divider <= 8, "Wrong peripheral clock divider value"); 
+    //
+    // decide if we need PCLKSEL0 or PCLKSEL1
+    //
+    pclkselreg = (peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_ACF) ? 
+                  CYGARC_HAL_LPC24XX_REG_PCLKSEL0 : 
+                  CYGARC_HAL_LPC24XX_REG_PCLKSEL1;  
+    HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval);
+    divider = (6 == divider) ? 8 : divider;
+    clock = clock_tbl[divider >> 1];
+    regval |= (clock << ((peripheral_id & 0xF) << 1));   
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval);             
+}
+
+
+//===========================================================================
+// initialize timer 0 as eCos realtime clock source
+//===========================================================================
+void hal_clock_initialize(cyg_uint32 period)
+{
+    CYG_ADDRESS timer = CYGARC_HAL_LPC24XX_REG_TIMER0_BASE;
+
+    period = period / (CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED / 
+                       hal_lpc_get_pclk(CYNUM_HAL_LPC24XX_PCLK_TIMER0));
+
+    // 
+    // Disable and reset counter, set prescale register to 0 and
+    // Set up match register 
+    //
+    HAL_WRITE_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxTCR, 2);
+    HAL_WRITE_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxPR, 0);
+    HAL_WRITE_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxMR0, period);
+    
+    //
+    // Reset and generate interrupt on match and Enable counter
+    //
+    HAL_WRITE_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxMCR, 
+                     CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_INT | 
+                     CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_RESET);
+    HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxTCR, 1);
+}
+
+
+//===========================================================================
+// Reset clock
+//===========================================================================
+void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+    static cyg_uint32 _period = 0;
+    CYG_ADDRESS        timer  = CYGARC_HAL_LPC24XX_REG_TIMER0_BASE;
+
+    HAL_WRITE_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxIR, 
+                     CYGARC_HAL_LPC24XX_REG_TxIR_MR0);  // Clear interrupt
+
+    if (period != _period) 
+    {
+        hal_clock_initialize(period);
+    }
+    _period = period;
+}
+
+
+//===========================================================================
+// Reset clock value
+//===========================================================================
+void hal_clock_read(cyg_uint32 *pvalue)
+{
+    CYG_ADDRESS timer = CYGARC_HAL_LPC24XX_REG_TIMER0_BASE;
+    cyg_uint32 val;
+
+    HAL_READ_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxTC, val);
+    *pvalue = val;
+}
+
+
+//===========================================================================
+// Delay for some number of micro-seconds - use TIMER1
+//===========================================================================
+void hal_delay_us(cyg_int32 usecs)
+{
+    CYG_ADDRESS timer = CYGARC_HAL_LPC24XX_REG_TIMER1_BASE;
+    cyg_uint32 stat;
+    cyg_uint64 ticks;
+
+    // Calculate how many timer ticks the required number of
+    // microseconds equate to. We do this calculation in 64 bit
+    // arithmetic to avoid overflow.
+    ticks = (((cyg_uint64)usecs) * 
+             ((cyg_uint64)hal_lpc_get_pclk(CYNUM_HAL_LPC24XX_PCLK_TIMER1))) / 
+               1000000LL;
+    
+    // Disable and reset counter
+    HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxTCR, 2);
+    
+    // Stop on match
+    HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxMR0, ticks);
+    HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxMCR, 
+                     CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_STOP | 
+                     CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_RESET);
+
+    //set prescale register to 0
+    HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxPR, 0);         
+
+    // Enable counter
+    HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxTCR, 1);
+
+    // Wait for the match
+    do {
+        HAL_READ_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxTC, stat);
+    } while (stat < ticks);
+}
+
+
+//===========================================================================
+// Perform variant setup. This optionally calls into the platform
+// HAL if it has defined HAL_PLF_HARDWARE_INIT.
+//===========================================================================
+void hal_hardware_init(void)
+{
+    cyg_uint32 i; 
+    
+    //
+    // Setup peripheral clocks here according to configuration
+    // 
+    hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_CAN1, CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV);
+    hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_CAN2, CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV);
+    hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_ACF,  CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV);
+    
+    //
+    // Fill vector address registers with interrupt number. If an interrupt
+    // occurs we can simply read the interrupt number from the vector
+    // address register later
+    //
+    cyg_uint32 addr = CYGARC_HAL_LPC24XX_REG_VIC_BASE + 
+                      CYGARC_HAL_LPC24XX_REG_VICVECTADDR0;    
+    for (i = 0; i < 32; ++i)
+    {
+        HAL_WRITE_UINT32(addr, i);
+        addr += 4;
+    }
+#ifdef HAL_PLF_HARDWARE_INIT
+    // Perform any platform specific initializations
+    HAL_PLF_HARDWARE_INIT();
+#endif
+
+    // Set up eCos/ROM interfaces
+    hal_if_init();
+}
+
+
+//===========================================================================
+// This routine is called to respond to a hardware interrupt (IRQ).  It
+// should interrogate the hardware and return the IRQ vector number.
+//===========================================================================
+int hal_IRQ_handler(void)
+{
+    cyg_uint32 irq_num;
+    
+    HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_VIC_BASE + 
+                    CYGARC_HAL_LPC24XX_REG_VICVECTADDR, irq_num);
+       
+    return (irq_num);
+}
+
+
+//===========================================================================
+// Block the interrupt associated with the vector
+//===========================================================================
+void hal_interrupt_mask(int vector)
+{
+    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_VIC_BASE + 
+                     CYGARC_HAL_LPC24XX_REG_VICINTENCLEAR, 1 << vector);
+}
+
+
+//===========================================================================
+// Unblock the interrupt associated with the vector
+//===========================================================================
+void hal_interrupt_unmask(int vector)
+{
+    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_VIC_BASE + 
+                     CYGARC_HAL_LPC24XX_REG_VICINTENABLE, 1 << vector);
+}
+
+
+//===========================================================================
+// Acknowledge the interrupt associated with the vector. This
+// clears the interrupt but may result in another interrupt being
+// delivered
+//===========================================================================
+void hal_interrupt_acknowledge(int vector)
+{
+
+    // External interrupts have to be cleared from the EXTINT register
+    if (vector >= CYGNUM_HAL_INTERRUPT_EINT0 &&
+        vector <= CYGNUM_HAL_INTERRUPT_EINT3)
+    {
+        // Map int vector to corresponding bit (0..3)
+        vector = 1 << (vector - CYGNUM_HAL_INTERRUPT_EINT0);
+        
+        // Clear the external interrupt
+        HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + 
+                         CYGARC_HAL_LPC24XX_REG_EXTINT, vector);
+    }
+    
+    // 
+    // Write any value to vector address register to
+    // acknowledge the interrupt
+    //
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_VIC_BASE + 
+                     CYGARC_HAL_LPC24XX_REG_VICVECTADDR, 0xFFFFFFFF);  
+}
+
+
+//===========================================================================
+// This provides control over how an interrupt signal is detected.
+// Options are between level or edge sensitive (level) and high/low
+// level or rising/falling edge triggered (up).
+//===========================================================================
+void hal_interrupt_configure(int vector, int level, int up)
+{
+    cyg_uint32 regval;
+
+    // Only external interrupts are configurable    
+    CYG_ASSERT(vector <= CYGNUM_HAL_INTERRUPT_EINT3 &&
+               vector >= CYGNUM_HAL_INTERRUPT_EINT0 , "Invalid vector");
+
+    // Map int vector to corresponding bit (0..3)
+    vector = 1 << (vector - CYGNUM_HAL_INTERRUPT_EINT0);
+    
+    // Read current mode and update for level (0) or edge detection (1)
+    HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + 
+                    CYGARC_HAL_LPC24XX_REG_EXTMODE, regval);
+    if (level)
+    {
+      regval &= ~vector;
+    }
+    else
+    {
+      regval |= vector;
+    }
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + 
+                     CYGARC_HAL_LPC24XX_REG_EXTMODE, regval);
+    
+    // Read current polarity and update for trigger level or edge
+    // level: high (1), low (0) edge: rising (1), falling (0)
+    HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + 
+                    CYGARC_HAL_LPC24XX_REG_EXTPOLAR, regval);
+    if (up)
+    {
+      regval |= vector;
+    }
+    else
+    {
+      regval &= ~vector;
+    }
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + 
+                     CYGARC_HAL_LPC24XX_REG_EXTPOLAR, regval);
+
+    // Clear any spurious interrupt that might have been generated
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + 
+                     CYGARC_HAL_LPC24XX_REG_EXTINT, vector);
+}
+
+
+//===========================================================================
+// These selects select a priority level for the 32 vectored IRQs. 
+// 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 interrupt to the 
+// lowest priority, allowing a single write to elevate the priority 
+// of an individual interrupt.
+//===========================================================================
+void hal_interrupt_set_level(int vector, int level)
+{
+    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+    CYG_ASSERT(level >= 0 && level <= 15, "Invalid level");
+       
+    cyg_uint32 prioreg_addr = CYGARC_HAL_LPC24XX_REG_VIC_BASE + 
+                              CYGARC_HAL_LPC24XX_REG_VICVECTPRIO0 + 
+                              (vector << 2);                   
+    HAL_WRITE_UINT32(prioreg_addr, level & 0xF);
+}
+
+
+//===========================================================================
+// Use the watchdog to generate a reset
+//===========================================================================
+void hal_lpc_watchdog_reset(void)
+{
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_WD_BASE + 
+                     CYGARC_HAL_LPC24XX_REG_WDTC, 0xFF);
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_WD_BASE + 
+                     CYGARC_HAL_LPC24XX_REG_WDMOD, 
+                     CYGARC_HAL_LPC24XX_REG_WDMOD_WDEN | 
+                     CYGARC_HAL_LPC24XX_REG_WDMOD_WDRESET);
+
+    // feed WD with the two magic values
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_WD_BASE + 
+                     CYGARC_HAL_LPC24XX_REG_WDFEED, 
+                     CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC1); 
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_WD_BASE + 
+                     CYGARC_HAL_LPC24XX_REG_WDFEED, 
+                     CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC2);
+    
+    while(1)
+      continue;
+}
+
+
+//--------------------------------------------------------------------------
+// EOF lpc24xx_misc.c
diff --git a/packages/hal/arm/lpc2xxx/phycore229x/v2_0/ChangeLog b/packages/hal/arm/lpc2xxx/phycore229x/v2_0/ChangeLog
new file mode 100755 (executable)
index 0000000..8fd6a81
--- /dev/null
@@ -0,0 +1,42 @@
+2008-01-04  Uwe Kindler  <uwe_kindler@web.de>
+
+       * cdl/hal_arm_lpc2xxx_phycore229x.cdl
+       * include/plf_io.h
+       * include/hal_platform_setup.h
+       * src/phycore229x_misc:
+         Initial release of phyCORE-LPC229x development board package
+
+
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+
diff --git a/packages/hal/arm/lpc2xxx/phycore229x/v2_0/cdl/hal_arm_lpc2xxx_phycore229x.cdl b/packages/hal/arm/lpc2xxx/phycore229x/v2_0/cdl/hal_arm_lpc2xxx_phycore229x.cdl
new file mode 100755 (executable)
index 0000000..920e697
--- /dev/null
@@ -0,0 +1,421 @@
+# ====================================================================
+#
+#      hal_arm_lpc2xxx_phycore229x.cdl
+#
+#      Phytec phyCORE-LPC2292/94 HAL package configuration data 
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2008 eCosCentric Limited
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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-11-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_LPC2XXX_PHYCORE229X {
+    display       "Phytec phyCORE-LPC2292/94 development board HAL"
+    parent        CYGPKG_HAL_ARM_LPC2XXX
+    define_header hal_arm_lpc2xxx_phycore229x.h
+    include_dir   cyg/hal
+    hardware
+    implements CYGINT_DEVS_CAN_LPC2XXX_CAN0
+    implements CYGINT_DEVS_CAN_LPC2XXX_CAN1
+    description   "
+        The phyCORE-229x HAL package provides the support needed to run
+        eCos on Phytec phyCORE-LPC2292/94 development board."
+
+    compile       phycore229x_misc.c
+
+    requires      { CYGHWR_HAL_ARM_LPC2XXX == "LPC2292" || CYGHWR_HAL_ARM_LPC2XXX == "LPC2294" }
+
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_arm.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H  <pkgconf/hal_arm_lpc2xxx.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_lpc2xxx_phycore229x.h>"
+        puts $::cdl_header "#define HAL_PLATFORM_CPU    \"ARM7TDMI-S\""
+        puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"Phytec phyCORE-LPC2292/94\""
+        puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+    }
+
+    cdl_component CYG_HAL_STARTUP {
+        display       "Startup type"
+        flavor        data
+        default_value {"ROM"}
+        legal_values  {"RAM" "ROM"}
+        no_define
+        define -file system.h CYG_HAL_STARTUP
+        description   "
+            Choose RAM or ROM startup type. Typically ROM startup is used for
+            building RedBoot. RedBoot runs from internal on chip flash of
+            LPC229x. Use RAM startup for building eCos applications.
+            RedBoot manages the external on board flash devices. It copies
+            the eCos application image from FLASH to phyCORE on board SRAM 
+            and then starts the eCos application."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+        display      "Number of communication channels on the board"
+        flavor       data
+        calculated   2
+        description "
+            Channel 0: UART0, Channel 1: UART1"
+    }
+    
+    
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT {
+        display      "Default console channel."
+        active_if    CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+        flavor       data
+        calculated   0
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+        display          "Debug serial port"
+        active_if        CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+        flavor           data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    0
+        description      "
+            Phytec phyCORE-LPC2292/94 board has two serial channels. This option
+            chooses which channel will be used to connect to a host
+            running GDB."
+     }
+
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+         display          "Diagnostic serial port"
+         active_if        CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+         flavor data
+         legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+         default_value    0
+         description "
+             The phyCORE-LPC2292/94 board has two serial ports. This option
+             chooses which port will be used for diagnostic output."
+     }
+
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+        display       "Diagnostic serial port baud rate"
+        flavor        data
+        legal_values  9600 19200 38400 57600 115200
+        default_value 38400
+        description   "
+            This option selects the baud rate used for the diagnostic port."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+         display       "GDB serial port baud rate"
+         flavor        data
+         legal_values  9600 19200 38400 57600 115200
+         default_value 38400
+         description   "
+             This option controls the baud rate used for the GDB
+             connection."
+    }
+    
+    cdl_component CYGHWR_HAL_ARM_PHYCORE229X_MEMCFG {
+        display "Memory configuration"
+        flavor  none
+        description   "
+            Configuration options for FLASH and SRAM memory of phyCORE
+            board."
+    
+        cdl_option CYGHWR_HAL_ARM_PHYCORE229X_FLASH {
+             display        "Flash configuration"
+             flavor         data
+             legal_values   { "AM29DL800" "AM29LV800" "AM29LV160" "AM29LV320" }
+             default_value { "AM29LV800" }
+             description    "
+                 Select the type of FLASH device that is fitted on the phyCORE
+                 board."       
+        }
+    
+        cdl_option CYGHWR_HAL_ARM_PHYCORE229X_FLASH_DEVICE_SIZE {
+            display       "FLASH device size"
+            flavor        data
+            calculated    { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29DL800" ? 
+                              0x100000 :
+                            CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV800" ? 
+                              0x100000 :
+                            CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV160" ? 
+                              0x200000 :
+                            CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV320" ? 
+                              0x400000 : 0x000 }
+            description   "
+                Size of one single flash device."                        
+        }
+    
+        cdl_option CYGHWR_HAL_ARM_PHYCORE229X_FLASH_CNT {
+            display        "Number of flash devices"
+            flavor         data
+            legal_values   { 0 2 4 }
+            default_value  { 2 }
+            description    "
+                This option defines the number of flash devices
+                fitted. The board supports two 16-bit data bus width
+                Flash devices in parallel connected to a 32-bit data
+                bus on the LPC2292/94. Flash devices are always fitted
+                in pairs and there is space for up to 4 devices."
+        }
+    
+        cdl_option CYGHWR_HAL_ARM_PHYCORE229X_FLASH_SIZE {
+            display      "FLASH size"
+            flavor        data
+            calculated   { CYGHWR_HAL_ARM_PHYCORE229X_FLASH_DEVICE_SIZE * 
+                           CYGHWR_HAL_ARM_PHYCORE229X_FLASH_CNT }
+            description    "
+                This option defines the size of the onboard FLASH. 
+                The board can be fitted with 0, 2 or 4 FLASH devices of
+                1MB, 2MB or 4MB."
+        }
+    
+        cdl_option CYGHWR_HAL_ARM_PHYCORE229X_SRAM_SIZE {
+            display       "SRAM size"
+            flavor        data
+            legal_values  { 0x100000 0x200000 0x400000 0x800000 }
+            default_value 0x100000
+            description   "
+                This option defines the size of the onboard SRAM. 
+                The board can be fittet with 2 or 4 SRAM devices of
+                512KB, 1MB or 2MB."
+        }
+    }
+    
+    cdl_component CYGHWR_HAL_ARM_PHYCORE229X_ETH {
+        display "Ethernet options"
+        flavor  none
+        description   "
+            Configuration options for on board SMSC LAN91C111 ethernet 
+            chip."
+    
+    
+        cdl_option CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT {
+            display       "Ethernet controller interrupt"
+            flavor        data
+            legal_values  { 0 1 }
+            default_value { 0 }
+            description   "
+                Jumper J501 selects, which of the microcontroller external
+                interrupts (EINT) connects with the interrupt output(LAN_IRQ) 
+                of the Ethernet controller. This configuration option should 
+                match the actual jumper settings. The LAN chip may use EINT0
+                or EINT1."
+        }
+    
+        cdl_option CYGHWR_HAL_ARM_PHYCORE229X_ETH_INT_PRIO {
+            display       "Ethernet interrupt priority"
+            flavor        data
+            legal_values  { 0 to 16 }
+            default_value { 15 }
+            description   "
+                Interrupt priority of ethernet interrupt.  The LPC2xxx
+                eCos HAL supports up to 17 interrupt levels.
+                Interrupt levels 0 - 15 are vectored IRQs. Vectored
+                IRQs have a higher priority then non vectored IRQs and
+                they are processed faster. Non vectored IRQs are all
+                chained together into one single slot and the ISR need
+                to find out which interrupt occured. The default value
+                for the ethernt interrupt is 15.  This is the lowest
+                vectored IRQ priority. That ensures that the ethernet
+                interrupt is processed fast while it has still a lower
+                priority than any other verctored interrupt."  
+        }
+    
+        cdl_option CYGHWR_HAL_ARM_PHYCORE229X_ETH_MEM_AREA {
+            display        "Ethernet controller memory area"
+            flavor         data
+            legal_values   { 0x82000000 0x83000000 }
+            default_value  { 0x82000000 }
+            description    "
+                Access to the optional Ethernet controller can be established
+                via /CS2 (addr. 0x82000000) or /CS3 (addr. 0x83000000) 
+                configurable with Jumper J502. The default configuration 
+                allows access via /CS2."
+        }
+    }
+
+    # Real-time clock/counter specifics
+    cdl_option CYGNUM_HAL_ARM_LPC2XXX_XTAL_FREQ {
+        display       "CPU xtal frequency"
+        flavor        data
+        default_value {10000000}
+    }
+
+    cdl_option CYGNUM_HAL_ARM_LPC2XXX_PLL_MUL {
+        display       "CPU PLL multiplier"
+        flavor        data
+        default_value {6}
+    }
+
+    cdl_option CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED {
+        display       "CPU clock speed"
+        flavor        data
+        calculated { CYGNUM_HAL_ARM_LPC2XXX_PLL_MUL * 
+                     CYGNUM_HAL_ARM_LPC2XXX_XTAL_FREQ }
+    }
+    
+    cdl_component CYGBLD_GLOBAL_OPTIONS {
+        display "Global build options"
+        flavor  none
+        parent  CYGPKG_NONE
+        description   "
+            Global build options including control over compiler flags,
+            linker flags and choice of toolchain."
+
+        cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+            display "Global command prefix"
+            flavor  data
+            no_define
+            default_value { "arm-elf" }
+            description "
+                This option specifies the command prefix used when
+                invoking the build tools."
+        }
+
+        cdl_option CYGBLD_GLOBAL_CFLAGS {
+            display "Global compiler flags"
+            flavor  data
+            no_define
+            default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mno-short-load-words -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+            description   "
+                This option controls the global compiler flags which
+                are used to compile all packages by default. Individual
+                packages may define options which override these global
+                flags."
+        }
+
+        cdl_option CYGBLD_GLOBAL_LDFLAGS {
+            display "Global linker flags"
+            flavor  data
+            no_define
+            default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mno-short-load-words -Wl,--gc-sections -Wl,-static -g -nostdlib" }
+            description   "
+                This option controls the global linker flags. Individual
+                packages may define options which override these global
+                flags."
+        }
+    }
+
+    cdl_option CYGSEM_HAL_ROM_MONITOR {
+        display       "Behave as a ROM monitor"
+        flavor        bool
+        default_value 0
+        parent        CYGPKG_HAL_ROM_MONITOR
+        requires      { CYG_HAL_STARTUP == "ROM"}
+        description   "
+            Enable this option if this program is to be used as a
+            ROM monitor, i.e. applications will be loaded into RAM on
+            the board, and this ROM monitor may process exceptions or
+            interrupts generated from the application. This enables
+            features such as utilizing a separate interrupt stack when
+            exceptions are generated."
+    }
+
+    cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+         display       "Work with a ROM monitor"
+         flavor        booldata
+         legal_values  { "Generic" "GDB_stubs" }
+         default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+         parent        CYGPKG_HAL_ROM_MONITOR
+         requires      { CYG_HAL_STARTUP == "RAM" }
+         description   "
+             Support can be enabled for different varieties of ROM
+             monitor.  This support changes various eCos semantics such
+             as the encoding of diagnostic output, or the overriding of
+             hardware interrupt vectors.
+             Firstly there is \"Generic\" support which prevents the
+             HAL from overriding the hardware vectors that it does not
+             use, to instead allow an installed ROM monitor to handle
+             them. This is the most basic support which is likely to be
+             common to most implementations of ROM monitor.
+             \"GDB_stubs\" provides support when GDB stubs are included
+             in the ROM monitor or boot ROM."
+    }
+
+    cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+        display       "Redboot HAL options"
+        flavor        none
+        no_define
+        parent        CYGPKG_REDBOOT
+        active_if     CYGPKG_REDBOOT
+        description   "
+            This option lists the target's requirements for a valid
+            Redboot configuration."
+
+        cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+            display       "Build Redboot ROM binary image"
+            active_if     CYGBLD_BUILD_REDBOOT
+            requires      { !CYGBLD_BUILD_REDBOOT_WITH_EXEC }
+            default_value 1
+            no_define
+            description "
+                This option enables the conversion of the Redboot ELF
+                image to a binary image suitable for ROM programming."
+
+            make -priority 325 {
+                <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+                $(OBJCOPY) --strip-debug $< $(@:.bin=.img)
+                $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+                $(OBJCOPY) -O ihex $< $(@:.bin=.hex)
+                $(OBJCOPY) -O binary $< $@
+            }
+
+        }
+    }
+
+    cdl_component CYGHWR_MEMORY_LAYOUT {
+        display "Memory layout"
+        flavor data
+        no_define
+        calculated { (CYG_HAL_STARTUP == "RAM") ? "arm_lpc2xxx_phycore229x_ram" :
+                                                  "arm_lpc2xxx_phycore229x_rom" }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+            display "Memory layout linker script fragment"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+            calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_lpc2xxx_phycore229x_ram.ldi>" :
+                                                      "<pkgconf/mlt_arm_lpc2xxx_phycore229x_rom.ldi>" }
+        }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_H {
+            display "Memory layout header file"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_H
+            calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_lpc2xxx_phycore229x_ram.h>" :
+                                                      "<pkgconf/mlt_arm_lpc2xxx_phycore229x_rom.h>" }
+        }
+    }
+}
diff --git a/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/hal_platform_setup.h b/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/hal_platform_setup.h
new file mode 100755 (executable)
index 0000000..fa51a29
--- /dev/null
@@ -0,0 +1,262 @@
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+/*=============================================================================
+//
+//      hal_platform_setup.h
+//
+//      Platform specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-12-02
+// Purpose:      phyCORE-LPC229x platform specific support routines
+// Description:
+// Usage:        #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+#include <pkgconf/system.h>
+#include <cyg/hal/var_io.h>
+
+//===========================================================================*/
+
+#define LINES (0xFE<<16)
+#define LINE  (1<<16)
+.macro  _line_init
+    // set to GPIO
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+    ldr r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PINSEL2]
+    bic r1, r1, #8
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PINSEL2]
+    // set to output
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_IO_BASE
+    ldr r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO1DIR]
+    orr r1,r1,#LINE
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO1DIR]
+    // turn ON
+    ldr r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO1PIN]
+    bic r1,r1,#LINES
+    orr r1,r1,#LINE
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO1PIN]
+.endm
+
+//----------------------------------------------------------------------------
+// The phyCORE Carrier Board HD200 offers a programmable LED at
+// D3 for user implementations. This LED can be connected to port pin
+// P0.8 (TxD1) of the phyCORE-LPC2292/94 which is available via
+// signal GPIO0 (JP17 = closed). A low-level at port pin P0.8 causes the
+// LED to illuminate, LED D3 remains off when writing a high-level to
+// P0.8.
+//
+.macro  _led_init
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_IO_BASE
+    ldr r1,=(1<<8)                                // GPIO0 pins 8 is LED output
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO0DIR]
+.endm
+
+.macro _led x
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_IO_BASE
+    ldr r1,=(1<<8)
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO0CLR]
+    ldr r1,=((\x & 1)<<8)
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO0SET]
+.endm
+#define CYGHWR_LED_MACRO _led \x 
+
+
+//----------------------------------------------------------------------------
+// PLL initialisation
+//
+.macro _pll_init
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_SCB_BASE
+
+    mov r2,#0xAA
+    mov r3,#0x55
+
+    mov r1,#(0x20 | (CYGNUM_HAL_ARM_LPC2XXX_PLL_MUL - 1))
+    // load the PLL configuration register
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLCFG] 
+
+    mov r1,#1
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLCON] // enable PLL
+
+    // perform validation sequence 0XAA followed by 0x55
+    str r2,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLFEED] 
+    str r3,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLFEED]
+
+1:
+    ldr r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLSTAT] // wait for it to lock
+    ands r1,r1,#(1<<10)
+    beq 1b
+
+    mov r1,#3 // connect PLL
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLCON]
+
+    // perform validation sequence 0XAA followed by 0x55
+    str r2,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLFEED] 
+    str r3,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLFEED] 
+.endm
+
+
+//----------------------------------------------------------------------------
+// External memory and bus initialisation
+//
+.macro _mem_init
+    //
+    // first map the vector table to internal flash - normally this should be
+    // the default value after boot - but we go the safe way here and force
+    // the mapping to internal flash (the value for
+    // CYGARC_HAL_LPC2XXX_REG_MEMMAP is 1)
+    //
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_SCB_BASE
+    mov r1,#1
+    str r1, [r0,#CYGARC_HAL_LPC2XXX_REG_MEMMAP]        
+    
+    //    
+    // Now its is save to copy the first 64 bytes of flash to RAM
+    //
+    mov r0,#0                                  
+    mov r1,#0x40000000
+    mov r2,#0x40
+1:
+    ldr r3,[r0,#4]!
+    str r3,[r1,#4]!
+    cmps r0,r2
+    bne 1b
+        
+    // 
+    // Now we can map the vector table to internal SRAM        because the SRAM no
+    // contains a copy of the vector tablefrom flash (the value for 
+    // CYGARC_HAL_LPC2XXX_REG_MEMMAP is 2 = SRAM)
+    //
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_SCB_BASE
+    // User RAM Mode. Interrupt vectors are re-mapped to Static RAM.
+    mov r1,#2                                   
+    str r1, [r0,#CYGARC_HAL_LPC2XXX_REG_MEMMAP]        
+    // 4 processor clocks fetch cycle
+    mov r1,#4                                                  
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_MAMTIM] // flash timings
+    mov r1,#2
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_MAMCR]  // enable full MAM
+    
+    //
+    // Set-up external memory - the main task here is to setup the
+    // wait states for the external memory properly
+    //
+    // Bank Configuration Registers 0-3 (BCFG0-3)
+    // [0..3]          IDCY: Min. number of idle Cycles <0-15>
+    // [4]             Reserved     
+    // [5..9]          WST1: Wait States 1 <0-31>
+    // [10]            RBLE: Read Byte Lane Enable
+    // [11..15]        WST2: Wait States 2 <0-31>
+    // [16..23]        Reserved
+    // [26]            WP: Write Protect
+    // [27]            BM: Burst ROM
+    // [28..29]        MW: Memory Width  <0=8-bit,1=16-bit,2=32-bit,3=Reserved>
+    // [30..31]        Reserved
+    //
+    
+    // enable external parallel bus signals
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+    // A0..1 enabled, CS0..3, OE, WE, BLS0..3, D0..31, A2..23, JTAG Pins
+    ldr r1,=0x0FE149E4 
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PINSEL2]        
+
+    // setup external FLASH wait states
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_BCFG0
+    ldr r1,=0x20003CE3
+    str r1, [r0]
+        
+    // setup external SRAM wait states
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_BCFG1
+    ldr r1,=0x020002483
+    str r1, [r0]
+
+    // setup Ethernet chip wait states for /CS2 and /CS3
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_BCFG2
+    ldr r1,=0x020000C23
+    str r1, [r0]
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_BCFG3
+    ldr r1,=0x020000C23
+    str r1, [r0]
+.endm
+               
+.macro _gpio_init
+    // enable  RX and TX on UART0 and UART1
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_PIN_BASE    
+    ldr r1,=0x00050005
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PINSEL0]
+    
+    // set pin function to EINT0
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_PIN_BASE    
+    ldr r1,=0x00000001
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PINSEL1]
+.endm
+
+.macro  _block
+    ldr r0,=CYGARC_HAL_LPC2XXX_REG_IO_BASE
+    ldr r1,=(1<<8)
+    str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO0CLR]
+2:
+    nop
+    b 2
+.endm
+#define PLATFORM_BLOCK _block 
+//===========================================================================*/
+                        
+#if defined(CYG_HAL_STARTUP_ROM)
+.macro  _setup
+        _line_init
+        _led_init
+        _led 1
+        _pll_init
+        _mem_init
+        _gpio_init
+.endm
+#define CYGSEM_HAL_ROM_RESET_USES_JUMP
+#else
+        .macro  _setup
+
+        .endm    
+#endif
+
+#define PLATFORM_SETUP1 _setup
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H
diff --git a/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_ram.h b/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_ram.h
new file mode 100755 (executable)
index 0000000..80ab082
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+
+#define CYGMEM_REGION_sram (0x40000000)
+#define CYGMEM_REGION_sram_SIZE (0x00004000)
+#define CYGMEM_REGION_sram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_ram (0x81000000)
+#define CYGMEM_REGION_ram_SIZE (0x00100000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x81100000 - (size_t) CYG_LABEL_NAME (__heap1))
+
diff --git a/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_ram.ldi b/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_ram.ldi
new file mode 100755 (executable)
index 0000000..6b02bdb
--- /dev/null
@@ -0,0 +1,26 @@
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_lpc2xxx_phycore229x.h>
+
+MEMORY
+{
+    sram : ORIGIN = 0x40000000, LENGTH = 0x4000
+    ram  : ORIGIN = 0x81000000, LENGTH = CYGHWR_HAL_ARM_PHYCORE229X_SRAM_SIZE
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    SECTION_fixed_vectors (sram, 0x40000400, LMA_EQ_VMA)
+    SECTION_rom_vectors (ram, 0x81010000, LMA_EQ_VMA)
+    SECTION_text (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fini (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
+
diff --git a/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_rom.h b/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_rom.h
new file mode 100755 (executable)
index 0000000..cd634ad
--- /dev/null
@@ -0,0 +1,31 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_sram (0x40000000)
+#define CYGMEM_REGION_sram_SIZE (0x00004000)
+#define CYGMEM_REGION_sram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_ram (0x81000000)
+#define CYGMEM_REGION_ram_SIZE (CYGHWR_HAL_ARM_PHYCORE229X_SRAM_SIZE)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_rom (0x00000000)
+#define CYGMEM_REGION_rom_SIZE (0x00040000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+
+#define CYGMEM_REGION_flash (0x80000000)
+#define CYGMEM_REGION_flash_SIZE (CYGHWR_HAL_ARM_PHYCORE229X_FLASH_SIZE)
+#define CYGMEM_REGION_flash_ATTR (CYGMEM_REGION_ATTR_R)
+
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x81000000 + CYGHWR_HAL_ARM_PHYCORE229X_SRAM_SIZE - (size_t) CYG_LABEL_NAME (__heap1))
+
diff --git a/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_rom.ldi b/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/pkgconf/mlt_arm_lpc2xxx_phycore229x_rom.ldi
new file mode 100755 (executable)
index 0000000..2128c6e
--- /dev/null
@@ -0,0 +1,27 @@
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_lpc2xxx_phycore229x.h>
+
+MEMORY
+{
+    rom    : ORIGIN = 0x00000000, LENGTH = 0x40000
+    sram   : ORIGIN = 0x40000000, LENGTH = 0x4000
+    ram    : ORIGIN = 0x81000000, LENGTH = CYGHWR_HAL_ARM_PHYCORE229X_SRAM_SIZE
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    SECTION_rom_vectors (rom, 0x00000000, LMA_EQ_VMA)
+    SECTION_text (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixed_vectors (sram, 0x40000400, LMA_EQ_VMA)
+    SECTION_data (ram, 0x81000000, FOLLOWING (.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
+
diff --git a/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/plf_io.h b/packages/hal/arm/lpc2xxx/phycore229x/v2_0/include/plf_io.h
new file mode 100755 (executable)
index 0000000..6bd9c7b
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef CYGONCE_HAL_PLF_IO_H
+#define CYGONCE_HAL_PLF_IO_H
+//=============================================================================
+//
+//      plf_io.h
+//
+//      Phytec phyCORE-LPC2292/94 board specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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: Sergei Gavrikov
+// Date:         2007-11-20
+// Purpose:      Phytec phyCORE-LPC2292/94 board specific registers
+// Description:
+// Usage:        #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+// On-chip device base addresses
+
+
+//----------------------------------------------------------------------
+// The platform needs this initialization during the
+// hal_hardware_init() function in the varient HAL.
+#ifndef __ASSEMBLER__
+extern void hal_plf_hardware_init(void);
+#define HAL_PLF_HARDWARE_INIT() \
+    hal_plf_hardware_init()
+#endif  //__ASSEMBLER__ 
+
+//-----------------------------------------------------------------------------
+// end of plf_io.h
+#endif // CYGONCE_HAL_PLF_IO_H
+
diff --git a/packages/hal/arm/lpc2xxx/phycore229x/v2_0/src/phycore229x_misc.c b/packages/hal/arm/lpc2xxx/phycore229x/v2_0/src/phycore229x_misc.c
new file mode 100755 (executable)
index 0000000..57eab93
--- /dev/null
@@ -0,0 +1,138 @@
+/*==========================================================================
+//
+//      phycore_misc.c
+//
+//      HAL misc board support code for Phytec phyCORE-LPC2292/94
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-11-20
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_lpc2xxx_phycore229x.h>
+#include <cyg/hal/hal_io.h>             // IO macros
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/hal/var_io.h>
+#include <cyg/hal/plf_io.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGPKG_REDBOOT
+#include <redboot.h>
+#endif
+extern void cyg_hal_plf_serial_init(void);
+
+void cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+       
+    if (initialized)
+        return;
+    initialized = 1;
+
+    cyg_hal_plf_serial_init();
+}
+
+//--------------------------------------------------------------------------
+// hal_plf_hardware_init
+//
+void hal_plf_hardware_init(void)
+{
+#if defined(CYG_HAL_STARTUP_ROM) && defined(CYGPKG_DEVS_ETH_ARM_PHYCORE229X)
+    cyg_uint32 regval; 
+    
+    //
+    // Configures the LAN IRQ
+    // The interrupt is being used as active high edge triggered.
+    // IMPORTANT: We execute this step only for ROM startup. If this is done
+    // for RAM startup then wrong values are stored in EXTMODE and EXTPOLAR
+    // register because of a bug in LPC229x hardware.
+    //
+    HAL_INTERRUPT_CONFIGURE(CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT + // the configured external interrupt
+                            CYGNUM_HAL_INTERRUPT_EINT0,           // the first external interrupt
+                            0,                                    // level = 0 - edge triggered
+                            1);                                   // up = 1 - rising edge
+    
+    //
+    // Set pin function of P0.16 to EINT0 or P0.14 to EINT1 for ethernet interrupt
+    //
+#if CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT == 0
+    HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_PIN_BASE + 
+                    CYGARC_HAL_LPC2XXX_REG_PINSEL1, regval);
+    regval |= 0x01;
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_PIN_BASE + 
+                     CYGARC_HAL_LPC2XXX_REG_PINSEL1, regval);
+#elif CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT == 1
+    HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_PIN_BASE + 
+                    CYGARC_HAL_LPC2XXX_REG_PINSEL0, regval);
+    regval |= (0x10 << 28);
+    HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_PIN_BASE + 
+                     CYGARC_HAL_LPC2XXX_REG_PINSEL0, regval);
+#else
+#error "Invalid CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT value"
+#endif
+#endif // #if defined(CYG_HAL_STARTUP_ROM) && defined(CYGPKG_DEVS_ETH_ARM_PHYCORE229X)
+}
+
+//--------------------------------------------------------------------------
+// hal_lpc2xxx_set_leds
+//
+void hal_lpc2xxx_set_leds (int mask)
+{
+    //
+    // implement function for setting diagnostic leds
+    //
+}
+
+//--------------------------------------------------------------------------
+// EOF phycore_misc.c
+
+
+
+
+
+
+
diff --git a/packages/hal/arm/lpc2xxx/var/v2_0/include/lpc2xxx_misc.h b/packages/hal/arm/lpc2xxx/var/v2_0/include/lpc2xxx_misc.h
new file mode 100644 (file)
index 0000000..4c93848
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef CYGONCE_HAL_ARM_LPC2XXX_VAR_LPC2XXX_MISC_H
+#define CYGONCE_HAL_ARM_LPC2XXX_VAR_LPC2XXX_MISC_H
+//=============================================================================
+//
+//      lpc2xxx_misc.h
+//
+//      HAL misc variant support code for Philips LPC2xxx header file
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Limited 
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    andyj 
+// Contributors: jani
+// Date:         2006-02-04
+// Purpose:      LPC2XXX specific miscellaneous support header file
+// Description: 
+// Usage:        #include <cyg/hal/lpc2xxx_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Macros to derive the baudrate divider values for the internal UARTs
+//-----------------------------------------------------------------------------
+#define CYG_HAL_ARM_LPC2XXX_BAUD_GENERATOR(baud) \
+            (CYGNUM_HAL_ARM_LPC2XXX_PCLK/((baud)*16))
+            
+//-----------------------------------------------------------------------------
+// LPX2xxx varaint specific initialisatio of CAN channels
+// This function configures the pin functions for CAN use
+//-----------------------------------------------------------------------------            
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX
+externC void hal_lpc_can_init(cyg_uint8 can_chan_no);            
+#define HAL_LPC2XXX_INIT_CAN(_can_chan_no_) hal_lpc_can_init(_can_chan_no_)
+#define CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK CYGNUM_HAL_ARM_LPC2XXX_PCLK
+#endif // CYGPKG_DEVS_CAN_LPC2XXX
+
+//-----------------------------------------------------------------------------
+// LPX2xxx watchdog support
+//-----------------------------------------------------------------------------
+externC void hal_lpc_watchdog_reset(void);
+
+#define HAL_PLATFORM_RESET() hal_lpc_watchdog_reset()
+#define HAL_PLATFORM_RESET_ENTRY 0
+
+//-----------------------------------------------------------------------------
+// end of lpc2xxx_misc.h
+#endif // CYGONCE_HAL_ARM_LPC2XXX_VAR_LPC2XXX_MISC_H
diff --git a/packages/hal/arm/mac7100/mac7100evb/v2_0/ChangeLog b/packages/hal/arm/mac7100/mac7100evb/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..15782d0
--- /dev/null
@@ -0,0 +1,46 @@
+2006-06-08  Ilija Koco  <ilijak@siva.com.mk>
+
+       * cdl/hal_arm_mac7100_mac7100evb.cdl: 
+       * include/plf_io.h:
+       * include/hal_platform_ints.h: 
+       * include/hal_platform_setup.h: 
+       * include/mac7100evb_misc.h:
+       * include/pkgconf/mlt_arm_mac7100_mac7100evb_rom.ldi: 
+       * include/pkgconf/mlt_arm_mac7100_mac7100evb_rom.h: 
+       * src/mac7100evb_misc.c: 
+       New HAL added to support the Freescale MAC7100 board.
+       Adapted from MACE1
+
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/arm/mac7100/mac7100evb/v2_0/cdl/hal_arm_mac7100_mac7100evb.cdl b/packages/hal/arm/mac7100/mac7100evb/v2_0/cdl/hal_arm_mac7100_mac7100evb.cdl
new file mode 100644 (file)
index 0000000..7a42964
--- /dev/null
@@ -0,0 +1,377 @@
+
+# ====================================================================
+#
+#      hal_arm_mac7100_mac7100evb.cdl
+#
+#      ARM MAC7100 MAC7100EVB HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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-06-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_MAC7100_MAC7100EVB {
+    display       "MAC7100EVB evaluation board HAL"
+    parent        CYGPKG_HAL_ARM_MAC7100
+    define_header hal_arm_mac7100_mac7100evb.h
+    include_dir   cyg/hal
+    hardware
+    description   "
+        The MAC7100EVB HAL package provides the support needed to run
+        eCos on the Freescale MAC7100EVB eval board."
+
+    compile       mac7100evb_misc.c
+
+    requires      { CYGHWR_HAL_ARM_MAC7100 == "MAC7111" }
+    requires      { CYGNUM_PIT_CHAN_CLOCK_PRIORITY == 
+                    CYGNUM_KERNEL_COUNTERS_CLOCK_ISR_PRIORITY }
+
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_arm.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H  <pkgconf/hal_arm_mac7100.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_mac7100_mac7100evb.h>"
+        puts $::cdl_header "#define HAL_PLATFORM_CPU    \"ARM7TDMI\""
+        puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"Freescale MAC7100/MAC7100EVB\""
+        puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+    }
+
+    cdl_component CYG_PIT_CLOCKS {
+        display "Real time clock configuration."
+        flavor   none
+        description "
+            Periodic Interrupt Timer Module - PIT comprise of 11 timer
+            channels.  RTI channel (PIT0) as well as PIT1 .. PIT4 can
+            generate interrupts and are eligible for the real time
+            clock."
+
+        cdl_option CYGNUM_PIT_CHAN_CLOCK {
+            display      "System CLOCK device"
+            flavor       data
+            legal_values 0 to 4
+            default_value   3
+            requires {CYGNUM_PIT_CHAN_CLOCK != CYGNUM_PIT_CHAN_US}
+            description "
+                RTI (PIT0) and PIT1 .. PIT4 can be used for real time
+                clock.  RTI is clocked by oscillator clock while
+                channels 1 to 4 by 1/2 system clock frequency.
+                Selection of RTI vs PIT1 .. PIT4 affects Real-time
+                clock period (see Real-time clock constants).  NOTE:
+                Real time clock channel must not be the same as US
+                delay channel.
+            "
+        }
+
+        cdl_option CYGNUM_PIT_CHAN_CLOCK_PRIORITY {
+            display      "System clock's INTC priority"
+            flavor       data
+            legal_values 0 to 15
+            default_value   12
+            description "
+                INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+            "
+        }
+
+        cdl_option CYGNUM_PIT_CHAN_US {
+            display      "PIT channel for us delay"
+            flavor       data
+            legal_values 0 to 4
+            default_value   0
+            requires {CYGNUM_PIT_CHAN_CLOCK != CYGNUM_PIT_CHAN_US}
+            description "
+                RTI is clocked by oscillator while channels PIT1
+                .. PIT4 by half system clock frequency, hence RTI
+                should allow for larger maximal period.  NOTE: US
+                delay channel must not be the same as real time clock
+                channel.
+            "
+        }
+    }
+    
+    cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+        display       "Real-time clock constants"
+        flavor        none
+
+        cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+            display       "Real-time clock numerator"
+            flavor        data
+            default_value 1000000000
+        }
+        cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+            display       "Real-time clock denominator"
+            flavor        data
+            default_value 100
+        }
+        cdl_option CYGNUM_HAL_RTC_PERIOD {
+            display       "Real-time clock period"
+            flavor        data
+            default_value (CYGNUM_PIT_CHAN_CLOCK !=0 ? \
+                (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED / 2 / CYGNUM_HAL_RTC_DENOMINATOR - 1) : \
+                (CYGNUM_HAL_ARM_MAC7100_Q_FREQ / CYGNUM_HAL_RTC_DENOMINATOR - 1))
+        }
+    }
+    
+    cdl_component CYG_HAL_STARTUP {
+        display       "Startup type"
+        flavor        data
+        calculated {"ROM"}
+        no_define
+        define -file system.h CYG_HAL_STARTUP
+        description   "
+            Current MAC7100EVB port supports only ROM startup type."
+    }
+
+    # Real-time clock/counter specifics
+
+    cdl_component CYG_HAL_MAC7100_OSC {
+        display "System Clocks Module"
+        flavor  none
+
+        cdl_option CYGNUM_HAL_ARM_MAC7100_F_OSC {
+            display       "FOSC - Oscillator clock"
+            flavor        data
+            default_value 8000000
+        }
+        
+        cdl_option CYGNUM_HAL_ARM_MAC7100_FDIV {
+            display       "FDIV - Frequency divider for PLL"
+            flavor        booldata
+            legal_values 0 to 16
+            default_value 2
+            description "
+                If enabled (FDIV != 0), 
+                   you set divider for PLL. 
+                   Then REFDV is calculated as REFDV=FDIV-1;
+                If disabled (FDIV == 0), 
+                   REFDV is calculated from FOSC so that referent frequency 
+                   for PLL is 500kHz.
+                   SYNR is then derived from desired CPU clock, FOSC and REFDV.
+                "
+        }
+    }
+
+    cdl_option CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED {
+        display       "CPU clock - PLL frequency"
+        flavor        data
+        default_value 48000000
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+        display      "Number of communication channels on the board"
+        flavor       data
+        legal_values 0 1 2
+        default_value   2
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+        display          "Debug serial port"
+        active_if        CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+        flavor data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    0
+        description      "
+            The MAC7100 MAC7100EVB board has two serial ports. This option
+            chooses which port will be used to connect to a host
+            running GDB."
+     }
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+         display          "Diagnostic serial port"
+         active_if        CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+         flavor data
+         legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+         default_value    0
+         description      "
+            The MAC7100 MAC7100EVB board has two serial ports. This option
+            chooses which port will be used for diagnostic output."
+     }
+     
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+        display       "Diagnostic serial port baud rate"
+        flavor        data
+        legal_values  9600 19200 38400
+        default_value 38400
+        description   "
+            This option selects the baud rate used for the diagnostic port."
+    }
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+         display       "GDB serial port baud rate"
+         flavor        data
+         legal_values  9600 19200 38400
+         default_value 38400
+         description   "
+            This option controls the baud rate used for the GDB connection."
+     }
+
+    cdl_option CYGSEM_HAL_ROM_MONITOR {
+        display       "Behave as a ROM monitor"
+        flavor        bool
+        default_value 0
+        parent        CYGPKG_HAL_ROM_MONITOR
+        requires      { CYG_HAL_STARTUP == "ROM" || 
+                        CYG_HAL_STARTUP == "ROMRAM" }
+        description   "
+            Enable this option if this program is to be used as a ROM monitor,
+            i.e. applications will be loaded into RAM on the board, and this
+            ROM monitor may process exceptions or interrupts generated from the
+            application. This enables features such as utilizing a separate
+            interrupt stack when exceptions are generated."
+    }
+
+    cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+         display       "Work with a ROM monitor"
+         flavor        booldata
+         legal_values  { "Generic" "GDB_stubs" }
+         default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+         parent        CYGPKG_HAL_ROM_MONITOR
+         requires      { CYG_HAL_STARTUP == "RAM" }
+         description   "
+             Support can be enabled for different varieties of ROM monitor.
+             This support changes various eCos semantics such as the encoding
+             of diagnostic output, or the overriding of hardware interrupt
+             vectors.
+             Firstly there is \"Generic\" support which prevents the HAL
+             from overriding the hardware vectors that it does not use, to
+             instead allow an installed ROM monitor to handle them. This is
+             the most basic support which is likely to be common to most
+             implementations of ROM monitor.
+             \"GDB_stubs\" provides support when GDB stubs are included in
+             the ROM monitor or boot ROM."
+     }
+
+    cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+        display       "Redboot HAL options"
+        flavor        none
+        no_define
+        parent        CYGPKG_REDBOOT
+        active_if     CYGPKG_REDBOOT
+        description   "
+            This option lists the target's requirements for a valid Redboot
+            configuration."
+
+        cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+            display       "Build Redboot ROM binary image"
+            active_if     CYGBLD_BUILD_REDBOOT
+            default_value 1
+            no_define
+            description "This option enables the conversion of the Redboot ELF
+                         image to a binary image suitable for ROM programming."
+    
+            make -priority 325 {
+                <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+                $(OBJCOPY) --strip-debug $< $(@:.bin=.img) 
+                $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+                $(OBJCOPY) -O binary $< $@
+            }
+
+        }
+    }
+    cdl_component CYGBLD_GLOBAL_OPTIONS {
+        display "Global build options"
+        flavor  none
+        parent  CYGPKG_NONE
+        description   "
+        Global build options including control over
+        compiler flags, linker flags and choice of toolchain."
+
+        cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+            display "Global command prefix"
+            flavor  data
+            no_define
+            default_value { "arm-elf" }
+            description "
+                This option specifies the command prefix used when
+                invoking the build tools."
+        }
+
+        cdl_option CYGBLD_GLOBAL_CFLAGS {
+            display "Global compiler flags"
+            flavor  data
+            no_define
+            default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mbig-endian -mno-short-load-words -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -gdwarf-2 -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+            description   "
+                This option controls the global compiler flags which
+                are used to compile all packages by
+                default. Individual packages may define options which
+                override these global flags."
+
+        }
+
+        cdl_option CYGBLD_GLOBAL_LDFLAGS {
+            display "Global linker flags"
+            flavor  data
+            no_define
+            default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mbig-endian -mno-short-load-words -Wl,--gc-sections -Wl,-static -gdwarf-2 -nostdlib" }
+            description   "
+                This option controls the global linker flags. Individual
+                packages may define options which override these global flags."
+        }
+    }
+
+    cdl_component CYGHWR_MEMORY_LAYOUT {
+        display "Memory layout"
+        flavor data
+        no_define
+        calculated { (CYG_HAL_STARTUP == "RAM") ?    "arm_mac7100_mac7100evb_ram" :
+                     (CYG_HAL_STARTUP == "ROMRAM") ? "arm_mac7100_mac7100evb_romram" :
+                                                     "arm_mac7100_mac7100evb_rom" }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+            display "Memory layout linker script fragment"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+            calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_mac7100_mac7100evb_ram.ldi>" :
+                         (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_arm_mac7100_mac7100evb_romram.ldi>" :
+                                                      "<pkgconf/mlt_arm_mac7100_mac7100evb_rom.ldi>" }
+        }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_H {
+            display "Memory layout header file"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_H
+            calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_mac7100_mac7100evb_ram.h>" :
+                         (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_arm_mac7100_mac7100evb_romram.h>" :
+                                                      "<pkgconf/mlt_arm_mac7100_mac7100evb_rom.h>" }
+        }
+    }
+}
diff --git a/packages/hal/arm/mac7100/mac7100evb/v2_0/include/hal_platform_ints.h b/packages/hal/arm/mac7100/mac7100evb/v2_0/include/hal_platform_ints.h
new file mode 100644 (file)
index 0000000..e987a26
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef CYGONCE_HAL_PLATFORM_INTS_H
+#define CYGONCE_HAL_PLATFORM_INTS_H
+//==========================================================================
+//
+//      hal_platform_ints.h
+//
+//      HAL Interrupt and clock assignments for MAC7100EVB
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2996 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-06-07
+// Purpose:      Define Interrupt support
+// Description:  The interrupt specifics for the MAC7100EVB board/platform 
+//               are defined here.
+//              
+// Usage:        #include <cyg/hal/hal_platform_ints.h>
+//               ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define CYGNUM_HAL_ISR_MIN                     0
+#define CYGNUM_HAL_ISR_MAX                     63
+#define CYGNUM_HAL_ISR_COUNT                   (CYGNUM_HAL_ISR_MAX + 1)
+
+// INTC levels
+
+#define MAC7100_EDMA0_LEVEL        (0)
+#define MAC7100_EDMA1_LEVEL        (0)
+#define MAC7100_EDMA2_LEVEL        (0)
+#define MAC7100_EDMA3_LEVEL        (0)
+#define MAC7100_EDMA4_LEVEL        (0)
+#define MAC7100_EDMA5_LEVEL        (0)
+#define MAC7100_EDMA6_LEVEL        (0)
+#define MAC7100_EDMA7_LEVEL        (0)
+#define MAC7100_EDMA8_LEVEL        (0)
+#define MAC7100_EDMA9_LEVEL        (0)
+#define MAC7100_EDMA10_LEVEL       (0)
+#define MAC7100_EDMA11_LEVEL       (0)
+#define MAC7100_EDMA12_LEVEL       (0)
+#define MAC7100_EDMA13_LEVEL       (0)
+#define MAC7100_EDMA14_LEVEL       (0)
+#define MAC7100_EDMA15_LEVEL       (0)
+#define MAC7100_EDMA_Error_LEVEL   (0)
+#define MAC7100_MCM_SWT_LEVEL      (0)
+#define MAC7100_CRG_LEVEL          (0)
+#define MAC7100_PIT1_LEVEL         (9)
+#define MAC7100_PIT2_LEVEL         (9)
+#define MAC7100_PIT3_LEVEL         (10)
+#define MAC7100_PIT4_RTI_LEVEL     (9)
+#define MAC7100_VREG_LEVEL         (4)
+#define MAC7100_CAN_A_MB_LEVEL     (4)
+#define MAC7100_CAN_A_MB14_LEVEL   (4)
+#define MAC7100_CAN_A_Error_LEVEL  (4)
+#define MAC7100_CAN_B_MB_LEVEL     (4)
+#define MAC7100_CAN_B_MB14_LEVEL   (4)
+#define MAC7100_CAN_B_Error_LEVEL  (4)
+#define MAC7100_CAN_C_MB_LEVEL     (4)
+#define MAC7100_CAN_C_MB14_LEVEL   (4)
+#define MAC7100_CAN_C_Error_LEVEL  (4)
+#define MAC7100_CAN_D_MB_LEVEL     (4)
+#define MAC7100_CAN_D_MB14_LEVEL   (4)
+#define MAC7100_CAN_D_Error_LEVEL  (4)
+#define MAC7100_I2C_LEVEL          (4)
+#define MAC7100_DSPI_A_LEVEL       (5)
+#define MAC7100_DSPI_B_LEVEL       (5)
+#define MAC7100_ESCI_A_LEVEL       (8)
+#define MAC7100_ESCI_B_LEVEL       (8)
+#define MAC7100_ESCI_C_LEVEL       (8)
+#define MAC7100_ESCI_D_LEVEL       (8)
+#define MAC7100_EMIOS0_LEVEL       (7)
+#define MAC7100_EMIOS1_LEVEL       (7)
+#define MAC7100_EMIOS2_LEVEL       (7)
+#define MAC7100_EMIOS3_LEVEL       (7)
+#define MAC7100_EMIOS4_LEVEL       (7)
+#define MAC7100_EMIOS5_LEVEL       (7)
+#define MAC7100_EMIOS6_LEVEL       (7)
+#define MAC7100_EMIOS7_LEVEL       (7)
+#define MAC7100_EMIOS8_LEVEL       (7)
+#define MAC7100_EMIOS9_LEVEL       (7)
+#define MAC7100_EMIOS10_LEVEL      (7)
+#define MAC7100_EMIOS11_LEVEL      (7)
+#define MAC7100_EMIOS12_LEVEL      (7)
+#define MAC7100_EMIOS13_LEVEL      (7)
+#define MAC7100_EMIOS14_LEVEL      (7)
+#define MAC7100_EMIOS15_LEVEL      (7)
+#define MAC7100_ATD_LEVEL          (11)
+#define MAC7100_CFM_LEVEL          (7)
+#define MAC7100_PIM_LEVEL          (11)
+#define MAC7100_IRQ_LEVEL          (12)
+#define MAC7100_XIRQ_LEVEL         (12)
+
+// The vector used by the Real time clock
+#if CYGNUM_PIT_CHAN_CLOCK==0
+#define CYGNUM_HAL_INTERRUPT_RTC MAC7100_PIT4_RTI_IV
+#else
+#define CYGNUM_HAL_INTERRUPT_RTC (MAC7100_PIT1_IV+CYGNUM_PIT_CHAN_CLOCK-1)
+#endif
+
+//----------------------------------------------------------------------------
+// Reset.
+__externC void hal_mac7100_reset_cpu(void);
+#define HAL_PLATFORM_RESET() hal_mac7100_reset_cpu()
+
+#define HAL_PLATFORM_RESET_ENTRY 0x01000000
+
+#endif // CYGONCE_HAL_PLATFORM_INTS_H
diff --git a/packages/hal/arm/mac7100/mac7100evb/v2_0/include/hal_platform_setup.h b/packages/hal/arm/mac7100/mac7100evb/v2_0/include/hal_platform_setup.h
new file mode 100644 (file)
index 0000000..c2c0c76
--- /dev/null
@@ -0,0 +1,133 @@
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+
+//=============================================================================
+//
+//      hal_platform_setup.h
+//
+//      Platform specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-06-07
+// Purpose:     MAC7100EVB platform specific support routines
+// Description:
+// Usage:       #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <cyg/hal/var_io.h>
+#include <cyg/hal/hal_var_setup.h>
+//===========================================================================
+
+    .macro _led y
+        ldr r0,=MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET)
+        ldrh r1,[r0]
+        and r1,r1,#0x00ff
+        orr r1,r1,#(((~\y)&0xff)<<8)
+        strh r1,[r0]
+    .endm
+
+
+// Initialize LED PORT
+// Set appropriate peripheral pins
+    .macro  _led_init
+        _led    0       // Set initial LED state. 
+        mov r1, #MAC7100_PIM_DDR  // Pin setting: Output+Low
+        ldr r0,=MAC7100_PIM_CONFIG(MAC7100_PORT_F_OFFSET, 8) // LED pin cfg
+        strh r1,[r0],#2 // LED: LSB ...
+        strh r1,[r0],#2
+        strh r1,[r0],#2
+        strh r1,[r0],#2
+        strh r1,[r0],#2
+        strh r1,[r0],#2
+        strh r1,[r0],#2
+        strh r1,[r0],#2 // LED: ... MSB
+    .endm
+
+
+// Clock initilalization
+    .macro  _pclock_init
+                _mac7100_setpll
+    .endm
+
+// Memory re-mapping
+    .macro _memory_remap
+                _mac7100_remap_single_chip
+    .endm
+
+
+// Initialize paralel port
+    .macro  _pio_init
+    .endm
+
+
+#define CYGHWR_LED_MACRO _led \x
+
+//===========================================================================
+                        
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+    .macro  _setup
+        ldr r0,=VAE_MAC7100_FlashSecurity
+        _led_init
+        _memory_remap
+        _pclock_init
+        _pio_init
+    .endm
+
+#define CYGSEM_HAL_ROM_RESET_USES_JUMP
+
+#else
+
+    .macro  _setup
+        _led_init
+        _led 16
+        _pclock_init
+        _pio_init        
+    .endm
+        
+#endif
+
+#define PLATFORM_SETUP1     _setup
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H
diff --git a/packages/hal/arm/mac7100/mac7100evb/v2_0/include/mac7100evb_misc.h b/packages/hal/arm/mac7100/mac7100evb/v2_0/include/mac7100evb_misc.h
new file mode 100644 (file)
index 0000000..65f008a
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef CYGONCE_HAL_MAC7100EVB_MISC_H
+#define CYGONCE_HAL_MAC7100EVB_MISC_H
+//=============================================================================
+//
+//      mac7100evb_misc.h
+//
+//      MAC7100EVB board specific functions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-05-07
+// Purpose:     MAC7100EVB board specific registers
+// Description:
+// Usage:       #include <cyg/hal/mac7100evb_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+void hal_mac7100evb_set_leds(int);
+void hal_mac7100evb_led_on(int);
+void hal_mac7100evb_led_off(int);
+int  hal_mac7100evb_get_leds(void);
+
+#define HAL_MAC7100_SET_LEDS(x) hal_mac7100evb_set_leds(x)
+#define HAL_MAC7100_LED_ON(x)   hal_mac7100evb_led_on(x)
+#define HAL_MAC7100_LED_OFF(x)  hal_mac7100evb_led_off(x)
+#define HAL_MAC7100_GET_LEDS(x) hal_mac7100evb_get_leds(x)
+
+//-----------------------------------------------------------------------------
+// end of mac7100evb_misc.h
+#endif // CYGONCE_HAL_MAC7100EVB_MISC_H
diff --git a/packages/hal/arm/mac7100/mac7100evb/v2_0/include/pkgconf/mlt_arm_mac7100_mac7100evb_rom.h b/packages/hal/arm/mac7100/mac7100evb/v2_0/include/pkgconf/mlt_arm_mac7100_mac7100evb_rom.h
new file mode 100644 (file)
index 0000000..7cc23f8
--- /dev/null
@@ -0,0 +1,24 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+// Initially RAM is at 0x40000000 but we ramap to 0x0
+#define CYGMEM_REGION_ram (0x00000000)
+#define CYGMEM_REGION_ram_SIZE (0x00008000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x20000000)
+#define CYGMEM_REGION_rom_SIZE (0x80000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE                                       \
+  ((CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE) -                         \
+   (size_t) CYG_LABEL_NAME (__heap1))
+
diff --git a/packages/hal/arm/mac7100/mac7100evb/v2_0/include/pkgconf/mlt_arm_mac7100_mac7100evb_rom.ldi b/packages/hal/arm/mac7100/mac7100evb/v2_0/include/pkgconf/mlt_arm_mac7100_mac7100evb_rom.ldi
new file mode 100644 (file)
index 0000000..2abf974
--- /dev/null
@@ -0,0 +1,39 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+
+MEMORY
+{
+    ram  : ORIGIN = 0x00000000, LENGTH = 0x8000
+    rom  : ORIGIN = 0x20000000, LENGTH = 0x80000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    SECTION_rom_vectors (rom, 0x20000000, LMA_EQ_VMA)
+
+//  MAC7100 Flash Security
+//  Following section is manually added to address MAC7100 flash security area
+//  It should actually be something like this
+//    SECTION_sgfm_config (rom, 0x20000400, LMA_EQ_VMA)
+
+    .mac7100_flash_security 0x20000400 : { KEEP (*(.mac7100_flash_security))} > rom
+
+//  END MAC7100 Flash Security
+    
+    SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+
+    SECTION_fixed_vectors (ram, 0x00000020, LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN(0x4), FOLLOWING(.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
diff --git a/packages/hal/arm/mac7100/mac7100evb/v2_0/include/plf_io.h b/packages/hal/arm/mac7100/mac7100evb/v2_0/include/plf_io.h
new file mode 100644 (file)
index 0000000..134abca
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef CYGONCE_HAL_PLF_IO_H
+#define CYGONCE_HAL_PLF_IO_H
+//=============================================================================
+//
+//      plf_io.h
+//
+//      MAC7100EVB board specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-06-07
+// Purpose:     MAC7100EVB board specific registers
+// Description:
+// Usage:       #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+// On-chip device base addresses
+
+#define CYGARC_PHYSICAL_ADDRESS(_x_)
+
+#endif // CYGONCE_HAL_PLF_IO_H
+//-----------------------------------------------------------------------------
+// end of plf_io.h
diff --git a/packages/hal/arm/mac7100/mac7100evb/v2_0/src/mac7100evb_misc.c b/packages/hal/arm/mac7100/mac7100evb/v2_0/src/mac7100evb_misc.c
new file mode 100644 (file)
index 0000000..969f690
--- /dev/null
@@ -0,0 +1,102 @@
+//==========================================================================
+//
+//      mac7100evb_misc.c
+//
+//      HAL misc board support code for MAC7100EVB board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-06-07
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/hal/hal_io.h>             // low level i/o
+#include <cyg/hal/var_io.h>             // common registers
+#include <cyg/hal/plf_io.h>             // platform registers
+#include <cyg/hal/mac7100evb_misc.h>    // mac7100evb misc functions
+
+void
+hal_mac7100evb_set_leds(int val)
+{
+    HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), 
+                     ~((val<<8)&0xff00)); // turn all LEDs off
+}
+
+void
+hal_mac7100evb_led_on(int val)
+{
+    cyg_uint16 leds;
+
+    // read old LED state
+    HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), leds); 
+    leds&=~(1<<(8+val));
+    // Write new state
+    HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), leds); 
+}
+
+void
+hal_mac7100evb_led_off(int val)
+{
+    cyg_uint16 leds;
+
+    // read old LED state
+    HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), leds); 
+    leds|=1<<(8+val);
+    // Write new state
+    HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), leds); 
+}
+
+int
+hal_mac7100evb_get_leds(void)
+{
+    cyg_uint16 leds = 0;
+
+    // read old LED state
+    HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), leds); 
+    return ~(leds>>8&0xFF);
+}
+
+//--------------------------------------------------------------------------
+// EOF mac7100evb_misc.c
diff --git a/packages/hal/arm/mac7100/mace1/v2_0/ChangeLog b/packages/hal/arm/mac7100/mace1/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..1829bb0
--- /dev/null
@@ -0,0 +1,52 @@
+2006-06-08  Ilija Koco  <ilijak@siva.com.mk>
+
+       * include/hal_platform_setup.h: PLL clock and memory remap
+       moved to hal_var_setup.h
+       * include/mace1_misc.h: LED macros added
+    
+2006-05-24  Ilija Koco  <ilijak@siva.com.mk>
+
+       * cdl/hal_arm_mac7100_mace1.cdl: 
+       * include/plf_io.h:
+       * include/hal_platform_ints.h: 
+       * include/hal_platform_setup.h: 
+       * include/mace1_misc.h:
+       * include/pkgconf/mlt_arm_mac7100_mace1_rom.ldi: 
+       * include/pkgconf/mlt_arm_mac7100_mace1_rom.h: 
+       * src/mace1_misc.c: 
+       New HAL added to support the SIvA MACE1 board. Adapted from the
+       EB55 by Nick Garnett
+
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/arm/mac7100/mace1/v2_0/cdl/hal_arm_mac7100_mace1.cdl b/packages/hal/arm/mac7100/mace1/v2_0/cdl/hal_arm_mac7100_mace1.cdl
new file mode 100644 (file)
index 0000000..5d88d71
--- /dev/null
@@ -0,0 +1,377 @@
+
+# ====================================================================
+#
+#      hal_arm_mac7100_mace1.cdl
+#
+#      ARM MAC7100 MACE1 HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_MAC7100_MACE1 {
+    display       "MACE1 - MAC7100 eval board HAL"
+    parent        CYGPKG_HAL_ARM_MAC7100
+    define_header hal_arm_mac7100_mace1.h
+    include_dir   cyg/hal
+    hardware
+    description   "
+        The MACE1 HAL package provides the support needed to run
+        eCos on an MACE1 - MAC7100 eval board."
+
+    compile       mace1_misc.c
+
+    requires      { CYGHWR_HAL_ARM_MAC7100 == "MAC7121" }
+    requires      { CYGNUM_PIT_CHAN_CLOCK_PRIORITY == 
+                    CYGNUM_KERNEL_COUNTERS_CLOCK_ISR_PRIORITY }
+
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_arm.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H  <pkgconf/hal_arm_mac7100.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_mac7100_mace1.h>"
+        puts $::cdl_header "#define HAL_PLATFORM_CPU    \"ARM7TDMI\""
+        puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"Freescale MAC7100/MACE1\""
+        puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+    }
+
+    cdl_component CYG_PIT_CLOCKS {
+        display "Real time clock configuration."
+        flavor   none
+        description "
+            Periodic Interrupt Timer Module - PIT comprizes 11 timer
+            channels.  RTI channel (PIT0) as well as PIT1 .. PIT4 can
+            generate interrupts and are eligible for the real time
+            clock.  "
+
+        cdl_option CYGNUM_PIT_CHAN_CLOCK {
+            display      "System CLOCK device"
+            flavor       data
+            legal_values 0 to 4
+            default_value   3
+            requires {CYGNUM_PIT_CHAN_CLOCK != CYGNUM_PIT_CHAN_US}
+            description "
+                RTI (PIT0) and PIT1 .. PIT4 can be used for ral time
+                clock.  RTI is clocked by oscillator clock while
+                channels 1 to 4 by 1/2 system clock frequency.
+                Selection of RTI vs PIT1 .. PIT4 affects Real-time
+                clock period (see Real-time clock constants).  NOTE:
+                Real time clock channel must not be the same as US
+                delay channel.
+            "
+        }
+
+        cdl_option CYGNUM_PIT_CHAN_CLOCK_PRIORITY {
+            display      "System clock's INTC priority"
+            flavor       data
+            legal_values 0 to 15
+            default_value   12
+            description "
+                INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+            "
+        }
+
+        cdl_option CYGNUM_PIT_CHAN_US {
+            display      "PIT channel for us delay"
+            flavor       data
+            legal_values 0 to 4
+            default_value   0
+            requires {CYGNUM_PIT_CHAN_CLOCK != CYGNUM_PIT_CHAN_US}
+            description "
+                RTI is clocked by oscillator while channels PIT1
+                .. PIT4 by half system clock frequency, hence RTI
+                should allow for larger maximal period.  NOTE: US
+                delay channel must not be the same as real time clock
+                channel.
+            "
+        }
+    }
+    
+    cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+        display       "Real-time clock constants"
+        flavor        none
+
+        cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+            display       "Real-time clock numerator"
+            flavor        data
+            default_value 1000000000
+        }
+        cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+            display       "Real-time clock denominator"
+            flavor        data
+            default_value 100
+        }
+        cdl_option CYGNUM_HAL_RTC_PERIOD {
+            display       "Real-time clock period"
+            flavor        data
+            default_value (CYGNUM_PIT_CHAN_CLOCK !=0 ? \
+                (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED / 2 / CYGNUM_HAL_RTC_DENOMINATOR - 1) : \
+                (CYGNUM_HAL_ARM_MAC7100_Q_FREQ / CYGNUM_HAL_RTC_DENOMINATOR - 1))
+        }
+    }
+    
+    cdl_component CYG_HAL_STARTUP {
+        display       "Startup type"
+        flavor        data
+        calculated {"ROM"}
+        no_define
+        define -file system.h CYG_HAL_STARTUP
+        description   "
+            Current MACE1 port supports only ROM startup type."
+    }
+
+    # Real-time clock/counter specifics
+
+    cdl_component CYG_HAL_MAC7100_OSC {
+        display "System Clocks Module"
+        flavor  none
+
+        cdl_option CYGNUM_HAL_ARM_MAC7100_F_OSC {
+            display       "FOSC - Oscillator clock"
+            flavor        data
+            default_value 8000000
+        }
+        
+        cdl_option CYGNUM_HAL_ARM_MAC7100_FDIV {
+            display       "FDIV - Frequency divider for PLL"
+            flavor        booldata
+            legal_values 0 to 16
+            default_value 2
+            description "
+                If enabled (FDIV != 0), 
+                   you set divider for PLL. 
+                   Then REFDV is calculated as REFDV=FDIV-1;
+                If disabled (FDIV == 0), 
+                   REFDV is calculated from FOSC so that referent frequency 
+                   for PLL is 500kHz.
+                   SYNR is then derived from desired CPU clock, FOSC and REFDV.
+                "
+        }
+    }
+
+    cdl_option CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED {
+        display       "CPU clock - PLL frequency"
+        flavor        data
+        default_value 48000000
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+        display      "Number of communication channels on the board"
+        flavor       data
+        legal_values 0 1 2
+        default_value   2
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+        display          "Debug serial port"
+        active_if        CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+        flavor data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    0
+        description      "
+            The MAC7100 MACE1 board has two serial ports. This option
+            chooses which port will be used to connect to a host
+            running GDB."
+     }
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+         display          "Diagnostic serial port"
+         active_if        CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+         flavor data
+         legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+         default_value    0
+         description      "
+            The MAC7100 MACE1 board has two serial ports. This option
+            chooses which port will be used for diagnostic output."
+     }
+     
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+        display       "Diagnostic serial port baud rate"
+        flavor        data
+        legal_values  9600 19200 38400
+        default_value 38400
+        description   "
+            This option selects the baud rate used for the diagnostic port."
+    }
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+         display       "GDB serial port baud rate"
+         flavor        data
+         legal_values  9600 19200 38400
+         default_value 38400
+         description   "
+            This option controls the baud rate used for the GDB connection."
+     }
+
+    cdl_option CYGSEM_HAL_ROM_MONITOR {
+        display       "Behave as a ROM monitor"
+        flavor        bool
+        default_value 0
+        parent        CYGPKG_HAL_ROM_MONITOR
+        requires      { CYG_HAL_STARTUP == "ROM" || 
+                        CYG_HAL_STARTUP == "ROMRAM" }
+        description   "
+            Enable this option if this program is to be used as a ROM monitor,
+            i.e. applications will be loaded into RAM on the board, and this
+            ROM monitor may process exceptions or interrupts generated from the
+            application. This enables features such as utilizing a separate
+            interrupt stack when exceptions are generated."
+    }
+
+    cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+         display       "Work with a ROM monitor"
+         flavor        booldata
+         legal_values  { "Generic" "GDB_stubs" }
+         default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+         parent        CYGPKG_HAL_ROM_MONITOR
+         requires      { CYG_HAL_STARTUP == "RAM" }
+         description   "
+             Support can be enabled for different varieties of ROM monitor.
+             This support changes various eCos semantics such as the encoding
+             of diagnostic output, or the overriding of hardware interrupt
+             vectors.
+             Firstly there is \"Generic\" support which prevents the HAL
+             from overriding the hardware vectors that it does not use, to
+             instead allow an installed ROM monitor to handle them. This is
+             the most basic support which is likely to be common to most
+             implementations of ROM monitor.
+             \"GDB_stubs\" provides support when GDB stubs are included in
+             the ROM monitor or boot ROM."
+     }
+
+    cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+        display       "Redboot HAL options"
+        flavor        none
+        no_define
+        parent        CYGPKG_REDBOOT
+        active_if     CYGPKG_REDBOOT
+        description   "
+            This option lists the target's requirements for a valid Redboot
+            configuration."
+
+        cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+            display       "Build Redboot ROM binary image"
+            active_if     CYGBLD_BUILD_REDBOOT
+            default_value 1
+            no_define
+            description "This option enables the conversion of the Redboot ELF
+                         image to a binary image suitable for ROM programming."
+    
+            make -priority 325 {
+                <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+                $(OBJCOPY) --strip-debug $< $(@:.bin=.img) 
+                $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+                $(OBJCOPY) -O binary $< $@
+            }
+
+        }
+    }
+    cdl_component CYGBLD_GLOBAL_OPTIONS {
+        display "Global build options"
+        flavor  none
+        parent  CYGPKG_NONE
+        description   "
+        Global build options including control over
+        compiler flags, linker flags and choice of toolchain."
+
+        cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+            display "Global command prefix"
+            flavor  data
+            no_define
+            default_value { "arm-elf" }
+            description "
+                This option specifies the command prefix used when
+                invoking the build tools."
+        }
+
+        cdl_option CYGBLD_GLOBAL_CFLAGS {
+            display "Global compiler flags"
+            flavor  data
+            no_define
+            default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mbig-endian -mno-short-load-words -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -gdwarf-2 -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+            description   "
+                This option controls the global compiler flags which
+                are used to compile all packages by
+                default. Individual packages may define options which
+                override these global flags."
+
+        }
+
+        cdl_option CYGBLD_GLOBAL_LDFLAGS {
+            display "Global linker flags"
+            flavor  data
+            no_define
+            default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mbig-endian -mno-short-load-words -Wl,--gc-sections -Wl,-static -gdwarf-2 -nostdlib" }
+            description   "
+                This option controls the global linker flags. Individual
+                packages may define options which override these global flags."
+        }
+    }
+
+    cdl_component CYGHWR_MEMORY_LAYOUT {
+        display "Memory layout"
+        flavor data
+        no_define
+        calculated { (CYG_HAL_STARTUP == "RAM") ?    "arm_mac7100_mace1_ram" :
+                     (CYG_HAL_STARTUP == "ROMRAM") ? "arm_mac7100_mace1_romram" :
+                                                     "arm_mac7100_mace1_rom" }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+            display "Memory layout linker script fragment"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+            calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_mac7100_mace1_ram.ldi>" :
+                         (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_arm_mac7100_mace1_romram.ldi>" :
+                                                      "<pkgconf/mlt_arm_mac7100_mace1_rom.ldi>" }
+        }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_H {
+            display "Memory layout header file"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_H
+            calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_mac7100_mace1_ram.h>" :
+                         (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_arm_mac7100_mace1_romram.h>" :
+                                                      "<pkgconf/mlt_arm_mac7100_mace1_rom.h>" }
+        }
+    }
+}
diff --git a/packages/hal/arm/mac7100/mace1/v2_0/include/hal_platform_ints.h b/packages/hal/arm/mac7100/mace1/v2_0/include/hal_platform_ints.h
new file mode 100644 (file)
index 0000000..30e9069
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef CYGONCE_HAL_PLATFORM_INTS_H
+#define CYGONCE_HAL_PLATFORM_INTS_H
+//==========================================================================
+//
+//      hal_platform_ints.h
+//
+//      HAL Interrupt and clock assignments for MAC7100/MACE1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2996 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-13
+// Purpose:      Define Interrupt support
+// Description:  The interrupt specifics for the MAC7100/MACE1 board/platform 
+//               are defined here.
+//              
+// Usage:        #include <cyg/hal/hal_platform_ints.h>
+//               ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define CYGNUM_HAL_ISR_MIN                     0
+#define CYGNUM_HAL_ISR_MAX                     63
+#define CYGNUM_HAL_ISR_COUNT                   (CYGNUM_HAL_ISR_MAX + 1)
+
+// INTC levels
+
+#define MAC7100_EDMA0_LEVEL        (0)
+#define MAC7100_EDMA1_LEVEL        (0)
+#define MAC7100_EDMA2_LEVEL        (0)
+#define MAC7100_EDMA3_LEVEL        (0)
+#define MAC7100_EDMA4_LEVEL        (0)
+#define MAC7100_EDMA5_LEVEL        (0)
+#define MAC7100_EDMA6_LEVEL        (0)
+#define MAC7100_EDMA7_LEVEL        (0)
+#define MAC7100_EDMA8_LEVEL        (0)
+#define MAC7100_EDMA9_LEVEL        (0)
+#define MAC7100_EDMA10_LEVEL       (0)
+#define MAC7100_EDMA11_LEVEL       (0)
+#define MAC7100_EDMA12_LEVEL       (0)
+#define MAC7100_EDMA13_LEVEL       (0)
+#define MAC7100_EDMA14_LEVEL       (0)
+#define MAC7100_EDMA15_LEVEL       (0)
+#define MAC7100_EDMA_Error_LEVEL   (0)
+#define MAC7100_MCM_SWT_LEVEL      (0)
+#define MAC7100_CRG_LEVEL          (0)
+#define MAC7100_PIT1_LEVEL         (9)
+#define MAC7100_PIT2_LEVEL         (9)
+#define MAC7100_PIT3_LEVEL         (10)
+#define MAC7100_PIT4_RTI_LEVEL     (9)
+#define MAC7100_VREG_LEVEL         (4)
+#define MAC7100_CAN_A_MB_LEVEL     (4)
+#define MAC7100_CAN_A_MB14_LEVEL   (4)
+#define MAC7100_CAN_A_Error_LEVEL  (4)
+#define MAC7100_CAN_B_MB_LEVEL     (4)
+#define MAC7100_CAN_B_MB14_LEVEL   (4)
+#define MAC7100_CAN_B_Error_LEVEL  (4)
+#define MAC7100_CAN_C_MB_LEVEL     (4)
+#define MAC7100_CAN_C_MB14_LEVEL   (4)
+#define MAC7100_CAN_C_Error_LEVEL  (4)
+#define MAC7100_CAN_D_MB_LEVEL     (4)
+#define MAC7100_CAN_D_MB14_LEVEL   (4)
+#define MAC7100_CAN_D_Error_LEVEL  (4)
+#define MAC7100_I2C_LEVEL          (4)
+#define MAC7100_DSPI_A_LEVEL       (5)
+#define MAC7100_DSPI_B_LEVEL       (5)
+#define MAC7100_ESCI_A_LEVEL       (8)
+#define MAC7100_ESCI_B_LEVEL       (8)
+#define MAC7100_ESCI_C_LEVEL       (8)
+#define MAC7100_ESCI_D_LEVEL       (8)
+#define MAC7100_EMIOS0_LEVEL       (7)
+#define MAC7100_EMIOS1_LEVEL       (7)
+#define MAC7100_EMIOS2_LEVEL       (7)
+#define MAC7100_EMIOS3_LEVEL       (7)
+#define MAC7100_EMIOS4_LEVEL       (7)
+#define MAC7100_EMIOS5_LEVEL       (7)
+#define MAC7100_EMIOS6_LEVEL       (7)
+#define MAC7100_EMIOS7_LEVEL       (7)
+#define MAC7100_EMIOS8_LEVEL       (7)
+#define MAC7100_EMIOS9_LEVEL       (7)
+#define MAC7100_EMIOS10_LEVEL      (7)
+#define MAC7100_EMIOS11_LEVEL      (7)
+#define MAC7100_EMIOS12_LEVEL      (7)
+#define MAC7100_EMIOS13_LEVEL      (7)
+#define MAC7100_EMIOS14_LEVEL      (7)
+#define MAC7100_EMIOS15_LEVEL      (7)
+#define MAC7100_ATD_LEVEL          (11)
+#define MAC7100_CFM_LEVEL          (7)
+#define MAC7100_PIM_LEVEL          (11)
+#define MAC7100_IRQ_LEVEL          (12)
+#define MAC7100_XIRQ_LEVEL         (12)
+
+// The vector used by the Real time clock
+#if CYGNUM_PIT_CHAN_CLOCK==0
+#define CYGNUM_HAL_INTERRUPT_RTC MAC7100_PIT4_RTI_IV
+#else
+#define CYGNUM_HAL_INTERRUPT_RTC (MAC7100_PIT1_IV+CYGNUM_PIT_CHAN_CLOCK-1)
+#endif
+
+//----------------------------------------------------------------------------
+// Reset.
+__externC void hal_mac7100_reset_cpu(void);
+#define HAL_PLATFORM_RESET() hal_mac7100_reset_cpu()
+
+#define HAL_PLATFORM_RESET_ENTRY 0x01000000
+
+#endif // CYGONCE_HAL_PLATFORM_INTS_H
diff --git a/packages/hal/arm/mac7100/mace1/v2_0/include/hal_platform_setup.h b/packages/hal/arm/mac7100/mace1/v2_0/include/hal_platform_setup.h
new file mode 100644 (file)
index 0000000..fd62e62
--- /dev/null
@@ -0,0 +1,133 @@
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+
+//=============================================================================
+//
+//      hal_platform_setup.h
+//
+//      Platform specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-03-12
+// Purpose:     MAC7100/MACE1 platform specific support routines
+// Description:
+// Usage:       #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <cyg/hal/var_io.h>
+#include <cyg/hal/hal_var_setup.h>
+//===========================================================================
+
+   .macro _led y
+        ldr r0,=MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET)
+        ldrh r1,[r0]
+        and r1,r1,#0x00ff
+        add r1,r1,#(\y<<8)
+        strh r1,[r0]
+    .endm
+
+
+// Initialize LED PORT
+// Set appropriate peripheral pins
+       .macro  _led_init
+        mov r1, #MAC7100_PIM_DDR  // Pin setting: Output+Low
+        ldr r0,=MAC7100_PIM_CONFIG(MAC7100_PORT_A_OFFSET, 8) // LED pin cfg
+        strh r1,[r0],#2 // LED: LSB ...
+        strh r1,[r0],#2
+        strh r1,[r0],#2
+        strh r1,[r0],#2
+        strh r1,[r0],#2
+        strh r1,[r0],#2
+        strh r1,[r0],#2
+        strh r1,[r0],#2 // LED: MSB ...
+      _led    0         // Set initial LED state. 
+    .endm
+
+
+// Clock initilalization
+       .macro  _pclock_init
+               _mac7100_setpll
+    .endm
+
+// Memory re-mapping
+       .macro _memory_remap
+               _mac7100_remap_single_chip
+    .endm
+
+
+// Initialize paralel port
+    .macro  _pio_init
+    .endm
+
+
+#define CYGHWR_LED_MACRO _led \x
+
+//===========================================================================
+                        
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+    .macro  _setup
+        ldr r0,=VAE_MAC7100_FlashSecurity
+        _led_init
+        _memory_remap
+        _pclock_init
+        _pio_init
+    .endm
+
+#define CYGSEM_HAL_ROM_RESET_USES_JUMP
+
+#else
+
+        .macro  _setup
+        _led_init
+        _led 16
+        _pclock_init
+        _pio_init        
+        .endm
+        
+#endif
+
+#define PLATFORM_SETUP1     _setup
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H
diff --git a/packages/hal/arm/mac7100/mace1/v2_0/include/mace1_misc.h b/packages/hal/arm/mac7100/mace1/v2_0/include/mace1_misc.h
new file mode 100644 (file)
index 0000000..260bdcc
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef CYGONCE_HAL_MACE1_MISC_H
+#define CYGONCE_HAL_MACE1_MISC_H
+//=============================================================================
+//
+//      mace1_misc.h
+//
+//      MACE1 board specific functions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-02-03
+// Purpose:     MACE1 board specific registers
+// Description:
+// Usage:       #include <cyg/hal/mece1_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+void hal_mace1_set_leds(int);
+void hal_mace1_led_on(int);
+void hal_mace1_led_off(int);
+int hal_mace1_get_leds(void);
+
+#define HAL_MAC7100_SET_LEDS(x) hal_mace1_set_leds(x)
+#define HAL_MAC7100_LED_ON(x) hal_mace1_led_on(x)
+#define HAL_MAC7100_LED_OFF(x) hal_mace1_led_off(x)
+#define HAL_MAC7100_GET_LEDS(x) hal_mace1_get_leds(x)
+
+
+//-----------------------------------------------------------------------------
+// end of mace1_misc.h
+#endif // CYGONCE_HAL_MACE1_MISC_H
diff --git a/packages/hal/arm/mac7100/mace1/v2_0/include/pkgconf/mlt_arm_mac7100_mace1_rom.h b/packages/hal/arm/mac7100/mace1/v2_0/include/pkgconf/mlt_arm_mac7100_mace1_rom.h
new file mode 100644 (file)
index 0000000..7cc23f8
--- /dev/null
@@ -0,0 +1,24 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+// Initially RAM is at 0x40000000 but we ramap to 0x0
+#define CYGMEM_REGION_ram (0x00000000)
+#define CYGMEM_REGION_ram_SIZE (0x00008000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x20000000)
+#define CYGMEM_REGION_rom_SIZE (0x80000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE                                       \
+  ((CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE) -                         \
+   (size_t) CYG_LABEL_NAME (__heap1))
+
diff --git a/packages/hal/arm/mac7100/mace1/v2_0/include/pkgconf/mlt_arm_mac7100_mace1_rom.ldi b/packages/hal/arm/mac7100/mace1/v2_0/include/pkgconf/mlt_arm_mac7100_mace1_rom.ldi
new file mode 100644 (file)
index 0000000..2abf974
--- /dev/null
@@ -0,0 +1,39 @@
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+
+MEMORY
+{
+    ram  : ORIGIN = 0x00000000, LENGTH = 0x8000
+    rom  : ORIGIN = 0x20000000, LENGTH = 0x80000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    SECTION_rom_vectors (rom, 0x20000000, LMA_EQ_VMA)
+
+//  MAC7100 Flash Security
+//  Following section is manually added to address MAC7100 flash security area
+//  It should actually be something like this
+//    SECTION_sgfm_config (rom, 0x20000400, LMA_EQ_VMA)
+
+    .mac7100_flash_security 0x20000400 : { KEEP (*(.mac7100_flash_security))} > rom
+
+//  END MAC7100 Flash Security
+    
+    SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+
+    SECTION_fixed_vectors (ram, 0x00000020, LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN(0x4), FOLLOWING(.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+    SECTIONS_END
+}
diff --git a/packages/hal/arm/mac7100/mace1/v2_0/include/plf_io.h b/packages/hal/arm/mac7100/mace1/v2_0/include/plf_io.h
new file mode 100644 (file)
index 0000000..98f8e08
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef CYGONCE_HAL_PLF_IO_H
+#define CYGONCE_HAL_PLF_IO_H
+//=============================================================================
+//
+//      plf_io.h
+//
+//      MACE1 board specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-02-03
+// Purpose:     MACE1 board specific registers
+// Description:
+// Usage:       #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+// On-chip device base addresses
+
+#define CYGARC_PHYSICAL_ADDRESS(_x_)
+
+#endif // CYGONCE_HAL_PLF_IO_H
+//-----------------------------------------------------------------------------
+// end of plf_io.h
diff --git a/packages/hal/arm/mac7100/mace1/v2_0/src/mace1_misc.c b/packages/hal/arm/mac7100/mace1/v2_0/src/mace1_misc.c
new file mode 100644 (file)
index 0000000..7e827ba
--- /dev/null
@@ -0,0 +1,102 @@
+//==========================================================================
+//
+//      mace1_misc.c
+//
+//      HAL misc board support code for MACE1 board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-12
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/hal/hal_io.h>             // low level i/o
+#include <cyg/hal/var_io.h>             // common registers
+#include <cyg/hal/plf_io.h>             // platform registers
+#include <cyg/hal/mace1_misc.h>         // mace1 misc functions
+
+void
+hal_mace1_set_leds(int val)
+{
+    HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), 
+                     ((val<<8)&0xff00)); // turn all LEDs off
+}
+
+void
+hal_mace1_led_on(int val)
+{
+    cyg_uint16 leds;
+
+    // read old LED state
+    HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), leds); 
+    leds|=1<<(8+val);
+    // Write new state
+    HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), leds); 
+}
+
+void
+hal_mace1_led_off(int val)
+{
+    cyg_uint16 leds;
+
+    // read old LED state
+    HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), leds); 
+    leds&=~(1<<(8+val));
+    // Write new state
+    HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), leds); 
+}
+
+int
+hal_mace1_get_leds(void)
+{
+    cyg_uint16 leds = 0;
+
+    // read old LED state
+    HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), leds); 
+    return (leds>>8)&0xFF;
+}
+
+//--------------------------------------------------------------------------
+// EOF mace1_misc.c
diff --git a/packages/hal/arm/mac7100/var/v2_0/ChangeLog b/packages/hal/arm/mac7100/var/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..07e06e0
--- /dev/null
@@ -0,0 +1,61 @@
+2007-01-10  Ilija Koco  <ilijak@siva.com.mk>
+
+       * hal_arm_mac7100.cdl: added property
+       "requires CYGPKG_IO_SERIAL_FREESCALE_ESCI_H"
+
+2006-08-08  Ilija Koco  <ilijak@siva.com.mk>
+
+       * var_io.h: Freescale eSCI platform dependent clock related macros
+       moved here from ser_esci.h
+       
+2006-06-08  Ilija Koco  <ilijak@siva.com.mk>
+
+       * hal_var_setup.h: (new) Assembly macros shared between targets.
+       * cdl/hal_arm_mac7100.cdl: some defaults changed in favour of
+       MAC7100EVB
+
+2006-05-24  Ilija Koco  <ilijak@siva.com.mk>
+
+       * cdl/hal_arm_mac7100.cdl:
+       * include/hal_cache.h: 
+       * include/hal_diag.h: 
+       * include/mac7100_misc.h: 
+       * include/plf_stub.h: unchanged from AT91
+       * include/var_arch.h:
+       * include/var_io.h:     
+       * src/flash_security.S:
+       * src/hal_diag.c:
+       * src/mac7100_misc.c
+       New variant port - based on at91 variant by Gary Thomas
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/arm/mac7100/var/v2_0/cdl/hal_arm_mac7100.cdl b/packages/hal/arm/mac7100/var/v2_0/cdl/hal_arm_mac7100.cdl
new file mode 100644 (file)
index 0000000..f7eb6f8
--- /dev/null
@@ -0,0 +1,128 @@
+# ====================================================================
+#
+#      hal_arm_mac7100.cdl
+#
+#      Freescale MAC7100 HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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-02-03
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_MAC7100 {
+    display       "Freescale MAC7100 variant HAL"
+    parent        CYGPKG_HAL_ARM
+    define_header hal_arm_mac7100.h
+    include_dir   cyg/hal
+    hardware
+    description   "
+        The MAC7100 HAL package provides the support needed to run
+        eCos on Freescale MAC7100 based targets."
+
+    compile       flash_security.S hal_diag.c mac7100_misc.c
+
+    implements    CYGINT_HAL_DEBUG_GDB_STUBS
+    implements    CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
+    implements    CYGINT_HAL_ARM_ARCH_ARM7
+    implements    CYGINT_HAL_ARM_THUMB_ARCH
+    implements    CYGINT_HAL_ARM_BIGENDIAN
+
+    requires      CYGHWR_HAL_ARM_BIGENDIAN == 1
+    
+    requires      CYGPKG_IO_SERIAL_FREESCALE_ESCI_H
+    
+    # Let the architectural HAL see this variant's files
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_IO_H"
+        puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_ARCH_H"
+    }
+
+    cdl_option CYGHWR_HAL_ARM_MAC7100 {
+        display        "MAC7100 variant used"
+        flavor         data
+        default_value  {"MAC7111"}
+        legal_values   {"MAC7111" "MAC7121" "MAC7116" }
+        description    "
+            The MAC7100 microcontroller family has several variants,
+            the main differences being the amount of on-chip SRAM,
+            peripherals and their layout. This option allows the
+            platform HALs to select the specific microcontroller being
+            used."
+    }
+
+    cdl_option CYGHWR_HAL_ARM_MAC7100_FIQ {
+        display       "handle FIQ as an IRQ"
+        flavor        bool
+        default_value 0
+        description   "
+            Enable this option if you need to handle FIQ interrupts in the
+            normal way, i.e. a FIQ interrupt will be treated as a normal IRQ 
+            using the highest priority
+            "
+    }
+
+    cdl_option CYGHWR_HAL_ARM_MAC7100_INTC_FIQDEF {
+        display       "Set FIQDEF"
+        flavor        data
+        default_value CYGHWR_HAL_ARM_MAC7100_FIQ ? 14 : 16
+        legal_values 0 to 32
+        description   "
+            Set maximum level that shall be routed to IRQ.
+            "
+    }
+
+    cdl_option CYGHWR_HAL_ARM_MAC7100_INTC_EMASK {
+        display       "enable INTC to automatically handle CLMASK"
+        flavor        data
+        default_value 0x20
+        legal_values 0x00 0x20
+        description   "
+            Enable this option if you need INTC to automatically mask 
+            lower level IRQ.
+            
+            - 0x00 - disable
+            - 0x20 - enable
+            
+            "
+    }
+}
diff --git a/packages/hal/arm/mac7100/var/v2_0/include/hal_cache.h b/packages/hal/arm/mac7100/var/v2_0/include/hal_cache.h
new file mode 100644 (file)
index 0000000..3f0c0c7
--- /dev/null
@@ -0,0 +1,189 @@
+#ifndef CYGONCE_HAL_CACHE_H
+#define CYGONCE_HAL_CACHE_H
+
+//=============================================================================
+//
+//      hal_cache.h
+//
+//      HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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, gthomas
+// Contributors:        nickg, gthomas
+// Date:        1998-09-28
+// Purpose:     Cache control API
+// Description: The macros defined here provide the HAL APIs for handling
+//              cache control operations.
+// Usage:
+//              #include <cyg/hal/hal_cache.h>
+//              ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//-----------------------------------------------------------------------------
+// Cache dimensions
+
+// Data cache
+//#define HAL_DCACHE_SIZE                 0    // Size of data cache in bytes
+//#define HAL_DCACHE_LINE_SIZE            0    // Size of a data cache line
+//#define HAL_DCACHE_WAYS                 0    // Associativity of the cache
+
+// Instruction cache
+//#define HAL_ICACHE_SIZE                 0    // Size of cache in bytes
+//#define HAL_ICACHE_LINE_SIZE            0    // Size of a cache line
+//#define HAL_ICACHE_WAYS                 0    // Associativity of the cache
+
+//#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
+//#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
+
+//-----------------------------------------------------------------------------
+// Global control of data cache
+
+// Enable the data cache
+#define HAL_DCACHE_ENABLE()
+
+// Disable the data cache
+#define HAL_DCACHE_DISABLE()
+
+// Invalidate the entire cache
+#define HAL_DCACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_DCACHE_SYNC()
+
+// Purge contents of data cache
+#define HAL_DCACHE_PURGE_ALL()
+
+// Query the state of the data cache (does not affect the caching)
+#define HAL_DCACHE_IS_ENABLED(_state_)          \
+    CYG_MACRO_START                             \
+    (_state_) = 0;                              \
+    CYG_MACRO_END
+
+// Set the data cache refill burst size
+//#define HAL_DCACHE_BURST_SIZE(_size_)
+
+// Set the data cache write mode
+//#define HAL_DCACHE_WRITE_MODE( _mode_ )
+
+//#define HAL_DCACHE_WRITETHRU_MODE       0
+//#define HAL_DCACHE_WRITEBACK_MODE       1
+
+// Load the contents of the given address range into the data cache
+// and then lock the cache so that it stays there.
+//#define HAL_DCACHE_LOCK(_base_, _size_)
+
+// Undo a previous lock operation
+//#define HAL_DCACHE_UNLOCK(_base_, _size_)
+
+// Unlock entire cache
+//#define HAL_DCACHE_UNLOCK_ALL()
+
+//-----------------------------------------------------------------------------
+// Data cache line control
+
+// Allocate cache lines for the given address range without reading its
+// contents from memory.
+//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ )
+
+// Write dirty cache lines to memory and invalidate the cache entries
+// for the given address range.
+//#define HAL_DCACHE_FLUSH( _base_ , _size_ )
+
+// Invalidate cache lines in the given range without writing to memory.
+//#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )
+
+// Write dirty cache lines to memory for the given address range.
+//#define HAL_DCACHE_STORE( _base_ , _size_ )
+
+// Preread the given range into the cache with the intention of reading
+// from it later.
+//#define HAL_DCACHE_READ_HINT( _base_ , _size_ )
+
+// Preread the given range into the cache with the intention of writing
+// to it later.
+//#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ )
+
+// Allocate and zero the cache lines associated with the given range.
+//#define HAL_DCACHE_ZERO( _base_ , _size_ )
+
+//-----------------------------------------------------------------------------
+// Global control of Instruction cache
+
+// Enable the instruction cache
+#define HAL_ICACHE_ENABLE()
+
+// Disable the instruction cache
+#define HAL_ICACHE_DISABLE()
+
+// Invalidate the entire cache
+#define HAL_ICACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_ICACHE_SYNC()
+
+// Query the state of the instruction cache (does not affect the caching)
+#define HAL_ICACHE_IS_ENABLED(_state_)          \
+    CYG_MACRO_START                             \
+    (_state_) = 0;                              \
+    CYG_MACRO_END
+
+// Set the instruction cache refill burst size
+//#define HAL_ICACHE_BURST_SIZE(_size_)
+
+// Load the contents of the given address range into the instruction cache
+// and then lock the cache so that it stays there.
+//#define HAL_ICACHE_LOCK(_base_, _size_)
+
+// Undo a previous lock operation
+//#define HAL_ICACHE_UNLOCK(_base_, _size_)
+
+// Unlock entire cache
+//#define HAL_ICACHE_UNLOCK_ALL()
+
+//-----------------------------------------------------------------------------
+// Instruction cache line control
+
+// Invalidate cache lines in the given range without writing to memory.
+//#define HAL_ICACHE_INVALIDATE( _base_ , _size_ )
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_CACHE_H
+// End of hal_cache.h
diff --git a/packages/hal/arm/mac7100/var/v2_0/include/hal_diag.h b/packages/hal/arm/mac7100/var/v2_0/include/hal_diag.h
new file mode 100644 (file)
index 0000000..f3a4922
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef CYGONCE_HAL_DIAG_H
+#define CYGONCE_HAL_DIAG_H
+
+//=============================================================================
+//
+//      hal_diag.h
+//
+//      HAL Support for Kernel Diagnostic Routines
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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, tkoeller, ilijak
+// Date:        2001-07-12
+// Purpose:     HAL Support for Kernel Diagnostic Routines
+// Description: Diagnostic routines for use during kernel development.
+// Usage:       #include <cyg/hal/hal_diag.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+//-----------------------------------------------------------------------------
+// LED
+externC void hal_diag_led(int mask);
+
+//-----------------------------------------------------------------------------
+// delay
+
+externC void hal_delay_us(cyg_int32 usecs);
+#define HAL_DELAY_US(n) hal_delay_us(n);
+
+//-----------------------------------------------------------------------------
+// reset
+
+extern void hal_mac7100_reset_cpu(void);
+
+//-----------------------------------------------------------------------------
+// end of hal_diag.h
+#endif // CYGONCE_HAL_DIAG_H
diff --git a/packages/hal/arm/mac7100/var/v2_0/include/hal_var_setup.h b/packages/hal/arm/mac7100/var/v2_0/include/hal_var_setup.h
new file mode 100644 (file)
index 0000000..7ac79f1
--- /dev/null
@@ -0,0 +1,140 @@
+#ifndef CYGONCE_HAL_VAR_SETUP_H
+#define CYGONCE_HAL_VAR_SETUP_H
+
+//=============================================================================
+//
+//      hal_var_setup.h
+//
+//      Variant specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-06-05
+// Purpose:     MAC7100 variant specific support routines
+// Description:
+// Usage:       in <cyg/hal/hal_platform_serup.h> include following:
+//              #include <cyg/hal/hal_var_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+// Clock initilalization
+// Initialize PLL
+#if defined(CYGNUM_HAL_ARM_MAC7100_FDIV)  // Divider set by user.
+#   define MAC7100_CRG_REFDV_VAL (CYGNUM_HAL_ARM_MAC7100_FDIV-1)
+#else                                     //  Divider calculated. 
+      //NOTE: works for f_osc <= 8MHz
+#   define MAC7100_CRG_REFDV_VAL (((CYGNUM_HAL_ARM_MAC7100_F_OSC/500000) - 1) & 0x0F) // 15 (1)
+#endif
+#define MAC7100_CRG_SYNR_VAL (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED / 2 / \
+        (CYGNUM_HAL_ARM_MAC7100_F_OSC / (MAC7100_CRG_REFDV_VAL+1))-1) // 47 (5)
+
+#define MAC7100_CRG_PLLCTL_VAL                                          \
+      (MAC7100_CRG_CME|MAC7100_CRG_PLLON|MAC7100_CRG_AUTO|              \
+       MAC7100_CRG_ACQ|MAC7100_CRG_SCME)
+#define MAC7100_CRG_CLKSEL_VAL (MAC7100_CRG_PLLSEL)
+
+        .macro  _mac7100_setpll
+        ldr r2,=MAC7100_CRG_BASE
+        mov r3,#0
+        // Disable clock interrupts
+        strb r3,[r2,#(MAC7100_CRG_CRGINT-MAC7100_CRG_BASE)]  
+        // DeSelect PLL clock
+        mov r3,#MAC7100_CRG_REFDV_VAL
+        // Reference Divider reg.
+        strb r3,[r2,#(MAC7100_CRG_REFDV-MAC7100_CRG_BASE)]   
+        mov r3,#MAC7100_CRG_SYNR_VAL
+        // Synthesizer register
+        strb r3,[r2,#(MAC7100_CRG_SYNR-MAC7100_CRG_BASE)]   
+        mov r3,#MAC7100_CRG_PLLCTL_VAL
+        // PLL control register
+        strb r3,[r2,#(MAC7100_CRG_PLLCTL-MAC7100_CRG_BASE)]   
+        // Wait PLL lock  <-----------------------------------<
+1:      ldrb r3,[r2,#(MAC7100_CRG_CRGFLG-MAC7100_CRG_BASE)] 
+        tst r3,#MAC7100_CRG_LOCK
+        bne 2f      // PLL locked, GO ON  ---------->>
+        b 1b        // Still waiting for PLL lock ------------>
+2:      mov r3,#MAC7100_CRG_CLKSEL_VAL  // <<-------<<
+        // Select PLL clock
+        strb r3,[r2,#(MAC7100_CRG_CLKSEL-MAC7100_CRG_BASE)]  
+        mov r3,#0
+        strb r3,[r2,#(MAC7100_CRG_BDMCTL-MAC7100_CRG_BASE)]  // Set CRG BDMCTL 
+        mov r3,r3
+    .endm
+
+// Memory re-mapping for single chip configuration
+// Re-map internal memory so that vectors can reside in RAM.
+//     RAM base   0x00000000 (as well as 0x40000000)
+//     Flash base 0x20000000
+    .macro _mac7100_remap_single_chip
+        _led    1
+        ldr     r1, _mac7100_teleport
+        ldr     r0, [r1]             //AAMR Register
+
+        mvn     r4, #0xf0000000      // 1.Copy telepoter to RAM
+        ldr     r2, _mac7100_teleport+4  //    TelePorter
+        ldr     r3, _mac7100_teleport+8  //    TelePort (TelePorter end)
+        and     r2,r2,r4
+        and     r3,r3,r4
+        mov     r4, #0x40000000      //    RAM address
+1: // Copy teleporter:               //    copying teleporter <---<                 
+            ldr     r5,[r2],#4      
+            str     r5,[r4],#4
+            cmp     r2,r3
+            bne     1b                //    Copy teleporter -------->
+        ldr     r3,_mac7100_teleport+12
+        mov     pc,#0x40000000        // 2.Jump to _mac7100_teleporter in RAM
+_mac7100_teleporter:
+        bic     r0,r0,#0x000000ff     // 3.Re-map memory
+        orr     r0,r0,#0x8b           //   Flash -> 0x20000000
+        str     r0,[r1]               //   RAM   -> 0x00000000 and 0x40000000
+        mov     pc,r3                 // 4.Teleport back to Flash
+_mac7100_teleport:
+        .long MAC7100_MCM_AAMR
+        .long _mac7100_teleporter
+        .long _mac7100_teleport
+        .long _mac7100_teleport_return
+_mac7100_teleport_return:
+    .endm
+
+// End memory re-mapping for single chip configuration
+
+//-----------------------------------------------------------------------------
+// end of hal_var_setup.h
+#endif // CYGONCE_HAL_VAR_SETUP_H
diff --git a/packages/hal/arm/mac7100/var/v2_0/include/mac7100_misc.h b/packages/hal/arm/mac7100/var/v2_0/include/mac7100_misc.h
new file mode 100644 (file)
index 0000000..1fb4473
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef CYGONCE_HAL_MAC7100_MISC_H
+#define CYGONCE_HAL_MAC7100_MISC_H
+//=============================================================================
+//
+//      mac7100_misc.h
+//
+//      Variant specific functions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-02-03
+// Purpose:     MAC7100 specific hal functions
+// Description: 
+// Usage:       #include <cyg/hal/mac7100_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// *********************************************************************
+//
+// ESCI Module
+//
+// *********************************************************************
+
+externC void hal_mac7100_esci_pins(cyg_uint32 i_esci);
+
+#endif // CYGONCE_HAL_MAC7100_MISC_H
+// end of mac7100_misc.h
diff --git a/packages/hal/arm/mac7100/var/v2_0/include/plf_stub.h b/packages/hal/arm/mac7100/var/v2_0/include/plf_stub.h
new file mode 100644 (file)
index 0000000..97d4d1d
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef CYGONCE_HAL_PLF_STUB_H
+#define CYGONCE_HAL_PLF_STUB_H
+
+//=============================================================================
+//
+//      plf_stub.h
+//
+//      Platform header for GDB stub support.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-07-12
+// Purpose:     Platform HAL stub support for MAC7100 based boards.
+// Usage:       #include <cyg/hal/plf_stub.h>
+//              
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h>         // CYG_UNUSED_PARAM
+
+#include <cyg/hal/arm_stub.h>           // architecture stub support
+
+//----------------------------------------------------------------------------
+// Define some platform specific communication details. This is mostly
+// handled by hal_if now, but we need to make sure the comms tables are
+// properly initialized.
+
+externC void cyg_hal_plf_comms_init(void);
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL()       cyg_hal_plf_comms_init()
+
+#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud))
+#define HAL_STUB_PLATFORM_INTERRUPTIBLE       0
+#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ()    CYG_EMPTY_STATEMENT
+
+//----------------------------------------------------------------------------
+// Stub initializer.
+#define HAL_STUB_PLATFORM_INIT()              CYG_EMPTY_STATEMENT
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_PLF_STUB_H
+// End of plf_stub.h
diff --git a/packages/hal/arm/mac7100/var/v2_0/include/var_arch.h b/packages/hal/arm/mac7100/var/v2_0/include/var_arch.h
new file mode 100644 (file)
index 0000000..c5ea1ec
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef CYGONCE_HAL_VAR_ARCH_H
+#define CYGONCE_HAL_VAR_ARCH_H
+//=============================================================================
+//
+//      var_arch.h
+//
+//      MAC7100 variant architecture overrides
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Jonathan Larmour <jifl@eCosCentric.com>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-02-03
+// Purpose:      MAC7100 variant architecture overrides
+// Description: 
+// Usage:        #include <cyg/hal/hal_arch.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_io.h>
+
+//--------------------------------------------------------------------------
+// Idle thread code.
+// This macro is called in the idle thread loop, and gives the HAL the
+// chance to insert code. Typical idle thread behaviour might be to halt the
+// processor. These implementations halt the system core clock.
+
+#ifndef HAL_IDLE_THREAD_ACTION
+
+// No idle action
+
+#endif
+
+#endif // CYGONCE_HAL_VAR_ARCH_H
+//-----------------------------------------------------------------------------
+// end of var_arch.h
diff --git a/packages/hal/arm/mac7100/var/v2_0/include/var_io.h b/packages/hal/arm/mac7100/var/v2_0/include/var_io.h
new file mode 100644 (file)
index 0000000..ca588cc
--- /dev/null
@@ -0,0 +1,470 @@
+#ifndef CYGONCE_HAL_VAR_IO_H
+#define CYGONCE_HAL_VAR_IO_H
+//=============================================================================
+//
+//      var_io.h
+//
+//      Variant specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-02-03
+// Purpose:     MAC7100 variant specific registers
+// Description: based on freescale's mac7100.h
+// Usage:       #include <cyg/hal/var_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/hal/plf_io.h>
+
+#if !defined HAL_IO_MACROS_NO_ADDRESS_MUNGING
+#define HAL_IO_MACROS_NO_ADDRESS_MUNGING 1
+#endif // HAL_IO_MACROS_NO_ADDRESS_MUNGING
+
+// *********************************************************************
+//
+// INTC Module
+//
+// *********************************************************************
+
+// Interrupt Controller Definitions 
+#define MAC7100_INTC_BASE      (0xFC048000)
+
+#define MAC7100_IPRH_OFFSET    (0x0000)
+#define MAC7100_IPRL_OFFSET    (0x0004)
+#define MAC7100_IMRH_OFFSET    (0x0008)
+#define MAC7100_IMRL_OFFSET    (0x000C)
+#define MAC7100_INTFRCH_OFFSET (0x0010)
+#define MAC7100_INTFRCL_OFFSET (0x0014)
+#define MAC7100_ICONFIG_OFFSET (0x001B)
+#define MAC7100_SIMR_OFFSET    (0x001C)
+#define MAC7100_CIMR_OFFSET    (0x001D)
+#define MAC7100_CLMASK_OFFSET  (0x001E) // CLMASK - Current Level Mask Register
+#define MAC7100_SLMASK_OFFSET  (0x001F) // SLMASK - Saved Level Mask Register 
+#define MAC7100_ICR_OFFSET     (0x0040)
+#define MAC7100_IRQIACK_OFFSET (0x00EC)
+#define MAC7100_FIQIACK_OFFSET (0x00F0)
+
+#define MAC7100_INTC_IPRH(intc_base)    (intc_base + MAC7100_IPRH_OFFSET)
+#define MAC7100_INTC_IPRL(intc_base)    (intc_base + MAC7100_IPRL_OFFSET)
+#define MAC7100_INTC_IMRH(intc_base)    (intc_base + MAC7100_IMRH_OFFSET)
+#define MAC7100_INTC_IMRL(intc_base)    (intc_base + MAC7100_IMRL_OFFSET)
+#define MAC7100_INTC_INTFRC(intc_base)  (intc_base + MAC7100_INTFRCH_OFFSET)
+#define MAC7100_INTC_INTFRCH(intc_base) (intc_base + MAC7100_INTFRCH_OFFSET)
+#define MAC7100_INTC_INTFRCL(intc_base) (intc_base + MAC7100_INTFRCL_OFFSET)
+#define MAC7100_INTC_ICONFIG(intc_base) (intc_base + MAC7100_ICONFIG_OFFSET)
+#define MAC7100_INTC_IRQIACK(intc_base) (intc_base + MAC7100_IRQIACK_OFFSET)
+#define MAC7100_INTC_FIQIACK(intc_base) (intc_base + MAC7100_FIQIACK_OFFSET)
+#define MAC7100_INTC_ICR(intc_base,src) (intc_base + MAC7100_ICR_OFFSET + src)
+#define MAC7100_INTC_SIMR(intc_base)    (intc_base + MAC7100_SIMR_OFFSET)
+#define MAC7100_INTC_CIMR(intc_base)    (intc_base + MAC7100_CIMR_OFFSET)
+#define MAC7100_INTC_CLMASK(intc_base)  (intc_base + MAC7100_CLMASK_OFFSET)
+#define MAC7100_INTC_SLMASK(intc_base)  (intc_base + MAC7100_SLMASK_OFFSET)
+
+#define MAC7100_INTC_INT_LEVEL(lev) (lev)
+
+// hardware interrupt source vector numbers 
+#define MAC7100_EDMA0_IV        (0)
+#define MAC7100_EDMA1_IV        (1)
+#define MAC7100_EDMA2_IV        (2)
+#define MAC7100_EDMA3_IV        (3)
+#define MAC7100_EDMA4_IV        (4)
+#define MAC7100_EDMA5_IV        (5)
+#define MAC7100_EDMA6_IV        (6)
+#define MAC7100_EDMA7_IV        (7)
+#define MAC7100_EDMA8_IV        (8)
+#define MAC7100_EDMA9_IV        (9)
+#define MAC7100_EDMA10_IV       (10)
+#define MAC7100_EDMA11_IV       (11)
+#define MAC7100_EDMA12_IV       (12)
+#define MAC7100_EDMA13_IV       (13)
+#define MAC7100_EDMA14_IV       (14)
+#define MAC7100_EDMA15_IV       (15)
+#define MAC7100_EDMA_Error_IV   (16)
+#define MAC7100_MCM_SWT_IV      (17)
+#define MAC7100_CRG_IV          (18)
+#define MAC7100_PIT1_IV         (19)
+#define MAC7100_PIT2_IV         (20)
+#define MAC7100_PIT3_IV         (21)
+#define MAC7100_PIT4_RTI_IV     (22)
+#define MAC7100_VREG_IV         (23)
+#define MAC7100_CAN_A_MB_IV     (24)
+#define MAC7100_CAN_A_MB14_IV   (25)
+#define MAC7100_CAN_A_Error_IV  (26)
+#define MAC7100_CAN_B_MB_IV     (27)
+#define MAC7100_CAN_B_MB14_IV   (28)
+#define MAC7100_CAN_B_Error_IV  (29)
+#define MAC7100_CAN_C_MB_IV     (30)
+#define MAC7100_CAN_C_MB14_IV   (31)
+#define MAC7100_CAN_C_Error_IV  (32)
+#define MAC7100_CAN_D_MB_IV     (33)
+#define MAC7100_CAN_D_MB14_IV   (34)
+#define MAC7100_CAN_D_Error_IV  (35)
+#define MAC7100_I2C_IV          (36)
+#define MAC7100_DSPI_A_IV       (37)
+#define MAC7100_DSPI_B_IV       (38)
+#define MAC7100_ESCI_A_IV       (39)
+#define MAC7100_ESCI_B_IV       (40)
+#define MAC7100_ESCI_C_IV       (41)
+#define MAC7100_ESCI_D_IV       (42)
+#define MAC7100_EMIOS0_IV       (43)
+#define MAC7100_EMIOS1_IV       (44)
+#define MAC7100_EMIOS2_IV       (45)
+#define MAC7100_EMIOS3_IV       (46)
+#define MAC7100_EMIOS4_IV       (47)
+#define MAC7100_EMIOS5_IV       (48)
+#define MAC7100_EMIOS6_IV       (49)
+#define MAC7100_EMIOS7_IV       (50)
+#define MAC7100_EMIOS8_IV       (51)
+#define MAC7100_EMIOS9_IV       (52)
+#define MAC7100_EMIOS10_IV      (53)
+#define MAC7100_EMIOS11_IV      (54)
+#define MAC7100_EMIOS12_IV      (55)
+#define MAC7100_EMIOS13_IV      (56)
+#define MAC7100_EMIOS14_IV      (57)
+#define MAC7100_EMIOS15_IV      (58)
+#define MAC7100_ATD_IV          (59)
+#define MAC7100_CFM_IV          (60)
+#define MAC7100_PIM_IV          (61)
+#define MAC7100_IRQ_IV          (62)
+#define MAC7100_XIRQ_IV         (63)
+
+#define MAC7100_IRQ_SPURIOUS     (-1)
+
+// *******************************************************************
+//
+// eSCI Module 
+//      Note: eSCI definitions are in cyg/devs/ser_esci.h
+// *******************************************************************
+#define CYGADDR_IO_SERIAL_FREESCALE_ESCI_A_BASE 0xFC0C4000
+#define CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_INT_VECTOR MAC7100_ESCI_A_IV
+
+#define CYGADDR_IO_SERIAL_FREESCALE_ESCI_B_BASE 0xFC0C8000
+#define CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_INT_VECTOR MAC7100_ESCI_B_IV
+
+#define CYGADDR_IO_SERIAL_FREESCALE_ESCI_C_BASE 0xFC0CC000
+#define CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_INT_VECTOR MAC7100_ESCI_C_IV
+
+#define CYGADDR_IO_SERIAL_FREESCALE_ESCI_D_BASE 0xFC0D0000
+#define CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_INT_VECTOR MAC7100_ESCI_D_IV
+
+#define CYGNUM_DEV_SER_FREESCALE_ESCI_SYSTEM_CLOCK \
+  (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED/2)
+#define FREESCALE_ESCI_BAUD(baud_rate)            \
+  ((CYGNUM_DEV_SER_FREESCALE_ESCI_SYSTEM_CLOCK)/(baud_rate*16))
+
+
+// *********************************************************************
+//
+// PIT Module
+//
+// *********************************************************************
+
+// Periodic Interrupt Timer Module Definitions 
+
+#define MAC7100_PIT_BASE         (0xFC08C000)
+#define MAC7100_TLVAL0_OFFSET    (0x0000)
+#define MAC7100_TVAL0_OFFSET     (0x0080)
+
+#define MAC7100_PIT_TLVAL(pit_base,chan)        \
+  (pit_base + MAC7100_TLVAL0_OFFSET + (4 * chan))
+#define MAC7100_PIT_TVAL(pit_base,chan)   \
+  (pit_base + MAC7100_TVAL0_OFFSET + (4 * chan))
+
+#define MAC7100_PITFLG_OFFSET         (0x0100)
+#define MAC7100_PITINTEN_OFFSET       (0x0104)
+#define MAC7100_PITINTSEL_OFFSET      (0x0108)
+#define MAC7100_PITEN_OFFSET          (0x010C)
+#define MAC7100_PITCTRL_OFFSET        (0x0110)
+
+#define MAC7100_PIT_FLAG_RTIF         (0x00000001)
+#define MAC7100_PIT_FLAG_TIF(chan)    (0x00000001 << chan)
+#define MAC7100_PIT_INTSEL_ISEL(chan) (0x00000001 << chan)
+#define MAC7100_PIT_INTEN_RTIE        (0x00000001)
+#define MAC7100_PIT_INTEN_TIE(chan)   (0x00000001 << chan)
+
+#define MAC7100_PIT_EN_RTIEN          (0x00000001)
+#define MAC7100_PIT_EN_PEN(chan)      (0x00000001 << chan)
+
+#define MAC7100_PIT_FLG(pit_base)    (pit_base + MAC7100_PITFLG_OFFSET)
+#define MAC7100_PIT_INTEN(pit_base)  (pit_base + MAC7100_PITINTEN_OFFSET)
+#define MAC7100_PIT_INTSEL(pit_base) (pit_base + MAC7100_PITINTSEL_OFFSET)
+#define MAC7100_PIT_EN(pit_base)     (pit_base + MAC7100_PITEN_OFFSET)
+
+#define MAC7100_PIT_CTRL(pit_base)   (pit_base + MAC7100_PITCTRL_OFFSET)
+#define MAC7100_PIT_MDIS    (0x01000000)
+
+
+// *********************************************************************
+//
+// PIM Module
+//
+// *********************************************************************/
+
+#define MAC7100_PIM_BASE  (0xFC0E8000)
+
+#define MAC7100_PORT_A_OFFSET (0x000)
+#define MAC7100_PORT_B_OFFSET (0x040)
+#define MAC7100_PORT_C_OFFSET (0x080)
+#define MAC7100_PORT_D_OFFSET (0x0C0)
+#define MAC7100_PORT_E_OFFSET (0x100)
+#define MAC7100_PORT_F_OFFSET (0x140)
+#define MAC7100_PORT_G_OFFSET (0x180)
+#define MAC7100_PORT_H_OFFSET (0x1C0)
+#define MAC7100_PORT_I_OFFSET (0x200)
+
+// PORT Pin Configuration Registers 
+#define MAC7100_PIM_CONFIG(port,pin)  (MAC7100_PIM_BASE+port+((pin)*2)) 
+// Port Wide Interrupt Flag Register 
+#define MAC7100_PIM_PORTIFR(port)     (MAC7100_PIM_BASE+port+0x20) 
+// Port Wide Data Read/Write Register 
+#define MAC7100_PIM_PORTDATA(port)    (MAC7100_PIM_BASE+port+0x24) 
+// Port Wide Input Register 
+#define MAC7100_PIM_PORTIR(port)      (MAC7100_PIM_BASE+port+0x26) 
+// Port Pin Data Registers 
+#define MAC7100_PIM_DATA(port,pin)    (MAC7100_PIM_BASE+port+0x28+pin) 
+
+// Global Interrupt Status Register 
+#define MAC7100_PIM_GLBLINT    (MAC7100_PIM_BASE+0x03C0) 
+// PIM Configuration Register 
+#define MAC7100_PIM_PIMCONFIG  (MAC7100_PIM_BASE+0x03C2) 
+// TDI Pin Configuration Register 
+#define MAC7100_PIM_CONFIG_TDI (MAC7100_PIM_BASE+0x03C4) 
+// TDO Pin Configuration Register 
+#define MAC7100_PIM_CONFIG_TDO (MAC7100_PIM_BASE+0x03C6) 
+// TMS Pin Configuration Register 
+#define MAC7100_PIM_CONFIG_TMS (MAC7100_PIM_BASE+0x03C8) 
+// TCK Pin Configuration Register 
+#define MAC7100_PIM_CONFIG_TCK (MAC7100_PIM_BASE+0x03CA) 
+// TA Pin Configuration Register 
+#define MAC7100_PIM_CONFIG_TA  (MAC7100_PIM_BASE+0x03CC) 
+
+// Bit definitions and macros for PIM_PA_CONFIGn 
+//  Pin Interrupt Flag Register 
+#define MAC7100_PIM_PIFR            (0x0001)       
+//  Pin Interrupt Enable Register 
+#define MAC7100_PIM_PIER            (0x0002)       
+//  Pull-up/down Enable Register 
+#define MAC7100_PIM_PULL(x)         (((x)&0x0003)<<2)    
+//  Reduced Drive Strength Register 
+#define MAC7100_PIM_RDR             (0x0010)       
+//  Open Drain Enable Register 
+#define MAC7100_PIM_ODER            (0x0020)       
+//  Data Direction Register 
+#define MAC7100_PIM_DDR             (0x0040)       
+#define MAC7100_PIM_MODE            (0x0080)       
+#define MAC7100_PIM_MODE_PERIPHERAL MAC7100_PIM_MODE
+
+// Bit definitions and macros for PIM_GLBLINT 
+//  Interrupt Pending 
+#define MAC7100_PIM_INT_PENDING(x)  (((x)&0x01FF)<<0)    
+
+// Bit definitions and macros for PIM_PIMCONFIG 
+//  Clock Enable for the EIM module 
+#define MAC7100_PIM_PORTHSEL        (0x0001)       
+//  Port H Select 
+#define MAC7100_PIM_EIMCLKEN        (0x0002)       
+
+#define MAC7100_PIM_PORT32IR(port32ir)  (MAC7100_PIM_BASE+0x03E0+port32ir)
+
+#define MAC7100_PIM_PORT32IR_AB (0x00)
+#define MAC7100_PIM_PORT32IR_CD (0x04)
+#define MAC7100_PIM_PORT32IR_EF (0x08)
+#define MAC7100_PIM_PORT32IR_GH (0x0C)
+#define MAC7100_PIM_PORT32IR_BC (0x10)
+#define MAC7100_PIM_PORT32IR_DE (0x14)
+#define MAC7100_PIM_PORT32IR_FG (0x18)
+#define MAC7100_PIM_PORT32IR_HI (0x1C)
+
+
+// ********************************************************************
+//
+// CRG Module
+//
+// ********************************************************************
+
+// Register read/write macros 
+#define MAC7100_CRG_BASE   0xFC088000 // SYNR - Synthesizer Register 
+#define MAC7100_CRG_SYNR   0xFC088000 // SYNR - Synthesizer Register 
+#define MAC7100_CRG_REFDV  0xFC088001 // REFDV - Reference Divider Register 
+#define MAC7100_CRG_CTFLG  0xFC088002 // CTFLG - Test Flags Register (reserved)
+#define MAC7100_CRG_CRGFLG 0xFC088003 // CRGFLG - Flags Register 
+#define MAC7100_CRG_CRGINT 0xFC088004 // CRGINT - Interrupt Enable Register 
+#define MAC7100_CRG_CLKSEL 0xFC088005 // CLKSEL - Clock Select Register 
+#define MAC7100_CRG_PLLCTL 0xFC088006 // PLLCTL - PLL Control Register 
+#define MAC7100_CRG_SDMCTL 0xFC088007 // SDMCTL - STOP/DOZE Control Register 
+#define MAC7100_CRG_BDMCTL 0xFC088008 // BDMCTL - BDM Control Register 
+#define MAC7100_CRG_FORBYP 0xFC088009 // FORBYP - Force and Bypass Test 
+#define MAC7100_CRG_CTCTL  0xFC08800A // CTCTL - Test Control Register (resvd) 
+
+// Bit definitions and macros for CRG_SYNR 
+#define MAC7100_CRG_SYN(x) (((x)&0x3F)<<0)  //  Synthesizer Count value 
+
+// Bit definitions and macros for CRG_REFDV 
+#define MAC7100_CRG_REFD(x) (((x)&0x0F)<<0)  //Reference divider 
+
+// Bit definitions and macros for CRG_CRGFLG 
+#define MAC7100_CRG_SCM     (0x01)         //Self Clock Mode Status 
+#define MAC7100_CRG_SCMIF   (0x02)         //Self Clock Mode Interrupt Flag 
+#define MAC7100_CRG_TRACK   (0x04)         //Track Status 
+#define MAC7100_CRG_LOCK    (0x08)         //Lock Status 
+#define MAC7100_CRG_LOCKIF  (0x10)         //PLL Lock Interrupt Flag 
+#define MAC7100_CRG_LVRF    (0x20)         //Low Voltage Reset Flag 
+#define MAC7100_CRG_PORF    (0x40)         //Power on Reset Flag 
+#define MAC7100_CRG_STPEF   (0x80)         //Stop Entry Flag 
+
+// Bit definitions and macros for CRG_CRGINT 
+#define MAC7100_CRG_SCMIE   (0x02)         //Self Clock Mode Interrupt Enable 
+#define MAC7100_CRG_LOCKIE  (0x10)         //Lock Interrupt Enable 
+
+// Bit definitions and macros for CRG_CLKSEL 
+#define MAC7100_CRG_SWTDOZE  (0x01)         //SWT stops in Doze Mode 
+#define MAC7100_CRG_RTIDOZE  (0x02)         /*  RTI stops in Doze Mode */
+#define MAC7100_CRG_PLLDOZE  (0x08)         /*  PLL stops in Doze Mode */
+#define MAC7100_CRG_DOZE_ROA (0x10)         /*  Reduced Osc Amp in Doze Mode */
+#define MAC7100_CRG_PSTP     (0x40)         /*  Pseudo Stop */
+#define MAC7100_CRG_PLLSEL   (0x80)         /*  PLL Select */
+
+// Bit definitions and macros for CRG_PLLCTL 
+#define MAC7100_CRG_SCME     (0x01)         //Self Clock Mode Enable 
+#define MAC7100_CRG_PWE      (0x02)         //SWT Enable during Pseudo Stop 
+#define MAC7100_CRG_PRE      (0x04)         //RTI Enable during Pseudo Stop 
+#define MAC7100_CRG_FSTWKP   (0x08)         //Fast Wake-up from Full Stop Bit 
+#define MAC7100_CRG_ACQ      (0x10)         //Acquisition 
+#define MAC7100_CRG_AUTO     (0x20)         //Automatic Bandwidth Control 
+#define MAC7100_CRG_PLLON    (0x40)         //Phase Lock Loop On 
+#define MAC7100_CRG_CME      (0x80)         //Clock Monitor Enable 
+
+// Bit definitions and macros for CRG_SDMCTL 
+#define MAC7100_CRG_STOP     (0x01)         //STOP mode 
+#define MAC7100_CRG_DOZE     (0x02)         //DOZE mode 
+
+// Bit definitions and macros for CRG_BDMCTL 
+#define MAC7100_CRG_RSBCK    (0x40)         //SWT & RTI stop in Active BDM mode
+
+
+// *********************************************************************
+//
+// MCM Module
+//
+// *********************************************************************
+
+// Register read/write macros
+#define MAC7100_MCM_PCT    0xFC040000 // 
+#define MAC7100_MCM_REV    0xFC040002 // 
+#define MAC7100_MCM_AMC    0xFC040004 // 
+#define MAC7100_MCM_ASC    0xFC040006 // 
+#define MAC7100_MCM_IMC    0xFC040008 // 
+// MRSR - Miscellaneous Reset Status Register 
+#define MAC7100_MCM_MRSR   0xFC04000F 
+// MWCR - Miscellaneous Wakeup Control Register 
+#define MAC7100_MCM_MWCR   0xFC040013 
+// MSWTCR - Miscellaneous Software Watchdog Timer Control Register 
+#define MAC7100_MCM_MSWTCR 0xFC040016 
+// MSWTSR - Miscellaneous Software Watchdog Timer Service Register 
+#define MAC7100_MCM_MSWTSR 0xFC04001B 
+// MSWTIR - Miscellaneous Software Watchdog Timer Interrupt Register 
+#define MAC7100_MCM_MSWTIR 0xFC04001F 
+// AAMR - AXBS Address Map Register 
+#define MAC7100_MCM_AAMR   0xFC040020 
+// CFADR - Core Fault Address Register 
+#define MAC7100_MCM_CFADR  0xFC040070 
+// CFLOC - Core Fault Location Register 
+#define MAC7100_MCM_CFLOC  0xFC040076 
+// CFATR - Core Fault Attributes Register 
+#define MAC7100_MCM_CFATR  0xFC040077 
+// CFDTR - Core Fault Data Register 
+#define MAC7100_MCM_CFDTR  0xFC04007C 
+
+// Bit definitions and macros for MCM_AMC 
+
+//  AXBS Master Configuration 
+#define MAC7100_MCM_AXMC(x)    (((x)&0x00FF)<<0)    
+
+// Bit definitions and macros for MCM_ASC 
+//  AXBS Slave Configuration 
+#define MAC7100_MCM_AXSC(x)    (((x)&0x00FF)<<0)    
+#define MAC7100_MCM_DP64       (0x8000)             //  64-bit Datapath 
+
+// Bit definitions and macros for MCM_MRSR 
+#define MAC7100_MCM_SWTR       (0x20)         //  Watchdog Timer Reset 
+#define MAC7100_MCM_DIR        (0x40)         //  Device Input Reset 
+#define MAC7100_MCM_POR        (0x80)         //  Power-On Reset 
+
+// Bit definitions and macros for MCM_MWCR 
+#define MAC7100_MCM_PRILVL(x)  (((x)&0x0F)<<0)  //  Interrupt Priority Level 
+#define MAC7100_MCM_ENBWCR     (0x80)           //  Enable WCR
+
+// Bit definitions and macros for MCM_MSWTCR 
+#define MAC7100_MCM_SWT(x)     (((x)&0x001F)<<0)  //  Watchdog Time-Out Period 
+#define MAC7100_MCM_SWRI(x)    (((x)&0x0003)<<5)  //  Watchdog Reset/Interrupt 
+#define MAC7100_MCM_SWE        (0x0080)       //  Watchdog Enable 
+#define MAC7100_MCM_SWRWH      (0x0100)       //  Watchdog Run While Halted 
+#define MAC7100_MCM_SWCIN16    (0x0200)       //  Force SWT CarryIn16 
+#define MAC7100_MCM_RO         (0x8000)       //  Read-Only 
+
+// Bit definitions and macros for MCM_MSWTIR 
+#define MAC7100_MCM_SWTIC      (0x01)         //  Watchdog Interrupt Flag 
+
+// Bit definitions and macros for MCM_AAMR
+
+
+//  Address 0 Slave Number 
+#define MAC7100_MCM_ASLAVE(adr_reg,sl_n) (((sl_n)&0x00000007)<<(adr_reg*4) 
+//  Enable Address Region 0 
+#define MAC7100_MCM_EA(adr_reg)        (0x00000008<<(adr_reg*4))  
+
+// Bit definitions and macros for MCM_CFLOC 
+#define MAC7100_MCM_LOCALERR               (0x80)  //  Bus Error Indicator 
+
+// Bit definitions and macros for MCM_CFATR 
+//  Protection fault type 
+#define MAC7100_MCM_PROTECTION(x)          (((x)&0x0F)<<0)  
+//  8-16-32-64-bit core access 
+#define MAC7100_MCM_SIZE(x)                (((x)&0x07)<<4)  
+//  Core read/write access 
+#define MAC7100_MCM_WRITE                  (0x80)         
+
+//=============================================================================
+// FIQ interrupt vector which is shared by all HAL variants.
+
+#define CYGNUM_HAL_INTERRUPT_FIQ 0
+#endif // CYGONCE_HAL_VAR_IO_H
+//-----------------------------------------------------------------------------
+// end of var_io.h
diff --git a/packages/hal/arm/mac7100/var/v2_0/src/flash_security.S b/packages/hal/arm/mac7100/var/v2_0/src/flash_security.S
new file mode 100644 (file)
index 0000000..d64acd6
--- /dev/null
@@ -0,0 +1,77 @@
+/*==========================================================================
+//
+//      flash_security.S
+//
+//      MAC7100 Flash security area
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-11
+// Purpose:      HAL board support
+// Description:  MAC7100 Flash security area.           
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+/////////////////////////////////////////////////////////////////////////////
+//    This section contains Common Flash Module (CFM) configuration field
+//        For detail description see Common Flash Module (CFM) chapter
+//        @ MAC7100 Microcontroller Familly  Reference Manual
+//
+//    Deafault factorry setting:
+//        0xffffffff for All words except Flash Security Word
+//        0xfffffffe for Flash Security Word
+/////////////////////////////////////////////////////////////////////////////
+
+    .section ".mac7100_flash_security", "a"
+    .code 32
+    .global VAE_MAC7100_FlashSecurity
+VAE_MAC7100_FlashSecurity:
+    .long 0xffffffff  // Backdoor Comparison Key bit 63-32
+    .long 0xffffffff  // Backdoor Comparison key bit 31-0
+    .long 0xffffffff  // Program FLASH protection Bytes 
+    .long 0xffffffff  // Program FLASH SUPV Access Bytes  
+    .long 0xffffffff  // Program FLASH DATA Access Bytes  
+    .long 0xfffffffe  // Flash Security Word
+    .long 0xffffffff  // Data FLASH protection, SUPV access, DATA access
+     
+    .long 0xe0f00420  // Just a placeholder (round to 0x420)
+    .end
+    
+//--------------------------------------------------------------------------
+// EOF flash_security.S
diff --git a/packages/hal/arm/mac7100/var/v2_0/src/hal_diag.c b/packages/hal/arm/mac7100/var/v2_0/src/hal_diag.c
new file mode 100644 (file)
index 0000000..bc1d576
--- /dev/null
@@ -0,0 +1,385 @@
+/*=============================================================================
+//
+//      hal_diag.c
+//
+//      HAL diagnostic output code
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-15
+// Purpose:     HAL diagnostic output
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+ */
+
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/infra/cyg_type.h>         // base types
+
+#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_if.h>             // interface API
+#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h>           // Helper functions
+#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/hal/var_io.h>             //
+#include <cyg/devs/ser_esci.h>           // ESCI registers
+
+//-----------------------------------------------------------------------------
+typedef struct {
+    void *base;
+    cyg_int32 msec_timeout;
+    int isr_vector;
+    int isr_level;
+    int baud_rate;
+} channel_data_t;
+
+
+
+//-----------------------------------------------------------------------------
+
+void
+cyg_hal_plf_serial_putc(void *__ch_data, char c);
+
+
+static void
+cyg_hal_plf_serial_init_channel(void* __ch_data)
+{
+        
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint8 *esci_base = chan->base;
+    
+
+    // Reset device
+    // 8-1-no parity.
+
+    HAL_WRITE_UINT8(FREESCALE_ESCI_CR3(esci_base), 0);
+    HAL_WRITE_UINT16(FREESCALE_ESCI_LINCTRL(esci_base), 0);
+    HAL_WRITE_UINT16(FREESCALE_ESCI_BD(esci_base), 
+                     FREESCALE_ESCI_BAUD(chan->baud_rate));
+
+    // Enable RX and TX
+    HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), (FREESCALE_ESCI_CR12_TE | 
+                                                      FREESCALE_ESCI_CR12_RE));
+}
+
+void
+cyg_hal_plf_serial_putc(void* __ch_data, char ch_out)
+{
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    CYG_ADDRESS esci_base = (CYG_ADDRESS) chan->base;
+    cyg_uint16 esci_sr;
+    
+    CYGARC_HAL_SAVE_GP();
+
+    do {
+        HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+    } while (!(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);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* p_ch_in)
+{
+    channel_data_t* chan = (channel_data_t*)__ch_data;    
+    CYG_ADDRESS esci_base = (CYG_ADDRESS) chan->base;
+    cyg_uint16 esci_sr;
+    cyg_uint8 ch_in;
+
+    HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+    if (!(esci_sr & FREESCALE_ESCI_SR_RDRF))
+        return false;
+
+    HAL_READ_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_in);
+    HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_RDRF);
+    *p_ch_in = ch_in;
+
+    return true;
+}
+
+cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+
+    CYGARC_HAL_RESTORE_GP();
+    return ch;
+}
+
+static void
+cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* p_ch_in)
+{
+    int delay_count;
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
+
+    // delay in .1 ms steps
+    delay_count = ((channel_data_t*)__ch_data)->msec_timeout * 10; 
+
+    for(;;) {
+        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, p_ch_in);
+        if (res || 0 == delay_count--)
+            break;
+        
+        CYGACC_CALL_IF_DELAY_US(100);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint16 ser_port_reg;
+    int ret = 0;
+    va_list ap;
+
+    CYGARC_HAL_SAVE_GP();
+    va_start(ap, __func);
+
+    switch (__func) {
+    case __COMMCTL_GETBAUD:
+        ret = chan->baud_rate;
+        break;
+    case __COMMCTL_SETBAUD:
+        chan->baud_rate = va_arg(ap, cyg_int32);
+        // Should we verify this value here?
+        cyg_hal_plf_serial_init_channel(chan);
+        ret = 0;
+        break;
+    case __COMMCTL_IRQ_ENABLE:
+        irq_state = 1;
+        HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+        HAL_INTERRUPT_UNMASK(chan->isr_vector);
+        
+        HAL_READ_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
+        ser_port_reg |= FREESCALE_ESCI_CR12_RIE;
+        HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
+        
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+        HAL_INTERRUPT_MASK(chan->isr_vector);
+        
+        HAL_READ_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
+        ser_port_reg &= ~(cyg_uint16)FREESCALE_ESCI_CR12_RIE;
+        HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = chan->isr_vector;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+        ret = chan->msec_timeout;
+        chan->msec_timeout = va_arg(ap, cyg_uint32);
+    default:
+        break;
+    }
+
+    va_end(ap);
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
+}
+
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
+                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    CYG_ADDRESS esci_base = (CYG_ADDRESS) chan->base;
+    cyg_uint16 esci_sr;
+    int res = 0;
+    cyg_uint8 ch_in;
+    CYGARC_HAL_SAVE_GP();
+
+    *__ctrlc = 0;
+    
+    HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+    if (esci_sr & FREESCALE_ESCI_SR_RDRF){
+        HAL_READ_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_in);
+        if( cyg_hal_is_break( &ch_in , 1 ) )
+            *__ctrlc = 1;
+
+        res = CYG_ISR_HANDLED;
+        HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_RDRF);
+    }
+
+    HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static channel_data_t mac7100_ser_channels[4] = {
+    { (cyg_uint16*)FREESCALE_ESCI_A_BASE, 1000, MAC7100_ESCI_A_IV, 
+      MAC7100_ESCI_A_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
+    { (cyg_uint16*)FREESCALE_ESCI_B_BASE, 1000, MAC7100_ESCI_B_IV, 
+      MAC7100_ESCI_B_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
+    { (cyg_uint16*)FREESCALE_ESCI_C_BASE, 1000, MAC7100_ESCI_C_IV, 
+      MAC7100_ESCI_C_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
+    { (cyg_uint16*)FREESCALE_ESCI_D_BASE, 1000, MAC7100_ESCI_D_IV, 
+      MAC7100_ESCI_D_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
+};
+
+static void
+cyg_hal_plf_serial_init(void)
+{
+    hal_virtual_comm_table_t* comm;
+    int cur;
+
+    cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+    // Init channels
+    cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[0]);
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
+    cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[1]);
+#endif
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 2
+    cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[2]);
+#endif
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 3
+    cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[3]);
+#endif
+    // Setup procs in the vector table
+
+    // Set channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[0]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
+    // Set channel 1
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[1]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 2    
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(2);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[2]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 3    
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(3);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[3]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+    initialized = 1;
+    cyg_hal_plf_serial_init();
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_diag.c
diff --git a/packages/hal/arm/mac7100/var/v2_0/src/mac7100_misc.c b/packages/hal/arm/mac7100/var/v2_0/src/mac7100_misc.c
new file mode 100644 (file)
index 0000000..faf1792
--- /dev/null
@@ -0,0 +1,341 @@
+/*==========================================================================
+//
+//      mac7100_misc.c
+//
+//      HAL misc board support code for Freescale MAC7100
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (c) 2006 eCosCentric Ltd
+//
+// Ecos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-12
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_trac.h>         // tracing macros
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#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>           // necessary?
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h>             // calling interface
+#include <cyg/hal/hal_misc.h>           // helper functions
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+#include <cyg/hal/drv_api.h>            // HAL ISR support
+#endif
+#include <cyg/hal/var_io.h>             // platform registers
+#include <cyg/devs/ser_esci.h>            // ESCI registers
+#include <pkgconf/io_serial_freescale_esci.h>
+
+// -------------------------------------------------------------------------
+// Clock support
+
+static cyg_uint32 _period;
+
+void hal_clock_initialize(cyg_uint32 period)
+{
+    CYG_ADDRESS pit_base = MAC7100_PIT_BASE;
+    cyg_uint32 pit_en;
+
+    CYG_ASSERT(period < 0x10000, "Invalid clock period");
+
+    // Disable counter
+    HAL_READ_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+    pit_en &= ~MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
+    HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+
+    // Set registers
+    _period=period;
+    HAL_WRITE_UINT32(MAC7100_PIT_TLVAL(pit_base, CYGNUM_PIT_CHAN_CLOCK), 
+                     period);
+
+    // Start timer
+    pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
+    HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+
+    // Enable timer interrupt    
+    HAL_READ_UINT32(MAC7100_PIT_INTEN(pit_base), pit_en);
+    pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
+    HAL_WRITE_UINT32(MAC7100_PIT_INTEN(pit_base), pit_en);
+
+    HAL_READ_UINT32(MAC7100_PIT_INTSEL(pit_base), pit_en);
+    pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
+    HAL_WRITE_UINT32(MAC7100_PIT_INTSEL(pit_base), pit_en);
+}
+
+void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+    HAL_WRITE_UINT32(MAC7100_PIT_FLG(MAC7100_PIT_BASE), 
+                     MAC7100_PIT_FLAG_TIF(CYGNUM_PIT_CHAN_CLOCK));
+}
+
+
+void hal_clock_read(cyg_uint32 *pvalue)
+{
+    cyg_uint32 val;
+
+    HAL_READ_UINT32(MAC7100_PIT_TLVAL(MAC7100_PIT_BASE,CYGNUM_PIT_CHAN_CLOCK),
+                    val);
+    *pvalue = _period-val;
+}
+
+// -------------------------------------------------------------------------
+//
+// Delay for some number of micro-seconds
+//
+
+#if CYGNUM_PIT_CHAN_US!=0
+#define CYGNUM_1_US (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED/2000000)
+#else
+#define CYGNUM_1_US (CYGNUM_HAL_ARM_MAC7100_F_OSC/1000000)
+#endif
+
+void hal_delay_us(cyg_int32 usecs)
+{
+    CYG_ADDRESS pit_base = MAC7100_PIT_BASE;
+    cyg_uint32 pit_en;
+    
+    
+    // Clear flag
+    HAL_WRITE_UINT32(MAC7100_PIT_FLG(pit_base), 
+                     MAC7100_PIT_FLAG_TIF(CYGNUM_PIT_CHAN_US));
+
+    // Set timer
+    HAL_WRITE_UINT32(MAC7100_PIT_TLVAL(pit_base, CYGNUM_PIT_CHAN_US), 
+                     usecs*CYGNUM_1_US-1);
+    HAL_READ_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+    pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_US);
+    HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+
+    do {
+      HAL_READ_UINT32(MAC7100_PIT_FLG(pit_base), pit_en); 
+    }while (!(pit_en & MAC7100_PIT_FLAG_TIF(CYGNUM_PIT_CHAN_US)));
+    
+    // Disable counter
+    HAL_READ_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+    pit_en &= ~MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_US);
+    HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+}
+
+
+// -------------------------------------------------------------------------
+// Hardware init
+
+void hal_intc_init(void);
+void hal_pit_init(void);
+static void hal_mac7100_esci_pins(cyg_uint32);
+void hal_hardware_init(void)
+{
+    // Reset all interrupts
+    //
+
+    // Flush internal priority level stack
+    //
+    
+    // Set up eCos/ROM interfaces
+#if (defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_A) || \
+    (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 0)
+    hal_mac7100_esci_pins(FREESCALE_ESCI_A_I);
+#endif
+#if (defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_B) || \
+    (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1)
+    hal_mac7100_esci_pins(FREESCALE_ESCI_B_I);
+#endif
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_C
+    hal_mac7100_esci_pins(FREESCALE_ESCI_C_I);
+#endif
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_D
+    hal_mac7100_esci_pins(FREESCALE_ESCI_D_I);
+#endif
+    
+    hal_intc_init();    // Initialize interrupt controller
+    hal_pit_init();     // Initilaize CLOCK for channels 1..10
+    hal_if_init();
+}
+
+void hal_pit_init(void)
+{
+    cyg_uint32 pit_ctrl;
+    
+    CYG_ADDRESS pit_base=MAC7100_PIT_BASE;
+    
+    HAL_READ_UINT32(MAC7100_PIT_CTRL(pit_base), pit_ctrl);
+    pit_ctrl &= ~MAC7100_PIT_MDIS;
+    HAL_WRITE_UINT32(MAC7100_PIT_CTRL(pit_base), pit_ctrl);
+}
+
+
+// -------------------------------------------------------------------------
+// This routine is called to respond to a hardware interrupt (IRQ).  It
+// should interrogate the hardware and return the IRQ vector number.
+
+typedef struct ClSlMask_T {
+  cyg_uint8 ClMask;
+  cyg_uint8 SlMask;
+} ClSlMask_T;
+
+static ClSlMask_T ClSlMasks[CYGNUM_HAL_ISR_COUNT];
+
+void hal_intc_init(void)
+{
+    cyg_uint8 iconfig;
+    CYG_ADDRESS intc_base=MAC7100_INTC_BASE;
+
+    iconfig = (CYGHWR_HAL_ARM_MAC7100_INTC_FIQDEF | 
+               CYGHWR_HAL_ARM_MAC7100_INTC_EMASK);
+    HAL_WRITE_UINT8(MAC7100_INTC_ICONFIG(intc_base), iconfig);
+}
+
+int hal_IRQ_handler(void)
+{
+    CYG_ADDRESS intc_base=MAC7100_INTC_BASE;
+    cyg_int8 irq_num;
+    ClSlMask_T clslmask;
+        
+    HAL_READ_UINT8(MAC7100_INTC_CLMASK(intc_base), clslmask.ClMask);
+    HAL_READ_UINT8(MAC7100_INTC_SLMASK(intc_base), clslmask.SlMask);
+#ifdef CYGHWR_HAL_ARM_MAC7100_FIQ
+    HAL_READ_UINT8(MAC7100_FIQIACK(intc_base), irq_num);
+    if((irq_num-=CYGNUM_HAL_ISR_COUNT)<0){
+#endif //CYGHWR_HAL_ARM_MAC7100_FIQ
+        HAL_READ_UINT8(MAC7100_INTC_IRQIACK(intc_base), irq_num);
+        if((irq_num-=CYGNUM_HAL_ISR_COUNT)<0){
+            irq_num=CYGNUM_HAL_INTERRUPT_NONE;
+        }else{
+            ClSlMasks[irq_num]=clslmask;
+        }
+    return irq_num;
+#ifdef CYGHWR_HAL_ARM_MAC7100_FIQ
+    }
+#endif // CYGHWR_HAL_ARM_MAC7100_FIQ
+}
+
+// -------------------------------------------------------------------------
+// Interrupt control
+//
+
+void hal_interrupt_mask(int vector)
+{
+    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+    
+    HAL_WRITE_UINT8(MAC7100_INTC_SIMR(MAC7100_INTC_BASE), vector);
+}
+
+void hal_interrupt_unmask(int vector)
+{
+    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+    
+    HAL_WRITE_UINT8(MAC7100_INTC_CIMR(MAC7100_INTC_BASE), vector);
+}
+
+void hal_interrupt_acknowledge(int vector)
+{
+    // ?? No check for valid vector here! Spurious interrupts
+    // ?? must be acknowledged, too.
+    
+    if(vector>=0)
+        HAL_WRITE_UINT8(MAC7100_INTC_CLMASK(MAC7100_INTC_BASE), 
+                        ClSlMasks[vector].ClMask);
+}
+
+void hal_interrupt_configure(int vector, int level, int up)
+{
+    // TO DO
+}
+
+void hal_interrupt_set_level(int vector, int level)
+{
+    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+    CYG_ASSERT(level >=0 level <= 15, "Invalid level");
+    
+    HAL_WRITE_UINT8(MAC7100_INTC_ICR(MAC7100_INTC_BASE,vector), 
+                    MAC7100_INTC_INT_LEVEL(level));
+}
+
+void hal_show_IRQ(int vector, int data, int handler)
+{
+//    UNDEFINED(__FUNCTION__);  // FIXME
+}
+
+
+void hal_mac7100_reset_cpu(void)
+{
+    // TO DO use watchdog to reset cpu 
+}
+
+// Set ESCI channel pins in perpheral mode
+
+void
+hal_mac7100_esci_pins(cyg_uint32 i_esci){
+    cyg_uint16 *p_pim_config=0;
+    
+    switch(i_esci){
+    case FREESCALE_ESCI_A_I:
+        p_pim_config=
+          (cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,2);
+        break;
+    case FREESCALE_ESCI_B_I:
+        p_pim_config=(cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,0);
+        break;
+    case FREESCALE_ESCI_C_I:
+        p_pim_config=
+          (cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,14);
+        break;
+    case FREESCALE_ESCI_D_I:
+        p_pim_config=
+          (cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,15);
+        break;
+    }
+    HAL_WRITE_UINT16(p_pim_config++, MAC7100_PIM_MODE_PERIPHERAL);
+    HAL_WRITE_UINT16(p_pim_config, MAC7100_PIM_MODE_PERIPHERAL);
+}
+
+
+//--------------------------------------------------------------------------
+// EOF mac7100_misc.c
diff --git a/packages/hal/coldfire/arch/v2_0/ChangeLog b/packages/hal/coldfire/arch/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..fb04365
--- /dev/null
@@ -0,0 +1,55 @@
+2005-06-24  Enrico Piria  <epiriaNOSPAM@NOSPAMfastwebnet.it>
+
+       * src/coldfire.ld:
+       * src/coldfire_stub.c:
+       * src/context.S:
+       * src/hal_misc.c:
+       * src/hal_mk_defs.c:
+       * src/hal_startup.c:
+       * src/vectors.S:
+       * include/arch.inc:
+       * include/basetype.h:
+       * include/coldfire_regs.h:
+       * include/coldfire_stub.h:
+       * include/hal_arch.h:
+       * include/hal_cache.h:
+       * include/hal_intr.h:
+       * include/hal_io.h:
+       * include/hal_startup.h:
+       * cdl/hal_coldfire.cdl:
+       * doc/readme.txt:
+       Rework of the original ColdFire architecture HAL contributed by
+       Wade Jensen.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/coldfire/arch/v2_0/cdl/hal_coldfire.cdl b/packages/hal/coldfire/arch/v2_0/cdl/hal_coldfire.cdl
new file mode 100644 (file)
index 0000000..544ad31
--- /dev/null
@@ -0,0 +1,106 @@
+# ====================================================================
+#
+#      hal_coldfire.cdl
+#
+#      ColdFire architecture HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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
+## Contributors:  Wade Jensen
+## Date:          2005-25-06
+##
+######DESCRIPTIONEND####
+##========================================================================
+
+cdl_package CYGPKG_HAL_COLDFIRE {
+    display "ColdFire architecture"
+    parent        CYGPKG_HAL
+    hardware
+    include_dir   cyg/hal
+    define_header hal_coldfire.h
+    description   "
+           The ColdFire architecture HAL package provides generic
+           support for this processor architecture. It is also
+           necessary to select a specific target platform HAL
+           package."
+
+    cdl_interface CYGINT_HAL_COLDFIRE_VARIANT {
+        display  "Number of variant implementations in this configuration"
+        no_define
+        requires 1 == CYGINT_HAL_COLDFIRE_VARIANT
+    }
+
+    compile hal_startup.c hal_misc.c coldfire_stub.c vectors.S context.S
+
+    # The "-o file" is a workaround for CR100958 - without it the
+    # output file would end up in the source directory under CygWin.
+    # n.b. grep does not behave itself under win32
+    make -priority 1 {
+        <PREFIX>/include/cyg/hal/cf_offsets.inc : <PACKAGE>/src/hal_mk_defs.c
+        $(CC) $(ACTUAL_CFLAGS) $(INCLUDE_PATH) -Wp,-MD,cf_offsets.tmp -o hal_mk_defs.tmp -S $<
+        fgrep .equ hal_mk_defs.tmp | sed s/#// > $@
+        @echo $@ ": \\" > $(notdir $@).deps
+        @tail -n +2 cf_offsets.tmp >> $(notdir $@).deps
+        @echo >> $(notdir $@).deps
+        @rm cf_offsets.tmp hal_mk_defs.tmp
+    }
+
+    make {
+        <PREFIX>/lib/vectors.o : <PACKAGE>/src/vectors.S
+        $(CC) -Wp,-MD,vectors.tmp $(INCLUDE_PATH) $(ACTUAL_CFLAGS) -c -o $@ $<
+        @echo $@ ": \\" > $(notdir $@).deps
+        @tail -n +2 vectors.tmp >> $(notdir $@).deps
+        @echo >> $(notdir $@).deps
+        @rm vectors.tmp
+    }
+
+    make {
+        <PREFIX>/lib/target.ld: <PACKAGE>/src/coldfire.ld
+        $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(ACTUAL_CFLAGS) -o $@ $<
+        @echo $@ ": \\" > $(notdir $@).deps
+        @tail -n +2 target.tmp >> $(notdir $@).deps
+        @echo >> $(notdir $@).deps
+        @rm target.tmp
+    }
+
+    cdl_option CYGBLD_LINKER_SCRIPT {
+        display "Linker script"
+        flavor data
+    no_define
+        calculated  { "src/coldfire.ld" }
+    }
+
+}
diff --git a/packages/hal/coldfire/arch/v2_0/doc/readme.txt b/packages/hal/coldfire/arch/v2_0/doc/readme.txt
new file mode 100644 (file)
index 0000000..67976d4
--- /dev/null
@@ -0,0 +1,70 @@
+SOME NOTES ON THE USAGE OF THE HAL FOR COLDFIRE
+
+This HAL was obtained by rewriting the original port of eCos to ColdFire done
+by Wade Jensen. The following guidelines give you hints about using this
+software.
+
+* Use at least GCC version 3.4.1. This version has an improved support for
+  ColdFire processors. However, this compiler might not be able to build the
+  "cxxsupp.cxx" test in the "infra" package.
+
+* The version of the binutils I used is 2.15.90.0.1.1.
+
+* The version of newlib I used is 1.13.0.
+
+* The version of the BDM tools I used is 1.3.0.
+
+* If you want to debug code by means of the serial connection to eCos, don't
+use a version of GDB with BDM support compiled into. There is some kind of
+interaction between BDM and serial targets that prevents the latter from
+functioning correctly. Do not even use a clean GDB 6.3 distribution to debug
+through the serial cable. The downloading of code to the target is broken in
+that version. Instead, use a version of GDB grabbed from CVS repository. I
+used a version downloaded after June 13, 2005, and the bug had been corrected.
+
+* Currently (version 6.3), GDB doesn't support the ColdFire MAC unit. Thus, it
+is not possible to show the MAC registers, via the "info registers" command,
+when debugging an eCos application through a serial connection. The BDM addon
+to GDB doesn't suffer from a similar limitation. However, there is a little
+hack in order to show and modify the MAC registers even with a serial
+connection. When a breakpoint is hit, the GDB module of eCos stores the
+current register values in a structure of type HAL_SavedRegisters, pointed to
+by the _hal_registers variable. If you included the GDB stub in your
+application, it is then possible to display the MAC registers (and all of the
+others) by issuing at the GDB prompt the following command:
+
+print *(struct HAL_SavedRegisters *)_hal_registers
+
+In case you are using a GDB stub burned in ROM to debug an application in RAM,
+you first have to determine where the GDB stub stores the _hal_registers
+variable in its own private region of RAM: use the tool m68k-elf-objdump to
+find that. For example, if the address of the _hal_registers variable used by
+the GDB stub is 0x1e88, then you should use the following command to display
+the registers of the application being debugged:
+
+print *(struct HAL_SavedRegisters *)*0x1e88
+
+It is also possible to modify the value of the MAC registers, by updating the
+relative field of the HAL_SavedRegisters structure. Don't try to modify the
+other registers because the modifications will be discarded when the
+application is restarted: use the usual GDB commands instead. Finally, the
+correct value of the PC register is the one shown by the "info registers"
+command.
+
+* I added at the architecture level only the features that I could directly
+test. When I developed the architecture HAL, I had a ColdFire MCF5272 at
+hands, which has a MAC unit. That's why in the architecture HAL there is
+currently only support for the MAC unit, and no support for the EMAC and
+floating point units. However, I tried to write the HAL in the most generic
+fashion I could imagine, in order to make it easy to add new architectural
+features and new processor variants.
+
+* If you want to burn an eCos image into the flash ROM, you cannot rely on the
+ROM monitor provided with the board, but you have to use the BDM interface.
+If you work under Windows, you can use the free CFFlasher utility, available
+on the Freescale Semiconductor web site. The BDM tools also contain a
+text-mode utility to do that, but I have not tested it. 
+
+
+Enrico Piria (epiria AT fastwebnet DOT it)
+November 16, 2005
diff --git a/packages/hal/coldfire/arch/v2_0/include/arch.inc b/packages/hal/coldfire/arch/v2_0/include/arch.inc
new file mode 100644 (file)
index 0000000..641c7e0
--- /dev/null
@@ -0,0 +1,257 @@
+#ifndef CYGONCE_HAL_ARCH_INC
+#define CYGONCE_HAL_ARCH_INC
+|=============================================================================
+|
+|  arch.inc
+|
+|  ColdFire architecture assembler header file
+|
+|=============================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| eCos is free software; you can redistribute it and/or modify it under
+| the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2 or (at your option) any later version.
+|
+| eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+| WARRANTY; without even the implied warranty of MERCHANTABILITY or
+| FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+| for more details.
+|
+| You should have received a copy of the GNU General Public License along
+| with eCos; if not, write to the Free Software Foundation, Inc.,
+| 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+|
+| As a special exception, if other files instantiate templates or use macros
+| or inline functions from this file, or you compile this file and link it
+| with other works to produce a work based on this file, this file does not
+| by itself cause the resulting work to be covered by the GNU General Public
+| License. However the source code for this file must still be made available
+| in accordance with section (3) of the GNU General Public License.
+|
+| This exception does not 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
+| Contributors:
+| Date:         2005-25-06
+| Purpose:      MCF5272 variant definitions.
+| Description:  This file contains macro definitions used in the
+|               architecture HAL assembler file.
+|
+|####DESCRIPTIONEND####
+|==========================================================================
+
+
+#define FUNC_START(name)    \
+    .text;                  \
+    .balign 4;              \
+    .type name,@function;   \
+    .globl name;            \
+name:
+
+
+| ----------------------------------------------------------------------------
+| Macros to deal with the interrupt priority level in the status register.
+
+        .macro hal_cpu_int_disable
+        move.w  #0x2700,%sr
+        .endm
+
+        
+        .macro hal_cpu_int_enable work
+        move.w  %sr,\work
+        and.l   #0xf8ff,\work
+        move.w  \work,%sr
+        .endm
+
+        
+        .macro hal_cpu_int_merge from work
+        move.w  %sr,\work
+        and.l   #0xf8ff,\work
+        and.l   #0x0700,\from
+        or.l    \from,\work
+        move.w \work,%sr
+        .endm
+
+| ----------------------------------------------------------------------------
+| Macro to find the value the SP register had before an exception.
+        
+        .macro find_original_sp out
+        move.b  CYGARC_CF_FMTVECWORD(%sp),\out
+        lsr.l   #4,\out
+        and.l   #0x00000003,\out
+        add.l   #CYGARC_CF_EXCEPTION_SIZE,\out
+        add.l   %sp,\out
+        .endm
+
+
+| ----------------------------------------------------------------------------
+| Macros used to save and restore MAC registers during interrupts/exceptions.
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        .macro  save_mac_registers work
+        | Store MACSR register
+        move.l  %macsr,\work
+        move.l  \work,CYGARC_CFREG_MACSR(%sp)
+
+        | Switch to integer mode. This allows to save the contents of ACC
+        | without rounding
+        and.l   #0x000000df,\work
+        move.l  \work,%macsr
+
+        | Store ACC register
+        move.l  %acc,\work
+        move.l  \work,CYGARC_CFREG_MACC(%sp)
+
+        | Store MASK register
+        move.l  %mask,\work
+        move.l  \work,CYGARC_CFREG_MASK(%sp)
+        .endm
+
+
+        .macro  restore_mac_registers work
+        | Load MACSR register
+        move.l  CYGARC_CFREG_MACSR(%sp),\work
+        move.l  \work,%macsr
+
+        | Load ACC register
+        move.l  CYGARC_CFREG_MACC(%sp),\work
+        move.l  \work,%acc
+
+        | Load MASK register
+        move.l  CYGARC_CFREG_MASK(%sp),\work
+        move.l  \work,%mask
+        .endm
+#endif
+
+
+| ----------------------------------------------------------------------------
+| Macros used to save registers in interrupt handlers. During an interrupt,
+| we save registers %d0-%d1 and %a0-%a1 because of the GNU C calling
+| conventions. During the handler we also need register %d2.
+
+#ifdef CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+        .macro int_pres_regs
+        lea.l     -CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
+        movem.l   %d0-%d2,CYGARC_CFREG_DREGS(%sp)
+        movem.l   %a0-%a1,CYGARC_CFREG_AREGS(%sp)
+        .endm
+
+        
+        .macro int_rest_regs
+        movem.l   CYGARC_CFREG_AREGS(%sp),%a0-%a1
+        movem.l   CYGARC_CFREG_DREGS(%sp),%d0-%d2
+        lea.l     CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
+        .endm
+
+#else /* CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT */
+
+        .macro int_pres_regs
+        lea.l     -CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
+        movem.l   %d0-%d7,CYGARC_CFREG_DREGS(%sp)
+        movem.l   %a0-%a6,CYGARC_CFREG_AREGS(%sp)
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        save_mac_registers %d0
+#endif
+
+        | Save old SP (before interrupt)
+        find_original_sp %d0
+        move.l    %d0,CYGARC_CFREG_SP(%sp)
+        .endm
+
+        
+        .macro int_rest_regs
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        restore_mac_registers %d0
+#endif
+        
+        movem.l   CYGARC_CFREG_AREGS(%sp),%a0-%a6
+        movem.l   CYGARC_CFREG_DREGS(%sp),%d0-%d7
+        lea.l     CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
+        .endm
+
+#endif /* CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT */
+
+
+| ----------------------------------------------------------------------------
+| Macros used to save/restore registers during context switches.
+| We don't save registers %d0-%d1 and %a0-%a1 because of the GNU C calling
+| conventions: these macros are used in a routine called by C code.
+
+#ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+
+        .macro ctx_save_registers
+        lea     -CYGARC_CF_CONTEXT_SIZE(%sp),%sp
+        movem.l %d2-%d7,CYGARC_CFREG_D2(%sp)
+        movem.l %a2-%a6,CYGARC_CFREG_A2(%sp)
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        save_mac_registers %d0
+#endif
+        | Save SR and interrupt level
+        move.w %sr,%d0
+        move.w %d0,CYGARC_CF_SR(%sp)        
+        .endm
+                                                    
+
+        .macro ctx_restore_registers
+        | Restore SR and interrupt level
+        move.w CYGARC_CF_SR(%sp),%d0
+        move.w %d0,%sr
+        
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        restore_mac_registers %d0
+#endif
+        movem.l CYGARC_CFREG_D2(%sp),%d2-%d7
+        movem.l CYGARC_CFREG_A2(%sp), %a2-%a6
+        lea     CYGARC_CF_CONTEXT_SIZE(%sp),%sp
+        .endm
+
+#else /* CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM */
+
+        .macro ctx_save_registers
+        | Save all of the registers
+        lea     -CYGARC_CF_CONTEXT_SIZE(%sp),%sp
+        movem.l %d0-%d7,CYGARC_CFREG_DREGS(%sp)
+        movem.l %a0-%a7,CYGARC_CFREG_AREGS(%sp)        
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        save_mac_registers %d0
+#endif
+
+        | Save pc (useful during debugging with GDB)
+        lea (%pc),%a0
+        move.l %a0,CYGARC_CFREG_PC(%sp)
+
+        | Save SR and interrupt level
+        move.w %sr,%d0
+        move.w %d0,CYGARC_CF_SR(%sp)        
+        .endm
+        
+
+        .macro ctx_restore_registers
+        | Restore SR and interrupt level
+        move.w CYGARC_CF_SR(%sp),%d0
+        move.w %d0,%sr
+        
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        restore_mac_registers %d0
+#endif
+        movem.l CYGARC_CFREG_DREGS(%sp),%d0-%d7
+        movem.l CYGARC_CFREG_AREGS(%sp),%a0-%a6                       
+        lea     CYGARC_CF_CONTEXT_SIZE(%sp),%sp     
+        .endm
+#endif /* CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM */
+
+| ----------------------------------------------------------------------------
+| End of arch.inc
+#endif /* ifndef CYGONCE_HAL_ARCH_INC */
diff --git a/packages/hal/coldfire/arch/v2_0/include/basetype.h b/packages/hal/coldfire/arch/v2_0/include/basetype.h
new file mode 100644 (file)
index 0000000..27db5c6
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef CYGONCE_HAL_BASETYPE_H
+#define CYGONCE_HAL_BASETYPE_H
+
+//=============================================================================
+//
+//      basetype.h
+//
+//      Standard types for this architecture
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:  Wade Jensen
+// Date:          2005-25-06
+// Purpose:       Provide ColdFire-specific type definitions.
+// Usage:         Included by "cyg_type.h", do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+// Include variant specific types
+#include <cyg/hal/var_basetype.h>
+
+
+// ---------------------------------------------------------------------------
+// Characterize the architecture
+
+#define CYG_BYTEORDER   CYG_MSBFIRST    // Big endian
+
+// The ColdFire architecture uses the default definitions of the base types,
+// so we do not need to define any here.
+
+// ---------------------------------------------------------------------------
+// Override the alignment definitions from cyg_type.h
+
+#ifndef CYGARC_ALIGNMENT
+#define CYGARC_ALIGNMENT 4
+#endif
+
+// The corresponding power of two alignment
+#ifndef CYGARC_P2ALIGNMENT
+#define CYGARC_P2ALIGNMENT 2
+#endif
+
+// ---------------------------------------------------------------------------
+// End of basetype.h
+#endif // CYGONCE_HAL_BASETYPE_H
diff --git a/packages/hal/coldfire/arch/v2_0/include/coldfire_regs.h b/packages/hal/coldfire/arch/v2_0/include/coldfire_regs.h
new file mode 100644 (file)
index 0000000..cc9af48
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef CYGONCE_HAL_CF_REGS_H
+#define CYGONCE_HAL_CF_REGS_H
+
+//==========================================================================
+//
+//      coldfire_regs.h
+//
+//      ColdFire CPU definitions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:         2005-25-06
+// Purpose:      Provide ColdFire register definitions.
+// Usage:        #include <cyg/hal/coldfire_regs.h>
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/var_regs.h>
+
+
+// Macro to embed movec instructions in C code
+#define CYGARC_MOVEC(_value_, _reg_) \
+    asm volatile("movec %0,%1" : : "d" (_value_), "i" (_reg_))
+
+
+// ---------------------------------------------------------------------------
+// End of coldfire_regs.h
+#endif // ifdef CYGONCE_HAL_CF_REGS_H
diff --git a/packages/hal/coldfire/arch/v2_0/include/coldfire_stub.h b/packages/hal/coldfire/arch/v2_0/include/coldfire_stub.h
new file mode 100644 (file)
index 0000000..51bc7b2
--- /dev/null
@@ -0,0 +1,135 @@
+#ifndef CYGONCE_HAL_COLDFIRE_STUB_H
+#define CYGONCE_HAL_COLDFIRE_STUB_H
+
+//========================================================================
+//
+//      coldfire_stub.h
+//
+//      ColdFire-specific definitions for generic stub
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       
+// Description:   ColdFire-specific definitions for generic stub.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NUMREGS 18
+
+// ColdFire stub has special needs for register handling because flating point
+// registers are bigger than the rest. Special put_register and get_register
+// are provided.
+#define CYGARC_STUB_REGISTER_ACCESS_DEFINED 1
+
+#define REGSIZE( _x_ ) (4)
+
+typedef unsigned long target_register_t;
+
+enum regnames {
+    D0, D1, D2, D3, D4, D5, D6, D7,
+    A0, A1, A2, A3, A4, A5, A6, A7,
+    SR, PC,
+};
+
+#define SP              A7
+
+typedef enum regnames regnames_t;
+
+// Given a trap value TRAP, return the corresponding signal
+extern int __computeSignal(unsigned int trap_number);
+
+// Return the ColdFire trap number corresponding to the last-taken trap
+extern int __get_trap_number(void);
+
+// Return the currently-saved value corresponding to register REG
+extern target_register_t get_register(regnames_t reg);
+
+// Store VALUE in the register corresponding to WHICH
+extern void put_register(regnames_t which, target_register_t value);
+
+// Read the contents of register WHICH into VALUE as raw bytes
+extern int get_register_as_bytes(regnames_t which, char *value);
+
+// Write the contents of register WHICH into VALUE as raw bytes
+extern int put_register_as_bytes(regnames_t which, char *value);
+
+// Set the currently-saved pc register value to PC. This also updates NPC
+// as needed.
+extern void set_pc(target_register_t pc);
+
+// Set things up so that the next user resume will execute one instruction.
+// This may be done by setting breakpoints or setting a single step flag
+// in the saved user registers, for example.
+extern void __single_step(void);
+
+// Clear the single-step state
+extern void __clear_single_step(void);
+
+// If the breakpoint we hit is in the breakpoint() instruction, return a
+// non-zero value
+extern int __is_breakpoint_function(void);
+
+// Skip the current instruction
+extern void __skipinst(void);
+
+extern void __install_breakpoints(void);
+
+extern void __clear_breakpoints(void);
+
+// We have to rewind the PC in case of a breakpoint.
+#define HAL_STUB_PLATFORM_STUBS_FIXUP()                         \
+CYG_MACRO_START                                                 \
+    if (CYGNUM_HAL_VECTOR_DEBUGTRAP == __get_trap_number())     \
+    {                                                           \
+        CYG_ADDRESS pc = get_register(PC) - HAL_BREAKINST_SIZE; \
+        put_register(PC, pc);                                   \
+    }                                                           \
+CYG_MACRO_END
+
+#ifdef __cplusplus
+}      // extern "C"
+#endif
+
+// ---------------------------------------------------------------------------
+// End of coldfire_stub.h
+#endif // ifndef CYGONCE_HAL_COLDFIRE_STUB_H
diff --git a/packages/hal/coldfire/arch/v2_0/include/hal_arch.h b/packages/hal/coldfire/arch/v2_0/include/hal_arch.h
new file mode 100644 (file)
index 0000000..b86976b
--- /dev/null
@@ -0,0 +1,473 @@
+#ifndef CYGONCE_HAL_ARCH_H
+#define CYGONCE_HAL_ARCH_H
+
+//=============================================================================
+//
+//      hal_arch.h
+//
+//      Architecture specific abstractions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:  Wade Jensen
+// Date:          2005-25-06
+// Purpose:       
+// Description:   Definitions for the ColdFire architecture HAL.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+// Include some variant specific architectural defines
+#include <cyg/hal/var_arch.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+#include <cyg/hal/coldfire_stub.h>
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+// ----------------------------------------------------------------------------
+// Macros to deal with exception stack frame fields
+
+// The ColdFire family of processors has a simplified exception stack
+// frame that looks like the following:
+//
+//          8 +----------------+----------------+
+//            |         Program Counter         |
+//          4 +----------------+----------------+
+//            |Fmt/FS/Vector/FS|      SR        |
+//  SP -->  0 +----------------+----------------+
+// The stack self-aligns to a 4-byte boundary at an exception, with
+// the Fmt/FS/Vector/FS field indicating the size of the adjustment
+// (SP += 0,1,2,3 bytes).
+
+// Define the Fmt/FS/Vector/FS word.
+// Bits 31-28 are the format word which tells the
+// RTI instruction how to align the stack.
+#define HAL_CF_EXCEPTION_FORMAT_MSK ((CYG_WORD16)0xF000)
+// Bits 25-18 are the vector number of the exception.
+#define HAL_CF_EXCEPTION_VECTOR_MSK ((CYG_WORD16)0x03FC)
+// Bits 27-26, and 17-16 are the fault status used
+// for bus and address errors.
+#define HAL_CF_EXCEPTION_FS32_MSK   ((CYG_WORD16)0x0C00)
+#define HAL_CF_EXCEPTION_FS10_MSK   ((CYG_WORD16)0x0003)
+
+// Macros to access fields in the format vector word.
+
+#define HAL_CF_EXCEPTION_FORMAT(_fmt_vec_word_)                            \
+    ((((CYG_WORD16)(_fmt_vec_word_)) & HAL_CF_EXCEPTION_FORMAT_MSK) >> 12)
+
+#define HAL_CF_EXCEPTION_VECTOR(_fmt_vec_word_)                            \
+    ((((CYG_WORD16)(_fmt_vec_word_)) & HAL_CF_EXCEPTION_VECTOR_MSK) >> 2)
+
+#define HAL_CF_EXCEPTION_FS(_fmt_vec_word_)                                \
+     (((((CYG_WORD16)(_fmt_vec_word_)) & HAL_CF_EXCEPTION_FS32_MSK) >> 8)  \
+     | (((CYG_WORD16)(_fmt_vec_word_)) & HAL_CF_EXCEPTION_FS10_MSK))
+
+// ----------------------------------------------------------------------------
+// HAL_SavedRegisters -- Saved by a context switch or by an exception/interrupt
+
+typedef struct
+{
+    // These are common to all saved states and are in the order
+    // stored and loaded by the movem instruction.
+
+    // Data regs D0-D7
+    CYG_WORD32 d[8];
+
+    // Address regs A0-A7
+    CYG_ADDRESS a[8];
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+    // MAC registers
+    CYG_WORD32 macc;
+    CYG_WORD32 macsr;
+    CYG_WORD32 mask;
+#endif
+
+    // On exception/interrupt PC, SR and exception are pushed on the
+    // stack automatically, so there is no need to allocate the entire
+    // structure.
+    
+    // 16-bit format/vector word
+    CYG_WORD16 fmt_vec_word;
+
+    // Status register
+    CYG_WORD16 sr;
+
+    // Program counter
+    CYG_ADDRESS pc;
+
+} __attribute__ ((aligned, packed)) HAL_SavedRegisters;
+
+#ifndef HAL_THREAD_SWITCH_CONTEXT
+
+// ***************************************************************************
+// HAL_THREAD_SWITCH_CONTEXT
+// 
+// This macro saves the state of the currently running thread and writes
+// its stack pointer to *(_fspptr_).
+// It then switches to the thread context that *(_tspptr_) points to.
+// 
+// INPUT:
+//  _fspptr_: A pointer to the location to save the current thread's stack
+//      pointer to.
+// 
+//   _tspptr_: A pointer to the location containing the stack pointer of
+//      the thread context to switch to.
+// 
+// OUTPUT:
+//   *(_fspptr_): Contains the stack pointer of the previous thread's context.
+// 
+// ***************************************************************************
+
+externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from );
+externC void hal_thread_load_context( CYG_ADDRESS to )
+    CYGBLD_ATTRIB_NORET;
+
+#define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_)                    \
+        hal_thread_switch_context((CYG_ADDRESS)_tspptr_,(CYG_ADDRESS)_fspptr_);
+#endif // HAL_THREAD_SWITCH_CONTEXT
+
+#ifndef HAL_THREAD_LOAD_CONTEXT
+
+// ***************************************************************************
+// hal_thread_load_context
+// 
+// This routine loads the thread context that *(_tspptr_) points to.
+// This routine does not return.
+// 
+// INPUT:
+//   _tspptr_: A pointer to  the location containing  the stack pointer  of
+//      the thread context to switch to.
+// 
+// ***************************************************************************
+
+#define HAL_THREAD_LOAD_CONTEXT(_tspptr_)                               \
+        hal_thread_load_context( (CYG_ADDRESS)_tspptr_ );
+#endif // HAL_THREAD_LOAD_CONTEXT
+
+
+#ifndef HAL_THREAD_INIT_CONTEXT
+
+// ***************************************************************************
+// HAL_THREAD_INIT_CONTEXT -- Context Initialization
+// 
+// Initialize the context of a thread.
+// 
+// INPUT:
+//   _sparg_: The name of the variable containing the current sp. This
+//      will be written with the new sp.
+// 
+//   _thread_: The thread object address, passed as argument to entry
+//      point.
+// 
+//   _entry_: The thread's entry point address.
+// 
+//   _id_: A bit pattern used in initializing registers, for debugging.
+// 
+// OUTPUT:
+//   _sparg_: Updated with the value of the new sp.
+// 
+// ***************************************************************************
+
+#define HAL_THREAD_INIT_CONTEXT(_sparg_, _thread_, _entry_, _id_)           \
+    CYG_MACRO_START                                                         \
+    CYG_WORD32 * _sp_ = ((CYG_WORD32*)((CYG_WORD32)(_sparg_) & ~15));       \
+    HAL_SavedRegisters * _regs_;                                            \
+    int _i_;                                                                \
+                                                                            \
+    /* Thread's parameter. */                                               \
+    *(--_sp_) = (CYG_WORD32)(_thread_);                                     \
+    /* Fake thread's return addr. Needed because thread is a function */    \
+    /* and parameters to functions are always follwed by the return   */    \
+    /* address on the stack.                                          */    \
+    *(--_sp_) = (CYG_WORD32)(0xDEADC0DE);                                   \
+     /* Thread's return addr. (used by hal_thread_load_context) */          \
+    *(--_sp_) = (CYG_WORD32)(_entry_);                                      \
+                                                                            \
+    _regs_ = (HAL_SavedRegisters *)                                         \
+              ((CYG_WORD32)_sp_ - sizeof(HAL_SavedRegisters));              \
+                                                                            \
+    for (_i_=0; _i_ < 8; _i_++)                                             \
+        _regs_->a[_i_] = _regs_->d[_i_] = (_id_);                           \
+    /* A6, initial frame pointer should be null */                          \
+    _regs_->a[6] = (CYG_ADDRESS)0;                                          \
+                                                                            \
+    /* Thread's starting SR. All interrupts enabled. */                     \
+    _regs_->sr = 0x3000;                                                    \
+                                                                            \
+    /* Thread's starting PC */                                              \
+    _regs_->pc = (CYG_ADDRESS)(_entry_);                                    \
+                                                                            \
+    (_sparg_) = (CYG_ADDRESS)_regs_;                                        \
+    CYG_MACRO_END
+#endif // HAL_THREAD_INIT_CONTEXT
+    
+// ----------------------------------------------------------------------------
+// Bit manipulation routines.
+
+externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask);
+externC cyg_uint32 hal_msbit_index(cyg_uint32 mask);
+
+#define HAL_LSBIT_INDEX(index, mask) (index) = hal_lsbit_index(mask);
+
+#define HAL_MSBIT_INDEX(index, mask) (index) = hal_msbit_index(mask);
+
+// ----------------------------------------------------------------------------
+// Idle thread code.
+// This macro is called in the idle thread loop, and gives the HAL the
+// chance to insert code. Typical idle thread behaviour might be to halt the
+// processor.
+
+externC void hal_idle_thread_action(cyg_uint32 loop_count);
+
+#define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_)
+
+// ----------------------------------------------------------------------------
+// Execution reorder barrier.
+// When optimizing the compiler can reorder code. In multithreaded systems
+// where the order of actions is vital, this can sometimes cause problems.
+// This macro may be inserted into places where reordering should not happen.
+
+#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" )
+
+// ----------------------------------------------------------------------------
+// Breakpoint support
+// HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen
+// if executed.
+// HAL_BREAKINST is the value of the breakpoint instruction and
+// HAL_BREAKINST_SIZE is its size in bytes.
+
+// The host side of GDB debugger uses trap #15 to install breakpoints.
+
+#define CYGNUM_HAL_VECTOR_DEBUGTRAP         47
+
+#define HAL_BREAKPOINT(_label_)                 \
+asm volatile (" .globl  " #_label_ ";"          \
+              #_label_":"                       \
+              " trap #15"                       \
+    );
+
+#define HAL_BREAKINST           0x4E4F
+
+#define HAL_BREAKINST_SIZE      2
+
+
+// ----------------------------------------------------------------------------
+// Thread register state manipulation for GDB support.
+
+typedef struct {
+    cyg_uint32  d[8];
+    cyg_uint32  a[8];
+    cyg_uint32  pc;
+    cyg_uint32  sr;
+} GDB_Registers;
+
+// Translate a stack pointer as saved by the thread context macros above into
+// a pointer to a HAL_SavedRegisters structure.
+#define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ )  \
+        (_regs_) = (HAL_SavedRegisters *)(_sp_)
+
+
+// Copy a set of registers from a HAL_SavedRegisters structure into a
+// GDB ordered array.
+#define HAL_GET_GDB_REGISTERS( _aregval_, _regs_ )              \
+    CYG_MACRO_START                                             \
+    union __gdbreguniontype {                                   \
+      __typeof__(_aregval_) _aregval2_;                         \
+      GDB_Registers *_gdbr;                                     \
+    } __gdbregunion;                                            \
+    __gdbregunion._aregval2_ = (_aregval_);                     \
+    GDB_Registers *_gdb_ = __gdbregunion._gdbr;                 \
+    int _i_;                                                    \
+                                                                \
+    for( _i_ = 0; _i_ < 8; _i_++ )                              \
+    {                                                           \
+        _gdb_->d[_i_] = (_regs_)->d[_i_];                       \
+        _gdb_->a[_i_] = (_regs_)->a[_i_];                       \
+    }                                                           \
+                                                                \
+    _gdb_->pc = (_regs_)->pc;                                   \
+    _gdb_->sr = (cyg_uint32) ((_regs_)->sr);                    \
+    CYG_MACRO_END
+
+// Copy a GDB ordered array into a HAL_SavedRegisters structure.
+#define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ )             \
+    CYG_MACRO_START                                             \
+    union __gdbreguniontype {                                   \
+      __typeof__(_aregval_) _aregval2_;                         \
+      GDB_Registers *_gdbr;                                     \
+    } __gdbregunion;                                            \
+    __gdbregunion._aregval2_ = (_aregval_);                     \
+    GDB_Registers *_gdb_ = __gdbregunion._gdbr;                 \
+    int _i_;                                                    \
+                                                                \
+    for( _i_ = 0; _i_ < 8; _i_++ )                              \
+    {                                                           \
+        (_regs_)->d[_i_] = _gdb_->d[_i_];                       \
+        (_regs_)->a[_i_] = _gdb_->a[_i_];                       \
+    }                                                           \
+                                                                \
+    (_regs_)->pc = _gdb_->pc;                                   \
+    (_regs_)->sr = (CYG_WORD16)(_gdb_->sr);                     \
+    CYG_MACRO_END
+
+
+#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
+      defined(CYGPKG_HAL_EXCEPTIONS)
+
+// ----------------------------------------------------------------------------
+// Exception handling function.
+// This function is defined by the kernel according to this prototype. It is
+// invoked from the HAL to deal with any CPU exceptions that the HAL does
+// not want to deal with itself. It usually invokes the kernel's exception
+// delivery mechanism.
+
+externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
+
+#endif // defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)
+
+// ----------------------------------------------------------------------------
+// Minimal and sensible stack sizes: the intention is that applications
+// will use these to provide a stack size in the first instance prior to
+// proper analysis. Idle thread stack should be this big.
+
+//    THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES.
+//           THEY ARE HOWEVER ENOUGH TO START PROGRAMMING.
+// YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES!
+
+// This is not a config option because it should not be adjusted except
+// under "enough rope" sort of disclaimers.
+
+// Stack frame overhead per call: 6 data registers, 5 address registers,
+// frame pointer, and return address. We can't guess the local variables so
+// just assume that using all of the registers averages out.
+
+#define CYGNUM_HAL_STACK_FRAME_SIZE ((6 + 5 + 1 + 1) * 4)
+
+// Stack needed for a context switch.
+// All registers + pc + sr + vector.
+
+#ifndef CYGNUM_HAL_STACK_CONTEXT_SIZE
+#define CYGNUM_HAL_STACK_CONTEXT_SIZE ((8+8+1)*4 + (1+1)*2)
+#endif // CYGNUM_HAL_STACK_CONTEXT_SIZE
+
+// Interrupt (rounded up) + call to ISR, interrupt_end() and the DSR.
+
+#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \
+    ((CYGNUM_HAL_STACK_CONTEXT_SIZE) + (2*CYGNUM_HAL_STACK_FRAME_SIZE))
+
+// We define a minimum stack size as the minimum any thread could ever
+// legitimately get away with. We can throw asserts if users ask for less
+// than this. Allow enough for four interrupt sources - clock, serial,
+// nic, and one other.
+
+// No separate interrupt stack exists. Make sure all threads contain
+// a stack sufficiently large.
+
+#define CYGNUM_HAL_STACK_SIZE_MINIMUM                   \
+        ((4*CYGNUM_HAL_STACK_INTERRUPT_SIZE)            \
+         + (16*CYGNUM_HAL_STACK_FRAME_SIZE))
+
+// Now make a reasonable choice for a typical thread size. Pluck figures
+// from thin air and say 30 call frames with an average of 16 words of
+// automatic variables per call frame.
+
+#define CYGNUM_HAL_STACK_SIZE_TYPICAL                   \
+        (CYGNUM_HAL_STACK_SIZE_MINIMUM +                \
+         (30 * (CYGNUM_HAL_STACK_FRAME_SIZE+(16*4))))
+
+// -------------------------------------------------------------------------
+// Macros for switching context between two eCos instances (jump from
+// code in ROM to code in RAM or vice versa).
+
+#define CYGARC_HAL_SAVE_GP()
+#define CYGARC_HAL_RESTORE_GP()
+
+// -------------------------------------------------------------------------
+// hal_setjmp/hal_longjmp
+
+
+// We must save all of the registers that are preserved across routine
+// calls. The assembly code assumes that this structure is defined in the
+// following format. Any changes to this structure will result in changes to
+// the assembly code!!
+
+typedef struct {
+    // D registers
+    cyg_uint32 d2;
+    cyg_uint32 d3;
+    cyg_uint32 d4;
+    cyg_uint32 d5;
+    cyg_uint32 d6;
+    cyg_uint32 d7;
+
+    // A registers
+    cyg_uint32 a2;
+    cyg_uint32 a3;
+    cyg_uint32 a4;
+    cyg_uint32 a5;
+    cyg_uint32 a6;
+    
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+    // MAC registers
+    cyg_uint32 macc;
+    cyg_uint32 macsr;
+    cyg_uint32 mask;
+#endif
+
+    // SP and PC
+    cyg_uint32 sp;
+    cyg_uint32 pc;
+} hal_jmp_buf_t;
+
+// This type is used by normal routines to pass the address of the structure
+// into our routines without having to explicitly take the address
+// of the structure.
+
+typedef cyg_uint32 hal_jmp_buf[sizeof(hal_jmp_buf_t) / sizeof(cyg_uint32)];
+
+// Define the generic setjmp and longjmp routines
+externC int hal_setjmp(hal_jmp_buf env);
+externC void hal_longjmp(hal_jmp_buf env, int val);
+#define hal_setjmp(_env) hal_setjmp(_env)
+#define hal_longjmp(_env, _val) hal_longjmp(_env, _val)
+
+// ---------------------------------------------------------------------------
+// End of hal_arch.h
+#endif // CYGONCE_HAL_ARCH_H
diff --git a/packages/hal/coldfire/arch/v2_0/include/hal_cache.h b/packages/hal/coldfire/arch/v2_0/include/hal_cache.h
new file mode 100644 (file)
index 0000000..579af19
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef CYGONCE_HAL_CACHE_H
+#define CYGONCE_HAL_CACHE_H
+
+//=============================================================================
+//
+//      hal_cache.h
+//
+//      HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Provide ColdFire-specific cache control definitions.
+// Usage:         #include <cyg/hal/hal_cache.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/var_cache.h>
+
+// ---------------------------------------------------------------------------
+// End of hal_cache.h
+#endif // ifndef CYGONCE_HAL_CACHE_H
diff --git a/packages/hal/coldfire/arch/v2_0/include/hal_intr.h b/packages/hal/coldfire/arch/v2_0/include/hal_intr.h
new file mode 100644 (file)
index 0000000..600b509
--- /dev/null
@@ -0,0 +1,344 @@
+#ifndef CYGONCE_HAL_HAL_INTR_H
+#define CYGONCE_HAL_HAL_INTR_H
+
+//==========================================================================
+//
+//      hal_intr.h
+//
+//      ColdFire interrupt/exception support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Provide ColdFire-specific interrupt and exception
+//                definitions.
+// Usage:         #include <cyg/hal/hal_intr.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/hal/var_intr.h>
+
+#include <cyg/infra/cyg_ass.h>      // CYG_FAIL
+
+// -------------------------------------------------------------------------
+// ColdFire exception vectors. These correspond to VSRs and are the values
+// to use for HAL_VSR_GET/SET.
+
+#define CYGNUM_HAL_VECTOR_RESETSP           0
+#define CYGNUM_HAL_VECTOR_RESETPC           1
+#define CYGNUM_HAL_VECTOR_BUSERR            2
+#define CYGNUM_HAL_VECTOR_ADDRERR           3
+#define CYGNUM_HAL_VECTOR_ILLINST           4
+#define CYGNUM_HAL_VECTOR_ZERODIV           5
+
+// Exception vectors 6-7 are reserved
+
+#define CYGNUM_HAL_VECTOR_PRIVVIOLATION     8
+#define CYGNUM_HAL_VECTOR_TRACE             9
+#define CYGNUM_HAL_VECTOR_L1010             10
+#define CYGNUM_HAL_VECTOR_L1111             11
+#define CYGNUM_HAL_VECTOR_DEBUG12           12
+#define CYGNUM_HAL_VECTOR_DEBUG13           13
+#define CYGNUM_HAL_VECTOR_FORMAT            14
+#define CYGNUM_HAL_VECTOR_UNINITINT         15
+
+// Exception vectors 16-23 are reserved
+
+#define CYGNUM_HAL_VECTOR_SPURINT           24
+
+#define CYGNUM_HAL_VECTOR_AUTOVEC1          25
+#define CYGNUM_HAL_VECTOR_AUTOVEC2          26
+#define CYGNUM_HAL_VECTOR_AUTOVEC3          27
+#define CYGNUM_HAL_VECTOR_AUTOVEC4          28
+#define CYGNUM_HAL_VECTOR_AUTOVEC5          29
+#define CYGNUM_HAL_VECTOR_AUTOVEC6          30
+#define CYGNUM_HAL_VECTOR_AUTOVEC7          31
+#define CYGNUM_HAL_NUMAUTOVEC               7
+
+#define CYGNUM_HAL_VECTOR_TRAPFIRST         32
+#define CYGNUM_HAL_VECTOR_TRAPLAST          47
+#define CYGNUM_HAL_NUMTRAPS                 16
+
+#define CYGNUM_HAL_VECTOR_FP_BRANCH         48
+#define CYGNUM_HAL_VECTOR_FP_INEXACT        49
+#define CYGNUM_HAL_VECTOR_FP_ZERODIV        50
+#define CYGNUM_HAL_VECTOR_FP_UNDERFLOW      51
+#define CYGNUM_HAL_VECTOR_FP_OPERAND        52
+#define CYGNUM_HAL_VECTOR_FP_OVERFLOW       53
+#define CYGNUM_HAL_VECTOR_FP_NAN            54
+#define CYGNUM_HAL_VECTOR_FP_DENORM         55
+
+// Exception vectors 56-60 are reserved
+
+#define CYGNUM_HAL_VECTOR_UNSUPINST         61
+
+// Exception vectors 62-63 are reserved
+
+#define CYGNUM_HAL_VECTOR_USERINTRFIRST     64
+#define CYGNUM_HAL_VECTOR_USERINTRLAST      255
+#define CYGNUM_HAL_NUMUSERINTR              192
+
+// -------------------------------------------------------------------------
+// Interrupt and exception vector table definitions.
+
+#define CYGNUM_HAL_VSR_MIN                  0
+#define CYGNUM_HAL_VSR_MAX                  255
+#define CYGNUM_HAL_VSR_COUNT                (CYGNUM_HAL_VSR_MAX - CYGNUM_HAL_VSR_MIN + 1)
+
+// To simplify things in interrupt handling code, we don't take into account
+// autovectored, spurious and uninitialized interrupts.
+
+#ifndef CYGNUM_HAL_ISR_RANGE_DEFINED
+#define CYGNUM_HAL_ISR_MIN                   CYGNUM_HAL_VECTOR_USERINTRFIRST
+#define CYGNUM_HAL_ISR_MAX                   CYGNUM_HAL_VECTOR_USERINTRLAST
+#define CYGNUM_HAL_ISR_COUNT                 (CYGNUM_HAL_ISR_MAX - CYGNUM_HAL_ISR_MIN + 1)
+#endif
+
+#ifndef CYGNUM_HAL_EXCEPTION_RANGE_DEFINED
+#define CYGNUM_HAL_EXCEPTION_MIN             CYGNUM_HAL_VECTOR_BUSERR
+#define CYGNUM_HAL_EXCEPTION_MAX             CYGNUM_HAL_VECTOR_UNSUPINST
+#define CYGNUM_HAL_EXCEPTION_COUNT           (CYGNUM_HAL_EXCEPTION_MAX -\
+    CYGNUM_HAL_EXCEPTION_MIN + 1)
+#endif
+
+// -------------------------------------------------------------------------
+// Equivalence between ColdFire exception names and target independent
+// exception names.
+// These are the values used when passed out to an
+// external exception handler using cyg_hal_deliver_exception().
+
+#define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION CYGNUM_HAL_VECTOR_ILLINST
+#define CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO         CYGNUM_HAL_VECTOR_ZERODIV
+#define CYGNUM_HAL_EXCEPTION_DATA_ACCESS         CYGNUM_HAL_VECTOR_BUSERR
+#define CYGNUM_HAL_EXCEPTION_CODE_ACCESS         CYGNUM_HAL_VECTOR_BUSERR
+
+// -------------------------------------------------------------------------
+// Spurious interrupt definition.
+
+#ifndef CYGNUM_HAL_SPURIOUS_INTERRUPT
+#define CYGNUM_HAL_SPURIOUS_INTERRUPT CYGNUM_HAL_VECTOR_SPURINT
+#endif
+
+// -------------------------------------------------------------------------
+// Static data used by HAL.
+
+// ISR tables
+externC volatile CYG_ADDRESS  cyg_hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
+externC volatile CYG_ADDRWORD cyg_hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
+externC volatile CYG_ADDRESS  cyg_hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
+
+// VSR table
+externC volatile CYG_ADDRESS  cyg_hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
+
+// ROM VSR table
+externC CYG_ADDRESS rom_vsr_table[CYGNUM_HAL_VSR_COUNT];
+
+// -------------------------------------------------------------------------
+// Interrupt stack definitions.
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+externC void hal_interrupt_stack_call_pending_DSRs(void);
+#define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \
+    hal_interrupt_stack_call_pending_DSRs()
+
+#endif
+
+// A separate stack always exist to allow the processor to initialize itself.
+// It depends on CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK macro
+// definition if this stack is used for interrupts too.
+
+#define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base
+#define HAL_INTERRUPT_STACK_TOP  cyg_interrupt_stack
+
+externC char HAL_INTERRUPT_STACK_BASE[];
+externC char HAL_INTERRUPT_STACK_TOP[];
+
+// --------------------------------------------------------------------------
+// Translate a vector number into an ISR table index.
+
+#ifndef HAL_TRANSLATE_VECTOR
+#define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_- CYGNUM_HAL_ISR_MIN)
+#endif
+
+// -------------------------------------------------------------------------
+// Interrupt state storage.
+
+typedef cyg_uint16 CYG_INTERRUPT_STATE;
+
+// --------------------------------------------------------------------------
+// Interrupt and VSR attachment macros.
+
+externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
+
+externC void hal_default_exception_handler(CYG_WORD vector,
+                                           HAL_SavedRegisters *regs);
+
+#define HAL_INTERRUPT_IN_USE( _vector_, _state_)        \
+CYG_MACRO_START                                         \
+    cyg_uint32 _index_;                                 \
+    HAL_TRANSLATE_VECTOR ((_vector_), _index_);         \
+                                                        \
+    if (cyg_hal_interrupt_handlers[_index_]             \
+        == (CYG_ADDRESS) &hal_default_isr)              \
+        (_state_) = 0;                                  \
+    else                                                \
+        (_state_) = 1;                                  \
+CYG_MACRO_END
+
+#define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ )       \
+CYG_MACRO_START                                                         \
+    cyg_uint32 _index_;                                                 \
+    HAL_TRANSLATE_VECTOR((_vector_), _index_);                          \
+                                                                        \
+    if (cyg_hal_interrupt_handlers[_index_]                             \
+        == (CYG_ADDRESS) &hal_default_isr)                              \
+    {                                                                   \
+        cyg_hal_interrupt_handlers[_index_] = (CYG_ADDRESS)(_isr_);     \
+        cyg_hal_interrupt_data[_index_] = (CYG_ADDRWORD)(_data_);       \
+        cyg_hal_interrupt_objects[_index_] = (CYG_ADDRESS)(_object_);   \
+    }                                                                   \
+CYG_MACRO_END
+
+#define HAL_INTERRUPT_DETACH( _vector_, _isr_ )                         \
+CYG_MACRO_START                                                         \
+    cyg_uint32 _index_;                                                 \
+    HAL_INTERRUPT_MASK(_vector_);                                       \
+    HAL_TRANSLATE_VECTOR((_vector_), _index_);                          \
+    if (cyg_hal_interrupt_handlers[_index_]                             \
+        == (CYG_ADDRESS)(_isr_))                                        \
+    {                                                                   \
+        cyg_hal_interrupt_handlers[_index_] =                           \
+            (CYG_ADDRESS)&hal_default_isr;                              \
+        cyg_hal_interrupt_data[_index_] = 0;                            \
+        cyg_hal_interrupt_objects[_index_] = 0;                         \
+    }                                                                   \
+CYG_MACRO_END
+
+#define HAL_VSR_GET( _vector_, _pvsr_ )                                 \
+    *((CYG_ADDRESS *)(_pvsr_)) = cyg_hal_vsr_table[(_vector_)];
+
+
+#define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ )                       \
+CYG_MACRO_START                                                         \
+    if( (_poldvsr_) != NULL )                                           \
+        *(CYG_ADDRESS *)(_poldvsr_) = cyg_hal_vsr_table[(_vector_)];    \
+    cyg_hal_vsr_table[(_vector_)] = (CYG_ADDRESS)(_vsr_);               \
+CYG_MACRO_END
+
+
+// This is an ugly name, but what it means is: grab the VSR back to eCos
+// internal handling, or if you like, the default handler. But if
+// cooperating with a ROM monitor, the default behaviour is to pass most
+// exceptions to it. This macro undoes that so that eCos handles the
+// exception. So use it with care.
+
+#define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ )              \
+    CYG_MACRO_START                                                     \
+    if( (void*)_poldvsr_ != (void*)NULL )                               \
+        *(CYG_ADDRESS *)_poldvsr_ = cyg_hal_vsr_table[_vector_];        \
+    cyg_hal_vsr_table[_vector_] = rom_vsr_table[_vector_];              \
+    CYG_MACRO_END
+
+// -------------------------------------------------------------------------
+// Interrupt control macros.
+
+// The following interrupt control macros are the default for the ColdFire
+// architecture. Some processor variants will override these definitions in
+// their var_intr.h file.
+
+#ifndef HAL_CF_SET_SR
+#define HAL_CF_SET_SR(__newsr__)                                            \
+    CYG_MACRO_START                                                         \
+    asm volatile ("move.w   %0,%%sr\n"                                      \
+                  :                                                         \
+                  : "d" ((CYG_INTERRUPT_STATE)(__newsr__)));                \
+    CYG_MACRO_END
+#endif // HAL_CF_SET_SR
+
+#ifndef HAL_ENABLE_INTERRUPTS
+#define HAL_ENABLE_INTERRUPTS()                                             \
+    CYG_MACRO_START                                                         \
+    CYG_INTERRUPT_STATE _msk_;                                              \
+    HAL_QUERY_INTERRUPTS(_msk_);                                            \
+    HAL_CF_SET_SR((_msk_ & (CYG_INTERRUPT_STATE)0xf8ff));                   \
+    CYG_MACRO_END
+#endif // HAL_ENABLE_INTERRUPTS
+
+#ifndef HAL_DISABLE_INTERRUPTS
+#define HAL_DISABLE_INTERRUPTS(_old_)                                       \
+    CYG_MACRO_START                                                         \
+    HAL_QUERY_INTERRUPTS(_old_);                                            \
+    HAL_CF_SET_SR((_old_ | (CYG_INTERRUPT_STATE)0x0700));                   \
+    CYG_MACRO_END
+#endif //HAL_DISABLE_INTERRUPTS
+
+#ifndef HAL_RESTORE_INTERRUPTS
+#define HAL_RESTORE_INTERRUPTS(_prev_)                                      \
+    CYG_MACRO_START                                                         \
+    CYG_INTERRUPT_STATE _msk_;                                              \
+    HAL_QUERY_INTERRUPTS(_msk_);                                            \
+    _msk_ &= (CYG_INTERRUPT_STATE)0xf8ff;                                   \
+    _msk_ |= (((CYG_INTERRUPT_STATE)(_prev_))                               \
+              & (CYG_INTERRUPT_STATE)0x0700);                               \
+    asm volatile ("move.w   %0,%%sr\n"                                      \
+                  :                                                         \
+                  : "d" (_msk_));                                           \
+    CYG_MACRO_END
+#endif // HAL_RESTORE_INTERRUPTS
+
+// Use the extra assignment to avoid warnings.
+// The compiler should optimize it out.
+#ifndef HAL_QUERY_INTERRUPTS
+#define HAL_QUERY_INTERRUPTS(__oldmask__)                                   \
+    CYG_MACRO_START                                                         \
+    CYG_INTERRUPT_STATE _omsk_ = (CYG_INTERRUPT_STATE)(__oldmask__);        \
+    asm volatile ("move.w   %%sr,%0\n"                                      \
+                  : "=d" (_omsk_)                                           \
+                  : );                                                      \
+    (__oldmask__) = (__typeof__(__oldmask__))_omsk_;                        \
+    CYG_MACRO_END
+#endif // HAL_QUERY_INTERRUPTS
+
+// ---------------------------------------------------------------------------
+// End of hal_intr.h
+#endif // ifndef CYGONCE_HAL_HAL_INTR_H
diff --git a/packages/hal/coldfire/arch/v2_0/include/hal_io.h b/packages/hal/coldfire/arch/v2_0/include/hal_io.h
new file mode 100644 (file)
index 0000000..ceae950
--- /dev/null
@@ -0,0 +1,154 @@
+#ifndef CYGONCE_HAL_HAL_IO_H
+#define CYGONCE_HAL_HAL_IO_H
+
+//=============================================================================
+//
+//      hal_io.h
+//
+//      HAL device IO register support
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:  Wade Jensen
+// Date:          2005-25-06
+// Purpose:       Provide ColdFire-specific IO register definitions.
+// Usage:         #include <cyg/hal/hal_io.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+// ---------------------------------------------------------------------------
+// IO Register address.
+// This type is for recording the address of an IO register.
+
+typedef volatile CYG_ADDRWORD HAL_IO_REGISTER;
+
+// ---------------------------------------------------------------------------
+// BYTE Register access.
+// Individual and vectorized access to 8 bit registers.
+
+#define HAL_READ_UINT8( _register_, _value_ )           \
+    CYG_MACRO_START                                     \
+    ((_value_) = *((volatile CYG_BYTE *)(_register_))); \
+    CYG_MACRO_END
+
+#define HAL_WRITE_UINT8( _register_, _value_ )          \
+    CYG_MACRO_START                                     \
+    (*((volatile CYG_BYTE *)(_register_)) = (_value_)); \
+    CYG_MACRO_END
+
+#define HAL_READ_UINT8_VECTOR( _register_, _buf_, _count_, _step_ )     \
+    CYG_MACRO_START                                                     \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) {   \
+        (_buf_)[_i_] = ((volatile CYG_BYTE *)(_register_))[_j_];        \
+    }                                                                   \
+    CYG_MACRO_END
+
+#define HAL_WRITE_UINT8_VECTOR( _register_, _buf_, _count_, _step_ )    \
+    CYG_MACRO_START                                                     \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) {   \
+        ((volatile CYG_BYTE *)(_register_))[_j_] = (_buf_)[_i_];        \
+    }                                                                   \
+    CYG_MACRO_END
+
+
+// ---------------------------------------------------------------------------
+// 16 bit access.
+// Individual and vectorized access to 16 bit registers.
+
+#define HAL_READ_UINT16( _register_, _value_ )                  \
+    CYG_MACRO_START                                             \
+    ((_value_) = *((volatile CYG_WORD16 *)(_register_)));       \
+    CYG_MACRO_END
+
+#define HAL_WRITE_UINT16( _register_, _value_ )                 \
+    CYG_MACRO_START                                             \
+    (*((volatile CYG_WORD16 *)(_register_)) = (_value_));       \
+    CYG_MACRO_END
+
+#define HAL_READ_UINT16_VECTOR( _register_, _buf_, _count_, _step_ )    \
+    CYG_MACRO_START                                                     \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) {   \
+        (_buf_)[_i_] = ((volatile CYG_WORD16 *)(_register_))[_j_];      \
+    }                                                                   \
+    CYG_MACRO_END
+
+#define HAL_WRITE_UINT16_VECTOR( _register_, _buf_, _count_, _step_ )   \
+    CYG_MACRO_START                                                     \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) {   \
+        ((volatile CYG_WORD16 *)(_register_))[_j_] = (_buf_)[_i_];      \
+    }                                                                   \
+    CYG_MACRO_END
+
+// ---------------------------------------------------------------------------
+// 32 bit access.
+// Individual and vectorized access to 32 bit registers.
+
+#define HAL_READ_UINT32( _register_, _value_ )                  \
+    CYG_MACRO_START                                             \
+    ((_value_) = *((volatile CYG_WORD32 *)(_register_)));       \
+    CYG_MACRO_END
+
+#define HAL_WRITE_UINT32( _register_, _value_ )                 \
+    CYG_MACRO_START                                             \
+    (*((volatile CYG_WORD32 *)(_register_)) = (_value_));       \
+    CYG_MACRO_END
+
+#define HAL_READ_UINT32_VECTOR( _register_, _buf_, _count_, _step_ )    \
+    CYG_MACRO_START                                                     \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) {   \
+        (_buf_)[_i_] = ((volatile CYG_WORD32 *)(_register_))[_j_];      \
+    }                                                                   \
+    CYG_MACRO_END
+
+#define HAL_WRITE_UINT32_VECTOR( _register_, _buf_, _count_, _step_ )   \
+    CYG_MACRO_START                                                     \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) {   \
+        ((volatile CYG_WORD32 *)(_register_))[_j_] = (_buf_)[_i_];      \
+    }                                                                   \
+    CYG_MACRO_END
+
+// ---------------------------------------------------------------------------
+// End of hal_io.h
+#endif // ifndef CYGONCE_HAL_HAL_IO_H
diff --git a/packages/hal/coldfire/arch/v2_0/include/hal_startup.h b/packages/hal/coldfire/arch/v2_0/include/hal_startup.h
new file mode 100644 (file)
index 0000000..b9b0c21
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef CYGONCE_HAL_STARTUP_H
+#define CYGONCE_HAL_STARTUP_H
+
+//=============================================================================
+//
+//      hal_startup.h
+//
+//      HAL startup definitions for the ColdFire architecture
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright eCosCentric Ltd.
+//
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Provide ColdFire-specific startup definitions.
+// Usage:         #include <cyg/hal/hal_startup.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_intr.h>
+
+// Include the variant-specific startup header
+#include <cyg/hal/var_startup.h>
+
+externC void hal_reset(void) __attribute__ ((section (".boot")));
+
+// ---------------------------------------------------------------------------
+// End of hal_startup.h
+#endif // CYGONCE_HAL_STARTUP_H
diff --git a/packages/hal/coldfire/arch/v2_0/src/coldfire.ld b/packages/hal/coldfire/arch/v2_0/src/coldfire.ld
new file mode 100644 (file)
index 0000000..68b202e
--- /dev/null
@@ -0,0 +1,265 @@
+//==========================================================================
+//
+//  coldfire.ld
+//
+//  Linker script
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:  Wade Jensen
+// Date:          2005-25-06
+// Purpose:       Coldfire-specific linker script definitions.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+STARTUP(vectors.o)
+ENTRY(_start)
+#ifdef EXTRAS
+INPUT(extras.o)
+#endif
+#if (__GNUC__ >= 3)
+GROUP(libtarget.a libgcc.a libsupc++.a)
+#else
+GROUP(libtarget.a libgcc.a)
+#endif
+
+#define ALIGN_LMA 4
+#define FOLLOWING(_section_) AT ((LOADADDR (_section_) + SIZEOF (_section_) + ALIGN_LMA - 1) & ~ (ALIGN_LMA - 1))
+#define LMA_EQ_VMA
+#define FORCE_OUTPUT . = .
+
+#define SECTIONS_BEGIN
+
+#define SECTION_boot(_region_, _vma_, _lma_)                            \
+    .boot _vma_ : _lma_                                                 \
+    {                                                                   \
+        FORCE_OUTPUT;                                                   \
+        *(.boot*)                                                       \
+        . = ALIGN(4);                                                   \
+    }                                                                   \
+    > _region_
+
+#define SECTION_text(_region_, _vma_, _lma_)                            \
+    .text _vma_ : _lma_                                                 \
+    {                                                                   \
+        _stext = .;                                                     \
+        *(.text*) *(.gnu.warning) *(.gnu.linkonce*) *(.init)            \
+        . = ALIGN(4);                                                   \
+    }                                                                   \
+    > _region_                                                          \
+    _etext = .;  PROVIDE (etext = .);
+
+#define SECTION_fini(_region_, _vma_, _lma_)                            \
+    .fini _vma_ : _lma_                                                 \
+    {                                                                   \
+        FORCE_OUTPUT;                                                   \
+        *(.fini)                                                        \
+        . = ALIGN(4);                                                   \
+    }                                                                   \
+    > _region_
+
+#define SECTION_rodata1(_region_, _vma_, _lma_)                         \
+    .rodata1 _vma_ : _lma_                                              \
+    {                                                                   \
+        FORCE_OUTPUT;                                                   \
+        *(.rodata1*)                                                    \
+        . = ALIGN(4);                                                   \
+    }                                                                   \
+    > _region_
+
+#define SECTION_rodata(_region_, _vma_, _lma_)                          \
+    .rodata _vma_ : _lma_                                               \
+    {                                                                   \
+        FORCE_OUTPUT;                                                   \
+        *(.rodata*)                                                     \
+        . = ALIGN(4);                                                   \
+    }                                                                   \
+    > _region_
+
+#define SECTION_fixup(_region_, _vma_, _lma_)                           \
+    .fixup _vma_ : _lma_                                                \
+    {                                                                   \
+        __FIXUP_START__ = ABSOLUTE(.);                                  \
+        *(.fixup)                                                       \
+        . = ALIGN(4);                                                   \
+        __FIXUP_END__ = ABSOLUTE(.);                                    \
+    }                                                                   \
+    > _region_
+
+#define SECTION_gcc_except_table(_region_, _vma_, _lma_)                \
+    .gcc_except_table _vma_ : _lma_                                     \
+    {                                                                   \
+        __EXCEPT_START__ = ABSOLUTE(.);                                 \
+        *(.gcc_except_table)                                            \
+        . = ALIGN(4);                                                   \
+        __EXCEPT_END__ = ABSOLUTE(.);                                   \
+    }                                                                   \
+    > _region_
+
+#define SECTION_data(_region_, _vma_, _lma_)                                        \
+    .data _vma_ : _lma_                                                             \
+    {                                                                               \
+        __ram_data_start = ABSOLUTE(.);                                             \
+        *(.data*)                                                                   \
+        __GOT1_START__ = ABSOLUTE(.);                                               \
+        *(.got1)                                                                    \
+        __GOT1_END__ = ABSOLUTE(.);                                                 \
+        . = ALIGN (4);                                                              \
+          /* Put .ctors and .dtors next to the .got2 section, so that */            \
+          /* the pointers get relocated with -mrelocatable.           */            \
+        __CTOR_LIST__ = ABSOLUTE(.);                                                \
+        KEEP(*(SORT(.ctors*)));                                                     \
+        __CTOR_END__ = ABSOLUTE(.);                                                 \
+        __DTOR_LIST__ = ABSOLUTE(.);                                                \
+        KEEP(*(SORT(.dtors*)))                                                      \
+        __DTOR_END__ = ABSOLUTE(.);                                                 \
+        . = ALIGN(4);                                                               \
+        KEEP(*( SORT (.ecos.table.*)));                                             \
+        . = ALIGN (4);                                                              \
+          *( .2ram.*) ;                                                             \
+        __GOT2_START__ = ABSOLUTE(.);                                               \
+        *(.got2)                                                                    \
+        __GOT2_END__ = ABSOLUTE(.);                                                 \
+        __GOT_START = ABSOLUTE(.);                                                  \
+        _GLOBAL_OFFSET_TABLE_ = ABSOLUTE(. + 32768);                                \
+        _SDA_BASE_ = ABSOLUTE(.);                                                   \
+        *(.got.plt) *(.got)                                                         \
+        __GOT_END__ = ABSOLUTE(.);                                                  \
+        *(.dynamic)                                                                 \
+        *(.eh_frame)                                                                \
+          /* We want the small data sections together, so single-instruction */     \
+          /* offsets can access them all, and initialized data all before    */     \
+          /* uninitialized, so we can shorten the on-disk segment size.      */     \
+        __SDATA_START__ = ABSOLUTE(.);                                              \
+        *(.sdata) *(.sdata.*)                                                       \
+        __SDATA2_START__ = ABSOLUTE(.);                                             \
+        *(.sdata2*)                                                                 \
+        . = ALIGN(4);                                                               \
+        __ram_data_end = ABSOLUTE(.);                                               \
+        __ram_data_size = ABSOLUTE (.) - ABSOLUTE(__ram_data_start);                \
+    }                                                                               \
+    > _region_                                                                      \
+    __rom_data_start = LOADADDR(.data);                                             \
+    __rom_data_size = SIZEOF(.data);                                                \
+    __rom_data_end = __rom_data_start + __rom_data_size;
+
+#define SECTION_bss(_region_, _vma_, _lma_)                                     \
+    .bss _vma_ : _lma_                                                          \
+    {                                                                           \
+        __bss_start = ABSOLUTE (.);                                             \
+        FORCE_OUTPUT;                                                           \
+        *(.dynbss*) *(.bss*) *(COMMON) *(.sbss*) *(.scommon*)                   \
+        . = ALIGN(4);                                                           \
+        __bss_end = ABSOLUTE (.);                                               \
+        __bss_size = ABSOLUTE (.) - ABSOLUTE(__bss_start);                      \
+    }                                                                           \
+    > _region_
+
+#define SECTION_stab    \
+    .stab 0 (NOLOAD) :  \
+    {                   \
+        *(.stab)        \
+    }
+
+#define SECTION_stabstr     \
+    .stabstr 0 (NOLOAD) :   \
+    {                       \
+        *(.stabstr)         \
+    }
+
+#define SECTION_comment     \
+    .comment 0 (NOLOAD) :   \
+    {                       \
+        *(.comment)         \
+    }
+
+#define SECTION_uninvar(_region_, _vma_, _lma_)                                 \
+    .uninvar _vma_ : _lma_                                                      \
+    {                                                                           \
+        __uninvar_start = ABSOLUTE (.);                                         \
+        FORCE_OUTPUT;                                                           \
+        *(.uninvar);                                                            \
+        . = ALIGN(4);                                                           \
+        __uninvar_end = ABSOLUTE (.);                                           \
+        __uninvar_size = ABSOLUTE (.) - ABSOLUTE(__uninvar_start);              \
+    }                                                                           \
+    > _region_
+
+#define SECTION_romvec(_region_, _vma_, _lma_)                                  \
+    .romvec _vma_ : _lma_                                                       \
+    {                                                                           \
+        __romvec_start = ABSOLUTE (.);                                          \
+        FORCE_OUTPUT;                                                           \
+        KEEP(*(.romvec));                                                       \
+        . = ALIGN(4);                                                           \
+        __romvec_end = ABSOLUTE (.);                                            \
+        __romvec_size = ABSOLUTE (.) - ABSOLUTE(__romvec_start);                \
+    }                                                                           \
+    > _region_
+
+#define SECTION_ramvec(_region_, _vma_, _lma_)                                  \
+    .ramvec _vma_ : _lma_                                                       \
+    {                                                                           \
+        __ramvec_start = ABSOLUTE (.);                                          \
+        FORCE_OUTPUT;                                                           \
+        KEEP(*(.ramvec));                                                       \
+        . = ALIGN(4);                                                           \
+        __ramvec_end = ABSOLUTE (.);                                            \
+        __ramvec_size = ABSOLUTE (.) - ABSOLUTE(__ramvec_start);                \
+    }                                                                           \
+    > _region_
+    
+#define SECTION_virtual_vec_table(_region_, _vma_, _lma_)                                   \
+    .virtual_vec_table _vma_ : _lma_                                                        \
+    {                                                                                       \
+        __virtual_vec_table_start = ABSOLUTE (.);                                           \
+        . += 0x100;                                                                         \
+        __virtual_vec_table_end = ABSOLUTE (.);                                             \
+        __virtual_vec_table_size = ABSOLUTE (.) - ABSOLUTE(__virtual_vec_table_start);      \
+    }                                                                                       \
+    > _region_
+
+#define SECTIONS_END                                \
+    SECTION_stab                                    \
+    SECTION_stabstr                                 \
+    SECTION_comment                                 \
+    . = ALIGN(0x4); _end = .; PROVIDE (end = .);
+
+#include <pkgconf/system.h>
+#include CYGHWR_MEMORY_LAYOUT_LDI
+
+hal_virtual_vector_table = __virtual_vec_table_start;
diff --git a/packages/hal/coldfire/arch/v2_0/src/coldfire_stub.c b/packages/hal/coldfire/arch/v2_0/src/coldfire_stub.c
new file mode 100644 (file)
index 0000000..27d8239
--- /dev/null
@@ -0,0 +1,268 @@
+//========================================================================
+//
+//      coldfire_stub.c
+//
+//      Helper functions for stub
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Helper functions for stub, generic to all ColdFire
+//                processors.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <stddef.h>
+#include <string.h>                     // memcpy, memset
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+#include <cyg/hal/hal_stub.h>
+
+#include <cyg/hal/hal_stub.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+#include <cyg/hal/dbg-threads-api.h>    // dbg_currthread_id
+#endif
+
+// Given a trap value TRAP, return the corresponding signal.
+int __computeSignal (unsigned int trap_number)
+{
+    switch (trap_number)
+    {
+
+        case CYGNUM_HAL_VECTOR_BUSERR:
+        case CYGNUM_HAL_VECTOR_ADDRERR:
+            return SIGBUS;
+
+        case CYGNUM_HAL_VECTOR_ILLINST:
+        case CYGNUM_HAL_VECTOR_UNSUPINST:
+            return SIGILL;
+
+        case CYGNUM_HAL_VECTOR_ZERODIV:
+        case CYGNUM_HAL_VECTOR_FP_BRANCH:
+        case CYGNUM_HAL_VECTOR_FP_INEXACT:
+        case CYGNUM_HAL_VECTOR_FP_ZERODIV:
+        case CYGNUM_HAL_VECTOR_FP_UNDERFLOW:
+        case CYGNUM_HAL_VECTOR_FP_OPERAND:
+        case CYGNUM_HAL_VECTOR_FP_OVERFLOW:
+        case CYGNUM_HAL_VECTOR_FP_NAN:
+        case CYGNUM_HAL_VECTOR_FP_DENORM:
+            // Although not quite accurate, use this signal also for
+            // integer division.
+            return SIGFPE;
+
+        case CYGNUM_HAL_VECTOR_PRIVVIOLATION:
+            return SIGILL;
+        case CYGNUM_HAL_VECTOR_TRACE:
+            // Instruction trace
+            return SIGTRAP;
+
+        case CYGNUM_HAL_VECTOR_L1010:
+        case CYGNUM_HAL_VECTOR_L1111:
+        case CYGNUM_HAL_VECTOR_UNINITINT:
+        case CYGNUM_HAL_VECTOR_SPURINT:
+            return SIGTRAP;
+
+        case CYGNUM_HAL_VECTOR_TRAPFIRST ... CYGNUM_HAL_VECTOR_TRAPLAST:
+            return SIGTRAP;
+
+        case CYGNUM_HAL_VECTOR_AUTOVEC1 ... CYGNUM_HAL_VECTOR_AUTOVEC7:
+        case CYGNUM_HAL_VECTOR_USERINTRFIRST ... CYGNUM_HAL_VECTOR_USERINTRLAST:
+            // External interrupt
+            return SIGINT;
+
+        default:
+            return SIGTERM;
+    }
+}
+
+
+// Return the trap number corresponding to the last-taken trap.
+int __get_trap_number (void)
+{
+    // The vector is not not part of the GDB register set so get it
+    // directly from the saved context.
+    return HAL_CF_EXCEPTION_VECTOR(_hal_registers->fmt_vec_word);
+}
+
+
+// Set the currently-saved pc register value to PC.
+void set_pc (target_register_t pc)
+{
+    put_register (PC, pc);
+}
+
+
+// Return the offset of a register in the GDB_Registers structure.
+static int reg_offset(regnames_t reg)
+{
+    switch(reg)
+    {
+        case D0 ... A7:
+            return reg * 4;
+    
+        case SR:
+            return offsetof(GDB_Registers, sr);
+
+        default:
+        case PC:
+            return offsetof(GDB_Registers, pc);
+    }
+}
+
+
+// Return the currently-saved value corresponding to register REG of
+// the exception context.
+target_register_t get_register(regnames_t reg)
+{
+    target_register_t val;
+    int offset = reg_offset(reg);
+
+    if (REGSIZE(reg) > sizeof(target_register_t))
+        return -1;
+
+    val = _registers[offset/sizeof(target_register_t)];
+
+    return val;
+}
+
+
+// Store VALUE in the register corresponding to WHICH in the exception
+// context.
+void put_register(regnames_t which, target_register_t value)
+{
+    int offset = reg_offset(which);
+
+    if (REGSIZE(which) > sizeof(target_register_t))
+        return;
+
+    _registers[offset/sizeof(target_register_t)] = value;
+}
+        
+
+// Write the contents of register WHICH into VALUE as raw bytes. This
+// is only used for registers larger than sizeof(target_register_t).
+// Return non-zero if it is a valid register.
+int get_register_as_bytes(regnames_t which, char *value)
+{
+    int offset = reg_offset(which);
+
+    memcpy (value, (char *)_registers + offset, REGSIZE(which));
+    return 1;
+}
+
+
+// Alter the contents of saved register WHICH to contain VALUE. This
+// is only used for registers larger than sizeof(target_register_t).
+// Return non-zero if it is a valid register.
+int put_register_as_bytes(regnames_t which, char *value)
+{
+    int offset = reg_offset(which);
+
+    memcpy ((char *)_registers + offset, value, REGSIZE(which));
+    return 1;
+}
+
+
+// ---------------------------------------------------------------------
+// Single-step support
+
+// Set things up so that the next user resume will execute one instruction.
+// This may be done by setting breakpoints or setting a single step flag
+// in the saved user registers, for example.
+
+#define SR_TRACE 0x8000
+
+void __single_step(void)
+{
+    target_register_t sr = get_register (SR);
+
+    // Set trace flag in the exception context.
+    sr |= SR_TRACE;
+
+    put_register (SR, sr);
+}
+
+
+// Clear the single-step state.
+void __clear_single_step(void)
+{
+    target_register_t sr = get_register (SR);
+
+    // Clear single-step flag in the exception context.
+    sr &= ~SR_TRACE;
+
+    put_register (SR, sr);
+}
+
+
+void __install_breakpoints(void)
+{
+    // NOP since single-step HW exceptions are used instead of
+    // breakpoints.
+}
+
+
+void __clear_breakpoints(void)
+{
+    // NOP since single-step HW exceptions are used instead of
+    // breakpoints.
+}
+
+
+// If the breakpoint we hit is in the breakpoint() instruction, return a
+// non-zero value.
+int __is_breakpoint_function(void)
+{
+    return (get_register(PC) == (target_register_t) &CYG_LABEL_NAME(_breakinst));
+}
+
+
+// Skip the current instruction. Since this is only called by the
+// stub when the PC points to a breakpoint or trap instruction,
+// we can safely just skip 2.
+void __skipinst(void)
+{
+    put_register (PC, get_register (PC) + HAL_BREAKINST_SIZE);
+}
+
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
diff --git a/packages/hal/coldfire/arch/v2_0/src/context.S b/packages/hal/coldfire/arch/v2_0/src/context.S
new file mode 100644 (file)
index 0000000..8fee00c
--- /dev/null
@@ -0,0 +1,249 @@
+|=============================================================================
+|
+|      context.S
+|
+|      ColdFire architecture context switch code
+|
+|=============================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|        
+| eCos is free software; you can redistribute it and/or modify it under
+| the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2 or (at your option) any later version.
+|
+| eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+| WARRANTY; without even the implied warranty of MERCHANTABILITY or
+| FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+| for more details.
+|
+| You should have received a copy of the GNU General Public License along
+| with eCos; if not, write to the Free Software Foundation, Inc.,
+| 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+|
+| As a special exception, if other files instantiate templates or use macros
+| or inline functions from this file, or you compile this file and link it
+| with other works to produce a work based on this file, this file does not
+| by itself cause the resulting work to be covered by the GNU General Public
+| License. However the source code for this file must still be made available
+| in accordance with section (3) of the GNU General Public License.
+|
+| This exception does not 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
+| Contributors:
+| Date:          2005-25-06
+| Purpose:       This file contains implementations of the thread context 
+|                switch routines. It also contains the longjmp() and setjmp()
+|                routines.
+|
+|####DESCRIPTIONEND####
+|========================================================================
+
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/cf_offsets.inc>
+#include <cyg/hal/arch.inc>
+
+
+| ----------------------------------------------------------------------------
+| hal_thread_switch_context - Switch between two threads
+|
+| externC void hal_thread_switch_context(CYG_ADDRESS to, CYG_ADDRESS from)
+|
+| INPUT:
+|   0(%sp) : return address
+|   4(%sp) : to - address of sp of next thread to execute
+|   8(%sp) : from - address of sp save location of current thread
+|
+| OUTPUT:
+|   None
+| 
+| RETURN VALUE:
+|   None
+|
+| d0, d1, a0, a1 are ours to abuse. Other registers are not touched.
+
+FUNC_START(hal_thread_switch_context)
+
+        ctx_save_registers
+
+        | Read to and from parameters from the stack        
+        move.l  CYGARC_CF_CONTEXT_SIZE+4(%sp),%a0  
+        move.l  CYGARC_CF_CONTEXT_SIZE+8(%sp),%a1  
+
+        | Store this thread's current stack pointer to *from
+        move.l  %sp,(%a1)
+                                            
+        | Load the stack pointer for the next thread from *to
+        move.l  (%a0),%sp
+                                            
+        ctx_restore_registers
+
+        | Return to caller
+        rts
+
+
+| ----------------------------------------------------------------------------
+| hal_thread_load_context - Load thread context
+|
+| externC void hal_thread_load_context(CYG_ADDRESS to)
+| 
+| INPUT:
+|   4(%sp) : to - address of sp of next thread to execute
+|
+| OUTPUT:
+|   None
+| 
+| RETURN VALUE:
+|   None
+|
+| d0, d1, a0, a1 are ours to abuse.
+
+FUNC_START(hal_thread_load_context)
+
+        | Read the to parameter from the stack and switch to that stack
+        | pointer
+        move.l  4(%sp),%a0                  
+        move.l  (%a0),%sp                   
+
+        | Load all of the  preserved registers from the stack
+        movem.l   CYGARC_CFREG_DREGS(%sp),%d0-%d7
+        movem.l   CYGARC_CFREG_AREGS(%sp),%a0-%a6
+
+        | Starting SR
+        move.w CYGARC_CF_SR(%sp), %d0
+        move.w %d0,%sr
+        
+        | Deallocate context frame
+        lea CYGARC_CF_CONTEXT_SIZE(%sp),%sp
+
+        | Return
+        rts
+
+
+| ----------------------------------------------------------------------------
+| The following routines are based on the hal_jmp_buf structure layout, defined
+| in hal_arch.h
+
+| ----------------------------------------------------------------------------
+| hal_setjmp - setjmp for the ColdFire architecture
+| 
+| externC int hal_setjmp(hal_jmp_buf env)
+| 
+| INPUT:
+|   0(%sp) : return address
+|   4(%sp) : env - address of a hal_jmp_buf structure
+| 
+| OUTPUT:
+|   None 
+| 
+| RETURN VALUE:
+|   This routine always returns zero in d0.l.
+| 
+| d0, d1, a0, a1 are ours to abuse.
+
+FUNC_START(hal_setjmp)
+
+        | Get a pointer to the register buffer
+        move.l   4(%sp),%a0
+
+        | Store all of the preserved registers
+        movem.l %d2-%d7,CYGARC_JMPBUF_REG_D2(%a0)
+        movem.l %a2-%a6,CYGARC_JMPBUF_REG_A2(%a0)
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        | Store MAC registers
+
+        | Store MACSR register
+        move.l  %macsr,%d0
+        move.l  %d0,CYGARC_JMPBUF_REG_MACSR(%a0)
+
+        | Switch to integer mode. This allows to save the contents of ACC
+        | without rounding
+        and.l   #0x000000df,%d0
+        move.l  %d0,%macsr
+
+        | Store ACC register
+        move.l  %acc,%d0
+        move.l  %d0,CYGARC_JMPBUF_REG_MACC(%a0)
+
+        | Store MASK register
+        move.l  %mask,%d0
+        move.l  %d0,CYGARC_JMPBUF_REG_MASK(%a0)
+#endif
+
+        | Store the stack pointer
+        move.l  %sp,CYGARC_JMPBUF_REG_SP(%a0)
+
+        | Store the return address into the structure
+        move.l  (%sp),CYGARC_JMPBUF_REG_PC(%a0)
+
+        | Load a zero return value
+        clr.l %d0
+
+        | Return
+        rts
+
+
+| ----------------------------------------------------------------------------
+| hal_longjmp - longjmp for the ColdFire architecture
+| 
+| externC void hal_longjmp(hal_jmp_buf env, int val)
+| 
+| INPUT:
+|   0(%sp): return address
+|   4(%sp): env - address of a hal_jmp_buf structure
+|   8(%sp): val - the non-zero value to return
+| 
+| OUTPUT:
+|   None
+| 
+| RETURN VALUE:
+|   This routine always returns the value from the val parameter in  d0.l
+|   and to the location of the PC in the env structure.
+
+FUNC_START(hal_longjmp)
+
+        | Load the return value parameter
+        move.l  8(%sp),%d0
+                                            
+        | Get a pointer to the buffer to read our state from
+        move.l  4(%sp),%a0                  
+                                            
+        | Load all of the preserved registers
+        movem.l CYGARC_JMPBUF_REG_D2(%a0),%d2-%d7
+        movem.l CYGARC_JMPBUF_REG_A2(%a0),%a2-%a6
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        | Load MAC registers
+
+        | Load MACSR register
+        move.l  CYGARC_JMPBUF_REG_MACSR(%a0),%d1
+        move.l  %d1,%macsr
+
+        | Load ACC register
+        move.l  CYGARC_JMPBUF_REG_MACC(%a0),%d1
+        move.l  %d1,%acc
+
+        | Load MASK register
+        move.l  CYGARC_JMPBUF_REG_MASK(%a0),%d1
+        move.l  %d1,%mask        
+#endif
+
+        | Load the stack pointer
+        move.l  CYGARC_JMPBUF_REG_SP(%a0),%sp                  
+
+        | Load return address and store it on stack
+        move.l  CYGARC_JMPBUF_REG_PC(%a0),(%sp)
+
+        | Return to caller
+        rts
diff --git a/packages/hal/coldfire/arch/v2_0/src/hal_misc.c b/packages/hal/coldfire/arch/v2_0/src/hal_misc.c
new file mode 100644 (file)
index 0000000..0a1f6d7
--- /dev/null
@@ -0,0 +1,198 @@
+//==========================================================================
+//
+//      hal_misc.c
+//
+//      HAL miscellaneous functions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Miscellaneous routine and variable definitions.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.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/infra/diag.h>             // diag_printf
+
+#include <cyg/hal/hal_arch.h>           // HAL header
+
+#include <cyg/hal/hal_intr.h>           // VSR/ISR defines
+
+// -------------------------------------------------------------------------
+// ISR table
+
+volatile CYG_ADDRESS  cyg_hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
+volatile CYG_ADDRWORD cyg_hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
+volatile CYG_ADDRESS  cyg_hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
+
+// -------------------------------------------------------------------------
+// VSR table
+
+externC void __handle_exception(void);
+
+externC HAL_SavedRegisters * _hal_registers;
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+externC void* volatile __mem_fault_handler;
+#endif
+
+// Defined in variant HAL
+externC void hal_interrupt_update_level(void);
+
+// --------------------------------------------------------------------------
+// Default exception handler.
+
+void hal_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs)
+{
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+    // If we caught an exception inside the stubs, see if we were expecting it
+    // and if so jump to the saved address.
+    if (__mem_fault_handler) {
+        regs->pc = (CYG_ADDRWORD)__mem_fault_handler;
+        // Caught an exception inside stubs
+        return;
+    }
+
+    // Set the pointer to the registers of the current exception
+    // context. At entry the GDB stub will expand the
+    // HAL_SavedRegisters structure into a (bigger) register array.
+    _hal_registers = regs;
+
+    __handle_exception();
+
+#elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
+      defined(CYGPKG_HAL_EXCEPTIONS)
+
+    // We should decode the vector and pass a more appropriate
+    // value as the second argument. For now we simply pass a
+    // pointer to the saved registers. We should also divert
+    // breakpoint and other debug vectors into the debug stubs.
+
+    cyg_hal_deliver_exception(vector, (CYG_ADDRWORD)regs);
+
+#else
+
+    CYG_FAIL("Exception!!!");
+
+#endif
+
+    return;
+}
+
+// --------------------------------------------------------------------------
+// Default ISR handler.
+
+cyg_uint32 hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+{
+    CYG_FAIL("Unexpected ISR");
+    return 0;
+}
+
+// --------------------------------------------------------------------------
+// Default spurious interrupt handler. This routine is called with all
+// interrupts disabled.
+
+#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS
+
+void hal_spurious_interrupt(HAL_SavedRegisters *regs) CYGBLD_ATTRIB_WEAK;
+
+void hal_spurious_interrupt(HAL_SavedRegisters *regs)
+{
+    CYG_FAIL("Spurious interrupt!!");
+}
+
+#endif
+
+// --------------------------------------------------------------------------
+// Idle thread action.
+
+void hal_idle_thread_action(cyg_uint32 count)
+{
+}
+
+// -----------------------------------------------------------------------
+// Determine the index of the ls bit of the supplied mask.
+
+cyg_uint32 hal_lsbit_index(cyg_uint32 mask)
+{
+    cyg_uint32 n = mask;
+
+    static const signed char tab[64] =
+    { -1, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10,
+      4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27 , 15, 31, 11,
+      5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0 , 20, 26, 30, 0, 0, 0,
+      0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0
+    };
+
+    n &= ~(n-1UL);
+    n = (n<<16)-n;
+    n = (n<<6)+n;
+    n = (n<<4)+n;
+
+    return tab[n>>26];
+}
+
+// -----------------------------------------------------------------------
+// Determine the index of the ms bit of the supplied mask.
+
+cyg_uint32 hal_msbit_index(cyg_uint32 mask)
+{
+    cyg_uint32 x = mask;    
+    cyg_uint32 w;
+
+    // Phase 1: make word with all ones from that one to the right
+    x |= x >> 16;
+    x |= x >> 8;
+    x |= x >> 4;
+    x |= x >> 2;
+    x |= x >> 1;
+
+    // Phase 2: calculate number of "1" bits in the word
+    w = (x & 0x55555555) + ((x >> 1) & 0x55555555);
+    w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
+    w = w + (w >> 4);
+    w = (w & 0x000F000F) + ((w >> 8) & 0x000F000F);
+    return (cyg_uint32)((w + (w >> 16)) & 0xFF) - 1;
+
+}
diff --git a/packages/hal/coldfire/arch/v2_0/src/hal_mk_defs.c b/packages/hal/coldfire/arch/v2_0/src/hal_mk_defs.c
new file mode 100644 (file)
index 0000000..d7ab069
--- /dev/null
@@ -0,0 +1,125 @@
+//==========================================================================
+//
+//      hal_mk_defs.c
+//
+//      HAL "make defs" program
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors: gthomas, jskov
+// Date:         2005-25-06
+// Purpose:      ColdFire architecture dependent definition generator
+// Description:  This file contains code that can be compiled by the target
+//               compiler and used to generate machine specific definitions
+//               suitable for use in assembly code.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>           // HAL header
+#include <cyg/hal/hal_intr.h>           // HAL header
+#ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+# include <cyg/kernel/instrmnt.h>
+#endif
+
+// This program is used to generate definitions needed by
+// assembly language modules.
+//
+// This technique was first used in the OSF Mach kernel code:
+// generate asm statements containing #defines,
+// compile this file to assembler, and then extract the
+// #defines from the assembly-language output.
+
+#define DEFINE(sym, val) \
+        asm volatile("\n\t.equ\t" #sym ",%0" : : "i" (val))
+
+int
+main(void)
+{
+    // Exception/interrupt/context save buffer
+    DEFINE(CYGARC_CFREG_AREGS, offsetof(HAL_SavedRegisters, a[0]));
+    DEFINE(CYGARC_CFREG_DREGS, offsetof(HAL_SavedRegisters, d[0]));
+    DEFINE(CYGARC_CFREG_A0, offsetof(HAL_SavedRegisters, a[0]));
+    DEFINE(CYGARC_CFREG_A1, offsetof(HAL_SavedRegisters, a[1]));
+    DEFINE(CYGARC_CFREG_A2, offsetof(HAL_SavedRegisters, a[2]));
+    DEFINE(CYGARC_CFREG_A6, offsetof(HAL_SavedRegisters, a[6]));
+    DEFINE(CYGARC_CFREG_D0, offsetof(HAL_SavedRegisters, d[0]));
+    DEFINE(CYGARC_CFREG_D1, offsetof(HAL_SavedRegisters, d[1]));
+    DEFINE(CYGARC_CFREG_D2, offsetof(HAL_SavedRegisters, d[2]));
+    DEFINE(CYGARC_CFREG_PC, offsetof(HAL_SavedRegisters, pc));
+    DEFINE(CYGARC_CFREG_SP, offsetof(HAL_SavedRegisters, a[7]));
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+    DEFINE(CYGARC_CFREG_MACC, offsetof(HAL_SavedRegisters, macc));
+    DEFINE(CYGARC_CFREG_MACSR, offsetof(HAL_SavedRegisters, macsr));
+    DEFINE(CYGARC_CFREG_MASK, offsetof(HAL_SavedRegisters, mask));
+#endif
+    
+    DEFINE(CYGARC_CF_CONTEXT_SIZE, sizeof(HAL_SavedRegisters));
+
+    // Below only saved on exceptions/interrupts
+    DEFINE(CYGARC_CF_FMTVECWORD, offsetof(HAL_SavedRegisters, fmt_vec_word));
+    DEFINE(CYGARC_CF_SR, offsetof(HAL_SavedRegisters, sr));
+    DEFINE(CYGARC_CF_EXCEPTION_SIZE, sizeof(HAL_SavedRegisters));
+    DEFINE(CYGARC_CF_EXCEPTION_DECREMENT, offsetof(HAL_SavedRegisters, fmt_vec_word));
+
+    // Some other exception related definitions
+    DEFINE(CYGNUM_HAL_ISR_MIN, CYGNUM_HAL_ISR_MIN);
+    DEFINE(CYGNUM_HAL_ISR_COUNT, CYGNUM_HAL_ISR_COUNT);
+    DEFINE(CYGNUM_HAL_SPURIOUS_INTERRUPT, CYGNUM_HAL_SPURIOUS_INTERRUPT);
+    DEFINE(CYGNUM_HAL_VECTOR_DEBUGTRAP, CYGNUM_HAL_VECTOR_DEBUGTRAP);
+
+    // setjmp/longjmp related definitions
+    DEFINE(CYGARC_JMPBUF_REG_D2, offsetof(hal_jmp_buf_t, d2));
+    DEFINE(CYGARC_JMPBUF_REG_A2, offsetof(hal_jmp_buf_t, a2));
+    DEFINE(CYGARC_JMPBUF_REG_SP, offsetof(hal_jmp_buf_t, sp));
+    DEFINE(CYGARC_JMPBUF_REG_PC, offsetof(hal_jmp_buf_t, pc));
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+    DEFINE(CYGARC_JMPBUF_REG_MACC, offsetof(hal_jmp_buf_t, macc));
+    DEFINE(CYGARC_JMPBUF_REG_MACSR, offsetof(hal_jmp_buf_t, macsr));
+    DEFINE(CYGARC_JMPBUF_REG_MASK, offsetof(hal_jmp_buf_t, mask));
+#endif
+
+    return 0;
+}
+
+// -------------------------------------------------------------------------
+// EOF hal_mk_defs.c
diff --git a/packages/hal/coldfire/arch/v2_0/src/hal_startup.c b/packages/hal/coldfire/arch/v2_0/src/hal_startup.c
new file mode 100644 (file)
index 0000000..6980097
--- /dev/null
@@ -0,0 +1,252 @@
+//==========================================================================
+//
+//      hal_startup.c
+//
+//      ColdFire architecture HAL startup code
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Architecture startup code.
+// Description:   This module contains code that sets up the hardware and the
+//                memory sections. All the code must be contained in the
+//                section called ".boot", in order for the ROMRAM startup
+//                to work properly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_startup.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+#include <cyg/hal/hal_if.h>         // hal_if_init
+#include <cyg/hal/hal_intr.h>       // Interrupt definitions
+#include <cyg/hal/hal_stub.h>       // initialize_stub
+
+externC void cyg_start(void);
+externC void hal_ctrlc_isr_init(void);
+
+static void hal_vsr_init(void) __attribute__ ((section (".boot")));
+static void hal_isr_init(void) __attribute__ ((section (".boot")));
+static void hal_init_ram_sections(void) __attribute__ ((section (".boot")));
+static void cyg_hal_invoke_constructors(void) __attribute__ ((section (".boot")));
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+externC unsigned char __romram_copy_source[];
+externC unsigned char __romram_copy_dest[];
+externC unsigned char __romram_copy_length[];
+
+#endif
+
+
+// -------------------------------------------------------------------------
+// Reset vector routine.
+
+void hal_reset(void)
+{
+    // Do any variant-specific reset initialization
+    var_reset();
+
+    // Do any platform-specific reset initialization
+    plf_reset();
+
+    // Initialize the RAM sections that the rest of the C code requires
+    hal_init_ram_sections();
+
+    // All program sections are now in place
+
+    // Make sure that every instruction above this one has been output by
+    // the compiler
+    HAL_REORDER_BARRIER();
+
+    // Now it is safe to use a stack in RAM
+    asm volatile ("lea cyg_interrupt_stack, %sp");
+   
+    // It is now safe to call C functions which may rely on initialized
+    // data
+    hal_vsr_init();
+    hal_isr_init();
+
+    // Initialize variant HAL private data
+    var_init_data();
+
+    // Initialize platform HAL private data
+    plf_init_data();
+
+    // Initialize the virtual vector table
+    hal_if_init();
+
+    // Call C++ constructors
+    cyg_hal_invoke_constructors();
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+    initialize_stub();
+#endif
+
+    // Init Ctrl-C debug ISR
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
+    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
+    hal_ctrlc_isr_init();
+#endif
+
+    // Call cyg_start. This routine should not return.
+    cyg_start();
+}
+
+
+// -------------------------------------------------------------------------
+// Initialize the vector table.
+
+static void hal_vsr_init(void)
+{
+    unsigned int i;
+    
+    // If we are starting up from ROM, or we are starting in
+    // RAM and NOT using a ROM monitor, initialize the VSR and ISR tables.
+#if defined(CYG_HAL_STARTUP_ROM) ||         \
+    defined(CYG_HAL_STARTUP_ROMRAM) ||      \
+        (defined(CYG_HAL_STARTUP_RAM) &&     \
+        !defined(CYGSEM_HAL_USE_ROM_MONITOR))
+
+    // Initialize the HAL's vector table with the ROM vector table
+    for (i = 0; i < CYGNUM_HAL_VSR_COUNT; i++)
+        cyg_hal_vsr_table[i] = rom_vsr_table[i];
+
+#elif defined(CYG_HAL_STARTUP_RAM) && defined(CYGSEM_HAL_USE_ROM_MONITOR)
+
+    // We only take control of the interrupt vectors,
+    // the rest are left to the ROM for now.
+    cyg_hal_vsr_table[CYGNUM_HAL_VECTOR_UNINITINT] =
+        rom_vsr_table[CYGNUM_HAL_VECTOR_UNINITINT];
+
+    cyg_hal_vsr_table[CYGNUM_HAL_VECTOR_SPURINT] =
+        rom_vsr_table[CYGNUM_HAL_VECTOR_SPURINT];
+
+    for(i = 0; i < CYGNUM_HAL_NUMAUTOVEC; i++)
+        cyg_hal_vsr_table[CYGNUM_HAL_VECTOR_AUTOVEC1 + i] =
+            rom_vsr_table[CYGNUM_HAL_VECTOR_AUTOVEC1 + i];
+    
+    for(i = 0; i < CYGNUM_HAL_NUMUSERINTR; i++)
+        cyg_hal_vsr_table[CYGNUM_HAL_VECTOR_USERINTRFIRST + i] =
+            rom_vsr_table[CYGNUM_HAL_VECTOR_USERINTRFIRST + i];
+
+#endif
+}
+
+
+// -------------------------------------------------------------------------
+// Initialize the ISRs.
+
+static void hal_isr_init(void)
+{
+    int i;
+
+    // Initialize all ISR entries to default
+    for (i = 0; i < CYGNUM_HAL_ISR_COUNT; i++)
+    {
+        cyg_hal_interrupt_handlers[i] = (CYG_ADDRESS) &hal_default_isr;
+        cyg_hal_interrupt_data[i] = (CYG_ADDRWORD) 0;
+        cyg_hal_interrupt_objects[i] = (CYG_ADDRESS) 0;
+    }
+}
+
+
+// -------------------------------------------------------------------------
+// Initialize the RAM sections
+// For an efficient copy, we suppose that the sections are aligned at a
+// 4-byte boundary and are a multiple of 4 bytes. Linker scripts should
+// guarantee this.
+
+static void hal_init_ram_sections(void)
+{
+    cyg_uint32 *m;
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+    {
+        // Initialize the RAM data section from the ROM image of the data
+        // section.
+        cyg_uint32 *p = (cyg_uint32 *) __romram_copy_dest;
+        cyg_uint32 *q = (cyg_uint32 *) __romram_copy_source;
+        cyg_uint32 length = 0;
+
+        while (length < (cyg_uint32) __romram_copy_length)
+        {
+            *p++ = *q++;
+            length += 4;
+        }
+    }       
+#endif
+
+    // Initialize the bss sections to zero
+    m = (cyg_uint32 *) __bss_start;
+    while (m != (cyg_uint32 *) __bss_end)
+        *m++ = 0x0;
+}
+
+
+// -------------------------------------------------------------------------
+// Call static constructors.
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+cyg_bool cyg_hal_stop_constructors;
+#endif
+
+typedef void (*pfunc) (void);
+extern pfunc __CTOR_LIST__[];
+extern pfunc __CTOR_END__[];
+
+static void cyg_hal_invoke_constructors(void)
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+    static pfunc *p = &__CTOR_END__[-1];
+
+    cyg_hal_stop_constructors = 0;
+    for (; p >= __CTOR_LIST__; p--) {
+        (*p) ();
+        if (cyg_hal_stop_constructors) {
+            p--;
+            break;
+        }
+    }
+#else
+    pfunc *p;
+
+    for (p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--)
+        (*p) ();
+#endif
+}
diff --git a/packages/hal/coldfire/arch/v2_0/src/vectors.S b/packages/hal/coldfire/arch/v2_0/src/vectors.S
new file mode 100644 (file)
index 0000000..eedacad
--- /dev/null
@@ -0,0 +1,646 @@
+|==========================================================================
+|
+|      vectors.S
+|
+|      ColdFire exception vectors
+|
+|==========================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| eCos is free software; you can redistribute it and/or modify it under
+| the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2 or (at your option) any later version.
+|
+| eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+| WARRANTY; without even the implied warranty of MERCHANTABILITY or
+| FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+| for more details.
+|
+| You should have received a copy of the GNU General Public License along
+| with eCos; if not, write to the Free Software Foundation, Inc.,
+| 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+|
+| As a special exception, if other files instantiate templates or use macros
+| or inline functions from this file, or you compile this file and link it
+| with other works to produce a work based on this file, this file does not
+| by itself cause the resulting work to be covered by the GNU General Public
+| License. However the source code for this file must still be made available
+| in accordance with section (3) of the GNU General Public License.
+|
+| This exception does not 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
+| Contributors: Wade Jensen
+| Date:         2005-25-06
+| Purpose:      ColdFire exception vectors
+| Description:  This file contains the first level default VSRs
+|               that save and restore state for both exceptions and
+|               interrupts.
+|
+|####DESCRIPTIONEND####
+|==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <cyg/hal/cf_offsets.inc>
+#include <cyg/hal/arch.inc>
+#include <cyg/hal/variant.inc>
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#endif
+
+| ----------------------------------------------------------------------------
+| Hardware reset vector
+
+        .section ".boot","x"
+        .balign 4
+        .globl cyg_hal_reset_vsr
+cyg_hal_reset_vsr:
+
+        | Define the entry point for the linker.
+        .globl _start
+_start:
+
+        | Make sure that all interrupts are masked.
+        hal_cpu_int_disable
+
+        | Initial setup. Just do the minimum to be able to perform
+        | initialization in C.
+
+        | Initialize CPU variant
+        hal_cpu_init
+
+        | Platform specific hardware initialization.
+        | This may include memory controller initialization.
+        hal_hardware_init
+
+        | Setup boot stack
+        hal_boot_stack_init
+        
+        | Set up the initial frame pointer.
+        lea     0,%fp
+        link    %fp,#0
+
+        | Call the C routine to complete the reset process.
+        .extern hal_reset
+        jsr    hal_reset
+
+        | If we return, stop.
+9:
+        stop    #0x2000
+        bra     9b
+
+
+| ----------------------------------------------------------------------------
+| Default exception vector handler
+|
+| The default handler for all machine exceptions. We save the
+| machine state and call the default C exception handler. This routine passes a
+| pointer to the saved state to the C exception handler. The stack pointer in
+| the saved state points to the the sp before the exception.
+| The format/vector word in the exception stack contains the vector
+| number.
+
+| void hal_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs);
+        
+        .text
+        .balign 4
+        .globl cyg_hal_default_exception_vsr
+cyg_hal_default_exception_vsr:
+
+        | Disable all interrupts
+        hal_cpu_int_disable
+
+        | Preserve the entire state.
+        | Allocate space for all registers (including the stack pointer).
+        | Write all registers to the stack space.
+        lea.l   -CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
+        movem.l %d0-%d7,CYGARC_CFREG_DREGS(%sp)
+        movem.l %a0-%a6,CYGARC_CFREG_AREGS(%sp)
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        save_mac_registers %d0
+#endif
+                                            
+        | Write the original stack pointer value to the stack.
+        | The format/vector word, sr, and pc are already on the stack.
+        find_original_sp %d0
+        move.l   %d0,CYGARC_CFREG_SP(%sp)
+                                           
+        | Calculate the vector number. The format/vector word on the stack
+        | contains the vector number.
+        move.w  CYGARC_CF_FMTVECWORD(%sp),%d0
+        and.l   #0x000003fc,%d0
+        lsr.l   #2,%d0
+
+        | Pass a pointer to the saved state to the exception handler.
+        pea.l   (%sp)
+                                            
+        | Push the vector number parameter.
+        move.l  %d0,-(%sp)
+
+        | Call the default exception handler. This routine may modify
+        | the exception context.
+        .extern hal_exception_handler
+        jsr    hal_exception_handler
+
+        | Remove the vector number and the state pointer from the stack.
+        addq.l  #2*4,%sp
+
+        | Get a pointer to the location following the exception context.
+        find_original_sp %d0
+                                            
+        | Restore all of the registers that we do not need in the following
+        | code. We will copy all registers that are not restored here
+        | to the new stack before restoring them.
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+        restore_mac_registers %d0
+#endif
+        
+        movem.l CYGARC_CFREG_D2(%sp),%d2-%d7
+        movem.l CYGARC_CFREG_A1(%sp),%a1-%a6
+                                            
+        | Load the address of the new SP.
+        move.l  CYGARC_CFREG_SP(%sp),%d1
+                                            
+        | We now have:
+        | d0.l : original stack pointer
+        | d1.l : final stack pointer
+
+        | ColdFire programmer's manual doesn't tell if rte instruction expects
+        | the stack frame to be aligned at 32-bit boundaries.
+        | So, we align the new stack value, and adjust the format field
+        | accordingly. At the end of rte instruction the stack will thus point
+        | to the desired location.
+
+        | Compare the new stack address to the end of the exception context.
+        | This will tell us the order that we need to copy the exception
+        | stack and the remaining registers from the old exception context to
+        | the new one. The order is important because the stack frames might
+        | overlap.
+        cmp.l   %d0,%d1
+
+        | If the new SP and the old one coincide.
+        beq     2f
+
+        | If the new SP is at a higher address than the old one. 
+        bgt     1f
+                                            
+        | The new SP is at a lower address than the old one. Copy from the
+        | lowest address to the highest address.
+
+        | Align stack at longword boundary
+        move.l  %d1,%d0
+        and.l   #0xfffffffc,%d0
+        move.l  %d0,%a0
+
+        | Allocate new frame
+        sub.l   #CYGARC_CF_CONTEXT_SIZE,%a0
+
+        | Copy D0, D1, A0, FVW, SR, and PC from the old stack to the new stack.
+        | Note that we copy in ascending order.
+
+        | Copy D0, D1, A0
+        move.l  CYGARC_CFREG_D0(%sp),CYGARC_CFREG_D0(%a0)
+        move.l  CYGARC_CFREG_D1(%sp),CYGARC_CFREG_D1(%a0)
+        move.l  CYGARC_CFREG_A0(%sp),CYGARC_CFREG_A0(%a0)
+        
+        | Based on target SP address, construct new format field
+        and.l   #0x00000003,%d1
+        or.l    #0x4,%d1
+        lsl.l   #8,%d1
+        lsl.l   #4,%d1
+
+        | Load old format field
+        move.w  CYGARC_CF_FMTVECWORD(%sp),%d0
+
+        | Clear old format field
+        and.l   #0x0fff,%d0
+
+        | Write the new one
+        or.l    %d1,%d0
+        move.w  %d0,CYGARC_CF_FMTVECWORD(%a0)
+
+        | Copy SR and PC
+        move.w  CYGARC_CF_SR(%sp),CYGARC_CF_SR(%a0)
+        move.l  CYGARC_CFREG_PC(%sp),CYGARC_CFREG_PC(%a0)
+
+        | A0 points to the top of the new stack
+        move.l  %a0,%sp
+
+        | Restore remaining registers and exit
+        jmp 2f
+
+1:
+
+        | The new SP is at a higher address than the old one. Copy from the
+        | highest address to the lowest address.
+        
+        | Align stack at longword boundary
+        move.l  %d1,%d0
+        and.l   #0xfffffffc,%d0
+        move.l  %d0,%a0
+        
+        | Allocate new frame
+        sub.l   #CYGARC_CF_CONTEXT_SIZE,%a0
+
+        | Copy D0, D1, A0, FVW, SR, and PC from the old stack to the new stack.
+        | Note that we copy in descending order.
+
+        | Copy PC and SR
+        move.l  CYGARC_CFREG_PC(%sp),CYGARC_CFREG_PC(%a0)
+        move.w  CYGARC_CF_SR(%sp),CYGARC_CF_SR(%a0)
+
+        | Based on target SP address, construct new format field
+        and.l   #0x00000003,%d1
+        or.l    #0x4,%d1
+        lsl.l   #8,%d1
+        lsl.l   #4,%d1
+
+        | Load old format field
+        move.w  CYGARC_CF_FMTVECWORD(%sp),%d0
+
+        | Clear old format field
+        and.l   #0x0fff,%d0
+
+        | Write the new one
+        or.l    %d1,%d0
+        move.w  %d0,CYGARC_CF_FMTVECWORD(%a0)
+
+        | Copy A0, D1, D0
+        move.l  CYGARC_CFREG_A0(%sp),CYGARC_CFREG_A0(%a0)
+        move.l  CYGARC_CFREG_D1(%sp),CYGARC_CFREG_D1(%a0)
+        move.l  CYGARC_CFREG_D0(%sp),CYGARC_CFREG_D0(%a0)
+
+        | A0 points to the top of the new stack
+        move.l  %a0,%sp
+
+2:
+        | Restore remaining registers
+        move.l  CYGARC_CFREG_D0(%sp),%d0
+        move.l  CYGARC_CFREG_D1(%sp),%d1
+        move.l  CYGARC_CFREG_A0(%sp),%a0
+        add.l   #CYGARC_CF_EXCEPTION_DECREMENT,%sp
+        
+        | Return from exception
+        rte
+
+
+| ----------------------------------------------------------------------------
+| Spurious interrupt vector handler
+|
+| Used for spurious and uninitialized interrupts.
+| It is unknown at which priority spurious interrupts are generated. So, the
+| safest thing to do is to disable all interrupts while processing spurious
+| ones.
+
+        .text
+        .balign 4
+        .globl cyg_hal_default_spurious_vsr
+cyg_hal_default_spurious_vsr:
+
+#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS
+
+        | Disable all interrupts. On the first instruction, interrupt sampling
+        | is always disabled.
+        hal_cpu_int_disable
+
+        | Preserve all registers that this handler needs to preserve.
+        | The C code will preserve all other registers.
+        int_pres_regs
+
+        | Pass a pointer to the saved state to the interrupt handler.
+        pea.l   (%sp)
+        
+        | Call spurious interrupt handler
+        .extern hal_spurious_interrupt
+        jsr hal_spurious_interrupt
+
+        | Remove the arguments from the stack.
+        addq.l  #4,%sp
+
+        | Restore the preserved registers for the current thread.        
+        int_rest_regs
+
+#endif /* ifndef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS */
+        
+        | Just return from interrupt.
+        rte
+
+
+| ----------------------------------------------------------------------------
+| User interrupt vector handler
+|
+| Control is transferred here from a user interrupt vector (#64-255).
+| Before branching to common code, load a value to translate the
+| vector table offset to the ISR table offset.
+
+        .text
+        .balign 4
+        .globl cyg_hal_default_interrupt_vsr
+cyg_hal_default_interrupt_vsr:
+
+        | Disable all interrupts. On the first instruction, interrupt sampling
+        | is always disabled.
+        hal_cpu_int_disable
+
+        | Preserve all registers that this handler needs to preserve.
+        | The C code will preserve all other registers.
+        int_pres_regs
+
+        | It is safe to use breakpoints below this point.
+        .globl _cyg_hal_default_interrupt_vsr_bp_safe
+_cyg_hal_default_interrupt_vsr_bp_safe:
+        
+        | Adding this value to the vector table offset will result in the
+        | corresponding offset into the ISR table.
+        move.l #(-CYGNUM_HAL_ISR_MIN)*4,%d2
+
+        | d2.l: Contains a value to translate the vector table offset to
+        | the ISR table offset.
+
+        | Calculate the vector offset. The format/vector word on the stack
+        | contains the vector number. Mask off all unused bits. The bit
+        | position of the vector number field makes it automatically multiplied
+        | by four.
+        move.w  CYGARC_CF_FMTVECWORD(%sp),%d1
+        and.l   #0x000003fc,%d1
+
+        | Calculate the ISR table offset. Add the vector table offset to the
+        | translation value.
+        add.l   %d1,%d2
+
+        | Calculate the vector number using the vector table offset.
+        asr.l   #2,%d1
+
+        | d2.l: Contains the offset into the ISR table.
+        | d1.l: Contains the vector number.
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
+    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
+
+        | If we are supporting Ctrl-C interrupts from GDB, we must squirrel
+        | away a pointer to the saved interrupt state here so that we can
+        | plant a breakpoint at some later time.
+
+        .extern hal_saved_interrupt_state
+        move.l %sp,(hal_saved_interrupt_state)
+
+#endif
+
+#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
+
+        | Lock the scheduler if we are using the kernel.
+        .extern cyg_scheduler_sched_lock
+        addq.l  #1,cyg_scheduler_sched_lock
+
+#endif /* CYGFUN_HAL_COMMON_KERNEL_SUPPORT */
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+        
+        | a0 = sp. We'll need it later
+        move.l %sp,%a0
+
+        cmp.l #__interrupt_stack_base,%sp
+        
+        | If sp < base : not on istack
+        blt 1f
+        
+        cmp.l #__interrupt_stack,%sp
+        
+        | If sp <= top : already on istack
+        ble 2f
+
+1:
+        | Switch to istack
+        lea __interrupt_stack,%sp
+
+2:
+        | Save old SP on istack
+        pea (%a0)
+
+#endif
+
+#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
+
+        .extern cyg_instrument
+
+        | Save d1
+        move.l %d1,-(%sp)
+
+        | arg2 = 0
+        move.l #0,-(%sp)
+
+        | arg1 = vector number
+        move.l %d1,-(%sp)
+
+        | type = INTR,RAISE
+        move.l #0x0301,-(%sp)
+
+        | Call instrumentation
+        jsr cyg_instrument
+
+        | Remove args from stack
+        add.l #12,%sp
+
+        | Restore %d1
+        move.l (%sp)+,%d1
+
+#endif
+
+
+#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
+
+        | If interrupt nesting is enabled, we have to determine the IPL of the
+        | current interrupt. We inline the following macro, which is defined
+        | by ColdFire variants. The vector number of the current interrupt
+        | is passed in d0, and the return value is in d0.
+        | Registers a0-a1/d0-d1 are for use by the macro, other registers
+        | must be saved explicitly before being used.
+
+        | Save %d1
+        move.l %d1,-(%sp)
+
+        | Pass d1 as argument to macro
+        move.l %d1,%d0
+
+        | Retrieve IPL, which will be contained in d0
+        hal_variant_retrieve_ipl
+
+        | Shift IPL up to the same position occupied in sr
+        lsl.l #8,%d0
+
+        | Transform d0 in a mask to be applied to sr
+        or.l #0xfffff0ff,%d0
+
+        | Update sr. Use d1 as working register
+        move.w %sr,%d1
+        and.l %d0,%d1
+        move.w %d1,%sr
+
+        | Restore d1
+        move.l (%sp)+,%d1
+
+#endif
+
+        | We need to call the following routines. The isr address, data, and
+        | intr are all from the ISR table. The interrupt_end routine is
+        | only called if we are using the kernel. regs points to the saved
+        | registers on the stack. isr_ret is the return value from the ISR.
+        | vector is the vector number.
+
+        | static cyg_uint32 isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+
+        | externC void interrupt_end(cyg_uint32 isr_ret, Cyg_Interrupt *intr,
+        |     HAL_SavedRegisters  *regs)
+
+
+        | Push the data value from the table.
+        .extern cyg_hal_interrupt_data
+        lea     cyg_hal_interrupt_data,%a0
+        move.l  (%a0,%d2.l),-(%sp)
+
+        | Get the address of the ISR from the table.
+        .extern cyg_hal_interrupt_handlers
+        lea     cyg_hal_interrupt_handlers,%a0
+        move.l  (%a0,%d2.l),%a0
+
+        | Push the vector number parameter.
+        move.l  %d1,-(%sp)
+
+        | Call the ISR.
+        jsr   (%a0)
+
+        | Remove the isr parameters from the stack.
+        addq.l  #4*2,%sp
+                                            
+        | d0.l now contains the return value from the ISR.
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+        | If we are returning from the last nested interrupt, move back
+        | to the thread stack. interrupt_end() must be called on the
+        | thread stack since it potentially causes a context switch.
+        | Since we have arranged for the top of stack location to
+        | contain the sp we need to go back to here, just pop it off
+        | and put it in SP.
+
+        move.l (%sp),%sp                           | sp = *sp
+        
+#endif
+
+#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
+
+        | We only need to call interrupt_end() when there is a kernel
+        | present to do any tidying up. To keep the following code simple,
+        | we enable all interrupts before calling DSRs only if a common
+        | interrupt stack is in use.
+
+        | Push the regs pointer.
+        pea     (%sp)
+
+        | Push the intr object pointer from the table.        
+        .extern cyg_hal_interrupt_objects
+        lea     cyg_hal_interrupt_objects,%a0
+        move.l  (%a0,%d2.l),-(%sp)
+
+        | Push ISR return value
+        move.l %d0,-(%sp)
+
+        | Even when this is not the last nested interrupt, we must call
+        | interrupt_end() to post the DSR and decrement the scheduler
+        | lock.
+
+        | Call the interrupt_end C routine.
+        .extern interrupt_end
+        jsr    interrupt_end
+
+        | Remove the isr_ret, intr, and regs parameters from the stack.
+        lea     (4*3)(%sp),%sp
+                                            
+#endif /* ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT */
+
+        | Restore the preserved registers for the current thread.        
+        int_rest_regs
+
+        | Restore the SR and PC.
+        rte
+
+
+| ----------------------------------------------------------------------------
+| Execute pending DSRs on the interrupt stack with interrupts enabled.
+| Note: this can only be called from code running on a thread stack
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+        .extern cyg_interrupt_call_pending_DSRs
+
+FUNC_START(hal_interrupt_stack_call_pending_DSRs)
+        | Change to interrupt stack, save state and set up stack for
+        | calls to C code.
+        | By virtue of GNU C calling conventions, we are free to use registers
+        | %d0-%d1 and %a0-%a1 without saving them.
+
+        | a0 = sp
+        move.l %sp, %a0
+
+        | Switch to istack
+        lea __interrupt_stack,%sp
+
+        | Save old SP on istack
+        pea (%a0)
+
+        | Save sr
+        move.w %sr,%d0
+        move.l %d0,-(%sp)
+
+        | Enable interrupts
+        hal_cpu_int_enable %d0
+        
+        | Call into kernel which will execute DSRs
+        jsr cyg_interrupt_call_pending_DSRs
+
+        move.l (%sp)+,%d0
+
+        | Restore previous interrupt state
+        hal_cpu_int_merge %d0,%d1
+
+        | Restore sp
+        move.l (%sp),%sp
+
+        | return to caller
+        rts
+
+#endif
+
+
+| ----------------------------------------------------------------------------
+| Interrupt and reset stack
+|
+| WARNING: Do not put this in any memory section that gets initialized.
+| Doing so may cause the C code to initialize its own stack.
+
+        .section ".uninvar","aw",@nobits
+
+        .balign 16
+        .global cyg_interrupt_stack_base
+cyg_interrupt_stack_base:
+__interrupt_stack_base:
+        .skip   CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
+        .balign 16
+        .global cyg_interrupt_stack
+cyg_interrupt_stack:
+__interrupt_stack:
+        .skip   0x10
+
diff --git a/packages/hal/coldfire/m5272c3/v2_0/ChangeLog b/packages/hal/coldfire/m5272c3/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..3a39b6c
--- /dev/null
@@ -0,0 +1,53 @@
+2006-05-09  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * include/pkgconf/mlt_coldfire_m5272c3_*.h: Added CYGMEM_REGION_RAM* 
+       so that the test cases compile.
+
+2005-06-24  Enrico Piria  <epiriaNOSPAM@NOSPAMfastwebnet.it>
+
+       * src/plf_mk_defs.c:
+       * src/plf_startup.c:
+       * include/hal_memmap.h:
+       * include/platform.inc:
+       * include/plf_intr.h:
+       * include/plf_serial.h:
+       * include/plf_startup.h:
+       * include/plf_stub.h:
+       * include/pkgconf/mlt_coldfire_m5272c3_ram.h:
+       * include/pkgconf/mlt_coldfire_m5272c3_ram.ldi:
+       * include/pkgconf/mlt_coldfire_m5272c3_rom.h:
+       * include/pkgconf/mlt_coldfire_m5272c3_rom.ldi:
+       * cdl/hal_coldfire_m5272c3.cdl:
+       Rework of the original M5272C3 platform HAL contributed by Wade Jensen.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/coldfire/m5272c3/v2_0/cdl/hal_coldfire_m5272c3.cdl b/packages/hal/coldfire/m5272c3/v2_0/cdl/hal_coldfire_m5272c3.cdl
new file mode 100644 (file)
index 0000000..5d6e9f6
--- /dev/null
@@ -0,0 +1,358 @@
+# ====================================================================
+#
+#      hal_coldfire_m5272c3.cdl
+#
+#      Freescale M5272C3 evaluation board HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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
+## Contributors:  Wade Jensen
+## Date:          2005-25-06
+##
+######DESCRIPTIONEND####
+##========================================================================
+
+cdl_package CYGPKG_HAL_COLDFIRE_M5272C3 {
+    display         "Freescale M5272C3 evaluation board"
+    parent          CYGPKG_HAL_COLDFIRE_MCF5272
+    define_header   hal_coldfire_m5272c3.h
+    include_dir     cyg/hal
+
+    description   "The Freescale M5272C3 evaluation board platform HAL
+                package should be used when targeting the actual hardware for
+                the Freescale M5272C3 evaluation board platform."
+
+    compile     plf_startup.c
+
+    implements      CYGINT_HAL_DEBUG_GDB_STUBS
+    implements      CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+    implements      CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+
+
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_coldfire.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H  <pkgconf/hal_coldfire_mcf5272.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_coldfire_m5272c3.h>"
+        puts $::cdl_system_header "#define HAL_PLATFORM_BOARD    \"Freescale M5272C3\""
+        puts $::cdl_system_header "#define HAL_PLATFORM_EXTRA    \"\""
+    }
+
+    # The "-o file" is a workaround for CR100958 - without it the
+    # output file would end up in the source directory under CygWin.
+    # n.b. grep does not behave itself under win32
+    make -priority 1 {
+        <PREFIX>/include/cyg/hal/plf_offsets.inc : <PACKAGE>/src/plf_mk_defs.c
+        $(CC) $(ACTUAL_CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_offsets.tmp -o plf_mk_defs.tmp -S $<
+        fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
+        @echo $@ ": \\" > $(notdir $@).deps
+        @tail -n +2 plf_offsets.tmp >> $(notdir $@).deps
+        @echo >> $(notdir $@).deps
+        @rm plf_offsets.tmp plf_mk_defs.tmp
+    }
+
+    cdl_component CYG_HAL_STARTUP {
+        display         "Startup type"
+        flavor          data
+        legal_values    {"RAM" "ROM" "ROMRAM"}
+        default_value   {"RAM"}
+        no_define
+        define -file system.h CYG_HAL_STARTUP
+
+        description "
+           This option is used to control where the application program will
+           run, either from RAM or ROM (flash) memory. ROM based applications
+           must be self contained, while RAM applications will typically assume
+           the existence of a debug environment, such as GDB stubs.
+           ROMRAM bootstrap is similar to ROM bootstrap, but everything
+           is copied to RAM before execution starts, thus improving performace,
+           but at the cost of an increased RAM footprint."
+    }
+    
+    cdl_option CYGHWR_HAL_ROM_LMA {
+       display          "Load address for ROM image"
+       active_if        { CYG_HAL_STARTUP == "ROM" || CYG_HAL_STARTUP == "ROMRAM" }
+       flavor           data
+       legal_values     0xFFE00000 0xFFF00000
+       default_value    0xFFF00000
+
+       description    "This option lets you decide in which half of flash
+                    memory to download the ROM image. As a safety measure,
+                    the default is to use the upper half (starting at
+                    0xFFF00000), thus preserving the ROM monitor shipped with
+                    the board. This option is meaningful only when ROM or
+                    ROMRAM startup is choosed."
+    }
+    
+    cdl_option CYGHWR_HAL_SYSTEM_CLOCK_MHZ {
+       display          "System clock speed in MHz"
+       flavor           data
+       legal_values     66 48
+       default_value    66
+
+       description    "This option identifies the system clock that the
+                    processor uses. This value is used to set clock dividers
+                    for some devices."
+    }
+
+    cdl_option CYGHWR_EXT_SRAM_INSTALLED {
+       display          "External 512Kb SRAM module"
+       flavor           bool
+       default_value    0
+
+       description    "If this option is enabled, chip-select module 2 is
+           configured to access the optional external 512Kb SRAM module."
+    }
+
+    cdl_option CYGHWR_INSTALLED_SDRAM_SIZE {
+       display          "Megabytes of SDRAM installed"
+       flavor           data
+       legal_values     16 4
+       default_value    16
+
+       description    "This option selects the size of the SDRAM installed.
+            Note that the linker scripts have been written for a board with
+            16 Mb of RAM. If you modify this option, you will have to change
+            them by hand."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+       display          "Number of communication channels on the board"
+       flavor           data
+       calculated       2
+       description      "
+            Port 0 is the terminal serial port; port 1 is the auxiliary
+            serial port."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+       display          "Debug serial port"
+       active_if        CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+       flavor data
+       legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+       default_value    0
+       description      "
+           This option chooses which port will be used to connect to a host
+           via the GDB remote protocol."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+        display       "Debug serial port baud rate"
+        active_if     CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+        flavor        data
+        legal_values  9600 19200 38400 57600 115200
+        default_value 19200
+        description   "
+            This option controls the baud rate used for the GDB connection."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+        display          "Diagnostic serial port"
+        active_if        CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+        flavor data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    0
+        description      "
+           This option chooses which port will be used for diagnostic output."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+       display          "Diagnostic serial port baud rate"
+       active_if        CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+       flavor           data
+       legal_values     9600 19200 38400 57600 115200
+       default_value    19200
+
+       description    "This option selects the baud rate used for the
+                    diagnostic port. Note: this should match the value chosen
+                    for the GDB port if the diagnostic and GDB port are the
+                    same."
+    }
+
+    # Real-time clock/counter specifics
+    cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+        display       "Real-time clock constants."
+        flavor        none
+
+        description   "Set the periodic timer on the MCF5272 to 10 ms or
+                    10000000 ns."
+
+        cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+            display       "Real-time clock numerator"
+            flavor        data
+            default_value 1000000000
+        }
+        cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+            display       "Real-time clock denominator"
+            flavor        data
+            default_value 100
+        }
+        cdl_option CYGNUM_HAL_RTC_PERIOD {
+            display       "Real-time clock period"
+            flavor        data
+            default_value 4125
+            description   "
+                The default value is calculated as: 
+                10 ms / ((1 / (66 MHz)) * 16 * 10)."
+        }
+    }
+
+    cdl_component CYGBLD_GLOBAL_OPTIONS {
+        display "Global build options"
+        flavor  none
+        parent  CYGPKG_NONE
+
+        description   "Global build options including control over compiler
+                    flags, linker flags and choice of toolchain."
+
+        cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+            display "Global command prefix"
+            flavor  data
+            no_define
+            default_value { "m68k-elf" }
+
+            description       "This option specifies the command prefix used
+                            when invoking the build tools."
+        }
+
+        cdl_option CYGBLD_GLOBAL_CFLAGS {
+            display "Global compiler flags"
+            flavor  data
+            no_define
+            default_value { "-m5206e -malign-int -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -finit-priority" }
+            description       "This option controls the global compiler flags
+                            which are used to compile all packages by default.
+                            Individual packages may define options which
+                            override these global flags."
+        }
+
+        cdl_option CYGBLD_GLOBAL_LDFLAGS {
+            display "Global linker flags"
+            flavor  data
+            no_define
+            default_value { "-m5206e -g -nostdlib -Wl,--gc-sections -Wl,-static" }
+
+            description       "This option controls the global linker flags.
+                            Individual packages may define options which
+                            override these global flags."
+        }
+
+        cdl_option CYGBLD_BUILD_GDB_STUBS {
+            display "Build GDB stub ROM image"
+            default_value 0
+            requires { CYG_HAL_STARTUP == "ROM" || CYG_HAL_STARTUP == "ROMRAM" }
+            requires CYGSEM_HAL_ROM_MONITOR
+            requires CYGBLD_BUILD_COMMON_GDB_STUBS
+            requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+            requires CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+            requires CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+            requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+            requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+            no_define
+
+            description       "This option enables the building of the GDB
+                            stubs for the board. The common HAL controls
+                            take care of most of the build process, but the
+                            final conversion from ELF image to binary data is
+                            handled by the platform CDL, allowing relocation
+                            of the data if necessary."
+
+            make -priority 320 {
+                <PREFIX>/bin/gdb_module.srec : <PREFIX>/bin/gdb_module.img
+                $(OBJCOPY) -S -O srec $< $@
+            }
+        }
+    }
+
+    cdl_component CYGHWR_MEMORY_LAYOUT {
+        display "Memory layout"
+        flavor data
+        no_define
+        calculated { (CYG_HAL_STARTUP == "RAM") ? "coldfire_m5272c3_ram" : \
+                     (CYG_HAL_STARTUP == "ROMRAM") ? "coldfire_m5272c3_romram" : \
+                                            "coldfire_m5272c3_rom" }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+            display "Memory layout linker script fragment"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+            calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_coldfire_m5272c3_ram.ldi>" : \
+                         (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_coldfire_m5272c3_romram.ldi>" : \
+                                                    "<pkgconf/mlt_coldfire_m5272c3_rom.ldi>" }
+        }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_H {
+            display "Memory layout header file"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_H
+            calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_coldfire_m5272c3_ram.h>" : \
+                         (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_coldfire_m5272c3_romram.h>" : \
+                                                    "<pkgconf/mlt_coldfire_m5272c3_rom.h>" }
+        }
+    }
+
+    cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+        display       "Work with a ROM monitor"
+        flavor        booldata
+        legal_values  { "GDB_stubs" }
+        default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+        requires      { CYG_HAL_STARTUP == "RAM" }
+        parent        CYGPKG_HAL_ROM_MONITOR
+
+        description       "Support can be enabled for boot ROMs or ROM
+                        monitors which contain GDB stubs. This support
+                        changes various eCos semantics such as the encoding of
+                        diagnostic output, and the overriding of hardware
+                        interrupt vectors."
+    }
+
+    cdl_option CYGSEM_HAL_ROM_MONITOR {
+        display       "Behave as a ROM monitor"
+        flavor        bool
+        default_value 0
+        parent        CYGPKG_HAL_ROM_MONITOR
+        requires      { CYG_HAL_STARTUP == "ROM" || CYG_HAL_STARTUP == "ROMRAM" }
+
+        description       "Enable this option if this program is to be used as
+                        a ROM monitor, i.e. applications will be loaded into
+                        RAM on the board, and this ROM monitor may process
+                        exceptions or interrupts generated from the
+                        application. This enables features such as utilizing
+                        a separate interrupt stack when exceptions are
+                        generated."
+    }
+}
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/hal_memmap.h b/packages/hal/coldfire/m5272c3/v2_0/include/hal_memmap.h
new file mode 100644 (file)
index 0000000..e959eea
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef CYGONCE_HAL_MEMMAP_H
+#define CYGONCE_HAL_MEMMAP_H
+
+//=============================================================================
+//
+//      hal_memmap.h
+//
+//      Platform specific memory section definitions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:  Wade Jensen
+// Date:          2005-25-06
+// Purpose:       Memory section definitions specific to the M5272C3 board
+// Usage:         Included via CYGHWR_MEMORY_LAYOUT_H
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+// WARNING: DO NOT CHANGE THE TYPE OF THESE LABELS. THE LINKER DEFINES
+// THESE AND WE WANT TO USE THE VARIABLE ADDRESSES NOT THE VARIABLES
+// THEMSELVES.
+
+#define SECTION_DEC(_name_) \
+    externC unsigned char __ ## _name_ ## _start[]; \
+    externC unsigned char __ ## _name_ ## _end[]; \
+    externC unsigned char __ ## _name_ ## _size[];
+
+SECTION_DEC(bss)
+SECTION_DEC(ram_data)
+SECTION_DEC(rom_data)
+SECTION_DEC(uninvar)
+SECTION_DEC(romvec)
+SECTION_DEC(ramvec)
+
+// ---------------------------------------------------------------------------
+// End of hal_memmap.h
+#endif // CYGONCE_HAL_MEMMAP_H
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_ram.h b/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_ram.h
new file mode 100644 (file)
index 0000000..3a5de18
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef CYGONCE_MLT_COLDFIRE_RAM_H
+#define CYGONCE_MLT_COLDFIRE_RAM_H
+
+//=============================================================================
+//
+//      mlt_coldfire_m5272c3_ram.h
+//
+//      Platform specific memory section definitions for RAM startup
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Memory section definitions specific to the M5272C3 board,
+//                used for RAM startup configuration.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+// eCos memory layout
+
+#include <cyg/hal/hal_memmap.h>
+
+#define CYGMEM_REGION_sdram (0x00000000)
+#define CYGMEM_REGION_sdram_SIZE (0x01000000)
+
+#define CYGMEM_REGION_devs (0x10000000)
+#define CYGMEM_REGION_devs_SIZE (0x00001800)
+
+#define CYGMEM_REGION_sram (0x20000000)
+#define CYGMEM_REGION_sram_SIZE (0x00001000)
+
+#define CYGMEM_REGION_ext_sram (0x30000000)
+#define CYGMEM_REGION_ext_sram_SIZE (0x00080000)
+
+#define CYGMEM_REGION_flash (0xFFE00000)
+#define CYGMEM_REGION_flash_SIZE (0x00200000)
+
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x01000000 - (size_t) CYG_LABEL_NAME (__heap1))
+externC unsigned char CYG_LABEL_NAME (__heap1) [];
+
+// These symbols are required by the test cases. Normally the memory tool would generate them,
+// but this file was been generated by hand and so is a little
+// different to normal.
+#define CYGMEM_REGION_ram       CYGMEM_REGION_sdram
+#define CYGMEM_REGION_ram_SIZE  CYGMEM_REGION_sdram_SIZE
+
+// ---------------------------------------------------------------------------
+// End of mlt_coldfire_m5272c3_ram.h
+#endif // CYGONCE_MLT_COLDFIRE_RAM_H
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_ram.ldi b/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_ram.ldi
new file mode 100644 (file)
index 0000000..2f8ac67
--- /dev/null
@@ -0,0 +1,85 @@
+//===========================================================================
+//
+//      mlt_coldfire_m5272c3_ram.ldi
+//
+//      RAM startup linker control script
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:  Wade Jensen
+// Date:          2005-25-06
+// Purpose:       Linker script specific to the M5272C3 board, used for
+//                RAM startup.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.inc>
+
+MEMORY
+{
+    sdram           : ORIGIN = 0x00000000, LENGTH = 0x01000000
+    devs            : ORIGIN = 0x10000000, LENGTH = 0x00001800
+    sram            : ORIGIN = 0x20000000, LENGTH = 0x00001000
+    ext_sram        : ORIGIN = 0x30000000, LENGTH = 0x00080000
+    flash           : ORIGIN = 0xFFE00000, LENGTH = 0x00200000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+
+    SECTION_ramvec              (sdram, 0x00000000 (NOLOAD), LMA_EQ_VMA)
+    SECTION_virtual_vec_table   (sdram, ALIGN(0x4) (NOLOAD), LMA_EQ_VMA)
+
+    // Reserve some space to the ROM monitor
+    SECTION_romvec              (sdram, 0x00020000, LMA_EQ_VMA)
+    SECTION_boot                (sdram, ALIGN(0x4), LMA_EQ_VMA)
+    SECTION_text                (sdram, ALIGN(0x4), LMA_EQ_VMA)
+    SECTION_fini                (sdram, ALIGN(0x4), LMA_EQ_VMA)
+    SECTION_rodata1             (sdram, ALIGN(0x4), LMA_EQ_VMA)
+    SECTION_rodata              (sdram, ALIGN(0x4), LMA_EQ_VMA)
+    SECTION_fixup               (sdram, ALIGN(0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table    (sdram, ALIGN(0x4), LMA_EQ_VMA)
+    SECTION_data                (sdram, ALIGN(0x4), LMA_EQ_VMA)
+    SECTION_bss                 (sdram, ALIGN(0x4) (NOLOAD), LMA_EQ_VMA)
+    SECTION_uninvar             (sdram, ALIGN(0x4) (NOLOAD), LMA_EQ_VMA)
+
+    // The heap starts here.
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x4);
+
+    SECTIONS_END
+}
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_rom.h b/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_rom.h
new file mode 100644 (file)
index 0000000..5adc7d8
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef CYGONCE_MLT_COLDFIRE_ROM_H
+#define CYGONCE_MLT_COLDFIRE_ROM_H
+
+//=============================================================================
+//
+//      mlt_coldfire_m5272c3_rom.h
+//
+//      Platform specific memory section definitions for ROM startup
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Memory section definitions specific to the M5272C3 board,
+//                used for ROM startup configuration.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+// eCos memory layout
+
+#include <cyg/hal/hal_memmap.h>
+
+#define CYGMEM_REGION_sdram (0x00000000)
+#define CYGMEM_REGION_sdram_SIZE (0x01000000)
+
+#define CYGMEM_REGION_devs (0x10000000)
+#define CYGMEM_REGION_devs_SIZE (0x00001800)
+
+#define CYGMEM_REGION_sram (0x20000000)
+#define CYGMEM_REGION_sram_SIZE (0x00001000)
+
+#define CYGMEM_REGION_ext_sram (0x30000000)
+#define CYGMEM_REGION_ext_sram_SIZE (0x00080000)
+
+#define CYGMEM_REGION_flash (0xFFE00000)
+#define CYGMEM_REGION_flash_SIZE (0x00200000)
+
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x01000000 - (size_t) CYG_LABEL_NAME (__heap1))
+externC unsigned char CYG_LABEL_NAME (__heap1) [];
+
+// These symbols are required by the test cases. Normally the memory tool would generate them,
+// but this file was been generated by hand and so is a little
+// different to normal.
+#define CYGMEM_REGION_ram       CYGMEM_REGION_sdram
+#define CYGMEM_REGION_ram_SIZE  CYGMEM_REGION_sdram_SIZE
+
+// ---------------------------------------------------------------------------
+// End of mlt_coldfire_m5272c3_rom.h
+#endif // CYGONCE_MLT_COLDFIRE_ROM_H
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_rom.ldi b/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_rom.ldi
new file mode 100644 (file)
index 0000000..3f32d96
--- /dev/null
@@ -0,0 +1,94 @@
+//===========================================================================
+//
+//      mlt_coldfire_m5272c3_rom.ldi
+//
+//      ROM startup linker control script
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:  Wade Jensen
+// Date:          2005-25-06
+// Purpose:       Linker script specific to the M5272C3 board, used for
+//                ROM startup.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.inc>
+#include CYGBLD_HAL_PLATFORM_H
+
+MEMORY
+{
+    sdram           : ORIGIN = 0x00000000, LENGTH = 0x01000000
+    devs            : ORIGIN = 0x10000000, LENGTH = 0x00001800
+    sram            : ORIGIN = 0x20000000, LENGTH = 0x00001000
+    ext_sram        : ORIGIN = 0x30000000, LENGTH = 0x00080000
+    flash           : ORIGIN = 0xFFE00000, LENGTH = 0x00200000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+
+#if (CYGHWR_HAL_ROM_LMA == 0xFFF00000)
+    SECTION_romvec              (flash, 0xFFF00000, LMA_EQ_VMA)
+#else
+    SECTION_romvec              (flash, 0xFFE00000, LMA_EQ_VMA)
+#endif
+
+    SECTION_boot                (flash, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_text                (flash, ALIGN (0x4),LMA_EQ_VMA)
+    SECTION_fini                (flash, ALIGN (0x4),LMA_EQ_VMA)
+    SECTION_rodata1             (flash, ALIGN (0x4),LMA_EQ_VMA)
+    SECTION_rodata              (flash, ALIGN (0x4),LMA_EQ_VMA)
+    SECTION_fixup               (flash, ALIGN (0x4),LMA_EQ_VMA)
+    SECTION_gcc_except_table    (flash, ALIGN (0x4),LMA_EQ_VMA)
+
+    SECTION_ramvec              (sdram, 0x00000000 (NOLOAD), LMA_EQ_VMA)
+    SECTION_virtual_vec_table   (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+    SECTION_data                (sdram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss                 (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+    SECTION_uninvar             (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+
+    // The heap starts here.
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x4);
+
+    CYG_LABEL_DEFN(__romram_copy_source) = LOADADDR(.data);
+    CYG_LABEL_DEFN(__romram_copy_dest) = ADDR(.data);
+    CYG_LABEL_DEFN(__romram_copy_length) = SIZEOF(.data);
+
+    SECTIONS_END
+}
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_romram.h b/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_romram.h
new file mode 100644 (file)
index 0000000..11ab83f
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef CYGONCE_MLT_COLDFIRE_ROMRAM_H
+#define CYGONCE_MLT_COLDFIRE_ROMRAM_H
+
+//=============================================================================
+//
+//      mlt_coldfire_m5272c3_romram.h
+//
+//      Platform specific memory section definitions for ROMRAM startup
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Memory section definitions specific to the M5272C3 board,
+//                used for ROMRAM startup configuration.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+// eCos memory layout
+
+#include <cyg/hal/hal_memmap.h>
+
+#define CYGMEM_REGION_sdram (0x00000000)
+#define CYGMEM_REGION_sdram_SIZE (0x01000000)
+
+#define CYGMEM_REGION_devs (0x10000000)
+#define CYGMEM_REGION_devs_SIZE (0x00001800)
+
+#define CYGMEM_REGION_sram (0x20000000)
+#define CYGMEM_REGION_sram_SIZE (0x00001000)
+
+#define CYGMEM_REGION_ext_sram (0x30000000)
+#define CYGMEM_REGION_ext_sram_SIZE (0x00080000)
+
+#define CYGMEM_REGION_flash (0xFFE00000)
+#define CYGMEM_REGION_flash_SIZE (0x00200000)
+
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x01000000 - (size_t) CYG_LABEL_NAME (__heap1))
+externC unsigned char CYG_LABEL_NAME (__heap1) [];
+
+// These symbols are required by the test cases. Normally the memory tool would generate them,
+// but this file was been generated by hand and so is a little
+// different to normal.
+#define CYGMEM_REGION_ram       CYGMEM_REGION_sdram
+#define CYGMEM_REGION_ram_SIZE  CYGMEM_REGION_sdram_SIZE
+
+// ---------------------------------------------------------------------------
+// End of mlt_coldfire_m5272c3_romram.h
+#endif // CYGONCE_MLT_COLDFIRE_ROMRAM_H
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_romram.ldi b/packages/hal/coldfire/m5272c3/v2_0/include/pkgconf/mlt_coldfire_m5272c3_romram.ldi
new file mode 100644 (file)
index 0000000..33791b2
--- /dev/null
@@ -0,0 +1,95 @@
+//===========================================================================
+//
+//      mlt_coldfire_m5272c3_romram.ldi
+//
+//      ROMRAM startup linker control script
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:  Wade Jensen
+// Date:          2005-25-06
+// Purpose:       Linker script specific to the M5272C3 board, used for
+//                ROMRAM startup.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.inc>
+#include CYGBLD_HAL_PLATFORM_H
+
+MEMORY
+{
+    sdram           : ORIGIN = 0x00000000, LENGTH = 0x01000000
+    devs            : ORIGIN = 0x10000000, LENGTH = 0x00001800
+    sram            : ORIGIN = 0x20000000, LENGTH = 0x00001000
+    ext_sram        : ORIGIN = 0x30000000, LENGTH = 0x00080000
+    flash           : ORIGIN = 0xFFE00000, LENGTH = 0x00200000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+
+#if (CYGHWR_HAL_ROM_LMA == 0xFFF00000)
+    SECTION_romvec              (flash, 0xFFF00000, LMA_EQ_VMA)
+#else
+    SECTION_romvec              (flash, 0xFFE00000, LMA_EQ_VMA)
+#endif
+    
+    SECTION_boot                (flash, ALIGN(0x4), FOLLOWING(.romvec))
+
+    SECTION_ramvec              (sdram, 0x00000000 (NOLOAD), LMA_EQ_VMA)
+    SECTION_virtual_vec_table   (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+    
+    SECTION_text                (sdram, ALIGN (0x4),FOLLOWING(.boot))
+    SECTION_fini                (sdram, ALIGN (0x4),FOLLOWING(.text))
+    SECTION_rodata1             (sdram, ALIGN (0x4),FOLLOWING(.fini))
+    SECTION_rodata              (sdram, ALIGN (0x4),FOLLOWING(.rodata1))
+    SECTION_fixup               (sdram, ALIGN (0x4),FOLLOWING(.rodata))
+    SECTION_gcc_except_table    (sdram, ALIGN (0x4),FOLLOWING(.fixup))
+    SECTION_data                (sdram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss                 (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+    SECTION_uninvar             (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+
+    // The heap starts here.
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x4);
+
+    CYG_LABEL_DEFN(__romram_copy_source) = LOADADDR(.text);
+    CYG_LABEL_DEFN(__romram_copy_dest) = ADDR(.text);
+    CYG_LABEL_DEFN(__romram_copy_length) = SIZEOF(.text) + SIZEOF(.fini) + SIZEOF(.rodata1) + SIZEOF(.rodata) + SIZEOF(.fixup) + SIZEOF(.gcc_except_table) + SIZEOF(.data);
+
+    SECTIONS_END
+}
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/platform.inc b/packages/hal/coldfire/m5272c3/v2_0/include/platform.inc
new file mode 100644 (file)
index 0000000..518a18e
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef CYGONCE_HAL_PLATFORM_INC
+#define CYGONCE_HAL_PLATFORM_INC
+
+|=============================================================================
+|
+|  platform.inc
+|
+|  M5272C3 board assembler header file
+|
+|=============================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| eCos is free software; you can redistribute it and/or modify it under
+| the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2 or (at your option) any later version.
+|
+| eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+| WARRANTY; without even the implied warranty of MERCHANTABILITY or
+| FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+| for more details.
+|
+| You should have received a copy of the GNU General Public License along
+| with eCos; if not, write to the Free Software Foundation, Inc.,
+| 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+|
+| As a special exception, if other files instantiate templates or use macros
+| or inline functions from this file, or you compile this file and link it
+| with other works to produce a work based on this file, this file does not
+| by itself cause the resulting work to be covered by the GNU General Public
+| License. However the source code for this file must still be made available
+| in accordance with section (3) of the GNU General Public License.
+|
+| This exception does not 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
+| Contributors:
+| Date:          2005-25-06
+| Purpose:       Assembler macro definitions specific to the M5272C3 board.
+| Usage:         Included by "variant.inc". Do not use directly.
+|
+|####DESCRIPTIONEND####
+|========================================================================
+
+#include <cyg/hal/plf_offsets.inc>
+
+|-------------------------------------------------------------------------------
+| Platform initialization macros
+
+        .macro hal_hardware_init
+        | Initialize RAMBAR: locate SRAM and validate it.
+        move.l  #CYGMEM_REGION_sram,%d0
+        add.l   #0x21,%d0
+        movec   %d0,%rambar0
+        .endm
+
+
+        | Setup stack for startup routines. Use SRAM module.
+        .macro hal_boot_stack_init
+        | Point Stack Pointer into SRAM temporarily. 
+        move.l   #CYGMEM_REGION_sram,%d0
+        add.l    #CYGMEM_REGION_sram_SIZE,%d0
+        move.l   %d0,%sp
+        .endm
+
+|-----------------------------------------------------------------------------
+| End of platform.inc
+#endif // CYGONCE_HAL_PLATFORM_INC
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/plf_intr.h b/packages/hal/coldfire/m5272c3/v2_0/include/plf_intr.h
new file mode 100644 (file)
index 0000000..f3174f7
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef CYGONCE_HAL_PLF_INTR_H
+#define CYGONCE_HAL_PLF_INTR_H
+
+//==========================================================================
+//
+//      plf_intr.h
+//
+//      Platform specific interrupt and clock support
+//
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:  Wade Jensen
+// Date:          2005-25-06
+// Purpose:       Interrupt and clock definitions specific to the M5272C3 board.
+// Usage:         Included via "var_intr.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+// ---------------------------------------------------------------------------
+// Reset
+
+#ifndef CYGHWR_HAL_RESET_DEFINED
+
+externC void cyg_hal_reset_vsr( void );
+
+#define CYGHWR_HAL_RESET_DEFINED
+#define HAL_PLATFORM_RESET() cyg_hal_reset_vsr()
+
+#define HAL_PLATFORM_RESET_ENTRY &cyg_hal_reset_vsr
+
+#endif // CYGHWR_HAL_RESET_DEFINED
+
+// ---------------------------------------------------------------------------
+// End of plf_intr.h
+#endif // CYGONCE_HAL_PLF_INTR_H
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/plf_serial.h b/packages/hal/coldfire/m5272c3/v2_0/include/plf_serial.h
new file mode 100644 (file)
index 0000000..7448f80
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef CYGONCE_PLF_SERIAL_H
+#define CYGONCE_PLF_SERIAL_H
+
+//=============================================================================
+//
+//      plf_serial.h
+//
+//      Platform specific definitions for diagnstic ouput via serial port
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Definitions for diagnostic output via serial port
+// Usage:         #include <cyg/hal/plf_serial.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#define MCF5272_UART_UMR_8BNP       (0x13)
+#define MCF5272_UART_UMR_1S         (0x07)
+
+#define MCF5272_UART_USR_RRDY       (1<<0)
+#define MCF5272_UART_USR_FFUL       (1<<1)
+#define MCF5272_UART_USR_TXRDY      (1<<2)
+#define MCF5272_UART_USR_TXEMP      (1<<3)
+#define MCF5272_UART_USR_OE         (1<<4)
+#define MCF5272_UART_USR_PE         (1<<5)
+#define MCF5272_UART_USR_FE         (1<<6)
+#define MCF5272_UART_USR_RB         (1<<7)
+
+#define MCF5272_UART_UCSR_CLKIN     (0xDD)
+
+#define MCF5272_UART_UCR_RMR        (0x01<<4)
+#define MCF5272_UART_UCR_RRX        (0x02<<4)
+#define MCF5272_UART_UCR_RTX        (0x03<<4)
+#define MCF5272_UART_UCR_RES        (0x04<<4)
+#define MCF5272_UART_UCR_RBC        (0x05<<4)
+#define MCF5272_UART_UCR_TXEN       (1<<2)
+#define MCF5272_UART_UCR_TXDE       (1<<3)
+#define MCF5272_UART_UCR_RXEN       (1<<0)
+#define MCF5272_UART_UCR_RXDE       (1<<1)
+
+#define MCF5272_UART_UCR_TXRXEN     \
+        (MCF5272_UART_UCR_TXEN |    \
+         MCF5272_UART_UCR_RXEN)
+        
+#define MCF5272_UART_UIMR_FFULL     (0x02)
+        
+#define MCF5272_UART_UTF_TXB        (0x1F)
+
+#define MCF5272_UART_UOP0_RTS       (0x01)
+#define MCF5272_UART_UOP1_RTS       (0x01)
+
+#define MCF5272_GPIO_PBCNT_URT0_EN      (0x00000155)
+#define MCF5272_GPIO_PBCNT_URT0_DE      (0x00000000)
+#define MCF5272_GPIO_PBCNT_URT0_MSK     (0x000003FF)
+
+#define MCF5272_GPIO_PDCNT_URT1_EN      (0x000002AA)
+#define MCF5272_GPIO_PDCNT_URT1_DE      (0x00000000)
+#define MCF5272_GPIO_PDCNT_URT1_MSK     (0x000003FF)
+
+// ---------------------------------------------------------------------------
+// End of plf_serial.h
+#endif // CYGONCE_PLF_SERIAL_H
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/plf_startup.h b/packages/hal/coldfire/m5272c3/v2_0/include/plf_startup.h
new file mode 100644 (file)
index 0000000..7558517
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef CYGONCE_PLF_STARTUP_H
+#define CYGONCE_PLF_STARTUP_H
+
+//=============================================================================
+//
+//      plf_startup.h
+//
+//      M5272C3 platform startup header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:         2005-25-06
+// Purpose:      M5272C3 platform startup header.
+// Usage:        Included via "var_startup.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// Platform specific reset vector initialization routine
+externC void plf_reset(void) __attribute__ ((section (".boot")));
+
+// Platform specific data initialization routine
+externC void plf_init_data(void) __attribute__ ((section (".boot")));
+
+// ---------------------------------------------------------------------------
+// End of plf_startup.h
+#endif // CYGONCE_PLF_STARTUP_H
diff --git a/packages/hal/coldfire/m5272c3/v2_0/include/plf_stub.h b/packages/hal/coldfire/m5272c3/v2_0/include/plf_stub.h
new file mode 100644 (file)
index 0000000..bdbfad5
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef CYGONCE_HAL_PLF_STUB_H
+#define CYGONCE_HAL_PLF_STUB_H
+
+//========================================================================
+//
+//      plf_stub.h
+//
+//      Platform specific definitions for generic stub
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       GDB stub definitions specific to the M5272C3 board.
+// Usage:         #include <cyg/hal/plf_stub.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h>         // CYG_UNUSED_PARAM
+
+#include <cyg/hal/coldfire_stub.h>      // architecture stub support
+
+
+externC void cyg_hal_plf_comms_init(void);
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL()       cyg_hal_plf_comms_init()
+
+#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int,(baud))
+#define HAL_STUB_PLATFORM_INTERRUPTIBLE       0
+#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ()    CYG_EMPTY_STATEMENT
+
+// ---------------------------------------------------------------------------
+// Stub initializer
+
+#define HAL_STUB_PLATFORM_INIT()              CYG_EMPTY_STATEMENT
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+// ---------------------------------------------------------------------------
+// End of plf_stub.h
+#endif // CYGONCE_HAL_PLF_STUB_H
diff --git a/packages/hal/coldfire/m5272c3/v2_0/src/plf_mk_defs.c b/packages/hal/coldfire/m5272c3/v2_0/src/plf_mk_defs.c
new file mode 100644 (file)
index 0000000..0689ac0
--- /dev/null
@@ -0,0 +1,85 @@
+//==========================================================================
+//
+//      plf_mk_defs.c
+//
+//      "make defs" program for M5272C3 platform
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors: gthomas, jskov
+// Date:         2005-25-06
+// Purpose:      Definition generator for M5272C3 board.
+// Description:  This file contains code that can be compiled by the target
+//               compiler and used to generate machine specific definitions
+//               suitable for use in assembly code.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include CYGHWR_MEMORY_LAYOUT_H     
+
+// This program is used to generate definitions needed by
+// assembly language modules.
+//
+// This technique was first used in the OSF Mach kernel code:
+// generate asm statements containing #defines,
+// compile this file to assembler, and then extract the
+// #defines from the assembly-language output.
+
+#define DEFINE(sym, val) \
+        asm volatile("\n\t.equ\t" #sym ",%0" : : "i" (val))
+
+int
+main(void)
+{
+    // Memory layout values
+    DEFINE(CYGMEM_REGION_sdram, CYGMEM_REGION_sdram);
+    DEFINE(CYGMEM_REGION_sdram_SIZE, CYGMEM_REGION_sdram_SIZE);
+    DEFINE(CYGMEM_REGION_devs, CYGMEM_REGION_devs);
+    DEFINE(CYGMEM_REGION_devs_SIZE, CYGMEM_REGION_devs_SIZE);
+    DEFINE(CYGMEM_REGION_sram, CYGMEM_REGION_sram);
+    DEFINE(CYGMEM_REGION_sram_SIZE, CYGMEM_REGION_sram_SIZE);
+    DEFINE(CYGMEM_REGION_flash, CYGMEM_REGION_flash);
+    DEFINE(CYGMEM_REGION_flash_SIZE, CYGMEM_REGION_flash_SIZE);
+    
+    return 0;
+}
+
+// -------------------------------------------------------------------------
+// EOF hal_mk_defs.c
diff --git a/packages/hal/coldfire/m5272c3/v2_0/src/plf_startup.c b/packages/hal/coldfire/m5272c3/v2_0/src/plf_startup.c
new file mode 100644 (file)
index 0000000..d3e72e1
--- /dev/null
@@ -0,0 +1,255 @@
+//==========================================================================
+//
+//      plf_startup.c
+//
+//      M5272C3 platform HAL startup code
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Platform startup code.
+// Description:   This module contains code that sets up the platform specific
+//                hardware and data. All the code must be contained in the
+//                section called ".boot", in order for the ROMRAM startup
+//                to work properly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_startup.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/coldfire_regs.h>
+
+static void plf_init_sim(void) __attribute__ ((section (".boot")));
+static void plf_init_intc(void) __attribute__ ((section (".boot")));
+static void plf_init_cs(void) __attribute__ ((section (".boot")));
+static void plf_init_sdramc(void) __attribute__ ((section (".boot")));
+static void plf_init_cache_acr(void) __attribute__ ((section (".boot")));
+
+
+// Platform-specific reset vector initialization routine
+void plf_reset(void)
+{
+    plf_init_sim();
+    plf_init_intc();
+    plf_init_cs();
+    plf_init_sdramc();
+
+    // Call a routine to set  up  the  cache  and  ACRs  for  this  specific
+    // platform.
+    plf_init_cache_acr();
+}
+
+
+// Initialize the cache and access control registers.
+// The reset procedure already invalidated the cache and ACRs.
+// This routine only needs to enable the ACRs that it will use.
+static void plf_init_cache_acr(void)
+{
+    // Enable the instruction cache with the following options:
+    // Enable CPUSHL invalidation.
+    // No freeze.
+    // Invalidate all cache lines (flush).
+    // No external arbiter control.
+    // Disable non-cacheable instruction bursting.
+    // Default memory is cacheable.
+    // Enable buffered writes.
+    // Read and write access permitted by default.
+    // Instruction fetch size is cache line.
+
+#ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
+    CYGARC_MOVEC((CYG_WORD32) 0x81000102, CYGARC_REG_CACR);
+#endif
+
+    // Leave the access control registers disabled.
+}
+
+
+// Initialize SIM module and system configuration registers
+void plf_init_sim(void)
+{
+    // Set up the mapping of our internal registers.  The LSB indicates that
+    // the register contents are valid.
+    CYGARC_MOVEC((CYG_WORD32)(CYGMEM_REGION_devs | 1), CYGARC_REG_MBAR);
+    
+    // Initialize System Config Register
+    // Setup Watch Dog Timeout
+    HAL_WRITE_UINT16(&MCF5272_DEVS->cfg.scr, MCF5272_SIM_SCR_HWWD_1024);
+        
+    // Initialize System Protection Register
+    // Enable all bus error exceptions
+    HAL_WRITE_UINT16(&MCF5272_DEVS->cfg.spr,
+        (0 | MCF5272_SIM_SPR_ADC | MCF5272_SIM_SPR_ADCEN
+        | MCF5272_SIM_SPR_WPV | MCF5272_SIM_SPR_WPVEN
+        | MCF5272_SIM_SPR_SMV | MCF5272_SIM_SPR_SMVEN
+        | MCF5272_SIM_SPR_SBE | MCF5272_SIM_SPR_SBEEN
+        | MCF5272_SIM_SPR_HWT | MCF5272_SIM_SPR_HWTEN
+        | MCF5272_SIM_SPR_RPV | MCF5272_SIM_SPR_RPVEN
+        | MCF5272_SIM_SPR_EXT | MCF5272_SIM_SPR_EXTEN
+        | MCF5272_SIM_SPR_SUV | MCF5272_SIM_SPR_SUVEN
+        )) ;
+}
+
+
+// Initialize interrupt controller
+void plf_init_intc(void)
+{
+    int i;
+
+    // Initialize the vector base register in the interrupt controller.
+    HAL_WRITE_UINT8(&MCF5272_DEVS->intc.ipvr, HAL_PROG_INT_VEC_BASE);
+
+    // Initialize the  interrupt  control  register.
+    // Disable all interrupts by setting all priorities to zero.
+    for (i = 0; i < 4; i++)
+    {
+        HAL_WRITE_UINT32(&MCF5272_DEVS->intc.icr[i], 0x88888888);
+    }
+
+    // Initialize the processor's vector base register (align to 1M boundary).
+    CYGARC_MOVEC((CYG_WORD32) __ramvec_start & 0xFFF00000, CYGARC_REG_VBR);
+}
+
+
+// Initialize chip-select modules
+void plf_init_cs(void)
+{
+    // ChipSelect 0 - 2MB FLASH
+    // At startup, CS0 is configured so that addresses starting at 0xXXX00000
+    // are aliased to 0x00000000, so, in ROM startup configuration, code can
+    // be placed starting at VMA address 0xFFE00000. When we are here,
+    // the PC points to addresses in 0xFFE00000 space, and we can safely
+    // reconfigure CS0 to respond uniquely to those addresses.
+    HAL_WRITE_UINT32(&MCF5272_DEVS->cs[0].csbr, (0
+        | MCF5272_CS_BR_BASE(CYGMEM_REGION_flash)
+        | MCF5272_CS_BR_SRAM
+        | MCF5272_CS_BR_PS_16
+        | MCF5272_CS_BR_EN));    
+
+    HAL_WRITE_UINT32(&MCF5272_DEVS->cs[0].csor,
+        (0 | MCF5272_CS_OR_MASK_2M
+        | MCF5272_CS_OR_WS(5)));
+
+#ifdef CYGHWR_EXT_SRAM_INSTALLED
+    // Chip Select 2 - 512KB SRAM
+    HAL_WRITE_UINT32(&MCF5272_DEVS->cs[2].csbr, (0
+        | MCF5272_CS_BR_BASE(CYGMEM_REGION_ext_sram)
+        | MCF5272_CS_BR_SRAM
+        | MCF5272_CS_BR_PS_32
+        | MCF5272_CS_BR_EN));
+
+    HAL_WRITE_UINT32(&MCF5272_DEVS->cs[2].csor, (0
+        | MCF5272_CS_OR_MASK_512K
+        | MCF5272_CS_OR_WS(0)));
+#endif // CYGHWR_EXT_SRAM_INSTALLED
+
+    // ChipSelect 7 - 16MB SDRAM
+    HAL_WRITE_UINT32(&MCF5272_DEVS->cs[7].csbr, (0
+        | MCF5272_CS_BR_BASE(CYGMEM_REGION_sdram)
+        | MCF5272_CS_BR_SDRAM 
+        | MCF5272_CS_BR_PS_LINE 
+        | MCF5272_CS_BR_EN));
+
+    HAL_WRITE_UINT32(&MCF5272_DEVS->cs[7].csor, (0
+#if (CYGHWR_INSTALLED_SDRAM_SIZE == 4)
+        | MCF5272_CS_OR_MASK_4M
+#else
+        | MCF5272_CS_OR_MASK_16M
+#endif
+        | MCF5272_CS_OR_WS(0x1F)));
+}
+
+
+// Initialize SDRAM controller
+void plf_init_sdramc(void)
+{
+    cyg_uint16 sdcr;
+
+    
+    HAL_READ_UINT16(&MCF5272_DEVS->sdramc.sdcr, sdcr);
+    
+    // Do not initialize SDRAM if it is already active
+    if (!(sdcr & MCF5272_SDRAMC_SDCCR_ACT))
+    {
+#if (CYGHWR_HAL_SYSTEM_CLOCK_MHZ == 66)
+        HAL_WRITE_UINT16(&MCF5272_DEVS->sdramc.sdtr, (0
+            | MCF5272_SDRAMC_SDCTR_RTP_66MHz
+            | MCF5272_SDRAMC_SDCTR_RC(0)
+            | MCF5272_SDRAMC_SDCTR_RP(1)
+            | MCF5272_SDRAMC_SDCTR_RCD(1)
+            | MCF5272_SDRAMC_SDCTR_CLT_2));
+#else
+        // Clock frequency must be 48 Mhz
+        HAL_WRITE_UINT16(&MCF5272_DEVS->sdramc.sdtr, (0
+            | MCF5272_SDRAMC_SDCTR_RTP_48MHz
+            | MCF5272_SDRAMC_SDCTR_RC(0)
+            | MCF5272_SDRAMC_SDCTR_RP(1)
+            | MCF5272_SDRAMC_SDCTR_RCD(0)
+            | MCF5272_SDRAMC_SDCTR_CLT_2));
+#endif
+
+        HAL_WRITE_UINT16(&MCF5272_DEVS->sdramc.sdcr, (0
+            | MCF5272_SDRAMC_SDCCR_MCAS_A9
+#if (CYGHWR_INSTALLED_SDRAM_SIZE == 4)
+            | MCF5272_SDRAMC_SDCCR_BALOC_A21
+#else
+            | MCF5272_SDRAMC_SDCCR_BALOC_A22
+#endif
+            | MCF5272_SDRAMC_SDCCR_REG
+            | MCF5272_SDRAMC_SDCCR_INIT));
+
+        // Start SDRAM controller with a memory write
+        *((volatile char *) CYGMEM_REGION_sdram) = 0;
+
+        // Wait until controller is ready
+        do
+        {
+            HAL_READ_UINT16(&MCF5272_DEVS->sdramc.sdcr, sdcr);
+        } while(!(sdcr & MCF5272_SDRAMC_SDCCR_ACT));
+    }
+}
+
+
+// Platform specific data initialization routine
+void plf_init_data(void)
+{
+    // Nothing to do
+}
diff --git a/packages/hal/coldfire/mcf5272/v2_0/ChangeLog b/packages/hal/coldfire/mcf5272/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..854a1ca
--- /dev/null
@@ -0,0 +1,49 @@
+2005-06-24  Enrico Piria  <epiriaNOSPAM@NOSPAMfastwebnet.it>
+
+       * src/var_misc.c:
+       * src/var_startup.c:
+       * src/hal_diag.c:
+       * src/variant.S:
+       * include/hal_diag.h:
+       * include/mcf5272_devs.h:
+       * include/var_arch.h:
+       * include/var_basetype.h:
+       * include/var_cache.h:
+       * include/var_intr.h:
+       * include/var_regs.h:
+       * include/var_startup.h:
+       * include/variant.inc:
+       * cdl/hal_coldfire_mcf5272.cdl:
+       Rework of the original MCF5272 variant HAL contributed by Wade Jensen.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/coldfire/mcf5272/v2_0/cdl/hal_coldfire_mcf5272.cdl b/packages/hal/coldfire/mcf5272/v2_0/cdl/hal_coldfire_mcf5272.cdl
new file mode 100644 (file)
index 0000000..ef513c5
--- /dev/null
@@ -0,0 +1,94 @@
+# ====================================================================
+#
+#      hal_coldfire_mcf5272.cdl
+#
+#      MCF5272 variant architectural HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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
+## Contributors:  Wade Jensen
+## Date:          2005-25-06
+##
+######DESCRIPTIONEND####
+##========================================================================
+
+cdl_package CYGPKG_HAL_COLDFIRE_MCF5272 {
+    display     "MCF5272 ColdFire variant HAL"
+    parent      CYGPKG_HAL_COLDFIRE
+    requires    CYGPKG_HAL_COLDFIRE
+    implements  CYGINT_HAL_COLDFIRE_VARIANT
+    implements  CYGARC_HAL_COLDFIRE_V2_CORE
+    implements  CYGARC_HAL_COLDFIRE_MAC
+    implements  CYGARC_HAL_COLDFIRE_ISA_A
+    hardware
+    include_dir   cyg/hal
+    define_header hal_coldfire_mcf5272.h
+
+    description   "The ColdFire 5272 variant HAL  package  provides
+                generic support for the ColdFire 5272 processor.  It is  also
+                necessary to select a specific target platform HAL package."
+
+    define_proc {
+        puts $::cdl_header "#include <pkgconf/hal_coldfire.h>"
+    }
+
+    compile     var_startup.c var_misc.c variant.S
+
+    cdl_option CYGHWR_HAL_COLDFIRE_MAC {
+        display       "MAC support"
+        flavor        bool
+        default_value 0
+        description "
+            Enable or disable support for MAC operations. MAC registers will be
+            saved during context switches, during exceptions, and in the
+            setjmp/longjmp routines. If you don't use the MAC unit, you can
+            leave this option disabled."
+    }
+
+    # With this calculated option, code for diagnostic/debug output is compiled
+    # only if it is really needed.
+    cdl_option CYGBLD_HAL_COLDFIRE_MCF5272_DIAG {
+        display     "Compile HAL diagnostic output code"
+        flavor      bool
+        no_define
+        calculated  { is_active(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL) ||
+                    is_active(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL) }
+        compile     hal_diag.c
+        description "
+            This calculated option is enabled only when code for
+            diagnostic/debug output is really needed."
+    }
+}
diff --git a/packages/hal/coldfire/mcf5272/v2_0/include/hal_diag.h b/packages/hal/coldfire/mcf5272/v2_0/include/hal_diag.h
new file mode 100644 (file)
index 0000000..b718371
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef CYGONCE_HAL_HAL_DIAG_H
+#define CYGONCE_HAL_HAL_DIAG_H
+
+//=============================================================================
+//
+//      hal_diag.h
+//
+//      HAL support for kernel diagnostic routines
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Provide ColdFire-specific diagnostic system definitions.
+// Usage:         #include <cyg/hal/hal_diag.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+// We suppose that CYGSEM_HAL_VIRTUAL_VECTOR_DIAG is always defined
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+// ---------------------------------------------------------------------------
+// End of hal_diag.h
+#endif // CYGONCE_HAL_HAL_DIAG_H
diff --git a/packages/hal/coldfire/mcf5272/v2_0/include/mcf5272_devs.h b/packages/hal/coldfire/mcf5272/v2_0/include/mcf5272_devs.h
new file mode 100644 (file)
index 0000000..c78a7bb
--- /dev/null
@@ -0,0 +1,708 @@
+#ifndef CYGONCE_MCF5272_DEVS_H
+#define CYGONCE_MCF5272_DEVS_H
+
+//=============================================================================
+//
+//      mcf5272_devs.h
+//
+//      Definitions for the MCF5272 on-chip peripherals
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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-25-06
+// Purpose:       Definitions for the MCF5272 on-chip peripherals.
+// Usage:         #include <cyg/hal/mcf5272_devs.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+// General configuration registers
+typedef struct
+{
+
+    // Module base  address  register
+    cyg_uint32 mbar;
+
+    // System configuration register
+    cyg_uint16 scr;
+
+    // System protection register
+    cyg_uint16 spr;
+    
+    // Power management register
+    cyg_uint32 pmr;
+
+    // Gap
+    cyg_uint16 _res1;
+
+    // Active low power register
+    cyg_uint16 alpr;
+
+    // Device identification register
+    cyg_uint32 dir;
+
+    // Gap
+    cyg_uint32 _res2[3];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_cfg_t;
+
+// Configuration registers macros
+
+#define MCF5272_SIM_SCR_HWWD_1024   0x0003
+
+#define MCF5272_SIM_SPR_ADC         0x8000
+#define MCF5272_SIM_SPR_ADCEN       0x0080
+#define MCF5272_SIM_SPR_WPV         0x4000
+#define MCF5272_SIM_SPR_WPVEN       0x0040
+#define MCF5272_SIM_SPR_SMV         0x2000
+#define MCF5272_SIM_SPR_SMVEN       0x0020
+#define MCF5272_SIM_SPR_SBE         0x1000
+#define MCF5272_SIM_SPR_SBEEN       0x0010
+#define MCF5272_SIM_SPR_HWT         0x0800
+#define MCF5272_SIM_SPR_HWTEN       0x0008
+#define MCF5272_SIM_SPR_RPV         0x0400
+#define MCF5272_SIM_SPR_RPVEN       0x0004
+#define MCF5272_SIM_SPR_EXT         0x0200
+#define MCF5272_SIM_SPR_EXTEN       0x0002
+#define MCF5272_SIM_SPR_SUV         0x0100
+#define MCF5272_SIM_SPR_SUVEN       0x0001
+
+// ---------------------------------------------------------------------------
+
+// Interrupt controller registers
+typedef struct
+{
+
+    // Interrupt control register 1-4
+    cyg_uint32 icr[4];
+
+    // Interrupt source register
+    cyg_uint32 isr;
+
+    // Programmable interrupt transition register
+    cyg_uint32 pitr;
+
+    // Programmable interrupt wakeup register
+    cyg_uint32 piwr;
+
+    // Gap
+    cyg_uint8  _res1[3];
+
+    // Programmable interrupt vector register
+    cyg_uint8  ipvr;
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_int_t;
+
+// Interrupt controller related macros
+
+#define MCF5272_SIM_PITR_INT1_POS_EDGE         (0x80000000)
+#define MCF5272_SIM_PITR_INT2_POS_EDGE         (0x40000000)
+#define MCF5272_SIM_PITR_INT3_POS_EDGE         (0x20000000)
+#define MCF5272_SIM_PITR_INT4_POS_EDGE         (0x10000000)
+#define MCF5272_SIM_PITR_INT5_POS_EDGE         (0x00000040)
+#define MCF5272_SIM_PITR_INT6_POS_EDGE         (0x00000020)
+
+#define MCF5272_SIM_PIWR_INT1_WAKE             (0x80000000)
+#define MCF5272_SIM_PIWR_INT2_WAKE             (0x40000000)
+#define MCF5272_SIM_PIWR_INT3_WAKE             (0x20000000)
+#define MCF5272_SIM_PIWR_INT4_WAKE             (0x10000000)
+#define MCF5272_SIM_PIWR_TMR0_WAKE             (0x08000000)
+#define MCF5272_SIM_PIWR_TMR1_WAKE             (0x04000000)
+#define MCF5272_SIM_PIWR_TMR2_WAKE             (0x02000000)
+#define MCF5272_SIM_PIWR_TMR3_WAKE             (0x01000000)
+#define MCF5272_SIM_PIWR_UART1_WAKE            (0x00800000)
+#define MCF5272_SIM_PIWR_UART2_WAKE            (0x00400000)
+#define MCF5272_SIM_PIWR_PLIP_WAKE             (0x00200000)
+#define MCF5272_SIM_PIWR_PLIA_WAKE             (0x00100000)
+#define MCF5272_SIM_PIWR_USB0_WAKE             (0x00080000)
+#define MCF5272_SIM_PIWR_USB1_WAKE             (0x00040000)
+#define MCF5272_SIM_PIWR_USB2_WAKE             (0x00020000)
+#define MCF5272_SIM_PIWR_USB3_WAKE             (0x00010000)
+#define MCF5272_SIM_PIWR_USB4_WAKE             (0x00008000)
+#define MCF5272_SIM_PIWR_USB5_WAKE             (0x00004000)
+#define MCF5272_SIM_PIWR_USB6_WAKE             (0x00002000)
+#define MCF5272_SIM_PIWR_USB7_WAKE             (0x00001000)
+#define MCF5272_SIM_PIWR_DMA_WAKE              (0x00000800)
+#define MCF5272_SIM_PIWR_ERX_WAKE              (0x00000400)
+#define MCF5272_SIM_PIWR_ETX_WAKE              (0x00000200)
+#define MCF5272_SIM_PIWR_ENTC_WAKE             (0x00000100)
+#define MCF5272_SIM_PIWR_QSPI_WAKE             (0x00000080)
+#define MCF5272_SIM_PIWR_INT5_WAKE             (0x00000040)
+#define MCF5272_SIM_PIWR_INT6_WAKE             (0x00000020)
+#define MCF5272_SIM_PIWR_SWTO_WAKE             (0x00000010)
+
+// ---------------------------------------------------------------------------
+
+// Chip-select module
+typedef struct
+{
+
+    // CS base register
+    cyg_uint32 csbr;
+
+    // CS option register
+    cyg_uint32 csor;
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_cs_t;
+
+// Chip-select modules related macros
+
+#define MCF5272_CS_BR_BASE(a)           ((a) & 0xFFFFF000)
+
+#define MCF5272_CS_OR_MASK_128M         (0xF8000000)
+#define MCF5272_CS_OR_MASK_64M          (0xFC000000)
+#define MCF5272_CS_OR_MASK_32M          (0xFE000000)
+#define MCF5272_CS_OR_MASK_16M          (0xFF000000)
+#define MCF5272_CS_OR_MASK_8M           (0xFF800000)
+#define MCF5272_CS_OR_MASK_4M           (0xFFC00000)
+#define MCF5272_CS_OR_MASK_2M           (0xFFE00000)
+#define MCF5272_CS_OR_MASK_1M           (0xFFF00000)
+#define MCF5272_CS_OR_MASK_512K         (0xFFF80000)
+#define MCF5272_CS_OR_MASK_256K         (0xFFFC0000)
+#define MCF5272_CS_OR_MASK_128K         (0xFFFE0000)
+#define MCF5272_CS_OR_MASK_64K          (0xFFFF0000)
+#define MCF5272_CS_OR_MASK_32K          (0xFFFF8000)
+#define MCF5272_CS_OR_MASK_16K          (0xFFFFC000)
+#define MCF5272_CS_OR_MASK_8K           (0xFFFFE000)
+#define MCF5272_CS_OR_MASK_4K           (0xFFFFF000)
+#define MCF5272_CS_OR_WS_MASK           (0x007C)
+#define MCF5272_CS_OR_WS(a)             (((a) & 0x1F) << 2)
+#define MCF5272_CS_OR_BRST              (0x0100)
+#define MCF5272_CS_OR_WR_ONLY           (0x0003)
+#define MCF5272_CS_OR_RD_ONLY           (0x0001)
+
+#define MCF5272_CS_BR_PS_8              (0x0100)
+#define MCF5272_CS_BR_PS_16             (0x0200)
+#define MCF5272_CS_BR_PS_32             (0x0000)
+#define MCF5272_CS_BR_PS_LINE           (0x0300)
+#define MCF5272_CS_BR_ROM               (0x0000)
+#define MCF5272_CS_BR_SRAM              (0x0000)
+#define MCF5272_CS_BR_SRAM_8            (0x0C00)
+#define MCF5272_CS_BR_SDRAM             (0x0400)
+#define MCF5272_CS_BR_ISA               (0x0800)
+#define MCF5272_CS_BR_SV                (0x0080)
+#define MCF5272_CS_BR_EN                (0x0001)
+
+// ---------------------------------------------------------------------------
+
+// General purpose I/O module
+typedef struct
+{
+
+    // Port A control register
+    cyg_uint32 pacnt;
+
+    // Port A data direction register
+    cyg_uint16 paddr;
+
+    // Port A data register
+    cyg_uint16 padat;
+
+    // Port B control register
+    cyg_uint32 pbcnt;
+
+    // Port B data direction register
+    cyg_uint16 pbddr;
+
+    // Port B data register
+    cyg_uint16 pbdat;
+
+    // Gap
+    cyg_uint32 _res1;
+
+    // Port C data direction register
+    cyg_uint16 pcddr;
+
+    // Port C data register
+    cyg_uint16 pcdat;
+
+    // Port D control register
+    cyg_uint32 pdcnt;
+
+    // Gap
+    cyg_uint16 _res2;
+    cyg_uint16 _res3;
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_gpio_t;
+
+// GPIO ports related macros
+
+#define MCF5272_GPIO_DDR_IN         (0)
+#define MCF5272_GPIO_DDR_OUT        (1)
+
+#define MCF5272_GPIO_PBCNT_ETH_EN   (0x55550000)
+#define MCF5272_GPIO_PBCNT_ETH_DE   (0x00000000)
+#define MCF5272_GPIO_PBCNT_ETH_MSK  (0xFFFF0000)
+
+#define MCF5272_GPIO_PBCNT_TA_EN    (0x00000400)
+#define MCF5272_GPIO_PBCNT_TA_DE    (0x00000000)
+#define MCF5272_GPIO_PBCNT_TA_MSK   (0x00000C00)
+
+#define MCF5272_GPIO_PBCNT_URT0_EN  (0x00000155)
+#define MCF5272_GPIO_PBCNT_URT0_DE  (0x00000000)
+#define MCF5272_GPIO_PBCNT_URT0_MSK (0x000003FF)
+
+#define MCF5272_GPIO_PDCNT_INT4_EN  (0x00000C00)
+#define MCF5272_GPIO_PDCNT_INT4_DE  (0x00000000)
+#define MCF5272_GPIO_PDCNT_INT4_MSK (0x00000C00)
+
+#define MCF5272_GPIO_PDCNT_URT1_EN  (0x000002AA)
+#define MCF5272_GPIO_PDCNT_URT1_DE  (0x00000000)
+#define MCF5272_GPIO_PDCNT_URT1_MSK (0x000003FF)
+
+// ---------------------------------------------------------------------------
+
+// UART module
+typedef struct
+{
+
+    // UART mode register
+    cyg_uint8 umr;
+
+    // Gap
+    cyg_uint8 _res1[3];
+
+    // UART status register (R) and clock-select register (W)
+    cyg_uint8 usr_ucsr;
+
+    // Gap
+    cyg_uint8 _res2[3];
+
+    // UART command register
+    cyg_uint8 ucr;
+
+    // Gap
+    cyg_uint8 _res3[3];
+
+    // UART receiver buffers (R) and transmitter buffers (W)
+    cyg_uint8 urb_utb;
+
+    // Gap
+    cyg_uint8 _res4[3];
+
+    // UART input port change register (R) and auxiliary control register (W)
+    cyg_uint8 uipcr_uacr;
+
+    // Gap
+    cyg_uint8 _res5[3];
+
+    // UART interrupt status register (R) and interrupt mask register (W)
+    cyg_uint8 uisr_uimr;
+
+    // Gap
+    cyg_uint8 _res6[3];
+
+    // UART divider upper register
+    cyg_uint8 udu;
+
+    // Gap
+    cyg_uint8 _res7[3];
+
+    // UART divider lower register
+    cyg_uint8 udl;
+
+    // Gap
+    cyg_uint8 _res8[3];
+
+    // UART autobaud register MSB
+    cyg_uint8 uabu;
+
+    // Gap
+    cyg_uint8 _res9[3];
+
+    // UART autobaud register LSB
+    cyg_uint8 uabl;
+
+    // Gap
+    cyg_uint8 _res10[3];
+
+    // UART transmitter FIFO register
+    cyg_uint8 utf;
+
+    // Gap
+    cyg_uint8 _res11[3];
+
+    // UART receiver FIFO register
+    cyg_uint8 urf;
+
+    // Gap
+    cyg_uint8 _res12[3];
+
+    // UART fractional precision divider register
+    cyg_uint8 ufpd;
+
+    // Gap
+    cyg_uint8 _res13[3];
+
+    // UART input port register
+    cyg_uint8 uip;
+
+    // Gap
+    cyg_uint8 _res14[3];
+
+    // UART output port register 1
+    cyg_uint8 uop1;
+
+    // Gap
+    cyg_uint8 _res15[3];
+
+    // UART output port register 0
+    cyg_uint8 uop0;
+
+    // Gap
+    cyg_uint8 _res16[3];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_uart_t;
+
+// ---------------------------------------------------------------------------
+
+// SDRAM controller
+typedef struct
+{
+
+    // Gap
+    cyg_uint8   _res1[2];
+
+    // SDRAM configuration register
+    cyg_uint16  sdcr;
+
+    // Gap
+    cyg_uint8   _res2[2];
+
+    // SDRAM timing register
+    cyg_uint16  sdtr;
+
+    // Gap
+    cyg_uint8   _res3[120];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_sdramctrl_t;
+
+// SDRAM controller related macros
+
+#define MCF5272_SDRAMC_SDCCR_MCAS_A7    (0x0 << 13)
+#define MCF5272_SDRAMC_SDCCR_MCAS_A8    (0x1 << 13)
+#define MCF5272_SDRAMC_SDCCR_MCAS_A9    (0x2 << 13)
+#define MCF5272_SDRAMC_SDCCR_MCAS_A10   (0x3 << 13)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A19  (0x0 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A20  (0x1 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A21  (0x2 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A22  (0x3 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A23  (0x4 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A24  (0x5 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A25  (0x6 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A26  (0x7 << 8)
+#define MCF5272_SDRAMC_SDCCR_GSL        (0x00000080)
+#define MCF5272_SDRAMC_SDCCR_REG        (0x00000010)
+#define MCF5272_SDRAMC_SDCCR_INV        (0x00000008)
+#define MCF5272_SDRAMC_SDCCR_SLEEP      (0x00000004)
+#define MCF5272_SDRAMC_SDCCR_ACT        (0x00000002)
+#define MCF5272_SDRAMC_SDCCR_INIT       (0x00000001)
+
+#define MCF5272_SDRAMC_SDCTR_RTP_66MHz  (0x3D << 10)
+#define MCF5272_SDRAMC_SDCTR_RTP_48MHz  (0x2B << 10)
+#define MCF5272_SDRAMC_SDCTR_RTP_33MHz  (0x1D << 10)
+#define MCF5272_SDRAMC_SDCTR_RTP_25MHz  (0x16 << 10)
+#define MCF5272_SDRAMC_SDCTR_RC(x)      ((x & 0x3) << 8)
+#define MCF5272_SDRAMC_SDCTR_RP(x)      ((x & 0x3) << 4)
+#define MCF5272_SDRAMC_SDCTR_RCD(x)     ((x & 0x3) << 2)
+#define MCF5272_SDRAMC_SDCTR_CLT_2      (0x00000001)
+#define MCF5272_SDRAMC_SDCTR_CLT_3      (0x00000002)
+#define MCF5272_SDRAMC_SDCTR_CLT_4      (0x00000003)
+
+// ---------------------------------------------------------------------------
+
+// Timer module
+typedef struct
+{
+
+    // Timer mode register
+    cyg_uint16 tmr;
+
+    // Gap
+    cyg_uint16 _res1;
+
+    // Timer reference register
+    cyg_uint16 trr;
+
+    // Gap
+    cyg_uint16 _res2;
+
+    // Timer capture register
+    cyg_uint16 tcap;
+
+    // Gap
+    cyg_uint16 _res3;
+
+    // Timer counter register
+    cyg_uint16 tcn;
+
+    // Gap
+    cyg_uint16 _res4;
+
+    // Timer event register
+    cyg_uint16 ter;
+
+    // Gap
+    cyg_uint16 _res5;
+
+    // Gap
+    cyg_uint32 _res6[3];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_timer_t;
+
+// Related macros
+
+#define MCF5272_TIMER_TMR_PS            (0xFF00)
+#define MCF5272_TIMER_TMR_PS_BIT        (8)
+#define MCF5272_TIMER_TMR_CE            (0x00C0)
+#define MCF5272_TIMER_TMR_CE_BIT        (6)
+#define MCF5272_TIMER_TMR_OM            (0x0020)
+#define MCF5272_TIMER_TMR_OM_BIT        (5)
+#define MCF5272_TIMER_TMR_ORI           (0x0010)
+#define MCF5272_TIMER_TMR_ORI_BIT       (4)
+#define MCF5272_TIMER_TMR_FRR           (0x0008)
+#define MCF5272_TIMER_TMR_FRR_BIT       (3)
+#define MCF5272_TIMER_TMR_CLK           (0x0006)
+#define MCF5272_TIMER_TMR_CLK_BIT       (1)
+#define MCF5272_TIMER_TMR_RST           (0x0001)
+#define MCF5272_TIMER_TMR_RST_BIT       (0)
+#define MCF5272_TIMER_TER_REF           (0x0002)
+#define MCF5272_TIMER_TER_REF_BIT       (1)
+#define MCF5272_TIMER_TER_CAP           (0x0001)
+#define MCF5272_TIMER_TER_CAP_BIT       (0)
+
+// ---------------------------------------------------------------------------
+
+// Watchdog timer
+typedef struct
+{
+
+    // Watchdog reset reference register
+    cyg_uint16 wrrr;
+
+    // Gap
+    cyg_uint16 _res1;
+
+    // Watchdog interrupt reference register
+    cyg_uint16 wirr;
+
+    // Gap
+    cyg_uint16 _res2;
+
+    // Watchdog counter register
+    cyg_uint16 wcr;
+
+    // Gap
+    cyg_uint16 _res3;
+
+    // Watchdog event register
+    cyg_uint16 wer;
+
+    // Gap
+    cyg_uint16 _res4;
+
+    // Gap
+    cyg_uint32 _res5[28];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_wdtmr_t;
+
+// ---------------------------------------------------------------------------
+
+// Fast Ethernet Controller module
+typedef struct
+{
+
+    // Ethernet control register
+    cyg_uint32 ecr;
+
+    // Ethernet interrupt event register
+    cyg_uint32 eir;
+
+    // Ethernet interrupt mask register
+    cyg_uint32 eimr;
+
+    // Interrupt vector status register
+    cyg_uint32 ivsr;
+                                        
+    // Receive descriptor active register
+    cyg_uint32 rdar;
+                                        
+    // Transmit descriptor active register
+    cyg_uint32 tdar;
+                                        
+    // Gap
+    cyg_uint8 _res2[0x0880 - 0x0858];
+
+    // MII management frame register
+    cyg_uint32 mmfr;
+
+    // MII speed control register
+    cyg_uint32 mscr;
+
+    // Gap
+    cyg_uint8 _res3[0x08cc - 0x0888];
+
+    // FIFO receive bound register
+    cyg_uint32 frbr;
+
+    // FIFO receive start register
+    cyg_uint32 frsr;
+
+    // Gap
+    cyg_uint8 _res4[0x08e4 - 0x08d4];
+
+    // Transmit FIFO watermark
+    cyg_uint32 tfwr;
+
+    // Gap
+    cyg_uint8 _res5[0x08ec - 0x08e8];
+
+    // Transmit FIFO start register
+    cyg_uint32 tfsr;
+
+    // Gap
+    cyg_uint8 _res6[0x0944 - 0x08f0];
+
+    // Receive control register
+    cyg_uint32 rcr;
+
+    // Maximum frame length register
+    cyg_uint32 mflr;
+
+    // Gap
+    cyg_uint8 _res7[0x0984 - 0x094c];
+
+    // Transmit control register
+    cyg_uint32 tcr;
+
+    // Gap
+    cyg_uint8 _res8[0x0c00 - 0x0988];
+
+    // RAM perfect match address low register
+    cyg_uint32 malr;
+
+    // RAM perfect match address high register
+    cyg_uint32 maur;
+
+    // Hash table high register
+    cyg_uint32 htur;
+
+    // Hash table low register
+    cyg_uint32 htlr;
+
+    // Pointer to receive descriptor ring
+    cyg_uint32 erdsr;
+
+    // Pointer to transmit descriptor ring
+    cyg_uint32 etdsr;
+                                        
+    // Maximum receive buffer size
+    cyg_uint32 emrbr;
+
+    // Gap
+    cyg_uint8 _res9[0x0c40 - 0x0c1c];
+
+    // FIFO RAM space
+    cyg_uint8 efifo[0x0e00 - 0x0c40];
+
+    // Gap
+    cyg_uint8 _res10[0x1000 - 0x0e00];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_fec_t;
+
+// ---------------------------------------------------------------------------
+
+// On-chip peripherals: this structure defines each register's offset from the
+// current value of the MBAR register.
+typedef struct
+{
+
+    // 0x0000: System Integration Module (SIM) general configuration registers
+    mcf5272_sim_cfg_t cfg;
+
+    // 0x0020: SIM interrupt controller registers
+    mcf5272_sim_int_t intc;
+
+    // 0x0040: SIM chip-select modules
+    mcf5272_sim_cs_t cs[8];             
+
+    // 0x0080: SIM general purpose I/O control registers
+    mcf5272_sim_gpio_t gpio;
+
+    // 0x00a0: QSPI module
+    // TODO: a specific data structure is needed
+    cyg_uint32 qspi[8];
+
+    // 0x00c0: PWM module
+    // TODO: a specific data structure is needed
+    cyg_uint32 pwm[8];
+
+    // 0x00e0: DMA controller
+    // TODO: a specific data structure is needed
+    cyg_uint32 dmac[8];
+
+    // 0x0100: UART modules
+    mcf5272_uart_t uart[2];
+
+    // 0x0180: SIM SDRAM controller
+    mcf5272_sim_sdramctrl_t sdramc;
+
+    // 0x0200: timer module
+    mcf5272_timer_t timer[4];
+
+    // 0x0280: SIM watchdog timer module
+    mcf5272_sim_wdtmr_t wdtimer;
+
+    // 0x0300: physical layer interface controller
+    // TODO: a specific data structure is needed
+    cyg_uint32 plic[336];
+                                        
+    // 0x0840: ethernet module
+    mcf5272_fec_t fec;
+
+    // 0x1000: USB module
+    // TODO: a specific data structure is needed
+    cyg_uint32 usb[512];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_devs_t;
+
+// ---------------------------------------------------------------------------
+// End of mcf5272_devs.h
+#endif // CYGONCE_MCF5272_DEVS_H
diff --git a/packages/hal/coldfire/mcf5272/v2_0/include/var_arch.h b/packages/hal/coldfire/mcf5272/v2_0/include/var_arch.h
new file mode 100644 (file)
index 0000000..f6c3378
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef CYGONCE_HAL_VAR_ARCH_H
+#define CYGONCE_HAL_VAR_ARCH_H
+
+//=============================================================================
+//
+//      var_arch.h
+//
+//      Processor variant specific definitions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Definitions specific to the MCF5272 processor.
+// Usage:         Included by "hal_arch.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/mcf5272_devs.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+
+// Declare the global pointer to the peripheral registers.
+// Everyone should use the MCF5272_DEVS macro so it can be easily changed.
+#define MCF5272_DEVS ((volatile mcf5272_devs_t *) CYGMEM_REGION_devs)
+
+// ---------------------------------------------------------------------------
+// End of var_arch.h
+#endif // CYGONCE_HAL_VAR_ARCH_H
diff --git a/packages/hal/coldfire/mcf5272/v2_0/include/var_basetype.h b/packages/hal/coldfire/mcf5272/v2_0/include/var_basetype.h
new file mode 100644 (file)
index 0000000..15a4697
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef CYGONCE_HAL_VAR_BASETYPE_H
+#define CYGONCE_HAL_VAR_BASETYPE_H
+
+//=============================================================================
+//
+//      var_basetype.h
+//
+//      Standard types for this architecture variant
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Type definitions specific to the MCF5272 processor.
+// Usage:         Included by "basetype.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+// Use defaults for this architecture.
+
+// ---------------------------------------------------------------------------
+// End of var_basetype.h
+#endif // CYGONCE_HAL_VAR_BASETYPE_H
diff --git a/packages/hal/coldfire/mcf5272/v2_0/include/var_cache.h b/packages/hal/coldfire/mcf5272/v2_0/include/var_cache.h
new file mode 100644 (file)
index 0000000..fcb95f0
--- /dev/null
@@ -0,0 +1,187 @@
+#ifndef CYGONCE_VAR_CACHE_H
+#define CYGONCE_VAR_CACHE_H
+
+//=============================================================================
+//
+//      var_cache.h
+//
+//      Variant HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Definitions specific to the MCF5272 processor cache.
+// Usage:         Included via "hal_cache.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/coldfire_regs.h>
+
+// We currently just enable the instruction cache on startup. There is
+// no data cache.
+
+// ----------------------------------------------------------------------------
+// Cache dimensions - these vary between the ColdFire sub-models
+
+// Data cache
+#define HAL_DCACHE_SIZE                 0       // Size of data cache in bytes
+
+// Size of a data cache line. Leave this value even if there is no data cache
+// on 5272, otherwise some tests won't compile.
+#define HAL_DCACHE_LINE_SIZE            16
+
+#define HAL_DCACHE_WAYS                 1       // Associativity of the cache
+
+// Instruction cache
+#define HAL_ICACHE_SIZE                 1024    // Size of cache in bytes
+#define HAL_ICACHE_LINE_SIZE            16      // Size of a cache line
+#define HAL_ICACHE_WAYS                 1       // Associativity of the cache
+
+#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
+#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
+
+// ----------------------------------------------------------------------------
+// Global control of data cache
+
+// Enable the data cache
+#define HAL_DCACHE_ENABLE()
+
+// Disable the data cache
+#define HAL_DCACHE_DISABLE()
+
+// Invalidate the entire cache
+// Note: Any locked lines will not be invalidated.
+#define HAL_DCACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_DCACHE_SYNC()
+
+// Query the state of the data cache
+#define HAL_DCACHE_IS_ENABLED(_state_)
+
+// Set the data cache refill burst size
+//#define HAL_DCACHE_BURST_SIZE(_size_)
+
+// Set the data cache write mode
+//#define HAL_DCACHE_WRITE_MODE( _mode_ )
+
+//#define HAL_DCACHE_WRITETHRU_MODE       0
+//#define HAL_DCACHE_WRITEBACK_MODE       1
+
+
+// Load the contents of the given address range into the data cache
+// and then lock the cache so that it stays there.
+#define HAL_DCACHE_LOCK(_base_, _size_)
+
+// Undo a previous lock operation
+#define HAL_DCACHE_UNLOCK(_base_, _size_)
+
+// Unlock entire cache
+#define HAL_DCACHE_UNLOCK_ALL()
+
+// ----------------------------------------------------------------------------
+// Data cache line control
+
+// Allocate cache lines for the given address range without reading its
+// contents from memory.
+//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ )
+
+// Write dirty cache lines to memory and invalidate the cache entries
+// for the given address range.
+#define HAL_DCACHE_FLUSH( _base_ , _size_ )
+
+// Invalidate cache lines in the given range without writing to memory.
+#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )
+
+// Write dirty cache lines to memory for the given address range.
+#define HAL_DCACHE_STORE( _base_ , _size_ )
+
+// Preread the given range into the cache with the intention of reading
+// from it later.
+#define HAL_DCACHE_READ_HINT( _base_ , _size_ )
+
+// Preread the given range into the cache with the intention of writing
+// to it later.
+#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ )
+
+// Allocate and zero the cache lines associated with the given range.
+#define HAL_DCACHE_ZERO( _base_ , _size_ )
+
+// ----------------------------------------------------------------------------
+// Global control of Instruction cache
+
+// Enable the instruction cache
+#define HAL_ICACHE_ENABLE() CYGARC_MOVEC((CYG_WORD32)0x80000102, CYGARC_REG_CACR)
+
+// Disable the instruction cache
+#define HAL_ICACHE_DISABLE() CYGARC_MOVEC((CYG_WORD32)0x00000102, CYGARC_REG_CACR)
+
+// Invalidate the entire cache
+#define HAL_ICACHE_INVALIDATE_ALL() CYGARC_MOVEC((CYG_WORD32)0x81000102, CYGARC_REG_CACR)
+
+// Synchronize the contents of the cache with memory.
+#define HAL_ICACHE_SYNC() CYGARC_MOVEC((CYG_WORD32)0x81000102, CYGARC_REG_CACR)
+
+// Query the state of the instruction cache
+//#define HAL_ICACHE_IS_ENABLED(_state_)
+
+// Set the instruction cache refill burst size
+//#define HAL_ICACHE_BURST_SIZE(_size_)
+
+
+// Load the contents of the given address range into the instruction cache
+// and then lock the cache so that it stays there.
+#define HAL_ICACHE_LOCK(_base_, _size_)
+
+// Undo a previous lock operation
+#define HAL_ICACHE_UNLOCK(_base_, _size_)
+
+// Unlock entire cache
+#define HAL_ICACHE_UNLOCK_ALL()
+
+// ----------------------------------------------------------------------------
+// Instruction cache line control
+
+// Invalidate cache lines in the given range without writing to memory.
+//#define HAL_ICACHE_INVALIDATE( _base_ , _size_ )
+
+// ---------------------------------------------------------------------------
+// End of var_cache.h
+#endif // ifndef CYGONCE_VAR_CACHE_H
diff --git a/packages/hal/coldfire/mcf5272/v2_0/include/var_intr.h b/packages/hal/coldfire/mcf5272/v2_0/include/var_intr.h
new file mode 100644 (file)
index 0000000..39b366a
--- /dev/null
@@ -0,0 +1,253 @@
+#ifndef CYGONCE_HAL_VAR_INTR_H
+#define CYGONCE_HAL_VAR_INTR_H
+
+//==========================================================================
+//
+//      var_intr.h
+//
+//      MCF5272 processor variant interrupt, exception and clock support
+//
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:  Wade Jensen
+// Date:          2005-25-06
+// Purpose:       Provide interrupt, exception and clock definitions specific
+//                to the MCF5272 processor.
+// Usage:         Included via "hal_intr.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+// Include any platform specific interrupt definitions.
+#include <cyg/hal/plf_intr.h>
+
+// Include for the device addresses (MCF5272_DEVS).
+#include <cyg/hal/var_arch.h>
+
+// Include for HAL I/O macros
+#include <cyg/hal/hal_io.h>
+
+// --------------------------------------------------------------------------
+// Interrupt controller management
+
+// This chip has a programmable interrupt vector base which is different
+// from the vector base  register (VBR). All interrupts from the interrupt
+// controller are offset from the programmable interrupt vector register
+// (PIVR). However, the only legal value is 64.
+
+#define HAL_PROG_INT_VEC_BASE 64
+
+// Vector numbers defined by the interrupt controller.
+// These are all relative to the interrupt vector base number.
+#define CYGNUM_HAL_INTERRUPT_USR_SPURINT       (0 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT1           (1 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT2           (2 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT3           (3 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT4           (4 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_TMR0              (5 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_TMR1              (6 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_TMR2              (7 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_TMR3              (8 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_UART1             (9 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_UART2             (10 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_PLIP              (11 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_PLIA              (12 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB0              (13 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB1              (14 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB2              (15 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB3              (16 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB4              (17 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB5              (18 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB6              (19 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB7              (20 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_DMA               (21 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_ERX               (22 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_ETX               (23 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_ENTC              (24 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_QSPI              (25 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT5           (26 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT6           (27 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_SWTO              (28 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_RES1              (29 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_RES2              (30 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_RES3              (31 + HAL_PROG_INT_VEC_BASE)
+
+// -------------------------------------------------------------------------
+// Interrupt and exception vector table definitions. We need to redifine 
+// CYGNUM_HAL_ISR_MIN because the first usable vector is 65
+
+#define CYGNUM_HAL_ISR_RANGE_DEFINED
+#define CYGNUM_HAL_ISR_MIN                   CYGNUM_HAL_INTERRUPT_EXTINT1
+#define CYGNUM_HAL_ISR_MAX                   CYGNUM_HAL_INTERRUPT_RES3
+#define CYGNUM_HAL_ISR_COUNT                 (CYGNUM_HAL_ISR_MAX - CYGNUM_HAL_ISR_MIN + 1)
+
+// -------------------------------------------------------------------------
+// Spurious interrupt definition. The MCF5272 returns vector number 64,
+// instead of 24, for spurious interrupts
+
+#define CYGNUM_HAL_SPURIOUS_INTERRUPT CYGNUM_HAL_INTERRUPT_USR_SPURINT
+
+// --------------------------------------------------------------------------
+// Interrupt controller definitions.
+
+// Interrupt priority tables
+externC volatile cyg_uint8 cyg_hal_ILVL_table[CYGNUM_HAL_ISR_COUNT];
+externC volatile cyg_uint8 cyg_hal_IMASK_table[CYGNUM_HAL_ISR_COUNT];
+
+externC void hal_interrupt_set_level(int vector, int level);
+externC void hal_interrupt_mask(int vector);
+externC void hal_interrupt_unmask(int vector);
+
+// Mask the interrupt associated with the given vector.
+#define HAL_INTERRUPT_MASK( _vector_ ) \
+    hal_interrupt_mask(_vector_)
+
+// Unmask the interrupt associated with the given vector.
+#define HAL_INTERRUPT_UNMASK( _vector_ ) \
+    hal_interrupt_unmask(_vector_)
+
+// Set the priority level of an interrupt.
+#define HAL_INTERRUPT_SET_LEVEL( _vector_, _prilevel_ ) \
+    hal_interrupt_set_level(_vector_, _prilevel_)
+
+// Acknowledge the interrupt by writing a 1 to the corresponding
+// interrupt pending bit. Write 0 to all other interrupt pending bits. Leave
+// all priority levels unchanged. Disable all interrupts while we access the
+// hardware registers.
+#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ )                           \
+CYG_MACRO_START                                                         \
+    cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1;    \
+    cyg_uint32 _icr = _vec_offset / 8;                                  \
+    cyg_uint32 _icr_msk = 0x80000000 >> ((_vec_offset % 8) * 4);        \
+    cyg_uint32 _icr_oldval;                                             \
+    CYG_INTERRUPT_STATE _intr_state;                                    \
+                                                                        \
+    HAL_DISABLE_INTERRUPTS(_intr_state);                                \
+    HAL_READ_UINT32(&MCF5272_DEVS->intc.icr[_icr], _icr_oldval);        \
+    HAL_WRITE_UINT32(&MCF5272_DEVS->intc.icr[_icr],                     \
+        _icr_oldval & (_icr_msk | 0x77777777));                         \
+    HAL_RESTORE_INTERRUPTS(_intr_state);                                \
+CYG_MACRO_END
+
+// Set/clear the interrupt transition register bit. Disable all
+// interrupts while we access the hardware registers.
+#define HAL_INTERRUPT_CONFIGURE( _vector_, _leveltriggered_, _up_ )                     \
+CYG_MACRO_START                                                                         \
+    if (!(_leveltriggered_))                                                            \
+    {                                                                                   \
+        cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1;                \
+        cyg_uint32 _itr_bit = 0x80000000 >> _vec_offset;                                \
+        cyg_uint32 _pitr_oldval;                                                        \
+        CYG_INTERRUPT_STATE _intr_state;                                                \
+                                                                                        \
+        HAL_DISABLE_INTERRUPTS(_intr_state);                                            \
+        HAL_READ_UINT32(&MCF5272_DEVS->intc.pitr, _pitr_oldval);                        \
+        if (_up_)                                                                       \
+        {                                                                               \
+            HAL_WRITE_UINT32(&MCF5272_DEVS->intc.pitr, _pitr_oldval | _itr_bit);        \
+        }                                                                               \
+        else                                                                            \
+        {                                                                               \
+            HAL_WRITE_UINT32(&MCF5272_DEVS->intc.pitr, _pitr_oldval & (~_itr_bit));     \
+        }                                                                               \
+        HAL_RESTORE_INTERRUPTS(_intr_state);                                            \
+    }                                                                                   \
+CYG_MACRO_END
+
+// --------------------------------------------------------------------------
+// Clock control
+
+// The MCF5272 has 4 timers, numbered 0...3. Define the timer number that we
+// want to use for the OS clock.
+#define CYGNUM_HAL_RTC_TIMER_NUM (3)
+
+// The vector used by the real-time clock
+#define CYGNUM_HAL_INTERRUPT_RTC (CYGNUM_HAL_INTERRUPT_TMR3)
+
+// Initialize the timer to generate an interrupt every 10 ms. Use the
+// system clock divided by 16 as the source. Using 10 as the prescaler
+// gives a 2.4 us counter. When this counter reaches _period_, generate
+// an interrupt.
+#define HAL_CLOCK_INITIALIZE(_period_)                                          \
+CYG_MACRO_START                                                                 \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tmr,            \
+                 0x0000);                                                       \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].trr,            \
+                 (_period_));                                                   \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tcn, 0);        \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].ter, 0x0003);   \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tmr,            \
+    (((10)-1) << MCF5272_TIMER_TMR_PS_BIT) |                                    \
+    (0 << MCF5272_TIMER_TMR_CE_BIT) |                                           \
+    (0 << MCF5272_TIMER_TMR_OM_BIT) |                                           \
+    (1 << MCF5272_TIMER_TMR_ORI_BIT) |                                          \
+    (0 << MCF5272_TIMER_TMR_FRR_BIT) |                                          \
+    (2 << MCF5272_TIMER_TMR_CLK_BIT) |                                          \
+    (1 << MCF5272_TIMER_TMR_RST_BIT));                                          \
+CYG_MACRO_END
+
+// We must clear the bit in the timer event register before we can get
+// another interrupt.
+#define HAL_CLOCK_RESET( _vector_, _period_ )                                   \
+CYG_MACRO_START                                                                 \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tcn, 0);        \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].ter, 0x0002);   \
+CYG_MACRO_END
+
+// Read the current counter from the timer
+#define HAL_CLOCK_READ( _pvalue_ )                                              \
+CYG_MACRO_START                                                                 \
+HAL_READ_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tcn,             \
+                *(_pvalue_));                                                   \
+CYG_MACRO_END
+
+// Measure clock latency
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY
+#define HAL_CLOCK_LATENCY( _pvalue_ )                                       \
+CYG_MACRO_START                                                             \
+    register cyg_int32 result;                                              \
+    HAL_CLOCK_READ( &result );                                              \
+    *_pvalue_ = result - CYGNUM_HAL_RTC_PERIOD;                             \
+CYG_MACRO_END
+#endif
+
+// ---------------------------------------------------------------------------
+// End of var_intr.h
+#endif // ifndef CYGONCE_HAL_VAR_INTR_H
diff --git a/packages/hal/coldfire/mcf5272/v2_0/include/var_regs.h b/packages/hal/coldfire/mcf5272/v2_0/include/var_regs.h
new file mode 100644 (file)
index 0000000..9233655
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef CYGONCE_HAL_VAR_REGS_H
+#define CYGONCE_HAL_VAR_REGS_H
+
+//==========================================================================
+//
+//      var_regs.h
+//
+//      ColdFire MCF5272 variant CPU definitions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:         2005-25-06
+// Purpose:      Provide register definitions for the MCF5272.
+// Description:
+// Usage:        Included via "coldfire_regs.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// CPU space registers definitions
+
+#define CYGARC_REG_CACR             0x002
+#define CYGARC_REG_ACR0             0x004
+#define CYGARC_REG_ACR1             0x005
+#define CYGARC_REG_VBR              0x801
+#define CYGARC_REG_ROMBAR0          0xC00
+#define CYGARC_REG_RAMBAR0          0xC04
+#define CYGARC_REG_MBAR             0xC0F
+
+// ---------------------------------------------------------------------------
+// End of var_regs.h
+#endif // ifdef CYGONCE_HAL_VAR_REGS_H
diff --git a/packages/hal/coldfire/mcf5272/v2_0/include/var_startup.h b/packages/hal/coldfire/mcf5272/v2_0/include/var_startup.h
new file mode 100644 (file)
index 0000000..a680ecb
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef CYGONCE_VAR_STARTUP_H
+#define CYGONCE_VAR_STARTUP_H
+
+//=============================================================================
+//
+//      var_startup.h
+//
+//      ColdFire MCF5272 CPU variant startup header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:         2005-25-06
+// Purpose:      ColdFire MCF5272 CPU variant startup header.
+// Description:
+// Usage:        Included via "hal_startup.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+// Include the platform-specific startup header.
+#include <cyg/hal/plf_startup.h>
+
+// Variant specific hardware initialization routine
+externC void var_reset(void) __attribute__ ((section (".boot")));
+
+// Variant specific data initialization routine
+externC void var_init_data(void) __attribute__ ((section (".boot")));
+
+// ---------------------------------------------------------------------------
+// End of var_startup.h
+#endif // CYGONCE_VAR_STARTUP_H
diff --git a/packages/hal/coldfire/mcf5272/v2_0/include/variant.inc b/packages/hal/coldfire/mcf5272/v2_0/include/variant.inc
new file mode 100644 (file)
index 0000000..c0b810d
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef CYGONCE_HAL_VARIANT_INC
+#define CYGONCE_HAL_VARIANT_INC
+
+|==========================================================================
+|
+|      variant.inc
+|
+|      MCF5272 variant assembler header file
+|
+|==========================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| eCos is free software; you can redistribute it and/or modify it under
+| the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2 or (at your option) any later version.
+|
+| eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+| WARRANTY; without even the implied warranty of MERCHANTABILITY or
+| FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+| for more details.
+|
+| You should have received a copy of the GNU General Public License along
+| with eCos; if not, write to the Free Software Foundation, Inc.,
+| 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+|
+| As a special exception, if other files instantiate templates or use macros
+| or inline functions from this file, or you compile this file and link it
+| with other works to produce a work based on this file, this file does not
+| by itself cause the resulting work to be covered by the GNU General Public
+| License. However the source code for this file must still be made available
+| in accordance with section (3) of the GNU General Public License.
+|
+| This exception does not 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
+| Contributors:
+| Date:         2005-25-06
+| Purpose:      MCF5272 variant definitions.
+| Description:  This file contains the definitions specific to the
+|               CPU variant, used in the architecture HAL assembler file.
+| Usage:        Included by "vectors.S". Do not use directly.
+|
+|####DESCRIPTIONEND####
+|==========================================================================
+
+#include <cyg/hal/platform.inc>
+
+
+| -----------------------------------------------------------------------------
+| CPU specific macros. These provide a common assembler interface to
+| operations that may have CPU specific implementations on different
+| variants of the architecture.     
+
+| CPU initialization macro
+        .macro hal_cpu_init
+
+        | Invalidate and disable the cache and ACRs.
+        move.l  #0x01000000,%d0
+        movec   %d0,%cacr
+
+        move.l  #0x0,%d0
+        movec   %d0,%acr0
+        movec   %d0,%acr1
+        .endm
+
+
+| ----------------------------------------------------------------------------
+| This macro retrieves the IPL of the current interrupt from the
+| interrupt controller register. This is needed because on inetrrupt entry
+| all interrupts are disabled by writing to the status register, and thus
+| loosing the current IPL.
+| Input: interrupt vector number in d0
+| Output: IPL associated to interrupt in d0
+
+        .macro hal_variant_retrieve_ipl
+
+        | Subtract minimum interrupt vector number
+        sub.l #CYGNUM_HAL_ISR_MIN,%d0
+    
+        | Load IPL table address in a0
+        lea cyg_hal_ILVL_table,%a0
+
+        | Retrieve IPL level for current interrupt
+        move.b  (%a0,%d0.l),%d0
+
+        .endm
+
+| ----------------------------------------------------------------------------
+| end of variant.inc
+#endif // ifndef CYGONCE_HAL_VARIANT_INC
diff --git a/packages/hal/coldfire/mcf5272/v2_0/src/hal_diag.c b/packages/hal/coldfire/mcf5272/v2_0/src/hal_diag.c
new file mode 100644 (file)
index 0000000..e9c9ab0
--- /dev/null
@@ -0,0 +1,416 @@
+//==========================================================================
+//
+//      hal_diag.c
+//
+//      HAL diagnostic I/O support routines for the MCF5272
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:         2005-25-06
+// Purpose:      Code to manage the serial ports for diagnostic output.
+// Description:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_intr.h>           // CYGNUM_HAL_INTERRUPT_UART1
+#include <cyg/hal/hal_if.h>             // __comm_control_cmd_t
+#include <cyg/hal/hal_io.h>             // HAL I/O macros
+#include <cyg/hal/hal_misc.h>           // cyg_hal_is_break
+#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
+
+#include <cyg/hal/plf_serial.h>
+
+
+typedef struct {
+    CYG_ADDRWORD                base;           // [Pointer] to Port base address
+    unsigned int                vector;         // UART interrupt vector
+    CYG_WORD                    msec_timeout;   // Timeout in msec
+} channel_data_t;
+
+static channel_data_t ports[] = {
+    {
+        (CYG_ADDRWORD) (&((mcf5272_devs_t *) 0)->uart[0]),
+        CYGNUM_HAL_INTERRUPT_UART1,
+        1000
+    },
+
+    {
+        (CYG_ADDRWORD) (&((mcf5272_devs_t *) 0)->uart[1]),
+        CYGNUM_HAL_INTERRUPT_UART2,
+        1000
+    }
+};
+
+
+static cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data);
+
+static void
+cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 ch);
+
+static void
+cyg_hal_plf_serial_init_channel(channel_data_t *port);
+
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch);
+
+static cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch);
+
+static void
+cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len);
+static void
+cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len);
+
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
+                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data);
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...);
+
+
+// ----------------------------------------------------------------------------
+// Early initialization of comm. channels.
+void
+cyg_hal_plf_comms_init(void)
+{
+    hal_virtual_comm_table_t* comm;
+    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+    cyg_uint32 portcnt;
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+    initialized = 1;
+
+#if (defined(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL) && \
+        CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL == 0) || \
+    (defined(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL) && \
+        CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 0)
+    
+    // UART0 pins are multplexed with GPIO port B. Enable them in
+    // port B control register.
+    HAL_READ_UINT32(&MCF5272_DEVS->gpio.pbcnt, portcnt);
+    HAL_WRITE_UINT32(&MCF5272_DEVS->gpio.pbcnt, ((portcnt &
+        ~(MCF5272_GPIO_PBCNT_URT0_MSK)) |
+        (MCF5272_GPIO_PBCNT_URT0_EN)));
+
+    // Init channel 0
+    cyg_hal_plf_serial_init_channel(&ports[0]);
+
+    // Setup procs in the vector table for channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &ports[0]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+
+#if (defined(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL) && \
+        CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL == 1) || \
+    (defined(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL) && \
+        CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 1)
+
+    // UART1 pins need to be enabled in port D control register.
+    HAL_READ_UINT32(&MCF5272_DEVS->gpio.pdcnt, portcnt);
+    HAL_WRITE_UINT32(&MCF5272_DEVS->gpio.pdcnt, ((portcnt &
+        ~(MCF5272_GPIO_PDCNT_URT1_MSK)) |
+        (MCF5272_GPIO_PDCNT_URT1_EN)));
+
+    // Init channel 1
+    cyg_hal_plf_serial_init_channel(&ports[1]);
+
+    // Setup procs in the vector table for channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &ports[1]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+
+void cyg_hal_plf_serial_init_channel(channel_data_t *port)
+{
+    CYG_WORD16 clk_div;
+    volatile mcf5272_uart_t *base =
+        (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
+    // Initialize variable to prevent compiler warnings
+    unsigned int baud_rate = 1200;
+
+
+#ifdef CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE    
+    if( (port-&ports[0]) == CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL )
+        baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD;
+#endif    
+#ifdef CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+    if( (port-&ports[0]) == CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL )
+        baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
+#endif
+
+    // Before we do anything else, make sure we have enabled RTS in case
+    // the device we are using relies on hardware flow control.
+    // Note that this step is our only attempt at hardware flow control.
+    HAL_WRITE_UINT8(&base->uop1, MCF5272_UART_UOP1_RTS);
+
+    // Initialize UART
+    
+    // Reset Transmitter
+    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RTX);
+
+    // Reset Receiver
+    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RRX);
+
+    // Reset Mode Register
+    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RMR);
+
+    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RES);
+    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RBC);
+
+    // Mode register 1 sets the UART to  8 data bits with no parity, and
+    // mode register 2 forces 1 stop  bit. Also, interrupt generation
+    // on RxRDY signal is enabled by default.
+    // Reading or write to the mode register switches it from umr1 to umr2.
+    // To set it to umr1, we must write a reset mode register command to the
+    // command register.
+    HAL_WRITE_UINT8(&base->umr, MCF5272_UART_UMR_8BNP);
+    HAL_WRITE_UINT8(&base->umr, MCF5272_UART_UMR_1S);
+
+    // Select a prescaled (by 1/16) CLKIN for the clock source
+    HAL_WRITE_UINT8(&base->usr_ucsr, MCF5272_UART_UCSR_CLKIN);
+
+    // Calculate baud settings
+    clk_div = (CYG_WORD16)
+              ((CYGHWR_HAL_SYSTEM_CLOCK_MHZ*1000000)/
+               (baud_rate * 32));
+    HAL_WRITE_UINT8(&base->udu, clk_div >> 8);
+    HAL_WRITE_UINT8(&base->udl, clk_div & 0x00ff);
+
+    // Enable the transmitter and receiver
+    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_TXRXEN);
+
+    // Set interrupt priority to highest maskable level
+    HAL_INTERRUPT_SET_LEVEL(port->vector, 6);
+}
+
+
+cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+
+
+    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+
+    return ch;
+}
+
+
+void cyg_hal_plf_serial_putc(void *__ch_data, cyg_uint8 ch)
+{
+    channel_data_t *port = (channel_data_t *) __ch_data;
+    volatile mcf5272_uart_t *base =
+        (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
+    cyg_uint8 usr_ucsr, utf;
+
+
+    // Loop until the transmit data holding register is empty
+    do
+    {
+        HAL_READ_UINT8(&base->usr_ucsr, usr_ucsr);
+    } while (!(usr_ucsr & MCF5272_UART_USR_TXRDY));
+
+    // Write the character to the transmit buffer
+    HAL_WRITE_UINT8(&base->urb_utb, ch);
+
+    // Loop until the transmit data FIFO and the shift register are empty
+    do
+    {
+        HAL_READ_UINT8(&base->utf, utf);
+        HAL_READ_UINT8(&base->usr_ucsr, usr_ucsr);
+    } while ((utf & MCF5272_UART_UTF_TXB) ||
+        (!(usr_ucsr & MCF5272_UART_USR_TXEMP)));
+}
+
+static void cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
+                                     cyg_uint32 __len)
+{
+    while(__len-- > 0)
+        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+}
+
+
+static void cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf,
+                                    cyg_uint32 __len)
+{
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+}
+
+
+static cyg_bool cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    channel_data_t *port = (channel_data_t *) __ch_data;
+    volatile mcf5272_uart_t *base =
+        (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
+    cyg_uint8 usr_ucsr;
+
+
+    // Read status
+    HAL_READ_UINT8(&base->usr_ucsr, usr_ucsr);
+
+    // Check if a character is present
+    if (usr_ucsr & MCF5272_UART_USR_RRDY)
+    {
+        // Read character
+        HAL_READ_UINT8(&base->urb_utb, *ch);
+        return true;
+    }
+
+    return false;
+}
+
+
+static cyg_bool cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    int delay_count;
+    cyg_bool res;
+
+
+    delay_count = ((channel_data_t *)__ch_data)->msec_timeout;
+
+    for(;;) {
+        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+        
+        CYGACC_CALL_IF_DELAY_US(100);
+    }
+
+    return res;
+}
+
+
+static int cyg_hal_plf_serial_control(void *__ch_data,
+                                      __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    channel_data_t *port = (channel_data_t *) __ch_data;
+    volatile mcf5272_uart_t *base =
+        (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
+    int ret = 0;
+
+
+    switch (__func) {
+    case __COMMCTL_IRQ_ENABLE:
+        irq_state = 1;
+
+        HAL_WRITE_UINT8(&base->uisr_uimr, MCF5272_UART_UIMR_FFULL);
+        HAL_INTERRUPT_UNMASK(port->vector);
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+
+        HAL_INTERRUPT_MASK(port->vector);
+        HAL_WRITE_UINT8(&base->uisr_uimr, 0);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = port->vector;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+    {
+        va_list ap;
+
+        va_start(ap, __func);
+
+        ret = port->msec_timeout;
+        port->msec_timeout = va_arg(ap, cyg_uint32);
+
+        va_end(ap);
+    }        
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+
+static int cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
+                                  CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    channel_data_t *port = (channel_data_t *) __ch_data;
+    volatile mcf5272_uart_t *base =
+        (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
+    char c;
+
+
+    // Disable the interrupt temporarily
+    HAL_WRITE_UINT8(&base->uisr_uimr, 0);
+
+    *__ctrlc = 0;
+
+    // Read character
+    HAL_READ_UINT8(&base->urb_utb, c);
+    if( cyg_hal_is_break( &c , 1 ) )
+    {
+        *__ctrlc = 1;
+    }
+
+    // Re-enable RxRDY interrupt
+    HAL_WRITE_UINT8(&base->uisr_uimr, MCF5272_UART_UIMR_FFULL);
+    
+    return CYG_ISR_HANDLED;
+}
diff --git a/packages/hal/coldfire/mcf5272/v2_0/src/var_misc.c b/packages/hal/coldfire/mcf5272/v2_0/src/var_misc.c
new file mode 100644 (file)
index 0000000..a11544f
--- /dev/null
@@ -0,0 +1,161 @@
+//==========================================================================
+//
+//      var_misc.c
+//
+//      Miscellaneous functions specific to the processor variant
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Miscellaneous functions specific to the MCF5272 processor.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+
+#include CYGHWR_MEMORY_LAYOUT_H
+
+// -------------------------------------------------------------------------
+// VSR table
+
+// For the MCF5272, we can point the VBR directly to the VSR table.
+// However, the table must be on a 1 MB boundary. Locate the VSR table where
+// the linker tells us to.
+
+volatile CYG_ADDRESS cyg_hal_vsr_table[CYGNUM_HAL_VSR_COUNT]
+                    __attribute__ ((section (".ramvec")));
+
+// -------------------------------------------------------------------------
+// Function prototypes
+
+static void hal_update_interrupt_controller(int vector);
+
+// -------------------------------------------------------------------------
+// Interrupt controller management
+//
+// With the MCF5272 interrupt controller, it is not possible to mask an
+// interrupt while retaining its associated priority. Moreover, if we enabled
+// the use of interrupts with different priorities, we don't have a means to
+// retrieve the priority of the current interrupt, after having raised the
+// IPL to the maximum, in the first instruction of the HAL ISR handler.
+// So, we use an auxiliary table (cyg_hal_ILVL_table) that records all the
+// priorities set for the various interrupts.
+// The purpose of the cyg_hal_IMASK_table table is to record wether an
+// interrupt is currently masked (0) or not (1).
+
+volatile cyg_uint8 cyg_hal_ILVL_table[CYGNUM_HAL_ISR_COUNT];
+volatile cyg_uint8 cyg_hal_IMASK_table[CYGNUM_HAL_ISR_COUNT];
+
+
+// Update priority table and interrupt controller
+void hal_interrupt_set_level(int vector, int level)
+{
+    cyg_uint32 index;
+    
+    CYG_ASSERT((0 <= (level) && 7 >= (level)), "Illegal level");
+    CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
+                && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
+
+    HAL_TRANSLATE_VECTOR(vector, index);
+    cyg_hal_ILVL_table[index] = (cyg_uint8) level;
+
+    hal_update_interrupt_controller(vector);
+}
+
+// Update mask table and interrupt controller
+void hal_interrupt_mask(int vector)
+{
+    cyg_uint32 index;
+    
+    CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
+        && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
+    
+    HAL_TRANSLATE_VECTOR(vector, index);
+    cyg_hal_IMASK_table[index] = 0;
+    
+    hal_update_interrupt_controller(vector);
+}
+
+// Update mask table and interrupt controller
+void hal_interrupt_unmask(int vector)
+{
+    cyg_uint32 index;
+
+    CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
+    && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
+    
+    HAL_TRANSLATE_VECTOR(vector, index);
+    cyg_hal_IMASK_table[index] = 1;
+         
+    hal_update_interrupt_controller(vector);
+}
+
+
+// Set the priority in the interrupt control register.
+// Disable all interrupts while we access the hardware registers.
+static void hal_update_interrupt_controller(int vector)
+{
+    cyg_uint32 index;
+    cyg_uint8 level;
+    cyg_uint32 vec_offset;
+    cyg_uint32 icr, icr_msk_offset, icr_msk, icr_val, icr_oldval;
+    CYG_INTERRUPT_STATE intr_state;
+    
+    HAL_TRANSLATE_VECTOR(vector, index); 
+    level = cyg_hal_IMASK_table[index] ? cyg_hal_ILVL_table[index] : 0;
+
+    vec_offset = (vector) - HAL_PROG_INT_VEC_BASE - 1;
+    icr = vec_offset / 8;
+    icr_msk_offset = ((8-1)*4) - (vec_offset % 8) * 4;
+    icr_msk = 0x0F << (icr_msk_offset);
+    icr_val = (0x08 | (level & 0x07)) << icr_msk_offset;
+    
+    HAL_DISABLE_INTERRUPTS(intr_state);
+    HAL_READ_UINT32(&MCF5272_DEVS->intc.icr[icr], icr_oldval);
+    icr_val |= icr_oldval & 0x77777777 & ~icr_msk;
+    HAL_WRITE_UINT32(&MCF5272_DEVS->intc.icr[icr], icr_val);
+    HAL_RESTORE_INTERRUPTS(intr_state);
+}
+// -------------------------------------------------------------------------
+// End of var_misc.c
diff --git a/packages/hal/coldfire/mcf5272/v2_0/src/var_startup.c b/packages/hal/coldfire/mcf5272/v2_0/src/var_startup.c
new file mode 100644 (file)
index 0000000..c739eaf
--- /dev/null
@@ -0,0 +1,75 @@
+//==========================================================================
+//
+//      var_startup.c
+//
+//      Functions for the processor variant startup
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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
+// Contributors:
+// Date:          2005-25-06
+// Purpose:       Functions needed for MCF5272 startup.
+// Description:   This module contains code that sets up the variant specific
+//                hardware and data. All the code must be contained in the
+//                section called ".boot", in order for the ROMRAM startup
+//                to work properly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_startup.h>
+
+
+// Variant specific initialization routine.
+// This routine must be called with interrupts disabled.
+void var_reset(void)
+{
+    // Nothing to do
+}
+
+// Variant specific data initialization routine
+void var_init_data(void)
+{
+    int i;
+
+    // Initialize priority and mask tables
+    for(i = 0; i < CYGNUM_HAL_ISR_COUNT; i++)
+    {
+        cyg_hal_IMASK_table[i] = 0;
+        cyg_hal_ILVL_table[i] = 0;
+    }
+}
diff --git a/packages/hal/coldfire/mcf5272/v2_0/src/variant.S b/packages/hal/coldfire/mcf5272/v2_0/src/variant.S
new file mode 100644 (file)
index 0000000..03e91db
--- /dev/null
@@ -0,0 +1,109 @@
+|==========================================================================
+|
+|      variant.S
+|
+|      MCF5272 variant code
+|
+|==========================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| eCos is free software; you can redistribute it and/or modify it under
+| the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2 or (at your option) any later version.
+|
+| eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+| WARRANTY; without even the implied warranty of MERCHANTABILITY or
+| FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+| for more details.
+|
+| You should have received a copy of the GNU General Public License along
+| with eCos; if not, write to the Free Software Foundation, Inc.,
+| 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+|
+| As a special exception, if other files instantiate templates or use macros
+| or inline functions from this file, or you compile this file and link it
+| with other works to produce a work based on this file, this file does not
+| by itself cause the resulting work to be covered by the GNU General Public
+| License. However the source code for this file must still be made available
+| in accordance with section (3) of the GNU General Public License.
+|
+| This exception does not 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
+| Contributors:
+| Date:         2005-25-06
+| Purpose:      MCF5272 variant code.
+| Description:  This file contains the VSR table for the MCF5272, and
+|               other definitions used by the rest of the ColdFire HAL.
+|
+|####DESCRIPTIONEND####
+|==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/cf_offsets.inc>
+
+
+| ----------------------------------------------------------------------------
+| ROM vector table
+
+        .section ".romvec","ax"
+
+        .extern cyg_interrupt_stack
+        .extern cyg_hal_reset_vsr
+        .extern cyg_hal_default_exception_vsr
+        .extern cyg_hal_default_spurious_vsr
+        .extern cyg_hal_default_interrupt_vsr
+
+        .globl  rom_vsr_table
+rom_vsr_table:
+
+        | 0 - Initial SSP
+        .long   cyg_interrupt_stack
+
+        | 1 - Initial PC
+        .long   cyg_hal_reset_vsr
+
+        | 2-14 - Default exception handlers
+        .rept   14-2+1
+        .long   cyg_hal_default_exception_vsr
+        .endr
+
+        | 15 - Uninitialized interrupt. It should never happen, because
+        | we configure interrupt controller at startup.
+        .long   cyg_hal_default_spurious_vsr
+
+        | 16-23 - Reserved, treat as exceptions
+        .rept   23-16+1
+        .long   cyg_hal_default_exception_vsr
+        .endr
+
+        | 24 - Spurious interrupt
+        .long   cyg_hal_default_spurious_vsr
+
+        | 25-31 - Autovectored interrupts 1-7. Not used in MCF5272.
+        .rept   31-25+1
+        .long   cyg_hal_default_interrupt_vsr
+        .endr
+
+        | 32-63 - Default exception handlers
+        .rept   63-32+1
+        .long   cyg_hal_default_exception_vsr
+        .endr
+
+        | 64 - User spurious interrupt. The MCF5272 interrupt controller
+        | returns this vector number instead of vector 24
+        .long   cyg_hal_default_spurious_vsr
+
+        | 65-255 - User interrupt vectors
+        .rept   255-65+1
+        .long   cyg_hal_default_interrupt_vsr
+        .endr
diff --git a/packages/hal/fr30/arch/v2_0/ChangeLog b/packages/hal/fr30/arch/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..a6a2a7f
--- /dev/null
@@ -0,0 +1,58 @@
+2008-07-01  Lars Poeschel  <larsi@wh2.tu-dresden.de>
+
+    * src/vectors.S:
+    * include/arch.inc:
+    * include/hal_arch.h: Introduced CYGPKG_HAL_FR30_LMA_OFFSET for supporting
+                          remapping a flash chip during initialisation.
+
+2007-07-09  Lars Poeschel  <larsi@wh2.tu-dresden.de>
+
+    * src/context.S:
+    * src/fr30_stub.c:
+    * src/hal_misc.c:
+    * src/vectors.S:
+    * include/arch.inc:
+    * include/basetype.h:
+    * include/fr30.inc:
+    * include/fr30_stub.h:
+    * include/hal_arch.h:
+    * include/hal_cache.h:
+    * include/hal_intr.h:
+    * include/hal_io.h:
+    * cdl/hal_fr30.cdl: Initial fr30 ecos port
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/fr30/arch/v2_0/cdl/hal_fr30.cdl b/packages/hal/fr30/arch/v2_0/cdl/hal_fr30.cdl
new file mode 100644 (file)
index 0000000..5e7f0bf
--- /dev/null
@@ -0,0 +1,80 @@
+# ====================================================================
+#
+#      hal_fr30.cdl
+#
+#      fr30 architectural HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      larsi
+# Original data:
+# Contributors:
+# Date:           2006-05-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_FR30 {
+    display       "fr30 architecture"
+    parent        CYGPKG_HAL
+    hardware
+    include_dir   cyg/hal
+    define_header hal_fr30.h
+    description   "
+        The fr30 architecture HAL package provides generic
+        support for Fujitsu's fr30/fr50/fr60 processor architecture.
+        It is also necessary to select a specific target platform HAL
+        package. If you have a fr50 device, choose the MB91360 variant."
+
+    cdl_interface CYGINT_HAL_FR30_VARIANT {
+        display  "Number of variant implementations in this configuration"
+        requires 1 == CYGINT_HAL_FR30_VARIANT
+    }
+
+    compile       hal_misc.c context.S vectors.S fr30_stub.c
+
+    make {
+        <PREFIX>/lib/vectors.o : <PACKAGE>/src/vectors.S
+        $(CC) -Wp,-MD,vectors.tmp $(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<
+        @echo $@ ": \\" > $(notdir $@).deps
+        @tail -n +2 vectors.tmp >> $(notdir $@).deps
+        @echo >> $(notdir $@).deps
+        @rm vectors.tmp
+    }
+}
diff --git a/packages/hal/fr30/arch/v2_0/include/arch.inc b/packages/hal/fr30/arch/v2_0/include/arch.inc
new file mode 100644 (file)
index 0000000..050df2b
--- /dev/null
@@ -0,0 +1,200 @@
+#ifndef CYGONCE_HAL_ARCH_INC
+#define CYGONCE_HAL_ARCH_INC
+##=============================================================================
+##
+##     arch.inc
+##
+##     fr30 assembler header file
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):   larsi
+## Contributors: larsi
+## Date:       2006-06-20
+## Purpose:    Architecture definitions.
+## Description:        This file contains various definitions and macros that are
+##              useful for writing assembly code for the fr30 CPU family.
+## Usage:
+##             #include <cyg/hal/arch.inc>
+##             ...
+##             
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <cyg/hal/fr30.inc>
+
+#include <cyg/hal/variant.inc>
+
+##-----------------------------------------------------------------------------
+## define some .equ's to access c-code #define's from assembler code
+.equ    CYGNUM_ASM_CALL_IF_TABLE_SIZE,   CYGNUM_CALL_IF_TABLE_SIZE
+
+##-----------------------------------------------------------------------------
+## CPU specific macros. These provide a common assembler interface to
+## operations that may have CPU specific implementations on different
+## variants of the architecture
+
+#ifndef CYGPKG_HAL_FR30_CPU_INIT_DEFINED
+    # Initialize CPU
+    .macro  hal_cpu_init
+    .endm
+#endif /* !CYGPKG_HAL_FR30_CPU_INIT_DEFINED */
+
+.macro  hal_cpu_int_enable
+    orccr   #0x10
+.endm
+
+.macro  hal_cpu_int_disable
+    andccr  #0xef
+.endm
+
+
+# Merge the interrupt enable state of the status register in
+# \sr with the current sr.
+
+.macro  hal_cpu_int_merge sr
+    FIXME hal_cpu_int_merge not implemented yet
+.endm
+
+##-----------------------------------------------------------------------------
+# Default FR30 interrupt controller macros. Every FR30 has an integrated
+# interrupt controller, which we use here. This should be enough if there is
+# no special external interrupt controller (which I did not see yet).
+
+#ifndef CYGPKG_HAL_FR30_INTC_DEFINED
+
+#ifndef CYGPKG_HAL_FR30_INTC_INIT_DEFINED
+# initialize all interrupts to disabled. This is done automatically during
+# CPU reset and the macro is not used during ECOS startup. It is not
+# supplied here but would be setting all ICRs to 31 (to disable the particular
+# interrupt and maybe setting ILM in PS to 0.
+    .macro   hal_intc_init
+    .endm
+#endif
+
+
+# Normally interrupts are decoded by hardware and can not be software decoded,
+# so this is empty here.
+
+    .macro  hal_intc_decode vnum
+    .endm
+
+# Also translation interrupt number <--> vector number is done automatically
+# in hardware, so the macros are not supplied here.
+
+#endif
+
+#------------------------------------------------------------------------------
+# These defines are for the ISR and VSR tables which are defined in assembler
+# code. (currently in variant.S / vectors.S) and have to be the same like in
+# hal_intr.h
+
+#define CYGNUM_HAL_VECTOR_INTRFIRST               15
+#define CYGNUM_HAL_VECTOR_INTRLAST                63
+#define CYGNUM_HAL_VECTOR_NUMINTRS                (CYGNUM_HAL_VECTOR_INTRLAST-CYGNUM_HAL_VECTOR_INTRFIRST+1)
+
+// Common interrupt vectors
+#ifndef CYGNUM_HAL_ISR_MIN
+#define CYGNUM_HAL_ISR_MIN                       CYGNUM_HAL_VECTOR_INTRFIRST
+#define CYGNUM_HAL_ISR_MAX                       CYGNUM_HAL_VECTOR_INTRLAST
+#define CYGNUM_HAL_ISR_COUNT                     (CYGNUM_HAL_VECTOR_NUMINTRS)
+#endif
+
+// The default size of the VSR table is 256 entries.
+#ifndef CYGNUM_HAL_VSR_MIN
+#define CYGNUM_HAL_VSR_MIN                        0
+#define CYGNUM_HAL_VSR_MAX                        255
+#define CYGNUM_HAL_VSR_COUNT                      256
+#endif
+
+#------------------------------------------------------------------------------
+# Register save and restore macros. These expect a pointer to a CPU save state
+# area in the register \ptr. The GPR indicated by \reg will be saved into its
+# slot in that structure.
+
+# TODO do this macros if needed, look at MIPS arch.inc for inspiration
+
+
+#------------------------------------------------------------------------------
+# Stack switching macros
+
+
+
+#------------------------------------------------------------------------------
+# MEMC macros.
+
+
+#------------------------------------------------------------------------------
+# Cache macros.
+
+#ifndef CYGPKG_HAL_FR30_CACHE_DEFINED
+
+    .macro  hal_cache_init
+
+    .endm
+
+#endif
+
+#------------------------------------------------------------------------------
+# Diagnostics macros.
+
+#------------------------------------------------------------------------------
+# Timer initialization.
+
+#ifndef CYGPKG_HAL_FR30_TIMER_DEFINED
+
+    .macro  hal_timer_init
+    .endm
+
+#endif
+
+#------------------------------------------------------------------------------
+# Difference of the flash memory from the linkers LMA (loadmemoryaddress) after
+# the new mapping in (mapping is done in hal_fr30_ram_startup_trampoline).
+
+#ifndef CYGPKG_HAL_FR30_LMA_OFFSET
+
+#define CYGPKG_HAL_FR30_LMA_OFFSET  0x0
+
+#endif
+
+
+#endif // ifndef CYGONCE_HAL_ARCH_INC
+# end of arch.inc
diff --git a/packages/hal/fr30/arch/v2_0/include/basetype.h b/packages/hal/fr30/arch/v2_0/include/basetype.h
new file mode 100644 (file)
index 0000000..9c2d39a
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef CYGONCE_HAL_BASETYPE_H
+#define CYGONCE_HAL_BASETYPE_H
+
+//=============================================================================
+//
+//      basetype.h
+//
+//      Standard types for this architecture.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   larsi
+// Contributors:larsi
+// Date:        2006-06-15
+// Purpose:     Define architecture base types.
+// Usage:       Included by "cyg_type.h", do not use directly
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Characterize the architecture
+
+#define CYG_BYTEORDER           CYG_MSBFIRST    // BIG endian
+
+// ---------------------------------------------------------------------------
+// Override the alignment definitions from cyg_type.h
+
+#ifndef CYGARC_ALIGNMENT
+#define CYGARC_ALIGNMENT 4
+#endif
+
+// The corresponding power of two alignment
+#ifndef CYGARC_P2ALIGNMENT
+#define CYGARC_P2ALIGNMENT 2
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_BASETYPE_H
+// End of basetype.h
diff --git a/packages/hal/fr30/arch/v2_0/include/fr30.inc b/packages/hal/fr30/arch/v2_0/include/fr30.inc
new file mode 100644 (file)
index 0000000..952c881
--- /dev/null
@@ -0,0 +1,65 @@
+##=============================================================================
+##
+##     fr30.inc
+##
+##     fr30 assembler header file
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):  larsi
+## Contributors:larsi
+## Date:       2006-06-15
+## Purpose:    fr30 definitions.
+## Description:        This file contains various definitions and macros that are
+##              useful for writing assembly code for the fr30
+## Usage:
+##             #include <cyg/hal/fr30.inc>
+##             ...
+##             
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#------------------------------------------------------------------------------
+# Exception, interrupt and thread context save area layout
+# The layout of this structure is also defined in "hal_arch.h", for C
+# code. Do not change this without changing that (or vice versa).
+
+#------------------------------------------------------------------------------
+# end of fr30.inc
diff --git a/packages/hal/fr30/arch/v2_0/include/fr30_stub.h b/packages/hal/fr30/arch/v2_0/include/fr30_stub.h
new file mode 100644 (file)
index 0000000..a3506c2
--- /dev/null
@@ -0,0 +1,160 @@
+//========================================================================
+//
+//      fr30_stub.h
+//
+//      FR30-specific definitions for remote debugging via gdb
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   larsi
+// Contributors:
+// Date:        2007-07-09
+// Purpose:     Fujitsu FR30-specific definitions for gdb stubs support
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#ifndef CYGONCE_HAL_FR30_STUB_H
+#define CYGONCE_HAL_FR30_STUB_H
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#ifdef CYGPKG_IO_SERIAL
+#include <pkgconf/io_serial.h>
+#endif
+
+#include <cyg/hal/hal_diag.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h>         // CYG_UNUSED_PARAM, externC
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL()       HAL_DIAG_INIT()
+
+#define HAL_STUB_PLATFORM_GET_CHAR()                                        \
+((cyg_int8)({                                                               \
+    cyg_int8 _ch_;                                                          \
+    HAL_DIAG_READ_CHAR(_ch_);                                               \
+    _ch_;                                                                   \
+}))
+
+#define HAL_STUB_PLATFORM_PUT_CHAR(c)         HAL_DIAG_WRITE_CHAR((c))
+
+#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int,(baud))
+
+#define HAL_STUB_PLATFORM_RESET()             HAL_DIAG_INIT()
+
+#define HAL_STUB_PLATFORM_INIT()              HAL_DIAG_INIT()
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#define FR30_GENREGS        16
+#define FR30_DEDICATEDREGS  8
+#define FR30_REGSIZE        4 /* bytes */
+
+// only NUMREGS and REGSIZE are the really needed macros
+
+#define NUMREGS (FR30_GENREGS + FR30_DEDICATEDREGS)
+#define REGSIZE( _x_ ) FR30_REGSIZE
+
+
+typedef unsigned long target_register_t;
+
+enum regnames {
+     R0,   R1,  R2,   R3,   R4,   R5,   R6,   R7,
+     R8,   R9,  R10,  R11,  R12,  R13,  R14,  SP,
+     PC,   PS,  TBR,  RP,   SSP,  USP,  MDH,  MDL
+};
+
+typedef enum regnames regnames_t;
+
+// Override generic stubs get_register() and use arch-specific version
+#define CYGARC_STUB_REGISTER_ACCESS_DEFINED
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
+#define HAL_GET_PROFILE_INFO( _thepc_, _thesp_ )                \
+    CYG_MACRO_START                                             \
+    extern HAL_SavedRegisters *hal_saved_interrupt_state;       \
+    if ( hal_saved_interrupt_state ) {                          \
+        (_thepc_) = (char *)(hal_saved_interrupt_state->pc);    \
+        (_thesp_) = (char *)(hal_saved_interrupt_state->sp);    \
+    }                                                           \
+    CYG_MACRO_END
+#endif
+
+/* Given a trap value TRAP, return the corresponding signal. */
+externC int __computeSignal (unsigned int trap_number);
+
+/* Return the trap number corresponding to the last-taken trap. */
+externC int __get_trap_number (void);
+
+/* Return the currently-saved value corresponding to register REG. */
+externC target_register_t get_register (regnames_t reg);
+
+/* Store VALUE in the register corresponding to WHICH. */
+externC void put_register (regnames_t which, target_register_t value);
+
+/* Set the currently-saved pc register value to PC. This also updates NPC
+   as needed. */
+externC void set_pc (target_register_t pc);
+
+/* Set things up so that the next user resume will execute one instruction.
+   This may be done by setting breakpoints or setting a single step flag
+   in the saved user registers, for example. */
+externC void __single_step (void);
+
+/* Clear the single-step state. */
+externC void __clear_single_step (void);
+
+/* If the breakpoint we hit is in the breakpoint() instruction, return a
+   non-zero value. */
+externC int __is_breakpoint_function (void);
+
+/* Skip the current instruction. */
+externC void __skipinst (void);
+
+externC void __install_breakpoints (void);
+
+externC void __clear_breakpoints (void);
+
+#endif // ifndef CYGONCE_HAL_FR30_STUB_H
+
+// EOF fr30_stub.h
diff --git a/packages/hal/fr30/arch/v2_0/include/hal_arch.h b/packages/hal/fr30/arch/v2_0/include/hal_arch.h
new file mode 100644 (file)
index 0000000..e537f26
--- /dev/null
@@ -0,0 +1,363 @@
+#ifndef CYGONCE_HAL_HAL_ARCH_H
+#define CYGONCE_HAL_HAL_ARCH_H
+
+//=============================================================================
+//
+//      hal_arch.h
+//
+//      Architecture specific abstractions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   larsi
+// Contributors:
+// Date:        2006-05-28
+// Purpose:     Define architecture abstractions
+// Usage:       #include <cyg/hal/hal_arch.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/var_arch.h>
+
+#define CYG_HAL_FR30_REG CYG_ADDRWORD
+
+//-----------------------------------------------------------------------------
+// Processor saved states. This structure is also defined in fr30.inc for
+// assembly code. Do not change this without changing that (or vice versa).
+
+typedef struct HAL_SavedRegisters
+{
+    cyg_uint32  r[16];  // general purpose registers with
+                        // r[13]: virtual accumulator (AC)
+                        // r[14]: frame pointer (FP)
+                        // r[15]: stack pointer (SP) r15 is not saved here!
+    cyg_uint32  pc;     // program counter
+    cyg_uint32  ps;     // program status (with ILM, SCR, CCR)
+    cyg_uint32  tbr;    // table base register (not neccessary,
+                        // as it is used system-wide not per thread)
+    cyg_uint32  rp;     // return pointer
+    // ssp is used system-wide for EIT processing and does not need to be saved here
+    // and therefore we don't store usp, because we have it already in r15
+    cyg_uint32  ssp;    // system stack pointer
+    cyg_uint32  usp;    // user stack pointer
+    cyg_uint32  mdh;    // multiplication and division regs /
+    cyg_uint32  mdl;    // with high and low words
+
+    cyg_uint32   last_trap; // the last taken trap (for GDB stubs)
+
+} HAL_SavedRegisters;
+
+
+//-----------------------------------------------------------------------------
+// Exception handling function.
+// This function is defined by the kernel according to this prototype. It is
+// invoked from the HAL to deal with any CPU exceptions that the HAL does
+// not want to deal with itself. It usually invokes the kernel's exception
+// delivery mechanism. FIXME
+// declared in src/hal_misc.c
+externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
+
+//-----------------------------------------------------------------------------
+// Bit manipulation routines
+// declared in src/hal_misc.c
+
+externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask);
+externC cyg_uint32 hal_msbit_index(cyg_uint32 mask);
+
+#define HAL_LSBIT_INDEX(index, mask) index = hal_lsbit_index(mask);
+
+#define HAL_MSBIT_INDEX(index, mask) index = hal_msbit_index(mask);
+
+//-----------------------------------------------------------------------------
+// Context Initialization
+// Initialize the context of a thread.
+// Arguments:
+// _sparg_ name of variable containing current sp, will be written with new sp
+// _thread_ thread object address, passed as argument to entry point
+// _entry_ entry point address.
+// _id_ bit pattern used in initializing registers, for debugging.
+
+#define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ )                     \
+    CYG_MACRO_START                                                                     \
+    register CYG_WORD _sp_ = ((CYG_WORD)_sparg_);                                       \
+    register HAL_SavedRegisters *_regs_;                                                \
+    int _i_;                                                                            \
+    _regs_ = (HAL_SavedRegisters *)(((_sp_) - sizeof(HAL_SavedRegisters)) & ~(CYGARC_ALIGNMENT - 1));             \
+    for( _i_ = 0; _i_ <= 14; _i_++ ) (_regs_)->r[_i_] = (_id_)|_i_;                     \
+    (_regs_)->r[15] = (CYG_HAL_FR30_REG)(_regs_);     /* r15 = USP = top of stack*/     \
+    (_regs_)->r[04] = (CYG_HAL_FR30_REG)(_thread_);   /* R4 = arg1 = thread ptr  */     \
+    (_regs_)->pc = (CYG_WORD)(_entry_);               /* PC = entry point        */     \
+    (_regs_)->ps = (CYG_HAL_FR30_REG)0x1f0030;        /* 0x000F0030;  set flags  */     \
+    (_regs_)->tbr = (CYG_HAL_FR30_REG)0x10ffc00;      /*system standard tbr value*/     \
+    (_regs_)->rp = (CYG_HAL_FR30_REG)0x0;             /* return pointer = 0x0    */     \
+    (_regs_)->ssp = (CYG_HAL_FR30_REG)0x0;            /* R4 = arg1 = thread ptr  */     \
+    (_regs_)->usp = (CYG_HAL_FR30_REG)(_regs_);       /* r15 = USP = top of stack*/     \
+    (_regs_)->mdh = (CYG_HAL_FR30_REG)0;              /* mdh = 0                 */     \
+    (_regs_)->mdl = (CYG_HAL_FR30_REG)0;              /* mdl = 0                 */     \
+    (_sparg_) = (CYG_ADDRESS)_regs_;                                                    \
+    CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+// Context switch macros.
+// The arguments are pointers to locations where the stack pointer
+// of the current thread is to be stored, and from where the sp of the
+// next thread is to be fetched.
+// declared in src/hal_misc.c
+
+externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from );
+externC void hal_thread_load_context( CYG_ADDRESS to )
+    __attribute__ ((noreturn));
+
+#define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_)                    \
+        hal_thread_switch_context((CYG_ADDRESS)_tspptr_,(CYG_ADDRESS)_fspptr_);
+
+#define HAL_THREAD_LOAD_CONTEXT(_tspptr_)                               \
+        hal_thread_load_context( (CYG_ADDRESS)_tspptr_ );
+
+//-----------------------------------------------------------------------------
+// Execution reorder barrier.
+// When optimizing the compiler can reorder code. In multithreaded systems
+// where the order of actions is vital, this can sometimes cause problems.
+// This macro may be inserted into places where reordering should not happen.
+
+#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" )
+
+//-----------------------------------------------------------------------------
+// Breakpoint support
+// HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen 
+// if executed.
+// HAL_BREAKINST is the value of the breakpoint instruction and
+// HAL_BREAKINST_SIZE is its size in bytes.
+
+#define HAL_BREAKPOINT(_label_)                 \
+CYG_MACRO_START                                 \
+    asm volatile (" .globl  " #_label_ ";\n"    \
+                  #_label_":\n"                 \
+                  "int #0x9\n"                  \
+        );                                      \
+CYG_MACRO_END
+
+// 0x9F30 is the INTE instruction (vector no.9, TBR offset 0x3D8)
+// 0x1f09 is the INT# 9 instruction (vector no.9, TBR offset 0x3D8)
+#define HAL_BREAKINST                    0x1f09
+#define HAL_BREAKINST_SIZE               2
+#define HAL_BREAKINST_TYPE               unsigned short
+
+//-----------------------------------------------------------------------------
+// Thread register state manipulation for GDB support.
+
+// Default to a 32 bit register size for GDB register dumps.
+#ifndef CYG_HAL_GDB_REG
+#define CYG_HAL_GDB_REG CYG_WORD32
+#endif
+
+// Register layout expected by GDB
+typedef struct 
+{
+    CYG_HAL_FR30_REG    r[16];          // was: r[0] GPR regs
+    CYG_HAL_FR30_REG    pc;
+    CYG_HAL_FR30_REG    ps;
+    CYG_HAL_FR30_REG    tbr;
+    CYG_HAL_FR30_REG    rp;
+    CYG_HAL_FR30_REG    ssp;
+    CYG_HAL_FR30_REG    usp;
+    CYG_HAL_FR30_REG    mdh;
+    CYG_HAL_FR30_REG    mdl;
+} GDB_Registers;
+
+// Translate a stack pointer as saved by the thread context macros above into
+// a pointer to a HAL_SavedRegisters structure declared in src/fr30_stub.h
+
+#define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ )  \
+         (_regs_) = (HAL_SavedRegisters *)(_sp_)
+
+// Copy a set of registers from a HAL_SavedRegisters structure into a
+// GDB ordered array.
+#define HAL_GET_GDB_REGISTERS( _aregval_, _regs_ )              \
+    CYG_MACRO_START                                             \
+    GDB_Registers *_gdb_ = (GDB_Registers *)(_aregval_);        \
+    int _i_;                                                    \
+                                                                \
+    for( _i_ = 0; _i_ <  16; _i_++ ) {                          \
+        _gdb_->r[_i_] = (_regs_)->r[_i_];                       \
+    }                                                           \
+                                                                \
+    _gdb_->pc = (_regs_)->pc;                                   \
+    _gdb_->ps = (_regs_)->ps;                                   \
+    _gdb_->tbr = (_regs_)->tbr;                                 \
+    _gdb_->rp = (_regs_)->rp;                                   \
+    _gdb_->ssp = (_regs_)->ssp;                                 \
+    _gdb_->usp = (_regs_)->usp;                                 \
+    _gdb_->mdh = (_regs_)->mdh;                                 \
+    _gdb_->mdl = (_regs_)->mdl;                                 \
+    CYG_MACRO_END
+
+// Copy a set of registers from a GDB_Registers structure into a
+// HAL_SavedRegisters structure.
+#define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ )             \
+    CYG_MACRO_START                                             \
+    GDB_Registers *_gdb_ = (GDB_Registers *)(_aregval_);        \
+    int _i_;                                                    \
+                                                                \
+    for( _i_ = 0; _i_ <  16; _i_++ )                            \
+        (_regs_)->r[_i_] = _gdb_->r[_i_];                       \
+                                                                \
+    (_regs_)->pc = _gdb_->pc;                                   \
+    (_regs_)->ps = _gdb_->ps;                                   \
+    (_regs_)->tbr = _gdb_->tbr;                                 \
+    (_regs_)->rp = _gdb_->rp;                                   \
+    (_regs_)->ssp = _gdb_->ssp;                                 \
+    (_regs_)->usp = _gdb_->usp;                                 \
+    (_regs_)->mdh = _gdb_->mdh;                                 \
+    (_regs_)->mdl = _gdb_->mdl;                                 \
+    CYG_MACRO_END
+
+
+// -------------------------------------------------------------------------
+// hal_setjmp/hal_longjmp
+
+
+// We must save all of the registers that are preserved across routine
+// calls. The assembly code assumes that this structure is defined in the
+// following format. Any changes to this structure will result in changes to
+// the assembly code!!
+
+typedef struct {
+    // registers
+    cyg_uint32 r8;
+    cyg_uint32 r9;
+    cyg_uint32 r10;
+    cyg_uint32 r11;
+    cyg_uint32 r14;
+
+    // SP and PC
+    cyg_uint32 r15; //USP
+    cyg_uint32 pc;
+} hal_jmp_buf_t;
+
+// This type is used by normal routines to pass the address of the structure
+// into our routines without having to explicitly take the address
+// of the structure.
+
+typedef cyg_uint32 hal_jmp_buf[sizeof(hal_jmp_buf_t) / sizeof(cyg_uint32)];
+
+// Define the generic setjmp and longjmp routines
+externC int hal_setjmp(hal_jmp_buf env);
+externC void hal_longjmp(hal_jmp_buf env, int val);
+//-----------------------------------------------------------------------------
+// Idle thread code.
+// This macro is called in the idle thread loop, and gives the HAL the
+// chance to insert code. Typical idle thread behaviour might be to halt the
+// processor. (contains an empty function call at the moment)
+// declared in src/hal_misc.c
+
+externC void hal_idle_thread_action(cyg_uint32 loop_count);
+
+#define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_)
+
+//-----------------------------------------------------------------------------
+// Minimal and sensible stack sizes: the intention is that applications
+// will use these to provide a stack size in the first instance prior to
+// proper analysis.  Idle thread stack should be this big.
+// 
+//    THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES.
+//           THEY ARE HOWEVER ENOUGH TO START PROGRAMMING.
+// YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES!
+
+// This is not a config option because it should not be adjusted except
+// under "enough rope" sort of disclaimers.
+
+//      Stack frame overhead per call.  13 registers (which is a maximum FIXME),
+// frame pointer, and return address.  We  can't guess the local variables  so
+// just assume that using all of the registers averages out.
+
+#define CYGNUM_HAL_STACK_FRAME_SIZE ((13 + 1 + 1) * 4)
+
+// Stack needed for a context switch.
+// it should be sizeof(HAL_SavedRegisters)
+//      All registers + PC + PS + RP + MDH + MDL
+
+#ifndef CYGNUM_HAL_STACK_CONTEXT_SIZE
+#define CYGNUM_HAL_STACK_CONTEXT_SIZE ((16+1+1+1+1+1)*4)
+#endif // CYGNUM_HAL_STACK_CONTEXT_SIZE
+
+// Interrupt + call to ISR, interrupt_end() and the DSR
+
+#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \
+((CYGNUM_HAL_STACK_CONTEXT_SIZE) + (4*CYGNUM_HAL_STACK_FRAME_SIZE))
+
+// We define a minimum stack size as the minimum any thread could ever
+// legitimately get away with. We can throw asserts if users ask for less
+// than this. Allow enough for four interrupt sources - clock, serial,
+// nic, and one other
+
+#define CYGNUM_HAL_STACK_SIZE_MINIMUM                   \
+((4*CYGNUM_HAL_STACK_INTERRUPT_SIZE)            \
+ + (16*CYGNUM_HAL_STACK_FRAME_SIZE))
+
+// Now make a reasonable choice for a typical thread size. Pluck figures
+// from thin air and say 30 call frames with an average of 16 words of
+// automatic variables per call frame
+
+#define CYGNUM_HAL_STACK_SIZE_TYPICAL                   \
+(CYGNUM_HAL_STACK_SIZE_MINIMUM +                \
+ (30 * (CYGNUM_HAL_STACK_FRAME_SIZE+(16*4))))
+
+//--------------------------------------------------------------------------
+// Memory access macros
+
+#define CYGARC_CACHED_ADDRESS(x)                       (x)
+#define CYGARC_UNCACHED_ADDRESS(x)                     (x)
+#define CYGARC_PHYSICAL_ADDRESS(x)                     (x)
+#define CYGARC_VIRTUAL_ADDRESS(x)                      (x)
+
+//--------------------------------------------------------------------------
+// Macros for switching context between two eCos instances (jump from
+// code in ROM to code in RAM or vice versa).
+
+#define CYGARC_HAL_SAVE_GP()
+#define CYGARC_HAL_RESTORE_GP()
+
+//--------------------------------------------------------------------------
+#endif // CYGONCE_HAL_HAL_ARCH_H
+// End of hal_arch.h
diff --git a/packages/hal/fr30/arch/v2_0/include/hal_cache.h b/packages/hal/fr30/arch/v2_0/include/hal_cache.h
new file mode 100644 (file)
index 0000000..6fee45d
--- /dev/null
@@ -0,0 +1,127 @@
+#ifndef CYGONCE_HAL_CACHE_H
+#define CYGONCE_HAL_CACHE_H
+
+//=============================================================================
+//
+//      hal_cache.h
+//
+//      HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   larsi
+// Contributors:
+// Date:        2007-07-09
+// Purpose:     Cache control API
+// Description: The macros defined here provide the HAL APIs for handling
+//              cache control operations.
+// Usage:
+//              #include <cyg/hal/hal_cache.h>
+//              ...
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//-----------------------------------------------------------------------------
+// Cache dimensions
+
+// Data cache
+#define HAL_DCACHE_SIZE                 4096    // Size of data cache in bytes
+#define HAL_DCACHE_LINE_SIZE            16      // Size of a data cache line
+#define HAL_DCACHE_WAYS                 2       // Associativity of the cache
+
+// Instruction cache
+#define HAL_ICACHE_SIZE                 4096    // Size of cache in bytes
+#define HAL_ICACHE_LINE_SIZE            16      // Size of a cache line
+#define HAL_ICACHE_WAYS                 2       // Associativity of the cache
+
+#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
+#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
+
+//-----------------------------------------------------------------------------
+// Global control of data cache
+
+// Enable the data cache
+#define HAL_DCACHE_ENABLE()
+
+// Disable the data cache
+#define HAL_DCACHE_DISABLE()
+
+// Query the state of the data cache
+#define HAL_DCACHE_IS_ENABLED(_state_) \
+CYG_MACRO_START                        \
+_state_ = 1;                          \
+CYG_MACRO_END
+
+// Invalidate the entire cache
+#define HAL_DCACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_DCACHE_SYNC()
+
+//-----------------------------------------------------------------------------
+// Global control of Instruction cache
+
+// Enable the instruction cache
+#define HAL_ICACHE_ENABLE()
+
+// Disable the instruction cache
+#define HAL_ICACHE_DISABLE()
+
+// Query the state of the instruction cache
+#define HAL_ICACHE_IS_ENABLED(_state_) \
+CYG_MACRO_START                        \
+_state_ = 1;                           \
+CYG_MACRO_END
+
+// Invalidate the entire cache
+#define HAL_ICACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_ICACHE_SYNC()
+
+//-----------------------------------------------------------------------------
+// Instruction cache line control
+
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_CACHE_H
+// End of hal_cache.h
diff --git a/packages/hal/fr30/arch/v2_0/include/hal_intr.h b/packages/hal/fr30/arch/v2_0/include/hal_intr.h
new file mode 100644 (file)
index 0000000..f9e4d14
--- /dev/null
@@ -0,0 +1,431 @@
+#ifndef CYGONCE_HAL_HAL_INTR_H
+#define CYGONCE_HAL_HAL_INTR_H
+
+//==========================================================================
+//
+//      hal_intr.h
+//
+//      FR30 HAL Interrupt and clock support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    larsi
+// Contributors: larsi
+// Date:         2006-06-09
+// Purpose:      Define Interrupt support
+// Description:  The macros defined here provide the HAL APIs for handling
+//               interrupts and the clock.
+//              
+// Usage:
+//               #include <cyg/hal/hal_intr.h>
+//               ...
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_fr30.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/var_intr.h>
+
+//--------------------------------------------------------------------------
+// Exception vectors.
+// Standard exception,interrupt and trap(EIT) vectors supported by FR30 CPUs
+// These values are the ones to use for HAL_VSR_GET/SET
+// The FR30 vector table lies in reversed in memory, therefore we do
+// the 255-x thing here.
+
+#define CYGNUM_HAL_VECTOR_RESET                   0
+// Values from 1 - 8 are system reserved
+#define CYGNUM_HAL_VECTOR_MODE_VECTOR             1
+#define CYGNUM_HAL_VECTOR_COPR_NOT_FOUND          7
+#define CYGNUM_HAL_VECTOR_COPR_ERROR              8
+#define CYGNUM_HAL_VECTOR_BREAKPOINT              9
+#define CYGNUM_HAL_VECTOR_INTE                    CYGNUM_HAL_VECTOR_BREAKPOINT
+// Values 10 and 11 are system reserved
+#define CYGNUM_HAL_VECTOR_INSTR_BREAK_EXCEPTION   10
+#define CYGNUM_HAL_VECTOR_OPERAND_BREAK_TRAP      11
+#define CYGNUM_HAL_VECTOR_DEBUG                   12
+#define CYGNUM_HAL_VECTOR_STEP_TRACE              CYGNUM_HAL_VECTOR_DEBUG
+// Value 13 is system reserved
+#define CYGNUM_HAL_VECTOR_NMI_INTR_TOOL           13
+// Value 14 undefined instruction exception
+#define CYGNUM_HAL_VECTOR_OPCODE                  14
+// NMI (special non maskable interrupt)
+#define CYGNUM_HAL_VECTOR_NMI                     15
+// interrupts
+// Note that these defines are for C code and have to be the same like those in
+// arch.inc for assembler code !
+#define CYGNUM_HAL_VECTOR_INTRFIRST               15
+#define CYGNUM_HAL_VECTOR_INTRLAST                63
+#define CYGNUM_HAL_VECTOR_NUMINTRS                (CYGNUM_HAL_VECTOR_INTRLAST-CYGNUM_HAL_VECTOR_INTRFIRST+1)
+// Values 64 and 65 are reserved for system
+// traps
+#define CYGNUM_HAL_VECTOR_TRAPFIRST               80
+#define CYGNUM_HAL_VECTOR_SYSTEM_CALL             CYGNUM_HAL_VECTOR_TRAPFIRST
+#define CYGNUM_HAL_VECTOR_TRAPLAST                255
+#define CYGNUM_HAL_VECTOR_NUMTRAPS                (CYGNUM_HAL_VECTOR_TRAPLAST-CYGNUM_HAL_VECTOR_TRAPFIRST+1)
+
+// The default size of the VSR table is 256 entries.
+#ifndef CYGNUM_HAL_VSR_MIN
+#define CYGNUM_HAL_VSR_MIN                        0
+#define CYGNUM_HAL_VSR_MAX                        255
+#define CYGNUM_HAL_VSR_COUNT                      256
+#endif
+
+// For ecos fr30 interrupts are interrupts and fr30 exceptions and
+// fr30 traps are both exceptions
+
+// Common interrupt vectors
+#ifndef CYGNUM_HAL_ISR_MIN
+#define CYGNUM_HAL_ISR_MIN                       CYGNUM_HAL_VECTOR_INTRFIRST
+#define CYGNUM_HAL_ISR_MAX                       CYGNUM_HAL_VECTOR_INTRLAST
+#define CYGNUM_HAL_ISR_COUNT                     (CYGNUM_HAL_VECTOR_NUMINTRS)
+#endif
+// Common exception vectors. (so these are fr30 exceptions and traps)
+#define CYGNUM_HAL_EXCEPTION_RESET               CYGNUM_HAL_VECTOR_RESET
+#define CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL       CYGNUM_HAL_VECTOR_COPR_NOT_FOUND
+#define CYGNUM_HAL_EXCEPTION_FPU                 CYGNUM_HAL_VECTOR_COPR_ERROR
+#define CYGNUM_HAL_EXCEPTION_TRAP                CYGNUM_HAL_VECTOR_INTE
+// #define CYGNUM_HAL_EXCEPTION_INTERRUPT           CYGNUM_HAL_VECTOR_BREAKPOINT
+// #define CYGNUM_HAL_EXCEPTION_TRAP                CYGNUM_HAL_VECTOR_STEP_TRACE
+#define CYGNUM_HAL_EXCEPTION_SINGLE_STEP         CYGNUM_HAL_VECTOR_STEP_TRACE
+#define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION CYGNUM_HAL_VECTOR_OPCODE
+
+// common interrupt vectors
+// I am sure more defines can be moved from variant to architecture HAL here
+#define CYGNUM_HAL_INTERRUPT_NMI                 15
+
+// here we define exceptions and traps as the fr30 docs termini
+#define CYGNUM_HAL_EXCEPTION_FR30_MIN            0
+#define CYGNUM_HAL_EXCEPTION_FR30_MAX            14
+#define CYGNUM_HAL_EXCEPTION_FR30_COUNT (CYGNUM_HAL_EXCEPTION_FR30_MAX - CYGNUM_HAL_EXCEPTION_FR30_MIN + 1)
+
+#define CYGNUM_HAL_TRAP_FR30_MIN                 80
+#define CYGNUM_HAL_TRAP_FR30_MAX                 255
+#define CYGNUM_HAL_TRAP_FR30_COUNT (CYGNUM_HAL_TRAP_FR30_MAX - CYGNUM_HAL_TRAP_FR30_MIN + 1)
+
+// here we define the ecos ones
+// nicht mehr aktuell:(calculated from fr30 ones) FIXME maybe have to
+// change to correspons to durchgaengig vector numbers. In this table
+// exceptions are unterbrochen from interrupts
+#define CYGNUM_HAL_EXCEPTION_MIN                 0
+#define CYGNUM_HAL_EXCEPTION_MAX                 255
+#define CYGNUM_HAL_EXCEPTION_COUNT           \
+                 ( CYGNUM_HAL_EXCEPTION_MAX - CYGNUM_HAL_EXCEPTION_MIN + 1 )
+
+//--------------------------------------------------------------------------
+// Interrupt levels
+// Lower numbers mean stronger interrupt levels
+// values 0 - 14 are system reserved and can not be set by a program
+// (setting them would add 16 to the value automatically)
+// value 15 is for NMI
+// value 31 disables the interrupt
+
+#ifndef CYGHWR_HAL_INTERRUPT_LEVELS_DEFINED
+
+#define CYGNUM_HAL_INTERRUPT_LEVEL_0                     16
+#define CYGNUM_HAL_INTERRUPT_LEVEL_1                     17
+#define CYGNUM_HAL_INTERRUPT_LEVEL_2                     18
+#define CYGNUM_HAL_INTERRUPT_LEVEL_3                     19
+#define CYGNUM_HAL_INTERRUPT_LEVEL_4                     20
+#define CYGNUM_HAL_INTERRUPT_LEVEL_5                     21
+#define CYGNUM_HAL_INTERRUPT_LEVEL_6                     22
+#define CYGNUM_HAL_INTERRUPT_LEVEL_7                     23
+#define CYGNUM_HAL_INTERRUPT_LEVEL_8                     24
+#define CYGNUM_HAL_INTERRUPT_LEVEL_9                     25
+#define CYGNUM_HAL_INTERRUPT_LEVEL_10                    26
+#define CYGNUM_HAL_INTERRUPT_LEVEL_11                    27
+#define CYGNUM_HAL_INTERRUPT_LEVEL_12                    28
+#define CYGNUM_HAL_INTERRUPT_LEVEL_13                    29
+#define CYGNUM_HAL_INTERRUPT_LEVEL_14                    30
+#define CYGNUM_HAL_INTERRUPT_LEVEL_15                    31
+#define CYGNUM_HAL_INTERRUPT_LEVEL_DISABLE              \
+  CYGNUM_HAL_INTERRUPT_LEVEL_15
+
+#define CYGHWR_HAL_INTERRUPT_LEVELS_DEFINED
+
+#endif
+
+//--------------------------------------------------------------------------
+// Static data used by HAL
+
+// ISR tables
+externC volatile CYG_ADDRESS  hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
+externC volatile CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
+externC volatile CYG_ADDRESS  hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
+
+// VSR table
+externC volatile CYG_ADDRESS  hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
+
+//--------------------------------------------------------------------------
+// Interrupt state storage
+
+typedef cyg_uint32 CYG_INTERRUPT_STATE;
+
+//---------------------------------------------------------------------------
+// Default ISR
+externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
+
+#define HAL_DEFAULT_ISR hal_default_isr
+
+//--------------------------------------------------------------------------
+// CPU interrupt enable/disable macros
+
+#define HAL_ENABLE_INTERRUPTS()                 \
+CYG_MACRO_START                                 \
+    asm volatile ("orccr #0x10;\n") ;           \
+CYG_MACRO_END
+
+#define HAL_DISABLE_INTERRUPTS(_old_)           \
+CYG_MACRO_START                                 \
+    register int x ;                            \
+    asm volatile ("st   r1, @-r15 ;\n"          \
+         "MOV PS, r1 ;\n"                       \
+         "LDI:8 #0x10,%0 ;\n"                   \
+         "AND r1, %0 ;\n"                       \
+         "LSR #1,%0 ;\n"                        \
+         "ld    @r15+,  r1 ;\n"                 \
+         "ANDCCR #0xEF \n"                      \
+         :  "=r" (x)                            \
+        );                                      \
+    (_old_) = (x);                              \
+CYG_MACRO_END
+
+#define HAL_RESTORE_INTERRUPTS(_old_)           \
+CYG_MACRO_START                                 \
+    register int x = _old_;                     \
+    asm volatile ( "CMP #8, %0 ;\n"             \
+                   "BEQ 0f ;\n"                 \
+                   "ANDCCR #0xEF ;\n"           \
+                   "BRA 1f;\n"                  \
+                   "0:\n"                       \
+                   "ORCCR #0x10 ;\n"            \
+                   "1:\n"                       \
+                   : /* No outputs */           \
+                   : "r"(x)                     \
+                 );                             \
+CYG_MACRO_END
+
+// 5th bit (0x10 / #10H) is interrupt flag
+// it is shifted right to be able to work with 4 bit immediate in the other macros
+#define HAL_QUERY_INTERRUPTS(_old_)             \
+CYG_MACRO_START                                 \
+    register int x ;                            \
+    asm volatile ("MOV PS,__tmp_reg__ ;\n"      \
+         "LDI:8 #10H,%0 ;\n"                    \
+         "AND __tmp_reg__,%0 ;\n"               \
+         "LSR #1,%0 ;\n"                        \
+         :  "=r" (x)                            \
+        );                                      \
+    (_old_) = (x);                              \
+CYG_MACRO_END
+
+//---------------------------------------------------------------------------
+// Interrupt and VSR attachment macros
+
+
+#define HAL_INTERRUPT_IN_USE( _vector_, _state_)        \
+    CYG_MACRO_START                                     \
+    cyg_uint32 _index_;                                 \
+    HAL_TRANSLATE_VECTOR ((_vector_), _index_);         \
+                                                        \
+    if (hal_interrupt_handlers[_index_]                 \
+        ==(CYG_ADDRESS)HAL_DEFAULT_ISR)                 \
+        (_state_) = 0;                                  \
+    else                                                \
+        (_state_) = 1;                                  \
+    CYG_MACRO_END
+
+#ifndef HAL_INTERRUPT_ATTACH
+externC void __default_interrupt_vsr(void);
+#define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ )               \
+    CYG_MACRO_START                                                             \
+    cyg_uint32 _index_;                                                         \
+    HAL_TRANSLATE_VECTOR((_vector_), _index_);                                  \
+                                                                                \
+    HAL_VSR_SET( _vector_, &__default_interrupt_vsr , NULL);                    \
+    if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR )       \
+    {                                                                           \
+        hal_interrupt_handlers[_index_] = (CYG_ADDRESS)(_isr_);                 \
+        hal_interrupt_data[_index_] = (CYG_ADDRWORD)(_data_);                   \
+        hal_interrupt_objects[_index_] = (CYG_ADDRESS)(_object_);               \
+    }                                                                           \
+    CYG_MACRO_END
+#endif /* HAL_INTERRUPT_ATTACH */
+
+#define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \
+    CYG_MACRO_START                             \
+    cyg_uint32 _index_;                         \
+    HAL_TRANSLATE_VECTOR((_vector_), _index_);  \
+                                                \
+    if (hal_interrupt_handlers[_index_]         \
+        == (CYG_ADDRESS)(_isr_))                \
+    {                                           \
+        hal_interrupt_handlers[_index_] =       \
+            (CYG_ADDRESS)HAL_DEFAULT_ISR;       \
+        hal_interrupt_data[_index_] = 0;        \
+        hal_interrupt_objects[_index_] = 0;     \
+    }                                           \
+    CYG_MACRO_END
+
+#define HAL_VSR_GET( _vector_, _pvsr_ )                         \
+    *((CYG_ADDRESS *)(_pvsr_)) = hal_vsr_table[(_vector_)];
+
+
+#define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ )               \
+    CYG_MACRO_START                                             \
+    CYG_ADDRESS *__poldvsr = (CYG_ADDRESS *)(_poldvsr_);        \
+    if( __poldvsr != NULL )                                     \
+        *__poldvsr = hal_vsr_table[(_vector_)];                 \
+    hal_vsr_table[(_vector_)] = (CYG_ADDRESS)(_vsr_);           \
+    CYG_MACRO_END
+
+// This is an ugly name, but what it means is: grab the VSR back to eCos
+// internal handling, or if you like, the default handler.  But if
+// cooperating with GDB and CygMon, the default behaviour is to pass most
+// exceptions to CygMon.  This macro undoes that so that eCos handles the
+// exception.  So use it with care.
+
+externC void __default_exception_vsr(void);
+externC void __default_interrupt_vsr(void);
+
+#define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ )                  \
+CYG_MACRO_START                                                             \
+    HAL_VSR_SET( _vector_, _vector_ > CYGNUM_HAL_EXCEPTION_MAX              \
+                              ? (CYG_ADDRESS)__default_interrupt_vsr        \
+                                : (CYG_ADDRESS)__default_exception_vsr,     \
+                 _poldvsr_ );                                               \
+CYG_MACRO_END
+
+//--------------------------------------------------------------------------
+// Vector translation.
+// For chained interrupts we only have a single vector though which all
+// are passed. For unchained interrupts we have a vector per interrupt.
+
+#ifndef HAL_TRANSLATE_VECTOR
+
+#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN)
+
+#define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = 0
+
+#else
+
+#define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_)
+
+#endif
+
+#endif
+
+//--------------------------------------------------------------------------
+// Clock control.
+// This code uses the 16 bit reload timer 1. The defines are used to specify
+// the IO adress of the registers, that are different in FR30 variants.
+
+#ifndef CYGHWR_HAL_CLOCK_CONTROL_DEFINED
+
+extern CYG_WORD32 cyg_hal_clock_period;
+
+#define CYGHWR_HAL_CLOCK_PERIOD_DEFINED
+
+#define HAL_CLOCK_INITIALIZE( _period_ )                    \
+CYG_MACRO_START                                             \
+    HAL_WRITE_UINT16( CYG_HAL_FR30_RTC_TMRLR , _period_);   \
+    HAL_WRITE_UINT16( CYG_HAL_FR30_RTC_TMCSR , 0x081b);     \
+    cyg_hal_clock_period = _period_;                        \
+CYG_MACRO_END
+
+// This clears the interrupt request for reload timer 1 (RTC)
+#define HAL_CLOCK_RESET( _vector_, _period_ )               \
+CYG_MACRO_START                                             \
+asm volatile("ldi:8     #0x57,  r0;\n"                      \
+             "bandl     #0xb,   @r0;\n"                     \
+             : : :"r0");                                    \
+CYG_MACRO_END
+
+#define HAL_CLOCK_READ( _pvalue_ )                          \
+CYG_MACRO_START                                             \
+    CYG_FAIL("clock_read");                                 \
+    register CYG_WORD32 result;                             \
+    HAL_READ_UINT16( CYG_HAL_FR30_RTC_TMR, result);         \
+    *(_pvalue_) = cyg_hal_clock_period - result;            \
+CYG_MACRO_END
+
+#define CYGHWR_HAL_CLOCK_CONTROL_DEFINED
+
+#endif
+
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && \
+    !defined(HAL_CLOCK_LATENCY)
+#define HAL_CLOCK_LATENCY( _pvalue_ )                       \
+CYG_MACRO_START                                             \
+    register CYG_WORD32 _cval_;                             \
+    HAL_CLOCK_READ(&_cval_);                                \
+    *(_pvalue_) = _cval_ - cyg_hal_clock_period;            \
+CYG_MACRO_END
+#endif
+
+//----------------------------------------------------------------------------
+// Reset
+// this clears BIT4 in STCR(0x481), which should issue a reset
+
+#define HAL_PLATFORM_RESET()                                \
+    asm volatile (                                          \
+        "ldi:20 #0x481, r0;\n"                              \
+        "bandh  #1,     @r0;\n"                             \
+        : : :"r0");
+
+externC void _start(void);
+#define HAL_PLATFORM_RESET_ENTRY        (&_start)
+
+//--------------------------------------------------------------------------
+// Microsecond delay
+// This uses reload timer 2, because timer 0 and 1 can cause DMA transfers.
+// Timer 2 is only used for delay service. We maybe support it out of the
+// scheduler clock in the future.
+
+externC void hal_delay_us(cyg_int32 usecs);
+#define HAL_DELAY_US(_millis_)           hal_delay_us(_millis_);
+
+//---------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_HAL_INTR_H
+// End of hal_intr.h
diff --git a/packages/hal/fr30/arch/v2_0/include/hal_io.h b/packages/hal/fr30/arch/v2_0/include/hal_io.h
new file mode 100644 (file)
index 0000000..c848073
--- /dev/null
@@ -0,0 +1,160 @@
+#ifndef CYGONCE_HAL_HAL_IO_H
+#define CYGONCE_HAL_HAL_IO_H
+
+//=============================================================================
+//
+//      hal_io.h
+//
+//      HAL device IO register support.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   larsi
+// Contributors:
+// Date:        2007-07-09
+// Purpose:     Define IO register support
+// Description: The macros defined here provide the HAL APIs for handling
+//              device IO control registers.
+//              
+// Usage:
+//              #include <cyg/hal/hal_io.h>
+//              ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/plf_io.h>
+
+//-----------------------------------------------------------------------------
+// IO Register address.
+// This type is for recording the address of an IO register.
+
+typedef volatile CYG_ADDRWORD HAL_IO_REGISTER;
+
+//-----------------------------------------------------------------------------
+// HAL IO macros.
+#ifndef HAL_IO_MACROS_DEFINED
+
+//-----------------------------------------------------------------------------
+// BYTE Register access.
+// Individual and vectorized access to 8 bit registers.
+
+#define HAL_READ_UINT8( _register_, _value_ ) \
+        asm volatile ("ldub  @%1, %0": "=r" (_value_): "r" (_register_));
+//        ((_value_) = *((volatile CYG_BYTE *)(_register_)))
+
+#define HAL_WRITE_UINT8( _register_, _value_ ) \
+        asm volatile ("stb  %0, @%1": : "r" (_value_), "r" (_register_));
+//        (*((volatile CYG_BYTE *)(_register_)) = (_value_))
+
+#define HAL_READ_UINT8_VECTOR( _register_, _buf_, _count_, _step_ )     \
+{                                                                       \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_))     \
+        (_buf_)[_i_] = ((volatile CYG_BYTE *)(_register_))[_j_];        \
+}
+
+#define HAL_WRITE_UINT8_VECTOR( _register_, _buf_, _count_, _step_ )    \
+{                                                                       \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_))     \
+        ((volatile CYG_BYTE *)(_register_))[_j_] = (_buf_)[_i_];        \
+}
+
+//-----------------------------------------------------------------------------
+// 16 bit access.
+// Individual and vectorized access to 16 bit registers.
+
+#define HAL_READ_UINT16( _register_, _value_ ) \
+        asm volatile ("lduh  @%1, %0": "=r" (_value_): "r" (_register_));
+
+#define HAL_WRITE_UINT16( _register_, _value_ ) \
+        asm volatile ("sth  %0, @%1": : "r" (_value_), "r" (_register_));
+
+#define HAL_READ_UINT16_VECTOR( _register_, _buf_, _count_, _step_ )    \
+{                                                                       \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_))     \
+        (_buf_)[_i_] = ((volatile CYG_WORD16 *)(_register_))[_j_];      \
+}
+
+#define HAL_WRITE_UINT16_VECTOR( _register_, _buf_, _count_, _step_ )   \
+{                                                                       \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_))     \
+        ((volatile CYG_WORD16 *)(_register_))[_j_] = (_buf_)[_i_];      \
+}
+
+//-----------------------------------------------------------------------------
+// 32 bit access.
+// Individual and vectorized access to 32 bit registers.
+    
+#define HAL_READ_UINT32( _register_, _value_ ) \
+        asm volatile ("ld  @%1, %0": "=r" (_value_): "r" (_register_));
+
+#define HAL_WRITE_UINT32( _register_, _value_ ) \
+        asm volatile ("st  %0, @%1": : "r" (_value_), "r" (_register_));
+
+#define HAL_READ_UINT32_VECTOR( _register_, _buf_, _count_, _step_ )    \
+{                                                                       \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_))     \
+        (_buf_)[_i_] = ((volatile CYG_WORD32 *)(_register_))[_j_];      \
+}
+
+#define HAL_WRITE_UINT32_VECTOR( _register_, _buf_, _count_, _step_ )   \
+{                                                                       \
+    cyg_count32 _i_,_j_;                                                \
+    for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_))     \
+        ((volatile CYG_WORD32 *)(_register_))[_j_] = (_buf_)[_i_];      \
+}
+
+#define HAL_IO_MACROS_DEFINED
+
+#endif
+
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_HAL_IO_H
+// End of hal_io.h
diff --git a/packages/hal/fr30/arch/v2_0/src/context.S b/packages/hal/fr30/arch/v2_0/src/context.S
new file mode 100644 (file)
index 0000000..2810bc8
--- /dev/null
@@ -0,0 +1,201 @@
+##=============================================================================
+##
+##      context.S
+##
+##      FR30 context switch and longjmp setjmp code
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):   larsi
+## Contributors:larsi
+## Date:        2006-06-03
+## Purpose:     fr30 context switch code
+## Description: This file contains implementations of the thread context 
+##              switch routines. It also contains the longjmp() and setjmp()
+##              routines.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/fr30.inc>
+
+#include <cyg/hal/arch.inc>
+       
+#------------------------------------------------------------------------------
+# function declaration macro
+
+#define FUNC_START(name)                        \
+        .globl name;                            \
+name:
+
+#------------------------------------------------------------------------------
+# hal_thread_switch_context
+# Switch thread contexts
+# 
+# a timer interrupt should have caused this function to be called
+# so interrupts are forbidden and we are in SSP mode (S flag=1)
+#
+# R4 and R5 contain our arguments.
+# R5 is _fspptr_ (old USP), R4 is _tspptr_ (new USP).
+# @(SSP) has the return address of the call to this function.
+# In @(SSP,4) the PS and in @(SSP,8) the PC are saved by hardware.
+# Before we RETI, we have to switch S flag in CCR to 0
+# to use SSP for returning. Interrupts have to be
+# reenabled before returning, but this is done by restoring PS.
+
+
+    .globl  hal_thread_switch_context
+hal_thread_switch_context:
+
+# at first switch to USP (set bit 5 in CCR in PS)
+    st      r0,     @-r15       ; push last_trap, cannot guarantee that it is
+                                ; the right value, but that should not matter
+                                ; as it is only for GDB
+    st      mdl,    @-r15
+    st      mdh,    @-r15
+
+    st      r0,     @-r15       ; store usp
+
+    st      r0,     @-r15       ; store ssp
+    st      rp,     @-r15
+    st      tbr,    @-r15
+    st      ps,     @-r15
+    st      rp,     @-r15       ; rp is our new pc when load_context executes
+
+    st      r15,    @-r15       ; store original r15 here
+
+    stm1    (r8, r9, r10, r11, r12, r13, r14)
+    stm0    (r0, r1, r2, r3 , r4 , r5 , r6 , r7)
+
+# we should be finished saving context here
+
+    st      r15,    @r5         ; store pointer to saved context
+
+#------------------------------------------------------------------------------
+# hal_thread_load_context
+# Load thread context
+.globl  hal_thread_load_context
+hal_thread_load_context:
+
+    ld      @r4,     r15
+
+    ldm0    (r0, r1, r2, r3, r4, r5, r6, r7)
+    ldm1    (r8, r9, r10, r11, r12, r13, r14)
+    ld      @r15+,  mdl
+    ld      @r15+,  rp
+    ld      @r15+,  ps
+    ld      @r15+,  tbr
+# TODO addsp to skip stack positions
+    ld      @r15+,  mdl
+    ld      @r15+,  mdl
+    ld      @r15+,  mdl
+    ld      @r15+,  mdh
+    ld      @r15+,  mdl
+    addsp   4
+    ret
+
+#------------------------------------------------------------------------------
+# HAL longjmp, setjmp implementations
+# hal_setjmp saves only to callee save registers r8, r9, r10, r11, r14, r15
+# into buffer supplied in r4
+# Note: These definitions are repeated in hal_arch.h. If changes are required
+# remember to update both sets.
+# setjmp/longjmp for FR30.  The jmpbuf looks like this:
+#
+# Register  jmpbuf offset
+# r8        0x00
+# r9        0x04
+# r10       0x08
+# r11       0x0c
+# r14 (FP)  0x10
+# r15 (SP)  0x14
+# pc  (rp)  0x18
+
+    .macro save reg
+    st      \reg,   @r4
+    addn    #4,     r4
+    .endm
+
+    .macro restore reg
+    ld      @r4,    \reg
+    addn    #4,     r4
+    .endm
+
+
+    .text
+    .global hal_setjmp
+    .type   hal_setjmp,@function
+hal_setjmp:
+    save    r8
+    save    r9
+    save    r10
+    save    r11
+    save    r14
+    save    r15
+    mov     rp,     r5
+    st      r5,     @r4
+
+# Return 0 to caller.
+    ldi:8   #0,     r4
+    ret
+
+    .global hal_longjmp
+hal_longjmp:
+    restore r8
+    restore r9
+    restore r10
+    restore r11
+    restore r14
+    restore r15
+    ld      @r4,    r4
+    mov     r4,     rp
+
+# If caller attempted to return 0, return 1 instead.
+
+    mov     r5,     r4
+    or      r4,     r4
+    bne     1f
+    ldi:8   #1,     r4
+1:
+    ret
+
+#-----------------------------------------------------------------------------
+# End of context.S
diff --git a/packages/hal/fr30/arch/v2_0/src/fr30_stub.c b/packages/hal/fr30/arch/v2_0/src/fr30_stub.c
new file mode 100644 (file)
index 0000000..4de53c5
--- /dev/null
@@ -0,0 +1,210 @@
+//========================================================================
+//
+//      fr30_stub.c
+//
+//      Fujitsu FR30-specific code for remote debugging via gdb
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     larsi
+// Contributors:  
+// Date:          2007-07-09
+// Purpose:       
+// Description:   Helper functions for gdb stub for FR30 processors
+// Usage:         
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+
+#include <stddef.h>
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
+
+#include <cyg/hal/hal_stub.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+#include <cyg/hal/dbg-threads-api.h>    // dbg_currthread_id
+#endif
+
+/* Given a trap value TRAP, return the corresponding signal. */
+
+int __computeSignal (unsigned int trap_number)
+{
+    switch (trap_number)
+    {
+
+    case CYGNUM_HAL_VECTOR_COPR_NOT_FOUND:
+    case CYGNUM_HAL_VECTOR_COPR_ERROR:
+        return SIGFPE;
+
+        // step trace TRAP
+    case CYGNUM_HAL_VECTOR_DEBUG:
+        // INTE
+    case CYGNUM_HAL_VECTOR_BREAKPOINT:
+        return SIGTRAP;
+        /* System call instruction executed */
+    case CYGNUM_HAL_VECTOR_SYSTEM_CALL ... CYGNUM_HAL_VECTOR_TRAPLAST:
+        return SIGSYS;
+        /* External interrupt */
+    case CYGNUM_HAL_INTERRUPT_0 ... CYGNUM_HAL_INTERRUPT_DELAYED_IRQ:
+      return SIGINT;
+      // Illegal or reserved instruction
+    case CYGNUM_HAL_VECTOR_OPCODE:
+        return SIGILL;
+
+    // Marks port does think to return SIGTRAP as default.
+    default:
+        return SIGTERM;
+    }
+}
+
+/* Return the trap number corresponding to the last-taken trap. */
+
+int __get_trap_number (void)
+{
+    // The vector is not not part of the GDB register set so get it
+    // directly from the save context.
+    return _hal_registers->last_trap;
+}
+
+/* Set the currently-saved pc register value to PC. This also updates NPC
+   as needed. */
+
+void set_pc (target_register_t pc)
+{
+    put_register (PC, pc);
+}
+
+/*----------------------------------------------------------------------
+ * Single-step support
+ */
+
+/* Set things up so that the next user resume will execute one instruction.
+   This may be done by setting breakpoints or setting a single step flag
+   in the saved user registers, for example. */
+
+void __single_step (void)
+{
+  /* Trying to use processors single stepping.
+     This means to set T flag in PS register. */
+    put_register (PS, get_register (PS) | 0x100);
+}
+
+/* Clear the single-step state. */
+void __clear_single_step (void)
+{
+    put_register (PS, get_register (PS) & ~0x100);
+}
+
+void __install_breakpoints ()
+{
+  /*  if (instrBuffer.targetAddr != NULL)
+    {
+      instrBuffer.savedInstr = *instrBuffer.targetAddr;
+      *instrBuffer.targetAddr = __break_opcode ();
+      } */
+
+  /* Install the breakpoints in the breakpoint list */
+  __install_breakpoint_list();
+
+  // No need to flush caches here; Generic stub code will handle this.
+}
+
+void __clear_breakpoints (void)
+{
+  __clear_breakpoint_list();
+}
+
+/* If the breakpoint we hit is in the breakpoint() instruction, return a
+   non-zero value. */
+
+int
+__is_breakpoint_function ()
+{
+    return get_register (PC) == (target_register_t)&_breakinst;
+}
+
+/* Skip the current instruction.  Since this is only called by the
+   stub when the PC points to a breakpoint or trap instruction,
+   we can safely just skip 2. */
+
+void __skipinst (void)
+{
+    put_register (PC, get_register (PC) + 2);
+}
+
+/* Get a register out of the GDB register structure */
+target_register_t
+get_register (regnames_t reg)
+{
+    GDB_Registers* gdb_regs;
+
+    gdb_regs = (GDB_Registers*)_registers;
+
+    if (reg >= R0 && reg <= MDL)
+        return gdb_regs->r[reg];
+
+    return 0xdeadbeef;
+}
+
+/* Put a register into the GDB register structure */
+void
+put_register (regnames_t reg, target_register_t value)
+{
+    GDB_Registers* gdb_regs;
+
+    gdb_regs = (GDB_Registers*)_registers;
+
+    if (reg >= R0 && reg <= MDL) {
+        gdb_regs->r[reg] = value;
+    } else {
+        CYG_FAIL("Attempt to write to non-existent register ");
+    }
+}
+
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+// EOF openrisc_stub.c
diff --git a/packages/hal/fr30/arch/v2_0/src/hal_misc.c b/packages/hal/fr30/arch/v2_0/src/hal_misc.c
new file mode 100644 (file)
index 0000000..b2dc9c0
--- /dev/null
@@ -0,0 +1,245 @@
+//==========================================================================
+//
+//      hal_misc.c
+//
+//      HAL miscellaneous functions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+#include <pkgconf/hal.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>           // VSR/ISR defines
+#include <cyg/hal/hal_misc.h>
+
+/*------------------------------------------------------------------------*/
+/* If required, define a variable to store the clock period.              */
+
+#ifdef CYGHWR_HAL_CLOCK_PERIOD_DEFINED
+
+CYG_WORD32 cyg_hal_clock_period;
+
+#endif
+
+
+/*****************************************************************************
+hal_default_exception_handler -- First level C exception handler
+
+     The assembly default VSR  handler calls  this routine  to handle  the
+exception.  When this routine returns, the  state is restored to the  state
+pointed to by regs.
+
+     We declare this  routine as  weak so  that other  handlers can  easily
+become the default exception handler.
+
+INPUT:
+
+     vector: The exception vector number.
+
+     regs: A pointer to the saved state.
+
+OUTPUT:
+
+RETURN VALUE:
+
+     None
+
+*****************************************************************************/
+
+externC void
+hal_default_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs)
+                                                    __attribute__ ((weak));
+
+void hal_default_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs)
+{
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+    externC void __handle_exception(void);
+    externC HAL_SavedRegisters * _hal_registers;
+
+    // Set the pointer to the registers of the current exception
+    // context. At entry the GDB stub will expand the
+    // HAL_SavedRegisters structure into a (bigger) register array.
+    _hal_registers = regs;
+
+    __handle_exception();
+
+#elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
+      defined(CYGPKG_HAL_EXCEPTIONS)
+
+    // We should decode the vector and pass a more appropriate
+    // value as the second argument. For now we simply pass a
+    // pointer to the saved registers. We should also divert
+    // breakpoint and other debug vectors into the debug stubs.
+
+    cyg_hal_deliver_exception(vector, (CYG_ADDRWORD)regs);
+
+#else
+
+    CYG_FAIL("Exception!!!");
+
+#endif
+
+    return;
+}
+
+//---------------------------------------------------------------------------
+// Default arch ISR
+
+externC cyg_uint32
+hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+{
+    CYG_FAIL("Spurious Interrupt!!!");
+    return 0;
+}
+
+//---------------------------------------------------------------------------
+// Idle thread action
+
+void
+hal_idle_thread_action( cyg_uint32 count )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Monitor initialization. This means to init the vsr vector table.
+// TODO maybe init hal_vsr_table through defining it in assembler code
+
+#ifndef CYGPKG_HAL_FR30_MON_DEFINED
+void hal_mon_init(void){
+    int i;
+    /* 0 - 14 exceptions */
+    for(i = 0; i < CYGNUM_HAL_VECTOR_INTRFIRST; i++){
+        hal_vsr_table[i] = (CYG_ADDRESS)__default_exception_vsr;
+    }
+    /* 15 - xx interrupts */
+    for( ; i < CYGNUM_HAL_VECTOR_INTRLAST; i++){
+        hal_vsr_table[i] = (CYG_ADDRESS)__default_interrupt_vsr;
+    }
+    /*  xx+1 - 255 exceptions (fr30 traps) */
+    for( ; i < CYGNUM_HAL_VSR_MAX; i++){
+        hal_vsr_table[i] = (CYG_ADDRESS)__default_exception_vsr;
+    }
+}
+#endif
+
+//---------------------------------------------------------------------------
+// Determine the index of the ls bit of the supplied mask.
+
+cyg_uint32
+hal_lsbit_index(cyg_uint32 mask)
+{
+    cyg_uint32 n = mask;
+
+    static const signed char tab[64] =
+    { -1, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10,
+      4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27 , 15, 31, 11,
+      5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0 , 20, 26, 30, 0, 0, 0,
+      0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0
+    };
+
+    n &= ~(n-1UL);
+    n = (n<<16)-n;
+    n = (n<<6)+n;
+    n = (n<<4)+n;
+
+    return tab[n>>26];
+}
+
+//---------------------------------------------------------------------------
+// Determine the index of the ms bit of the supplied mask. FIXME: since we
+// have hardware support for it, use it! (bit search module)
+
+cyg_uint32
+hal_msbit_index(cyg_uint32 mask)
+{
+    cyg_uint32 x = mask;
+    cyg_uint32 w;
+
+    // Phase 1: make word with all ones from that one to the right.
+    x |= x >> 16;
+    x |= x >> 8;
+    x |= x >> 4;
+    x |= x >> 2;
+    x |= x >> 1;
+
+    // Phase 2: calculate number of "1" bits in the word.
+    w = (x & 0x55555555) + ((x >> 1) & 0x55555555);
+    w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
+    w = w + (w >> 4);
+    w = (w & 0x000F000F) + ((w >> 8) & 0x000F000F);
+    return (cyg_uint32)((w + (w >> 16)) & 0xFF);
+
+}
+
+/*------------------------------------------------------------------------*/
+/* C++ support - run initial constructors                                 */
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+cyg_bool cyg_hal_stop_constructors;
+#endif
+
+typedef void (*pfunc) (void);
+extern pfunc __CTOR_LIST__[];
+extern pfunc __CTOR_END__[];
+
+void
+        cyg_hal_invoke_constructors (void)
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+    static pfunc *p = &__CTOR_END__[-1];
+
+    cyg_hal_stop_constructors = 0;
+    for (; p >= __CTOR_LIST__; p--) {
+        (*p) ();
+        if (cyg_hal_stop_constructors) {
+            p--;
+            break;
+        }
+    }
+#else
+    pfunc *p;
+    for (p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--) {
+        (*p) ();
+    }
+#endif
+}
+
+//---------------------------------------------------------------------------
diff --git a/packages/hal/fr30/arch/v2_0/src/vectors.S b/packages/hal/fr30/arch/v2_0/src/vectors.S
new file mode 100644 (file)
index 0000000..49481d1
--- /dev/null
@@ -0,0 +1,566 @@
+##=============================================================================
+##
+##      vectors.S
+##
+##      fr30 startup code and exception and interrupt vectors
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):   larsi
+## Contributors:larsi
+## Date:        2006-06-26
+## Purpose:     fr30 exception vectors
+## Description: This file defines the code placed into the exception
+##              vectors. It also contains the startup code and first
+##              level default VSRs that save and restore state for
+##              both exceptions and interrupts.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#endif /* CYGPKG_KERNEL */
+
+#include <cyg/hal/arch.inc>
+
+#==============================================================================
+
+    .file   "vectors.S"
+
+#==============================================================================
+# Real startup code. We jump here from the various reset vectors to set up the
+# world.
+
+    .text
+    .globl     _start
+
+_start:
+
+# disable interrupts and set priority to lowest (=disable)
+    andccr  #0xef
+    stilm   #0x0
+
+    hal_diag_init_led
+#ifdef CYGPKG_HAL_FR30_FLASH_INIT_DEFINED
+    hal_flash_init
+#endif
+    hal_cpu_init
+
+#ifdef CYGPKG_HAL_FR30_MEMC_INIT_DEFINED
+    hal_memc_init
+#endif
+
+    hal_intc_init
+
+    hal_cache_init
+
+    hal_timer_init
+
+# Zero the BSS. If the BSS is not a whole number of words
+# long we will write up to 3 extra bytes at the end.
+# (This should not be a problem usually).
+    ldi:32  #__bss_end - 8,     r12
+    ldi:32  #__bss_start - 4,   r13
+    eor     r0, r0 ; zero r0
+2:
+    add     #0x4,   r13
+    cmp     r12,    r13
+    ble:d   2b
+    st      r0,     @r13
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+# In a ROM booted system, we also need to copy the data section
+# out to the RAM.
+
+    ldi:32  #__rom_data_start - 4 + CYGPKG_HAL_FR30_LMA_OFFSET,  r11
+    ldi:32  #__ram_data_start - 4,  r9
+    ldi:32  #__ram_data_end - 8,    r10
+3:
+    add     #0x4,   r11
+    add     #0x4,   r9
+    ld      @r11,   r0
+    cmp     r10,    r9
+    ble:d   3b
+    st      r0,     @r9
+
+#endif
+
+
+    # Set up the stacks
+    # Begin with interrupt (system) stack
+
+    ldi:32  #__interrupt_stack, r11
+    mov     r11,    ssp
+
+    # and now continue with user stack
+
+    orccr   #0x20
+    ldi:32  #__user_stack,  r11
+    mov     r11,    usp
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+# If we are here, initialize the hal_vsr_table. RAM startup
+# configurations can assume that Redboot has already set it up.
+
+    .extern hal_mon_init
+    ldi:32  #hal_mon_init,  r11
+    call    @r11
+
+#endif
+
+    .extern hal_variant_init
+    ldi:32  #hal_variant_init,  r11
+    call       @r11
+
+    .extern hal_platform_init
+    ldi:32  #hal_platform_init,  r11
+    call    @r11
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+    // This is here so we can debug the constructors.
+    .extern initialize_stub
+    ldi:32  #initialize_stub,   r11
+    call    @r11
+#endif
+
+    .extern cyg_hal_invoke_constructors
+    ldi:32  #cyg_hal_invoke_constructors,  r11
+    call    @r11
+
+# TODO integrate into hal_intr.h
+# set irq 25 priority (for reload timer 1)
+    ldi:20  #0x449,     r4
+    ldi:8   #0x10,      r5
+    stb     r5,         @r4
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INITIAL_BREAK
+        .extern breakpoint
+        call breakpoint
+#endif
+
+
+    .extern cyg_start
+    ldi:32  #cyg_start,  r11
+    call    @r11
+
+# Hmm.  Not expecting to return from cyg_start, endless nop loop
+1:  nop
+    call   1b
+
+#==============================================================================
+# Default exception VSR
+
+    .align  2, 0xcc
+    .globl  __default_exception_vsr
+__default_exception_vsr:
+
+    ## We enter here with the CPU state still in the registers and:
+    ##  @(ssp,8)    PS pushed by hardware
+    ##  @(ssp,4)    PC pushed by hardware
+    ##  @(ssp)      old register r0 content pushed by trampoline
+    ##  r0 now contains the vector number
+
+# at first switch to USP (set bit 5 in CCR in PS)
+    orccr   #0x20
+
+    st      r0,     @-r15
+    st      mdl,    @-r15
+    st      mdh,    @-r15
+
+    mov     r0,     mdh         ; save exception/interrupt number
+    mov     r15,    r0
+    addn    #+12,   r0
+    mov     r0,     mdl         ; save r15 also in mdl
+
+    st      r0,     @-r15       ; store usp
+    mov     ssp,    r0
+    st      r0,     @-r15       ; store ssp (TODO maybe have to sub 12 before)
+    st      rp,     @-r15
+    st      tbr,    @-r15
+    addsp   #-8                 ; skip 2 positions for PS and PC
+    mov     r15,    r0          ; save stack position to later store PS and PC
+
+    st      mdl,    @-r15       ; store original r15 here
+    stm1    (r8, r9, r10, r11, r12, r13, r14)
+    stm0    (r1, r2, r3, r4, r5, r6, r7)
+
+    mov     ssp,    r14
+    ld      @r14,   r1          ; get original r0 content
+    st      r1,     @-r15       ; and store it
+
+    ld      @(r14,4),   r2      ; get hardware pushed PC
+    st      r2,     @r0         ; and store it
+    ld      @(r14,8),   r3      ; get hardware pushed PS
+    addn    #4,     r0          ; and
+    st      r3,     @r0         ; store it
+
+# we should be finished saving context here
+
+# Call exception handler
+    .extern hal_default_exception_handler
+
+    ldi:32  #hal_default_exception_handler,  r11
+    mov     r15,    r5          ; pointer to saved state as second argument
+    call:d  @r11
+    mov     mdh,    r4          ; exception number as first argument
+
+__default_exception_vsr_return:
+
+
+    ## At this point, the user stack (USP) contains:
+    ## @(usp,0x60) trap number
+    ## @(usp,0x5c) mdl
+    ## @(usp,0x58) mdh
+    ## @(usp,0x54) usp
+    ## @(usp,0x50) ssp
+    ## @(usp,0x4c) rp
+    ## @(usp,0x48) tbr
+    ## @(usp,0x44) ps
+    ## @(usp,0x40) pc
+    ## @(usp,0x3c) r15
+    ## @(usp,0x38) r14
+    ## @(usp,0x34) r13
+    ## @(usp,0x30) r12
+    ## @(usp,0x2c) r11
+    ## @(usp,0x28) r10
+    ## @(usp,0x24) r9
+    ## @(usp,0x20) r8
+    ## @(usp,0x1c) r7
+    ## @(usp,0x18) r6
+    ## @(usp,0x14) r5
+    ## @(usp,0x10) r4
+    ## @(usp,0xc)  r3
+    ## @(usp,8)    r2
+    ## @(usp,4)    r1
+    ## @(usp)      r0
+    ##
+    ## and system stack (SSP) contains:
+    ## @(ssp,8) PS
+    ## @(ssp,4) PC
+    ## @(ssp)   old r0 content
+
+# we can reuse the code from __default_interrupt_vsr
+    ldi:32  #hal_exception_return,  r0
+    jmp    @r0
+
+#==============================================================================
+# Default interrupt VSR
+#
+#
+
+    .align  2, 0xcc
+    .globl  __default_interrupt_vsr
+__default_interrupt_vsr:
+
+    ## We enter here with the CPU state still in the registers and:
+    ##  r0          vector number
+    ##  @(ssp)      old register r0 content pushed by trampoline
+    ##  @(ssp,4)    PS pushed by hardware
+    ##  @(ssp,8)    PC pushed by hardware
+
+    # begin to save registers (to USP)
+    orccr   #0x20
+
+    st      mdl,    @-r15
+    st      mdh,    @-r15
+    st      rp,     @-r15
+
+    stm1    (r8, r9, r10, r11, r12, r13)
+    stm0    (r1, r2, r3 , r4 , r5 , r6, r7)
+
+    andccr  #0xdf
+    ld      @r15+,  r8          ; read old r0 content from SSP
+    ld      @r15+,  r9          ; read pc pushed by hardware
+    ld      @r15+,  r10         ; read ps pushed by hardware
+    orccr   #0x20
+
+    st      r8,     @-r15       ; push old r0 content to USP
+
+# we should be finished saving irq context here
+
+#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)
+# Increment scheduler lock
+    .extern cyg_scheduler_sched_lock
+    ldi:32  #cyg_scheduler_sched_lock,   r1
+    ld      @r1,    r2
+    addn    #1,     r2
+    st      r2,     @r1
+#endif
+
+# Call hal_interrupt_handlers[vector](vector, cyg_hal_interrupt_data[vector])
+    mov     r0,     r8                      ; copy the vector
+    lsl     #2,     r8                      ; multiply vector by 4
+
+    ldi:32  #hal_interrupt_handlers,    r13 ; load handlers table
+    ld      @(r13, r8), r1                  ; current handler
+    ldi:32  #hal_interrupt_data,    r13     ; load data table
+    ld      @(r13, r8), r5                  ; current data, second argument
+    call:d  @r1
+    mov     r0,    r4                      ; exception number as argument
+
+# At this point:
+# r15 = stack pointer /*(should be usable as pointer to HAL_SavedRegisters)*/
+# r4  = ISR return code (returned by call)
+# r8  = ISR table offset (saved across call)
+# r0  = vector number (NOT saved across call, but we don't need it)
+
+/*
+       # If we are returning from the last nested interrupt, move back
+       # to the thread stack. interrupt_end() must be called on the
+       # thread stack since it potentially causes a context switch.
+       
+       hal_from_intstack       
+*/
+
+#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
+
+# Call interrupt_end(return_value, hal_interrupt_objects[vector], regs)
+# - r4 is the return value from the ISR
+# - regs points to saved CPU context
+
+    ldi:32  #hal_interrupt_objects,  r13    ; load objects table
+    ld      @(r13, r8), r5                  ; current object, second argument
+    ldi:32  #interrupt_end, r12
+    call:d  @r12
+    mov     r15,    r6                      ; third argument TODO is not in
+                                            ; HAL_Saved_Registers format
+
+#endif
+
+##.globl hal_exception_return
+hal_exception_return:
+
+# Now pull saved state from stack and return to
+# what thread was originally doing.
+
+# at first store return values to SSP
+    andccr  #0xdf
+    st      r10,    @-r15                   ; store ps
+    st      r9,     @-r15                   ; store pc
+    orccr   #0x20
+
+# and then restore normal registers from USP
+    ldm0    (r0, r1, r2 , r3 , r4 , r5, r6, r7)
+    ldm1    (r8, r9, r10, r11, r12, r13)
+
+    ld      @r15+,  rp
+    ld      @r15+,  mdh
+    ld      @r15+,  mdl
+
+    andccr  #0xdf
+    reti
+
+
+#==============================================================================
+# Exception trampolines
+# TBR table points to these short code sequences here that push the vector
+# number on to the stack and then indirect via the VSR table to a handler.
+# (__default_interrupt_vsr)
+
+    .text
+
+# macro to create exception handler (no error code)
+
+.macro  hal_fr30_exception_noerr idx
+    .globl hal_fr30_exception_noerr_\idx
+hal_fr30_exception_noerr_\idx:
+    st r0,  @-r15
+    ldi:32  #hal_vsr_table + \idx * 4,  r0
+    ld  @r0,    r0
+    jmp:d   @r0
+    ldi:8   #\idx,    r0
+.endm
+
+    # Now generate all the default exception VSR trampolines.
+
+#   hal_fr30_exception_noerr  1 no trampoline needed for reset and mode vector
+    hal_fr30_exception_noerr  2
+    hal_fr30_exception_noerr  3
+    hal_fr30_exception_noerr  4
+    hal_fr30_exception_noerr  5
+    hal_fr30_exception_noerr  6
+    hal_fr30_exception_noerr  7
+    hal_fr30_exception_noerr  8
+    hal_fr30_exception_noerr  9
+    hal_fr30_exception_noerr 10
+    hal_fr30_exception_noerr 11
+    hal_fr30_exception_noerr 12
+    hal_fr30_exception_noerr 13
+    hal_fr30_exception_noerr 14
+
+#==============================================================================
+# IRQ handler trampolines
+
+# macro to create exception handler (no error code)
+
+.macro  hal_fr30_irq_handler idx
+    .globl hal_fr30_irq_\idx
+hal_fr30_irq_\idx:
+    st  r0, @-r15
+    ldi:32  #hal_vsr_table + \idx * 4,  r0
+    ld  @r0,    r0
+    jmp:d   @r0
+    ldi:8   #\idx,    r0
+.endm
+
+    hal_fr30_irq_handler 15
+    hal_fr30_irq_handler 16
+    hal_fr30_irq_handler 17
+    hal_fr30_irq_handler 18
+    hal_fr30_irq_handler 19
+    hal_fr30_irq_handler 20
+    hal_fr30_irq_handler 21
+    hal_fr30_irq_handler 22
+    hal_fr30_irq_handler 23
+    hal_fr30_irq_handler 24
+    hal_fr30_irq_handler 25
+    hal_fr30_irq_handler 26
+    hal_fr30_irq_handler 27
+    hal_fr30_irq_handler 28
+    hal_fr30_irq_handler 29
+    hal_fr30_irq_handler 30
+    hal_fr30_irq_handler 31
+    hal_fr30_irq_handler 32
+    hal_fr30_irq_handler 33
+    hal_fr30_irq_handler 34
+    hal_fr30_irq_handler 35
+    hal_fr30_irq_handler 36
+    hal_fr30_irq_handler 37
+    hal_fr30_irq_handler 38
+    hal_fr30_irq_handler 39
+    hal_fr30_irq_handler 40
+    hal_fr30_irq_handler 41
+    hal_fr30_irq_handler 42
+    hal_fr30_irq_handler 43
+    hal_fr30_irq_handler 44
+    hal_fr30_irq_handler 45
+    hal_fr30_irq_handler 46
+    hal_fr30_irq_handler 47
+    hal_fr30_irq_handler 48
+    hal_fr30_irq_handler 49
+    hal_fr30_irq_handler 50
+    hal_fr30_irq_handler 51
+    hal_fr30_irq_handler 52
+    hal_fr30_irq_handler 53
+    hal_fr30_irq_handler 54
+    hal_fr30_irq_handler 55
+    hal_fr30_irq_handler 56
+    hal_fr30_irq_handler 57
+    hal_fr30_irq_handler 58
+    hal_fr30_irq_handler 59
+    hal_fr30_irq_handler 60
+    hal_fr30_irq_handler 61
+    hal_fr30_irq_handler 62
+    hal_fr30_irq_handler 63
+
+
+    .data
+//
+// "Vectors" - fixed location data items
+// This section contains any data which might be shared between
+// an eCos application and any other environment, e.g. the debug
+// ROM.
+//
+    .section ".fixed_vectors"
+// Space for the virtual vectors        
+    .balign 4
+// Vectors used to communicate between eCos and ROM environments
+    .globl  hal_virtual_vector_table
+hal_virtual_vector_table:
+    .rept   64                  // CYGNUM_CALL_IF_TABLE_SIZE
+    .long   0
+    .endr
+
+    .globl  hal_vsr_table
+hal_vsr_table:
+    .rept   CYGNUM_HAL_VSR_COUNT            // exceptions & interrupts
+    .long   0
+    .endr
+
+#==============================================================================
+# Initial and interrupt stack
+
+    .section ".bss"
+
+    .balign 4
+    .global cyg_interrupt_stack_base
+cyg_interrupt_stack_base:
+__interrupt_stack_base:
+    .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
+    .byte 0
+    .endr
+    .balign 4
+    .global cyg_interrupt_stack
+cyg_interrupt_stack:
+__interrupt_stack:
+    .long   0,0,0,0,0,0,0,0
+
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+    .global __stub_stack_base
+__stub_stack_base:
+    .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
+    .byte 0
+    .endr
+    .balign 4
+    .global __stub_stack
+__stub_stack:
+
+    .long   0,0,0,0,0,0,0,0
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+    .balign 4
+__user_stack_base:
+//  FIXME TODO import symbolic constant from C-code
+    .rept 4532
+    .byte 0
+    .endr
+    .balign 4
+__user_stack:
+    .long   0
+
+#------------------------------------------------------------------------------
+# end of vectors.S
diff --git a/packages/hal/fr30/mb91301/v2_0/ChangeLog b/packages/hal/fr30/mb91301/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..99dd979
--- /dev/null
@@ -0,0 +1,53 @@
+2008-07-01  Lars Poeschel  <larsi@wh2.tu-dresden.de>
+
+    * src/fr30_md91301.ld: Reworked memory layout for flash support.
+    * src/hal_diag.c:      Little updates in serial0 configuration registers.
+    * src/variant.S:       Made it possible for the platform to override
+                           variants rom vectors.
+    * include/variant.inc: Moved macros for sdram config addresses to platform.
+
+2007-07-09  Lars Poeschel  <larsi@wh2.tu-dresden.de>
+
+    * src/fr30_md91301.ld:
+    * src/hal_diag.c:
+    * src/var_misc.c:
+    * include/hal_diag.h:
+    * include/var_arch.h:
+    * include/variant.inc:
+    * include/var_intr.h:
+    * cdl/hal_fr30_mb91301.cdl: Initial fr30 ecos port
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/fr30/mb91301/v2_0/cdl/hal_fr30_mb91301.cdl b/packages/hal/fr30/mb91301/v2_0/cdl/hal_fr30_mb91301.cdl
new file mode 100644 (file)
index 0000000..1a44bf0
--- /dev/null
@@ -0,0 +1,192 @@
+# ====================================================================
+#
+#      hal_fr30_mb91301.cdl
+#
+#      FR30/mb91301 variant architectural HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      larsi
+# Original data:  bartv, nickg
+# Contributors:
+# Date:           2006-07-09
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_FR30_MB91301 {
+    display       "MB91301 variant"
+    parent        CYGPKG_HAL_FR30
+    implements    CYGINT_HAL_FR30_VARIANT
+    hardware
+    include_dir   cyg/hal
+    define_header hal_fr30_mb91301.h
+    description   "
+           The MB91301 architecture HAL package provides generic support
+           for this processor architecture. It is also necessary to
+           select a specific target platform HAL package."
+
+
+    define_proc {
+        puts $::cdl_header "#include <pkgconf/hal_fr30.h>"
+    }
+
+    cdl_component CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ {
+        display "System clock speed in MHz"
+        flavor data
+        calculated { (CYGHWR_HAL_FR30_MB91301_CRYSTAL_SPEED * \
+                    CYGHWR_HAL_FR30_MB91301_CLKR) }
+        description    "This is the resulting base clock speed for the board.
+                It is calculated
+                CLKR * CRYSTAL_SPEED.
+                This is NOT the CPU Frequency."
+
+        cdl_option CYGHWR_HAL_FR30_MB91301_CRYSTAL_SPEED {
+            display "Crystal speed in Mhz"
+            flavor data
+            description  "You have to enter the speed of the mounted crystal here.
+                    The resulting base clock is calculated:
+                    CLKR * CRYSTAL_SPEED / CLKB_DIVIDER"
+            legal_values    1 to 17
+            default_value   15
+        }
+
+        cdl_option CYGHWR_HAL_FR30_MB91301_CLKR {
+            display "Main PLL multiply-by rate"
+            flavor data
+            description  "Using this value you can set the resulting base clock
+                    speed. It is calculated:
+                    CLKR * CRYSTAL_SPEED.
+                    DO NOT DO A SETTING HIGHER THAN 4 UNLESS YOU EXACTLY
+                    KNOW WHAT YOU A DOING! "
+            legal_values    1 to 8
+            default_value   4
+        }
+
+        cdl_option CYGHWR_HAL_FR30_MB91301_CLKB_DIVIDER {
+            display "Base clock divider"
+            flavor data
+            description  "Using this value you can limit the base clock speed.
+                    You set the divider. The resulting base clock speed
+                    is calculated:
+                    CLKB = system clock / divider
+                    CPU, internal memory and internal buses use this base clock!
+                    A value other than 1 can cause problems when using the stop
+                    mode of the CPU.
+                    See Fujitsu MB91301 hardware manual Chapter 5 for
+                    constraints on setting this value!"
+            legal_values    1 to 16
+            default_value   1
+        }
+
+        cdl_option CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER {
+            display "Peripheral clock divider"
+            flavor data
+            description  "Using this value you can set the peripheral clock
+                    speed. You set the divider. The resulting peripheral clock
+                    speed is calculated:
+                    CLKP = system clock / divider
+                    See Fujitsu MB91301 hardware manual Chapter 5 for constraints on setting
+                    this value!"
+            legal_values    1 to 16
+            default_value   4
+        }
+
+        cdl_option CYGHWR_HAL_FR30_MB91301_CLKT_DIVIDER {
+            display "External buses clock divider"
+            flavor data
+            description  "Using this value you can set the external buses clock
+                    speed. You set the divider. The resulting external buses
+                    clock speed is calculated:
+                    CLKT = system clock / divider
+                    See Fujitsu MB91301 hardware manual Chapter 5 for constraints on setting
+                    this value!"
+            legal_values    1 to 16
+            default_value   1
+        }
+
+    }
+
+
+    # Real-time clock/counter specifics
+    cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+        display       "Real-time clock constants."
+        flavor        none
+
+        cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+            display       "Real-time clock numerator"
+            flavor        data
+            default_value 1000000000
+        }
+        cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+            display       "Real-time clock denominator"
+            flavor        data
+            default_value 100
+        }
+        cdl_option CYGNUM_HAL_RTC_PERIOD {
+            display       "Real-time clock period"
+            flavor        data
+            default_value {(CYGHWR_HAL_FR30_MB91301_CRYSTAL_SPEED * CYGHWR_HAL_FR30_MB91301_CLKR * 1000000) / (CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER * CYGNUM_HAL_RTC_DENOMINATOR * 32)}
+            description   "
+                The tick timer facility is used
+                to drive the eCos kernel RTC. Reload Timer 1 is used. The count
+                register decrements at the CLKP clock speed. We use prescaler 32.
+                By default we want 100 Hz."
+        }
+    }
+
+
+    compile       hal_diag.c var_misc.c variant.S
+
+    make {
+        <PREFIX>/lib/target.ld: <PACKAGE>/src/fr30_mb91301.ld
+        $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $@ $<
+        @echo $@ ": \\" > $(notdir $@).deps
+        @tail -n +2 target.tmp >> $(notdir $@).deps
+        @echo >> $(notdir $@).deps
+        @rm target.tmp
+    }
+
+   cdl_option CYGBLD_LINKER_SCRIPT {
+       display "Linker script"
+       flavor data
+       no_define
+       calculated  { "src/fr30_mb91301.ld" }
+   }
+
+}
diff --git a/packages/hal/fr30/mb91301/v2_0/include/hal_diag.h b/packages/hal/fr30/mb91301/v2_0/include/hal_diag.h
new file mode 100644 (file)
index 0000000..c08de03
--- /dev/null
@@ -0,0 +1,128 @@
+/*=============================================================================
+//
+//      hal_diag.h
+//
+//      HAL Support for Kernel Diagnostic Routines
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   larsi
+// Contributors:
+// Date:        2007-07-09
+// Purpose:     HAL Support for Kernel Diagnostic Routines
+// Description: Diagnostic routines for use during kernel development.
+// Usage:       #include <cyg/hal/hal_diag.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#ifndef CYGONCE_HAL_DIAG_H
+#define CYGONCE_HAL_DIAG_H
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+
+#else // old way of doing diagnostic I/O
+
+/*---------------------------------------------------------------------------*/
+/* functions implemented in hal_diag.c (old way without virtual vectors)     */
+
+externC void hal_diag_init(void);
+externC void hal_diag_write_char(char c);
+externC void hal_diag_read_char(char *c);
+
+/*---------------------------------------------------------------------------*/
+
+#define HAL_DIAG_INIT() hal_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_diag_read_char(&_c_)
+
+#endif  /* CYGSEM_HAL_VIRTUAL_VECTOR_DIAG */
+
+/*---------------------------------------------------------------------------*/
+// serial port0 defines
+#define CYG_HAL_FR30_MB91301_SMR0     0x63
+#define CYG_HAL_FR30_MB91301_SCR0     0x62
+#define CYG_HAL_FR30_MB91301_SIDR0    0x61
+#define CYG_HAL_FR30_MB91301_SODR0    0x61
+#define CYG_HAL_FR30_MB91301_SSR0     0x60
+#define CYG_HAL_FR30_MB91301_UTIM0    0x64
+#define CYG_HAL_FR30_MB91301_UTIMR0   0x64
+#define CYG_HAL_FR30_MB91301_DRCL0    0x66
+#define CYG_HAL_FR30_MB91301_UTIMC0   0x67
+
+/*---------------------------------------------------------------------------*/
+// serial port1 defines
+#define CYG_HAL_FR30_MB91301_SMR1     0x6b
+#define CYG_HAL_FR30_MB91301_SCR1     0x6a
+#define CYG_HAL_FR30_MB91301_SIDR1    0x69
+#define CYG_HAL_FR30_MB91301_SODR1    0x69
+#define CYG_HAL_FR30_MB91301_SSR1     0x68
+#define CYG_HAL_FR30_MB91301_UTIM1    0x6c
+#define CYG_HAL_FR30_MB91301_UTIMR1   0x6c
+#define CYG_HAL_FR30_MB91301_DRCL1    0x6e
+#define CYG_HAL_FR30_MB91301_UTIMC1   0x6f
+
+#define CYG_HAL_FR30_MB91301_PDRJ 0x13
+#define CYG_HAL_FR30_MB91301_DDRJ 0x403
+#define CYG_HAL_FR30_MB91301_PFRJ 0x413
+
+/*---------------------------------------------------------------------------*/
+// LED
+#define CYG_HAL_FR30_MB91301_PDRG 0x10
+#define CYG_HAL_FR30_MB91301_DDRG 0x400
+#define CYG_HAL_FR30_MB91301_PFRG 0x410
+// our MB91302A does not have PCRG (pull up resistor register G)
+// but it is here anyway
+#define CYG_HAL_FR30_MB91301_PCRG 0x420
+
+// externC void hal_diag_init_led(void);
+externC void hal_diag_led(cyg_uint8);
+
+/*---------------------------------------------------------------------------*/
+/* end of hal_diag.h                                                         */
+#endif /* CYGONCE_HAL_DIAG_H */
diff --git a/packages/hal/fr30/mb91301/v2_0/include/var_arch.h b/packages/hal/fr30/mb91301/v2_0/include/var_arch.h
new file mode 100644 (file)
index 0000000..4a8285f
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef CYGONCE_HAL_VAR_ARCH_H
+#define CYGONCE_HAL_VAR_ARCH_H
+
+//==========================================================================
+//
+//      var_arch.h
+//
+//      Architecture specific abstractions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    larsi
+// Contributors:
+// Date:         2007-07-09
+// Purpose:      Define architecture abstractions
+// Description:  This file contains any extra or modified definitions for
+//               this variant of the architecture.
+// Usage:        #include <cyg/hal/var_arch.h>
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+
+//--------------------------------------------------------------------------
+#endif // CYGONCE_HAL_VAR_ARCH_H
+// End of var_arch.h
diff --git a/packages/hal/fr30/mb91301/v2_0/include/var_intr.h b/packages/hal/fr30/mb91301/v2_0/include/var_intr.h
new file mode 100644 (file)
index 0000000..81a0064
--- /dev/null
@@ -0,0 +1,275 @@
+#ifndef CYGONCE_HAL_IMP_INTR_H
+#define CYGONCE_HAL_IMP_INTR_H
+
+//==========================================================================
+//
+//      var_intr.h
+//
+//      MB91301 Interrupt and clock support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    larsi
+// Contributors: larsi
+// Date:         2006-07-14
+// Purpose:      MB91301 Interrupt support
+// Description:  The macros defined here provide the HAL APIs for handling
+//               interrupts and the clock for variants of the MB91301
+//               architecture.
+//              
+// Usage:
+//              #include <cyg/hal/imp_intr.h>
+//              ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/hal/plf_intr.h>
+
+//--------------------------------------------------------------------------
+// Interrupt vectors.
+
+#ifndef CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
+
+#define CYGNUM_HAL_INTERRUPT_0                     16
+#define CYGNUM_HAL_INTERRUPT_1                     17
+#define CYGNUM_HAL_INTERRUPT_2                     18
+#define CYGNUM_HAL_INTERRUPT_3                     19
+#define CYGNUM_HAL_INTERRUPT_4                     20
+#define CYGNUM_HAL_INTERRUPT_5                     21
+#define CYGNUM_HAL_INTERRUPT_6                     22
+#define CYGNUM_HAL_INTERRUPT_7                     23
+#define CYGNUM_HAL_INTERRUPT_RELOAD_TIMER0         24
+#define CYGNUM_HAL_INTERRUPT_RELOAD_TIMER1         25
+#define CYGNUM_HAL_INTERRUPT_RELOAD_TIMER2         26
+#define CYGNUM_HAL_INTERRUPT_UART0_RX              27
+#define CYGNUM_HAL_INTERRUPT_UART1_RX              28
+#define CYGNUM_HAL_INTERRUPT_UART2_RX              29
+#define CYGNUM_HAL_INTERRUPT_UART0_TX              30
+#define CYGNUM_HAL_INTERRUPT_UART1_TX              31
+#define CYGNUM_HAL_INTERRUPT_UART2_TX              32
+#define CYGNUM_HAL_INTERRUPT_DMAC0                 33
+#define CYGNUM_HAL_INTERRUPT_DMAC1                 34
+#define CYGNUM_HAL_INTERRUPT_DMAC2                 35
+#define CYGNUM_HAL_INTERRUPT_DMAC3                 36
+#define CYGNUM_HAL_INTERRUPT_DMAC4                 37
+#define CYGNUM_HAL_INTERRUPT_AD                    38
+#define CYGNUM_HAL_INTERRUPT_PPG0                  39
+#define CYGNUM_HAL_INTERRUPT_PPG1                  40
+#define CYGNUM_HAL_INTERRUPT_PPG2                  41
+#define CYGNUM_HAL_INTERRUPT_PPG3                  42
+// system reserved #define CYGNUM_HAL_INTERRUPT_                43
+#define CYGNUM_HAL_INTERRUPT_UTIMER0               44
+#define CYGNUM_HAL_INTERRUPT_UTIMER1               45
+#define CYGNUM_HAL_INTERRUPT_UTIMER2               46
+#define CYGNUM_HAL_INTERRUPT_TIMEBASE_OVERFLOW     47
+#define CYGNUM_HAL_INTERRUPT_I2C0                  48
+#define CYGNUM_HAL_INTERRUPT_I2C1                  49
+// system reserved #define CYGNUM_HAL_INTERRUPT_                 50
+// system reserved #define CYGNUM_HAL_INTERRUPT_                 51
+#define CYGNUM_HAL_INTERRUPT_FREERUN_TIMER         52
+#define CYGNUM_HAL_INTERRUPT_ICU0                  53
+#define CYGNUM_HAL_INTERRUPT_ICU1                  54
+#define CYGNUM_HAL_INTERRUPT_ICU2                  55
+#define CYGNUM_HAL_INTERRUPT_ICU3                  56
+// system reserved #define CYGNUM_HAL_INTERRUPT_             57
+// system reserved #define CYGNUM_HAL_INTERRUPT_             58
+// system reserved #define CYGNUM_HAL_INTERRUPT_             59
+// system reserved #define CYGNUM_HAL_INTERRUPT_             60
+// system reserved #define CYGNUM_HAL_INTERRUPT_             61
+// system reserved #define CYGNUM_HAL_INTERRUPT_             62
+#define CYGNUM_HAL_INTERRUPT_DELAYED_IRQ           63
+
+// The interrupt vector used by the RTC, aka tick timer
+#define CYGNUM_HAL_INTERRUPT_RTC            CYGNUM_HAL_INTERRUPT_RELOAD_TIMER1
+
+#define CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
+
+#endif
+
+//--------------------------------------------------------------------------
+// Interrupt controller access.
+
+// currently only external interrupts are masked using the external
+// interrupt controller. This means only vectors 16 to 23 are valid.
+// Other interrupts may be masked in the future
+// using the mask mechanism for interrupt levels, if needed.
+
+#ifndef CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
+
+#define CYG_HAL_FR30_MB91301_ENIR     0x41
+#define CYG_HAL_FR30_MB91301_EIRR     0x40
+#define CYG_HAL_FR30_MB91301_ELVR     0x42
+#define CYG_HAL_FR30_MB91301_ICR00    0x440
+
+// Array which stores the configured priority levels for the configured
+// interrupts.
+// this will be useful, if we implement masking of non external interrupts
+// externC volatile CYG_BYTE hal_interrupt_level[CYGNUM_HAL_ISR_COUNT];
+
+
+#define HAL_INTERRUPT_MASK( _vector_ )                       \
+{                                                            \
+    CYG_WORD32 _ilr_;                                        \
+    if ((_vector_ >= CYGNUM_HAL_INTERRUPT_7) &&              \
+          (_vector_ <= CYGNUM_HAL_INTERRUPT_0)){             \
+        HAL_READ_UINT8( CYG_HAL_FR30_MB91301_ENIR, _ilr_ );  \
+        _ilr_ &= ~(1<<((_vector_)>>4));                      \
+        HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_ENIR, _ilr_ ); \
+    }                                                        \
+    /* Handle RTC masking special */                         \
+    if (_vector_ == CYGNUM_HAL_INTERRUPT_RTC)                \
+        asm volatile("ldi:8     #0x57,  r0;\n"               \
+                     "bandl     #0x7,   @r0;\n"              \
+                      : : :"r0");                            \
+}
+
+#define HAL_INTERRUPT_UNMASK( _vector_ )                     \
+{                                                            \
+    CYG_WORD32 _ilr_;                                        \
+    if ((_vector_ >= CYGNUM_HAL_INTERRUPT_7) &&              \
+          (_vector_ <= CYGNUM_HAL_INTERRUPT_0)){             \
+        HAL_READ_UINT8( CYG_HAL_FR30_MB91301_ENIR, _ilr_ );  \
+        _ilr_ |= (1<<((_vector_)>>4));                       \
+        HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_ENIR, _ilr_ ); \
+    }                                                        \
+    /* Handle RTC unmasking special */                       \
+    if (_vector_ == CYGNUM_HAL_INTERRUPT_RTC)                \
+        asm volatile("ldi:8     #0x57,  r0;\n"               \
+                     "borl      #0x8,   @r0;\n"              \
+                      : : :"r0");                            \
+}
+
+#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ )                \
+{                                                            \
+    CYG_WORD32 _ilr_;                                        \
+    if ((_vector_ >= CYGNUM_HAL_INTERRUPT_7) &&              \
+          (_vector_ <= CYGNUM_HAL_INTERRUPT_0)){             \
+        HAL_READ_UINT8( CYG_HAL_FR30_MB91301_EIRR, _ilr_ );  \
+        _ilr_ &= ~(1<<((_vector_)>>4));                      \
+        HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_EIRR, _ilr_ ); \
+    }                                                        \
+    /* Handle RTC acknowledging special */                   \
+    if (_vector_ == CYGNUM_HAL_INTERRUPT_RTC)                \
+        asm volatile("ldi:8     #0x57,  r0;\n"               \
+                     "bandl     #0xb,   @r0;\n"              \
+                      : : :"r0");                            \
+}
+
+#define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ )              \
+{                                                                       \
+        /* subtract 15 from vector */                                   \
+        cyg_uint32 _v_ = _vector_ >> 4;                                 \
+        cyg_uint16 _val_ = 0;                                           \
+        cyg_uint16 _reg_;                                               \
+                                                                        \
+            if ((_vector_ >= CYGNUM_HAL_INTERRUPT_7) &&                 \
+                (_vector_ <= CYGNUM_HAL_INTERRUPT_0)){                  \
+                                                                        \
+        /* set bits according to requirements */                        \
+        if( _up_ ) _val_ |= 1;                                          \
+        if( !(_level_) ) _val_ |= 2;                                    \
+                                                                        \
+        /* get old ELVR */                                              \
+        HAL_READ_UINT16( CYG_HAL_FR30_MB91301_ELVR, _reg_ );            \
+                                                                        \
+        /* clear old value and set new */                               \
+        _reg_ &= ~(3 << _v_);                                           \
+        _reg_ |= _val_ << _v_;                                          \
+        HAL_WRITE_UINT16( CYG_HAL_FR30_MB91301_ELVR, _reg_ );           \
+    }                                                                   \
+}
+
+#define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ )                    \
+{                                                                       \
+    /* subtract 15 from vector */                                       \
+    cyg_uint32 _v_ = _vector_ >> 4;                                     \
+    CYG_WORD32 _ilr_;                                                   \
+/*    HAL_READ_UINT8( CYG_HAL_FR30_MB91301_ICR00 + _vector_, _ilr_ );*/ \
+/* reading before writing is only needed, if UINT8 writing is not */    \
+/* possible to IO 0x440   */                                              \
+    _ilr_ = (_level_);                                                  \
+    HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_ICR00 + _vector_, _ilr_ );    \
+/*  for later use:  */                                                    \
+/*    hal_interrupt_level[_vector_] = _level_;      */                    \
+}
+
+#define CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
+
+#endif
+
+//--------------------------------------------------------------------------
+// Clock control registers
+
+// MB91301 series has 3 built-in timer channels.
+// Timer 2 is used for delay and timer 1 for RTC/*delay*/.
+// Timer 0 and 1 can activate DMA and this feature is propably needed by
+// the application. Timer 0 is free to use by the application.
+
+#define CYG_HAL_FR30_DLY_TMCSR          0x5e
+#define CYG_HAL_FR30_DLY_TMR            0x5a
+#define CYG_HAL_FR30_DLY_TMRLR          0x58
+#define CYG_HAL_FR30_RTC_TMCSR          0x56
+#define CYG_HAL_FR30_RTC_TMR            0x52
+#define CYG_HAL_FR30_RTC_TMRLR          0x50
+
+
+
+//--------------------------------------------------------------------------
+// Control-C support.
+
+#if defined(CYGDBG_HAL_FR30_DEBUG_GDB_CTRLC_SUPPORT)
+
+#define CYGHWR_HAL_GDB_PORT_VECTOR CYGNUM_HAL_INTERRUPT_DUART
+
+externC cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
+
+#define HAL_CTRLC_ISR hal_ctrlc_isr
+
+#endif
+
+//--------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_IMP_INTR_H
+// End of imp_intr.h
diff --git a/packages/hal/fr30/mb91301/v2_0/include/variant.inc b/packages/hal/fr30/mb91301/v2_0/include/variant.inc
new file mode 100644 (file)
index 0000000..8bd8685
--- /dev/null
@@ -0,0 +1,341 @@
+#ifndef CYGONCE_HAL_VARIANT_INC
+#define CYGONCE_HAL_VARIANT_INC
+##=============================================================================
+##
+##     variant.inc
+##
+##     MB91301 family assembler header file
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):  larsi
+## Contributors:larsi
+## Date:       2006-07-24
+## Purpose:    MB91301 family definitions.
+## Description:        This file contains various definitions and macros that are
+##              useful for writing assembly code for the TX39 CPU family.
+## Usage:
+##             #include <cyg/hal/variant.inc>
+##             ...
+##             
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/fr30.inc>
+
+#include <cyg/hal/platform.inc>
+
+##-----------------------------------------------------------------------------
+## Define CPU variant for architecture HAL.
+
+#define        CYG_HAL_FR30_MB91301
+
+##-----------------------------------------------------------------------------
+## Indicate that the ISR tables are defined in variant.S
+
+#ifndef CYG_HAL_FR30_ISR_TABLES_DEFINED
+#define CYG_HAL_FR30_ISR_TABLES_DEFINED
+#endif
+
+##-----------------------------------------------------------------------------
+## CPU initialisation, we set the clock to PLL 48 Mhz (12 * 4Mhz) here.
+## PLL lock waiting time is implemented as a busy loop.
+
+#ifndef CYGPKG_HAL_FR30_CPU_INIT_DEFINED
+#define CYGPKG_HAL_FR30_CPU_INIT_DEFINED
+#
+# busy wait loop
+# pollutes r11, r12
+#
+.macro wait_loop no=0x1
+    ldi:20  #\no,   r12
+    ldi:8   #0x1,   r11
+8:
+    sub     r11,    r12
+    bne     8b
+.endm
+
+##-----------------------------------------------------------------------------
+## Clock Modulator control registers
+
+    .equ FR30_MB91301_CMCR,     0x164
+    .equ FR30_MB91301_CMCRH,    0x164
+    .equ FR30_MB91301_CMCRL,    0x165
+    .equ FR30_MB91301_CMPR,     0x166
+    .equ FR30_MB91301_CMLS0,    0x168
+    .equ FR30_MB91301_CMLS1,    0x16a
+    .equ FR30_MB91301_CMLS2,    0x16c
+    .equ FR30_MB91301_CMLT0,    0x170
+    .equ FR30_MB91301_CMLT1,    0x172
+    .equ FR30_MB91301_CMLT2,    0x174
+    .equ FR30_MB91301_CMAC,     0x176
+    .equ FR30_MB91301_CMACH,    0x178
+    .equ FR30_MB91301_CMACL,    0x179
+    .equ FR30_MB91301_CMTS,     0x17a
+    .equ FR30_MB91301_CMTSH,    0x17a
+    .equ FR30_MB91301_CMTSL,    0x17b
+    .equ FR30_MB91301_ICR31,    0x45f
+
+##-----------------------------------------------------------------------------
+## Registers for Clock Generation and Reset
+
+    .equ FR30_MB91301_RSRR,     0x480
+    .equ FR30_MB91301_STCR,     0x481
+    .equ FR30_MB91301_TBCR,     0x482
+    .equ FR30_MB91301_CTBR,     0x483
+    .equ FR30_MB91301_CLKR,     0x484
+    .equ FR30_MB91301_WPR,      0x485
+    .equ FR30_MB91301_DIVR0,    0x486
+    .equ FR30_MB91301_DIVR1,    0x487
+
+##-----------------------------------------------------------------------------
+## ext bus interface registers
+## part used for flash
+
+    .equ FR30_MB91301_ASR0,     0x640
+    .equ FR30_MB91301_ACR0,     0x642
+    .equ FR30_MB91301_AWR0,     0x660
+    .equ FR30_MB91301_CSER,     0x680
+
+    .equ FR30_MB91301_PDR9,     0x9
+    .equ FR30_MB91301_DDR9,     0x609
+    .equ FR30_MB91301_PFR9,     0x619
+    .equ FR30_MB91301_PCR9,     0x629
+
+    .equ FR30_MB91301_PDR8,     0x8
+    .equ FR30_MB91301_DDR8,     0x608
+    .equ FR30_MB91301_PFR8,     0x618
+    .equ FR30_MB91301_PCR8,     0x628
+
+## part used for sdram
+    .equ FR30_MB91301_ASR6,     0x658
+    .equ FR30_MB91301_ACR6,     0x65a
+    .equ FR30_MB91301_AWR6,     0x66c
+    .equ FR30_MB91301_MCRA,     0x670
+    .equ FR30_MB91301_MCRB,     0x671
+    .equ FR30_MB91301_RCR,      0x684
+
+
+##-----------------------------------------------------------------------------
+## registers for serial0 and U-timer settings
+##
+    .equ FR30_MB91301_PDRJ,     0x13
+    .equ FR30_MB91301_DDRJ,     0x403
+    .equ FR30_MB91301_PFRJ,     0x413
+    .equ FR30_MB91301_UTIM0,    0x64
+    .equ FR30_MB91301_UTIMR0,   0x64
+    .equ FR30_MB91301_UTIMC0,   0x67
+    .equ FR30_MB91301_DRCL,     0x66
+    .equ FR30_MB91301_SMR0,     0x63
+    .equ FR30_MB91301_SCR0,     0x62
+    .equ FR30_MB91301_SIDR0,    0x61
+    .equ FR30_MB91301_SODR0,    0x61
+    .equ FR30_MB91301_SSR0,     0x60
+
+##-----------------------------------------------------------------------------
+## registers for clock settings
+##
+    .equ FR30_MB91301_RTC_TMRLR,      0x50
+    .equ FR30_MB91301_RTC_TMR,        0x52
+    .equ FR30_MB91301_RTC_TMCSR,      0x56
+
+
+
+##------------------------------------------------------------------------------
+## CPU initialisation macro
+## This is mainly for setting clock speeds.
+##------------------------------------------------------------------------------
+.macro  hal_cpu_init
+
+    ldi:8   #0x00,  r0
+
+    ldi:20  #FR30_MB91301_CLKR, r10     ; PLLx4 and enable it, still use source
+    ldi:8   (CYGHWR_HAL_FR30_MB91301_CLKR - 1) * 16 + 4,  r1 ;
+    stb     r1,     @r10                ; oscillation as clock source
+
+    ldi:20  #FR30_MB91301_TBCR, r11     ; set time base counter to
+    ldi:8   #0x18,  r1                  ; about 60 ms and disable
+    stb     r1,     @r11                ; its interrupt (we poll below)
+
+    ldi:20  #FR30_MB91301_CTBR, r12     ; and
+    ldi:8   #0xa5,  r2                  ; start
+    ldi:8   #0x5a,  r3                  ; the
+    stb     r2,     @r12                ; time base
+    stb     r3,     @r12                ; counter
+
+    ldi:20  #FR30_MB91301_STCR, r13     ; set oscillation stabilisation time
+    ldi:8   #0x17,  r1                  ; to about 250 us
+    stb     r1,     @r13                ;
+
+    ldi:20  #FR30_MB91301_DIVR0, r12    ; set CLKB divider
+    ldi:8   (CYGHWR_HAL_FR30_MB91301_CLKB_DIVIDER - 1) * 16 + (CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER - 1),  r1 ; and
+    stb     r1,     @r12                ; CLKP divider
+
+    ldi:20  #FR30_MB91301_DIVR1, r13    ; CLKT divider
+    ldi:8   (CYGHWR_HAL_FR30_MB91301_CLKT_DIVIDER - 1) * 16,    r1
+    stb     r1,     @r13                ;
+
+    ldi:8   #0x80,  r2                  ; wait the rest
+1:                                      ; of the
+    ldub    @r11,   r3                  ; time base counter time
+    and     r2,     r3                  ; (we set it to
+    beq     1b                          ; 60 ms above)
+
+    ldi:8   #0x36,  r1                  ; and now we are ready to
+    stb     r1,     @r10                ; switch clock to PLL
+
+.endm
+
+#endif /* !CYGPKG_HAL_FR30_CPU_INIT_DEFINED */
+
+##-----------------------------------------------------------------------------
+## FR30 interrupt handling.
+## nothing is here because the intc is initialized correctly by hardware reset
+## if something is needed it should be implemented in arch.inc with define'd
+## adresses to the registers. It should be the same for all FR30s
+
+
+##------------------------------------------------------------------------------
+## Diagnostics macros.
+## Indicate that the diagnostic macros are defined in variant.S / hal_diag.c
+
+#ifndef CYGPKG_HAL_FR30_DIAG_DEFINED
+
+##-----------------------------------------------------------------------------
+## registers for led settings
+##
+
+    .equ FR30_MB91301_PDRG,     0x10
+    .equ FR30_MB91301_DDRG,     0x400
+    .equ FR30_MB91301_PFRG,     0x410
+## our MB91301A does not have PCRG (pull up resistor register G)
+## but it is here anyway
+    .equ FR30_MB91301_PCRG,     0x420
+
+
+.macro hal_diag_init_led
+    ldi:8   #0xff,      r4
+    ldi:20  #FR30_MB91301_DDRG, r5
+    stb     r4,         @r5
+    ldi:8   #0x00,      r13
+    ldi:20  #FR30_MB91301_PFRG, r5
+    stb     r13,         @r5
+    dmovb   r13,        @FR30_MB91301_PDRG
+.endm
+
+##
+## switch on led on "hardcoded" value supplied after this macro
+## pollutes r13
+##
+.macro hal_diag_led led=0x0
+##st      r13, @-r15
+    ldi:8   #\led , r13
+    dmovb   r13,    @FR30_MB91301_PDRG
+##ld      @r15+,  r13
+.endm
+
+##------------------------------------------------------------------------------
+## UARTa macros
+##
+
+## output a value to UART a
+## the value has to be in r4
+## register r1 will be polluted
+.macro uarta_putc
+    ldi:8   #FR30_MB91301_SODR0,  r1
+    stb     r4, @r1
+.endm
+
+
+## wait for the data in UART a SODR0 register to be drained
+## registers r1, r2, r3 will be polluted
+.macro uarta_drain
+    ldi:8   #FR30_MB91301_SSR0,     r3  ;
+    ldi:8   #0x08,  r1                  ; TDRE bit of SSR0
+1:                                      ;
+    ldub    @r3,    r2                  ;
+    and     r1,     r2                  ;
+    beq     1b
+.endm
+
+## receive a value from UART a
+## value is returned in r4
+## register r1, r2 and r3 will be polluted
+.macro uarta_getc
+    ldi:8   #FR30_MB91301_SSR0,     r3  ;
+    ldi:8   #0x10,  r1                  ; RDRF bit of SSR0
+2:
+    ldub    @r3,    r2                  ;
+    and     r1,     r2                  ;
+    beq     2b                          ; wait until a byte is received
+
+    ldi:8   #FR30_MB91301_SIDR0,    r3  ;
+    ldub    @r3,    r4                  ; and get the value
+.endm
+
+#define CYGPKG_HAL_FR30_DIAG_DEFINED
+
+#endif
+
+#------------------------------------------------------------------------------
+# Timer initialization.
+
+#ifndef CYGPKG_HAL_FR30_TIMER_DEFINED
+
+    .macro  hal_timer_init
+
+    # load reload value into reload register
+        ldi:8   #FR30_MB91301_RTC_TMRLR,  r4
+        ldi:20  #CYGNUM_HAL_RTC_PERIOD, r5
+        sth     r5,     @r4
+    # set parameters to TODO
+        ldi:8   #FR30_MB91301_RTC_TMCSR,  r4
+        ldi:20  #0x0813,    r5
+        sth     r5,     @r4
+    .endm
+
+#define CYGPKG_HAL_FR30_TIMER_DEFINED
+
+#endif
+
+#------------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_VARIANT_INC
+# end of variant.inc
diff --git a/packages/hal/fr30/mb91301/v2_0/src/fr30_mb91301.ld b/packages/hal/fr30/mb91301/v2_0/src/fr30_mb91301.ld
new file mode 100644 (file)
index 0000000..9f6f727
--- /dev/null
@@ -0,0 +1,166 @@
+//=============================================================================
+//
+// MLT linker script for Fujitsu FR30
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+
+#include <pkgconf/system.h>
+
+STARTUP(vectors.o)
+ENTRY(_start)
+#ifdef EXTRAS
+INPUT(extras.o)
+#endif
+#if (__GNUC__ >= 3)
+// GROUP(libtarget.a libgcc.a libsupc++.a)
+GROUP(libtarget.a libgcc.a)
+#else
+GROUP(libtarget.a libgcc.a)
+#endif
+
+#define ALIGN_LMA 4
+#define FOLLOWING(_section_) AT ((LOADADDR (_section_) + SIZEOF (_section_) + ALIGN_LMA - 1) & ~ (ALIGN_LMA - 1))
+#define LMA_EQ_VMA
+#define FORCE_OUTPUT . = .
+
+#define SECTIONS_BEGIN                          \
+  /* Debug information */                       \
+  .debug_aranges  0 : { *(.debug_aranges) }     \
+  .debug_pubnames 0 : { *(.debug_pubnames) }    \
+  .debug_info     0 : { *(.debug_info) }        \
+  .debug_abbrev   0 : { *(.debug_abbrev) }      \
+  .debug_line     0 : { *(.debug_line) }        \
+  .debug_frame    0 : { *(.debug_frame) }       \
+  .debug_str      0 : { *(.debug_str) }         \
+  .debug_loc      0 : { *(.debug_loc) }         \
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+
+#define SECTION_fixed_vectors(_region_, _vma_, _lma_) \
+    .fixed_vectors _vma_ : _lma_ \
+    { FORCE_OUTPUT; KEEP (*(.fixed_vectors)) } \
+    > _region_
+
+#define SECTION_rom_vectors(_region_, _vma_, _lma_) \
+    .rom_vectors _vma_ : _lma_ \
+    { FORCE_OUTPUT; KEEP (*(.rom_vectors)) } \
+    > _region_
+
+#define SECTION_rom_startup(_region_, _vma_, _lma_) \
+    .rom_startup_trampoline _vma_ : _lma_ \
+    { FORCE_OUTPUT; KEEP(*(.rom_startup_trampoline*)) } \
+    > _region_
+
+#define SECTION_ram_startup(_region_, _vma_, _lma_) \
+    .ram_startup_trampoline _vma_ : _lma_ \
+    { __ram_trampoline_start = ABSOLUTE (.); FORCE_OUTPUT; KEEP(*(.ram_startup_trampoline*)) } \
+    > _region_ \
+    __rom_trampoline_start = LOADADDR (.ram_startup_trampoline); \
+    __rom_trampoline_end = LOADADDR (.ram_startup_trampoline) + SIZEOF(.ram_startup_trampoline);
+
+#define SECTION_text(_region_, _vma_, _lma_) \
+    .text _vma_ : _lma_ \
+    { _stext = ABSOLUTE(.); \
+    PROVIDE (__stext = ABSOLUTE(.)); \
+    *(.text*) *(.gnu.warning) *(.gnu.linkonce*) *(.init) \
+    *(.glue_7) *(.glue_7t)  \
+    } > _region_ \
+    _etext = .; PROVIDE (__etext = .);
+
+#define SECTION_fini(_region_, _vma_, _lma_) \
+    .fini _vma_ : _lma_ \
+    { FORCE_OUTPUT; *(.fini) } \
+    > _region_
+
+#define SECTION_rodata(_region_, _vma_, _lma_) \
+    .rodata _vma_ : _lma_ \
+    { FORCE_OUTPUT; *(.rodata*) } \
+    > _region_
+
+#define SECTION_rodata1(_region_, _vma_, _lma_) \
+    .rodata1 _vma_ : _lma_ \
+    { FORCE_OUTPUT; *(.rodata1) } \
+    > _region_
+
+#define SECTION_fixup(_region_, _vma_, _lma_) \
+    .fixup _vma_ : _lma_ \
+    { FORCE_OUTPUT; *(.fixup) } \
+    > _region_
+
+#define SECTION_gcc_except_table(_region_, _vma_, _lma_) \
+    .gcc_except_table _vma_ : _lma_ \
+    { FORCE_OUTPUT; *(.gcc_except_table) } \
+    > _region_
+
+#define SECTION_sram(_region_, _vma_, _lma_) \
+    .sram _vma_ : _lma_ \
+    { FORCE_OUTPUT; *(.sram*) } \
+    > _region_
+
+#define SECTION_data(_region_,  _vma_, _lma_) \
+    .data _vma_ : _lma_ \
+    { __ram_data_start = ABSOLUTE (.); *(.data*) *(.data1) \
+    . = ALIGN (8); \
+    KEEP(*( SORT (.ecos.table.*))) ;            \
+    . = ALIGN (8); \
+    __CTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.ctors*))) __CTOR_END__ = ABSOLUTE (.); \
+    __DTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.dtors*))) __DTOR_END__ = ABSOLUTE (.); \
+    *(.sdata*) \
+    *(.eh_frame) \
+    . = ALIGN (8); *(.2ram.*) \
+    /* Global pointer stuff */ \
+    . = ALIGN(8);    _gp = . + 2048;     __global = _gp; \
+    _GOT_START_ = ABSOLUTE (.); *(.got) _GOT_END_ = ABSOLUTE (.); \
+    _GOT_PLT_START_ = ABSOLUTE (.); *(.got_plt) _GOT_PLT_END_ = ABSOLUTE (.); \
+    _GOT1_START_ = ABSOLUTE (.); *(.got1) _GOT1_END_ = ABSOLUTE (.); \
+    _GOT2_START_ = ABSOLUTE (.); *(.got2) _GOT2_END_ = ABSOLUTE (.); \
+    _DYNAMIC_ = ABSOLUTE (.); *(.dynamic) _DYNAMIC_ = ABSOLUTE (.); \
+    } \
+    > _region_ \
+    __rom_data_start = LOADADDR (.data); \
+    __ram_data_end = .; PROVIDE (__ram_data_end = .); _edata = .; PROVIDE (edata = .); \
+    __rom_data_end = LOADADDR (.data) + SIZEOF(.data);
+
+#define SECTION_bss(_region_,  _vma_, _lma_) \
+    .bss _vma_ : _lma_ \
+    { __bss_start = ABSOLUTE (.); \
+    *(.scommon) *(.dynbss) *(.sbss) *(.sbss.*) *(.bss*) *(.bss.*) *(COMMON) \
+    __bss_end = ABSOLUTE (.); } \
+    > _region_
+
+#define SECTIONS_END . = ALIGN(4); _end = .; PROVIDE (end = .);
+
+#include <pkgconf/hal_fr30.h>
+#include CYGHWR_MEMORY_LAYOUT_LDI
diff --git a/packages/hal/fr30/mb91301/v2_0/src/hal_diag.c b/packages/hal/fr30/mb91301/v2_0/src/hal_diag.c
new file mode 100644 (file)
index 0000000..be392e2
--- /dev/null
@@ -0,0 +1,566 @@
+/*=============================================================================
+//
+//      hal_diag.c
+//
+//      HAL diagnostic output code
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   larsi
+// Contributors:larsi
+// Date:        2006-07-26
+// Purpose:     HAL diagnostic output
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_trac.h>         // tracing macros
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/hal/hal_intr.h>
+
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/hal/hal_misc.h>
+/*---------------------------------------------------------------------------*/
+
+//#define CYG_KERNEL_DIAG_LCD
+#define CYG_KERNEL_DIAG_SERIAL0 // For ROM start but see immediately below:
+
+#if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon)
+#undef CYG_KERNEL_DIAG_SERIAL0
+#undef CYG_KERNEL_DIAG_LCD
+#define CYG_KERNEL_DIAG_CYGMON
+#define CYG_KERNEL_DIAG_GDB
+
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+#if defined(CYG_KERNEL_DIAG_SERIAL0) || defined(CYG_KERNEL_DIAG_CYGMON)
+
+/*---------------------------------------------------------------------------*/
+// LED diag function
+/*
+void hal_diag_init_led(){
+// we only init the first 4 leds here
+       asm volatile(
+        "ldi:8 #0xf,   r4;\n"
+        "ldi:20        #CYG_HAL_FR30_MB91360_DDRJ,     r5;\n"
+        "stb   r4,     @r5;\n"
+        "ldi:20        #CYG_HAL_FR30_MB91360_PFRJ, r5;\n"
+        "stb   r4,     @r5;\n"
+        : : :"r4", "r5"
+    );
+}
+*/
+// static cyg_uint8 leds = 0;
+
+void hal_diag_init(void){
+
+    // PJ2(SCK0) & PJ1(SOT0) output, PJ0(SIN0) input
+    HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_DDRJ, 0x6);
+    // PJ2(SCK0) & PJ1(SOT0) & PJ0(SIN0) to peripheral operation
+    HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PFRJ, 0x7);
+
+    // set up U-Timer
+    HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_UTIMC0, 0x02);
+    // 115200 bps
+    HAL_WRITE_UINT16(CYG_HAL_FR30_MB91301_UTIMR0, 0x7);
+
+    // setup UART
+    HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_SCR0, 0x13);
+    HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_SMR0, 0x30);
+}
+
+
+void hal_diag_led(cyg_uint8 leds)
+{
+
+    HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PDRG, leds);
+
+}
+
+/*---------------------------------------------------------------------------*/
+
+void hal_diag_write_char_serial0( char c)
+{
+    cyg_uint8 ssr;
+
+    do
+    {
+        HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SSR0 , ssr );
+    } while (!(ssr & BIT3));
+
+    HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_SODR0, c );
+
+}
+
+void hal_diag_write_hex_serial0(unsigned int c)
+{
+    unsigned char chr;
+    int i;
+
+    hal_diag_write_char_serial0('0');
+    hal_diag_write_char_serial0('x');
+
+    for(i = 28; i >= 0; i = i - 4)
+    {
+        chr = (c >> i) & 0xf;
+        if (chr >= 10) chr = chr + 55;   /* for A-F */
+        else  chr = chr + 48;  /* for 0-9 */
+        hal_diag_write_char_serial0(chr);
+    }
+    hal_diag_write_char_serial0('\n');
+    hal_diag_write_char_serial0('\r');
+}
+
+
+void hal_diag_drain(void)
+{
+    cyg_uint8 ssr;
+
+       do
+    {
+        HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SSR0 , ssr );
+    } while (!(ssr & BIT3));
+}
+
+void hal_diag_read_char_serial0(char *c)
+{
+    cyg_uint8 ssr;
+
+    do
+    {
+        HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SSR0 , ssr );
+    } while (!(ssr & BIT4));
+
+    HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SIDR0, *c );
+
+}
+
+
+#if defined(CYG_KERNEL_DIAG_CYGMON)
+void hal_diag_dumb_write_char(char c)
+#else
+void hal_diag_write_char(char c)
+#endif
+{
+#ifdef CYG_KERNEL_DIAG_GDB
+    static char line[100];
+    static int pos = 0;
+//    register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR;    
+
+    // No need to send CRs
+    if( c == '\r' ) return;
+
+    line[pos++] = c;
+
+    if( c == '\n' || pos == sizeof(line) )
+    {
+
+        // Disable interrupts. This prevents GDB trying to interrupt us
+        // while we are in the middle of sending a packet. The serial
+        // receive interrupt will be seen when we re-enable interrupts
+        // later.
+        CYG_INTERRUPT_STATE oldstate;
+        HAL_DISABLE_INTERRUPTS(oldstate);
+        
+        while(1)
+        {
+            static char hex[] = "0123456789ABCDEF";
+            cyg_uint8 csum = 0;
+            int i;
+            char c1;
+        
+            hal_diag_write_char_serial0('$');
+            hal_diag_write_char_serial0('O');
+            csum += 'O';
+            for( i = 0; i < pos; i++ )
+            {
+                char ch = line[i];
+                char h = hex[(ch>>4)&0xF];
+                char l = hex[ch&0xF];
+                hal_diag_write_char_serial0(h);
+                hal_diag_write_char_serial0(l);
+                csum += h;
+                csum += l;
+            }
+            hal_diag_write_char_serial0('#');
+            hal_diag_write_char_serial0(hex[(csum>>4)&0xF]);
+            hal_diag_write_char_serial0(hex[csum&0xF]);
+
+            hal_diag_read_char_serial0( &c1 );
+
+            if( c1 == '+' ) break;
+
+            {
+                extern void cyg_hal_user_break(CYG_ADDRWORD *regs);
+                extern cyg_bool cyg_hal_is_break(char *buf, int size);
+                if( cyg_hal_is_break( &c1 , 1 ) )
+                    cyg_hal_user_break( NULL );    
+            }
+            
+            break;
+        }
+        
+        pos = 0;
+
+        // Wait for all data from serial line to drain
+        // and clear ready-to-send indication.
+        hal_diag_drain_serial0();
+        
+        // And re-enable interrupts
+        HAL_RESTORE_INTERRUPTS( oldstate );
+        
+    }
+#else
+    hal_diag_write_char_serial0(c);
+#endif    
+}
+
+
+void hal_diag_read_char(char *c)
+{
+    for(;;)
+    {
+#if defined(CYG_KERNEL_DIAG_GDB) && defined(CYGSEM_HAL_USE_ROM_MONITOR)
+
+        typedef void rom_read_fn(char *c);
+        rom_read_fn *fn = ((rom_read_fn **)0x80000100)[62];
+
+        fn(c);
+    
+#else    
+        hal_diag_read_char_serial0(c);
+
+#endif    
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+        if( *c == 3 )
+        {
+            // Ctrl-C: breakpoint.
+            extern void breakpoint(void);
+            breakpoint();
+            continue;
+        }
+#elif defined(CYGSEM_HAL_USE_ROM_MONITOR)
+        if( *c == 3 )
+        {
+            // Ctrl-C: breakpoint.
+
+//                HAL_BREAKPOINT(_breakinst);
+            typedef void bpt_fn(void);
+            bpt_fn *bfn = ((bpt_fn **)0x80000100)[61];
+
+            bfn();
+            continue;            
+        }
+#endif
+
+        break;      
+    }
+}
+
+#endif // defined(CYG_KERNEL_DIAG_SERIAL0) || defined(CYG_KERNEL_DIAG_CYGMON)
+
+
+#if defined(CYG_KERNEL_DIAG_CYGMON) // only
+
+/* This code has been imported from the BSP module. The definitions have
+ * been left as-is, even though there was scope for doing more, to avoid
+ * too much drift from the original sources
+ */
+
+struct bsp_comm_procs {
+    void *ch_data;
+    void (*__write)(void *ch_data, const char *buf, int len);
+    int  (*__read)(void *ch_data, char *buf, int len);
+    void (*__putc)(void *ch_data, char ch);
+    int  (*__getc)(void *ch_data);
+    int  (*__control)(void *ch_data, int func, ...);
+};
+
+// This is pointed to by entry BSP_NOTVEC_BSP_COMM_PROCS:
+typedef struct {
+    int  version;       /* version number for future expansion */
+    void *__ictrl_table;
+    void *__exc_table;
+    void *__dbg_vector;
+    void *__kill_vector;
+    struct bsp_comm_procs *__console_procs;
+    struct bsp_comm_procs *__debug_procs;
+    void *__flush_dcache;
+    void *__flush_icache;
+    void *__cpu_data;
+    void *__board_data;
+    void *__sysinfo;
+    int  (*__set_debug_comm)(int __comm_id);
+    int  (*__set_console_comm)(int __comm_id);
+    int  (*__set_serial_baud)(int __comm_id, int baud);
+    void *__dbg_data;
+    void (*__reset)(void);
+    int  __console_interrupt_flag;
+} bsp_shared_t;
+
+/*
+ * Core Exception vectors.
+ */
+#define BSP_EXC_INT        0
+#define BSP_EXC_TLBMOD     1
+#define BSP_EXC_TLBL       2
+#define BSP_EXC_TLBS       3
+#define BSP_EXC_ADEL       4
+#define BSP_EXC_ADES       5
+#define BSP_EXC_IBE         6
+#define BSP_EXC_DBE         7
+#define BSP_EXC_SYSCALL     8
+#define BSP_EXC_BREAK       9
+#define BSP_EXC_ILL        10
+#define BSP_EXC_CPU        11
+#define BSP_EXC_OV         12
+#define BSP_EXC_TRAP       13
+#define BSP_EXC_VCEI       14
+#define BSP_EXC_FPE        15
+#define BSP_EXC_RSV16      16
+#define BSP_EXC_RSV17      17
+#define BSP_EXC_RSV18      18
+#define BSP_EXC_RSV19      19
+#define BSP_EXC_RSV20      20
+#define BSP_EXC_RSV21      21
+#define BSP_EXC_RSV22      22
+#define BSP_EXC_WATCH      23
+#define BSP_EXC_RSV24      24
+#define BSP_EXC_RSV25      25
+#define BSP_EXC_RSV26      26
+#define BSP_EXC_RSV27      27
+#define BSP_EXC_RSV28      28
+#define BSP_EXC_RSV29      29
+#define BSP_EXC_RSV30      30
+#define BSP_EXC_VCED       31
+/* tx39 debug exception */
+#define BSP_EXC_DEBUG      32
+#define BSP_EXC_TLB        33
+#define BSP_EXC_NMI        34
+/*
+ * Hack for eCos on tx39 to set an async breakpoint.
+ */
+#define BSP_VEC_BP_HOOK    35
+
+#define BSP_EXC_XTLB      36
+#define BSP_EXC_CACHE     37
+
+#define BSP_MAX_EXCEPTIONS 38
+
+/*
+ * Another hack for tx39 eCos compatibility.
+ */
+#if defined(__CPU_R3900__)
+#define BSP_VEC_MT_DEBUG   15
+#else
+#define BSP_VEC_MT_DEBUG   38
+#endif
+
+#define BSP_VEC_STUB_ENTRY 39
+#define BSP_VEC_BSPDATA    40
+#define BSP_VEC_MAGIC      41
+#define BSP_VEC_IRQ_CHECK  42
+
+#define BSP_VEC_PAD        43
+#define NUM_VTAB_ENTRIES   44
+
+
+#define BSP_MAGIC_VAL      0x55aa4321
+
+#define SYS_interrupt 1000
+
+// These vectors should be called with:
+//
+//  k0 - Exception Number
+
+#define CYGMON_VECTOR_TABLE_BASE 0x80000100
+#define CYGMON_VECTOR_TABLE ((CYG_ADDRESS *)CYGMON_VECTOR_TABLE_BASE)
+
+#if 0 // UNUSED
+static int
+hal_bsp_set_debug_comm(int arg)
+{
+    bsp_shared_t *shared;
+
+    shared = (bsp_shared_t *)
+        (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]);
+
+    if (0 != shared->__set_debug_comm) {
+        return (*(shared->__set_debug_comm))(arg);
+    }
+    return 0;
+}
+
+static int
+hal_bsp_set_console_comm(int arg)
+{
+    bsp_shared_t *shared;
+
+    shared = (bsp_shared_t *)
+        (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]);
+
+    if (0 != shared->__set_console_comm) {
+        return (*(shared->__set_console_comm))(arg);
+    }
+    return 0;
+}
+#endif // 0 UNUSED
+
+static void bsp_trap(int trap_num);
+
+static int
+hal_bsp_console_write(const void *p, int len)
+{
+    bsp_shared_t *shared;
+    struct bsp_comm_procs *com;
+    int  magic;
+
+    /*hal_bsp_set_console_comm(0);*/
+
+    /* If this is not a BSP-based CygMon, return 0 */
+    magic = (int)(CYGMON_VECTOR_TABLE[ BSP_VEC_MAGIC ]);
+    if (magic != BSP_MAGIC_VAL)
+       return 0;
+
+    shared = (bsp_shared_t *)
+        (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]);
+
+    com = shared->__console_procs;
+
+    if (0 != com) {
+       shared->__console_interrupt_flag = 0;
+        com->__write(com->ch_data, p, len);
+       if (shared->__console_interrupt_flag) {
+           /* debug interrupt; stop here */
+           bsp_trap(SYS_interrupt);
+       }
+
+        return 1;
+    }
+    return 0;
+}
+
+static void
+bsp_trap(int trap_num)
+{
+    asm("syscall\n");
+}
+
+
+static void
+hal_dumb_serial_write(const char *p, int len)
+{
+    int i;
+    for ( i = 0 ; i < len; i++ ) {
+       hal_diag_dumb_write_char(p[i]);
+    }
+} 
+/*
+void hal_diag_write_char(char c)
+{
+    static char line[100];
+    static int pos = 0;
+
+    // No need to send CRs
+    if( c == '\r' ) return;
+
+    line[pos++] = c;
+
+    if( c == '\n' || pos == sizeof(line) ) {
+        CYG_INTERRUPT_STATE old;
+
+        // Disable interrupts. This prevents GDB trying to interrupt us
+        // while we are in the middle of sending a packet. The serial
+        // receive interrupt will be seen when we re-enable interrupts
+        // later.
+        
+        HAL_DISABLE_INTERRUPTS(old);
+        
+        if ( ! hal_bsp_console_write( line, pos ) )
+            // then there is no function registered, just spew it out serial
+            hal_dumb_serial_write( line, pos );
+        
+        pos = 0;
+
+        // And re-enable interrupts
+        HAL_RESTORE_INTERRUPTS(old);
+
+    }
+}*/
+
+int
+hal_diag_irq_check(int vector)
+{
+    typedef int irq_check_fn(int irq_nr);
+    irq_check_fn *fn = (irq_check_fn *)(CYGMON_VECTOR_TABLE[ BSP_VEC_IRQ_CHECK ]);
+    int  magic;
+    
+
+    /* If this is not a BSP-based CygMon, return 0 */
+    magic = (int)(CYGMON_VECTOR_TABLE[ BSP_VEC_MAGIC ]);
+    if (magic != BSP_MAGIC_VAL)
+       return 0;
+
+#if defined(CYGPKG_HAL_MIPS_TX3904)
+    /* convert vector to BSP irq number */
+    if (vector == 16)
+       vector = 2;
+    else
+       vector += 3;
+#endif
+
+    return fn(vector);
+}
+
+#endif // defined(CYG_KERNEL_DIAG_CYGMON) *only*
+
+
+/*---------------------------------------------------------------------------*/
+/* End of hal_diag.c */
diff --git a/packages/hal/fr30/mb91301/v2_0/src/var_misc.c b/packages/hal/fr30/mb91301/v2_0/src/var_misc.c
new file mode 100644 (file)
index 0000000..10f0aed
--- /dev/null
@@ -0,0 +1,125 @@
+//==========================================================================
+//
+//      var_misc.c
+//
+//      HAL implementation miscellaneous functions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    larsi
+// Contributors:
+// Date:         2007-07-09
+// Purpose:      HAL miscellaneous functions
+// Description:  This file contains miscellaneous functions provided by the
+//               HAL.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // Base types
+#include <cyg/infra/cyg_trac.h>         // tracing macros
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#include <cyg/hal/hal_intr.h>
+
+#include <cyg/hal/hal_misc.h>
+/*------------------------------------------------------------------------*/
+// Array which stores the configured priority levels for the configured
+// interrupts.
+
+/* this may be useful later when interrupt masking of internal interrupt
+   sources is implemented
+
+volatile CYG_BYTE hal_interrupt_level[CYGNUM_HAL_ISR_COUNT];
+*/
+/*------------------------------------------------------------------------*/
+
+void hal_variant_init(void)
+{
+}
+
+//--------------------------------------------------------------------------
+// Microsecond delay
+// This uses reload timer 2, because timer 0 and 1 can cause DMA transfers
+// and may be used by the application.
+// Timer is initialized with 32 prescaler. If we need more precise delay
+// this has to change.
+
+void hal_delay_us(cyg_int32 n){
+#define TIMER_TIME  CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ * 1000000 / CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER / 32
+
+    unsigned int calc(unsigned long long n){
+        return n * TIMER_TIME / 1000000;
+    }
+
+    cyg_uint16  timer_status;
+
+    n = 21;//calc(n);
+    // stop eventually running counter and initialize
+    HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x812);
+
+    HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMRLR, 0xFFFF);
+    while(n > 0xffff){
+        // start counting
+        HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x813);
+        n = n - 0xffff;
+        // look for underflow
+        do {
+            HAL_READ_UINT16(CYG_HAL_FR30_DLY_TMCSR, timer_status);
+        } while (!(timer_status & BIT2));
+        // clear underflow bit
+        HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x813);
+    }
+    // clear count enable bit
+    HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x810);
+    // set new remaining count value
+    HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMRLR, n);
+    // start counting
+    HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x813);
+    // look for underflow
+    do {
+        HAL_READ_UINT16(CYG_HAL_FR30_DLY_TMCSR, timer_status);
+    } while (!(timer_status & BIT2));
+    // clear underflow and count enable bits
+    HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x810);
+}
+
+/*------------------------------------------------------------------------*/
+/* End of var_misc.c                                                      */
diff --git a/packages/hal/fr30/mb91301/v2_0/src/variant.S b/packages/hal/fr30/mb91301/v2_0/src/variant.S
new file mode 100644 (file)
index 0000000..cf81809
--- /dev/null
@@ -0,0 +1,198 @@
+##=============================================================================
+##
+##     variant.S
+##
+##     FR30 MB91301 variant code
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):  larsi
+## Contributors:larsi
+## Date:       2006-07-22
+## Purpose:    FR30 MB91301 variant code
+## Description:        Variant specific code for MB91301 processor family.
+##
+##
+##
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <pkgconf/system.h>    
+#include <pkgconf/hal.h>
+
+#ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>   
+#endif
+
+#include <cyg/hal/arch.inc>    
+
+#==============================================================================
+# Vector table for storage in flash
+# base address is 0x000FFC00, which stores the vector address for number 255
+# address 0x000FFFFC is the last vector, the reset vector, which is not
+# alterable. Vectors 255 to 80 are used by the INT instruction and set to 0
+# here for now ...
+
+#ifndef CYGPKG_HAL_FR30_ROM_VECTORS_DEFINED
+#define CYGPKG_HAL_FR30_ROM_VECTORS_DEFINED
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+     .section ".rom_vectors","ax"
+
+    .balign 4
+    .global hal_fr30_vector_table
+hal_fr30_vector_table:
+    .rept   255-80 + 1
+    .long   0x0
+    .endr
+    .rept   79-67 + 1
+    .long   0x0
+    .endr
+
+    .long   0x0
+    .long   0x0
+    .long   0x0
+# number 63 first interrupt source
+    .long   hal_fr30_irq_63
+    .long   hal_fr30_irq_62
+    .long   hal_fr30_irq_61
+    .long   hal_fr30_irq_60
+    .long   hal_fr30_irq_59
+    .long   hal_fr30_irq_58
+    .long   hal_fr30_irq_57
+    .long   hal_fr30_irq_56
+    .long   hal_fr30_irq_55
+    .long   hal_fr30_irq_54
+    .long   hal_fr30_irq_53
+    .long   hal_fr30_irq_52
+    .long   hal_fr30_irq_51
+    .long   hal_fr30_irq_50
+    .long   hal_fr30_irq_49
+    .long   hal_fr30_irq_48
+    .long   hal_fr30_irq_47
+    .long   hal_fr30_irq_46
+    .long   hal_fr30_irq_45
+    .long   hal_fr30_irq_44
+    .long   hal_fr30_irq_43
+    .long   hal_fr30_irq_42
+    .long   hal_fr30_irq_41
+    .long   hal_fr30_irq_40
+    .long   hal_fr30_irq_39
+    .long   hal_fr30_irq_38
+    .long   hal_fr30_irq_37
+    .long   hal_fr30_irq_36
+    .long   hal_fr30_irq_35
+    .long   hal_fr30_irq_34
+    .long   hal_fr30_irq_33
+    .long   hal_fr30_irq_32
+    .long   hal_fr30_irq_31
+    .long   hal_fr30_irq_30
+    .long   hal_fr30_irq_29
+    .long   hal_fr30_irq_28
+    .long   hal_fr30_irq_27
+    .long   hal_fr30_irq_26
+    .long   hal_fr30_irq_25
+    .long   hal_fr30_irq_24
+    .long   hal_fr30_irq_23
+    .long   hal_fr30_irq_22
+    .long   hal_fr30_irq_21
+    .long   hal_fr30_irq_20
+    .long   hal_fr30_irq_19
+    .long   hal_fr30_irq_18
+    .long   hal_fr30_irq_17
+    .long   hal_fr30_irq_16
+    .long   hal_fr30_irq_15
+    .long   hal_fr30_exception_noerr_14
+    .long   hal_fr30_exception_noerr_13
+    .long   hal_fr30_exception_noerr_12
+    .long   hal_fr30_exception_noerr_11
+    .long   hal_fr30_exception_noerr_10
+    .long   hal_fr30_exception_noerr_9
+    .long   hal_fr30_exception_noerr_8
+    .long   hal_fr30_exception_noerr_7
+    .long   hal_fr30_exception_noerr_6
+    .long   hal_fr30_exception_noerr_5
+    .long   hal_fr30_exception_noerr_4
+    .long   hal_fr30_exception_noerr_3
+    .long   hal_fr30_exception_noerr_2
+
+# mode vector (only the first of the four byte is relevant)
+    .byte   0x1
+    .byte   0
+    .byte   0
+    .byte   0
+
+# reset vector
+    .long   _start
+
+#endif /*CYG_HAL_STARTUP_ROM || CYG_HAL_STARTUP_ROMRAM*/
+#endif /*CYGPKG_HAL_FR30_ROM_VECTORS_DEFINED*/
+
+##-----------------------------------------------------------------------------
+# Interrupt vector tables.
+# These tables contain the isr, data and object pointers used to deliver
+# interrupts to user code.
+
+    .extern hal_default_isr
+
+    .data
+    .balign 4
+
+    .globl  hal_interrupt_handlers
+hal_interrupt_handlers:
+    .rept  CYGNUM_HAL_ISR_COUNT
+    .long   hal_default_isr
+    .endr
+
+    .globl  hal_interrupt_data
+hal_interrupt_data:
+    .rept   CYGNUM_HAL_ISR_COUNT
+    .long   0
+    .endr
+
+    .globl  hal_interrupt_objects
+hal_interrupt_objects:
+    .rept   CYGNUM_HAL_ISR_COUNT
+    .long   0
+    .endr
+
+##-----------------------------------------------------------------------------
+## end of variant.S
+       
diff --git a/packages/hal/fr30/skmb91302/v2_0/ChangeLog b/packages/hal/fr30/skmb91302/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..4de285c
--- /dev/null
@@ -0,0 +1,66 @@
+2008-07-01  Lars Poeschel  <larsi@wh2.tu-dresden.de>
+
+    * src/platform.S: Startup routines for remapping the flash during
+      startup. Defined own rom_vector table.
+    * src/ser.c: Little updates that could cause problems after a reset with 
+      wrong settings in the serial configuration registers.
+    * include/pkgconf/mlt_fr30_skmb91302_rom.h:
+    * include/pkgconf/mlt_fr30_skmb91302_rom.ldi: Reworked memory layout for
+      flash support.
+
+
+2007-07-09  Lars Poeschel  <larsi@wh2.tu-dresden.de>
+
+    * src/platform.S:
+    * src/plf_misc.c:
+    * src/plf_stub.c:
+    * src/ser.c:
+    * misc/redboot_RAM.ecm:
+    * misc/redboot_ROM.ecm:
+    * include/pkgconf/mlt_fr30_skmb91302_ram.h:
+    * include/pkgconf/mlt_fr30_skmb91302_ram.ldi:
+    * include/pkgconf/mlt_fr30_skmb91302_rom.h:
+    * include/pkgconf/mlt_fr30_skmb91302_rom.ldi:
+    * include/platform.inc:
+    * include/plf_cache.h:
+    * include/plf_intr.h:
+    * include/plf_io.h:
+    * include/plf_stub.h:
+    * cdl/hal_fr30_skmb91302.cdl: Initial fr30 ecos port
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/hal/fr30/skmb91302/v2_0/cdl/hal_fr30_skmb91302.cdl b/packages/hal/fr30/skmb91302/v2_0/cdl/hal_fr30_skmb91302.cdl
new file mode 100644 (file)
index 0000000..335ab5b
--- /dev/null
@@ -0,0 +1,282 @@
+# ====================================================================
+#
+#      hal_fr30_skmb91302.cdl
+#
+#   Fujitsu Starterkit MB91302 board HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+
+cdl_package CYGPKG_HAL_FR30_MB91301_SKMB91302 {
+    display         "Fujitsu Starterkit MB91302 board"
+    parent          CYGPKG_HAL_FR30
+    requires        CYGPKG_HAL_FR30_MB91301
+    define_header   hal_fr30_skmb91302.h
+    include_dir     cyg/hal
+
+    description   "Fujitsu Starterkit MB91302 board platform HAL
+                package should be used when targeting the actual hardware for
+                the Fujitsu Starterkit MB91302 board platform."
+
+    compile     platform.S plf_misc.c ser.c
+    implements      CYGINT_HAL_DEBUG_GDB_STUBS
+    implements      CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+    implements  CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+
+    define_proc {
+        puts $::cdl_header "#include <pkgconf/hal_fr30_mb91301.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_fr30.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H <pkgconf/hal_fr30_mb91301.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_fr30_skmb91302.h>"
+    }
+
+    cdl_component CYG_HAL_STARTUP {
+        display         "Startup type"
+        flavor          data
+        legal_values    {"RAM" "ROM" "ROMRAM"}
+        default_value   {"ROM"}
+           no_define
+           define -file system.h CYG_HAL_STARTUP
+
+        description   "Should the system run from RAM, ROM, or copy itself from ROM 
+                       and RAM and then run in RAM?"
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+        display      "Number of communication channels on the board"
+        flavor       data
+        calculated   2
+        description      "The MB91302 board has 3 serial ports. Only the first
+                          2 have mounted 9 pin connectors. The 3rd is not
+                          connected and should therefore not be used."
+    }
+
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT {
+         display      "Default console channel."
+         flavor       data
+         legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+         calculated   0
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+        display          "Debug serial port"
+        flavor data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    0
+        description      "This option chooses which port will be used to connect
+            to a host running GDB."
+    }
+
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+         display          "Diagnostic serial port"
+         flavor data
+         legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+         default_value    CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT
+         description      "
+            This option chooses which port will be used for diagnostic output."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+        display       "Diagnostic serial port baud rate"
+        flavor        data
+        legal_values  9600 19200 38400 57600 115200
+        default_value 57600
+        description   "
+            This option selects the baud rate used for the diagnostic port.
+            Note: this should match the value chosen for the GDB port if the
+            diagnostic and GDB port are the same."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+        display       "GDB serial port baud rate"
+        flavor        data
+        legal_values  9600 19200 38400 57600 115200
+        default_value 57600
+        description   "
+            This option selects the baud rate used for the diagnostic port.
+            Note: this should match the value chosen for the GDB port if the
+            diagnostic and GDB port are the same."
+    }
+
+    cdl_component CYGBLD_GLOBAL_OPTIONS {
+        display "Global build options"
+        flavor  none
+        parent  CYGPKG_NONE
+
+        description   "Global build options including control over compiler
+                       flags, linker flags and choice of toolchain."
+
+        cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+            display "Global command prefix"
+            flavor  data
+            no_define
+            default_value { "fr30-unknown-elf" }
+            description       "This option specifies  the command prefix  used
+                               when invoking the build tools."
+
+        }
+
+        cdl_option CYGBLD_GLOBAL_CFLAGS {
+            display "Global compiler flags"
+            flavor  data
+            no_define
+            default_value { "-Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -finit-priority -fomit-frame-pointer" }
+            description       "This option controls the global compiler  flags
+                               which are used to compile all packages by default.
+                               Individual  packages  may  define  options   which
+                               override these global flags."
+
+        }
+
+        cdl_option CYGBLD_GLOBAL_LDFLAGS {
+            display "Global linker flags"
+            flavor  data
+            no_define
+            default_value { " -g -nostdlib -Wl,--gc-sections -Wl,-static" }
+            description       "This option controls  the global linker  flags.
+                               Individual  packages  may  define  options   which
+                               override these global flags."
+
+        }
+
+        cdl_option CYGBLD_BUILD_GDB_STUBS {
+            display "Build GDB stub ROM image"
+            default_value 0
+            requires { CYG_HAL_STARTUP == "ROM" }
+            requires CYGSEM_HAL_ROM_MONITOR
+            requires CYGBLD_BUILD_COMMON_GDB_STUBS
+            requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+            requires ! CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+            requires ! CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+            requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+            requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+            no_define
+            description       "This option enables the  building  of  the  GDB
+                               stubs for the  board.   The  common  HAL  controls
+                               takes care of most of  the build process, but  the
+                               final conversion from ELF image to binary data  is
+                               handled by the  platform CDL, allowing  relocation
+                               of the data if necessary."
+
+            make -priority 320 {
+                <PREFIX>/bin/gdb_module.srec : <PREFIX>/bin/gdb_module.img
+                $(OBJCOPY) -O srec $< $@
+            }
+        }
+    }
+
+    cdl_component CYGHWR_MEMORY_LAYOUT {
+        display "Memory layout"
+        flavor data
+        no_define
+        calculated { CYG_HAL_STARTUP == "RAM" ? "mlt_fr30_skmb91302_ram" : \
+                                               "mlt_fr30_skmb91302_rom" }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+            display "Memory layout linker script fragment"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+            calculated { CYG_HAL_STARTUP == "RAM" ? "<pkgconf/mlt_fr30_skmb91302_ram.ldi>" : \
+                                                    "<pkgconf/mlt_fr30_skmb91302_rom.ldi>" }
+        }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_H {
+            display "Memory layout header file"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_H
+            calculated { CYG_HAL_STARTUP == "RAM" ? "<pkgconf/mlt_fr30_skmb91302_ram.h>" : \
+                                                    "<pkgconf/mlt_fr30_skmb91302_rom.h>" }
+        }
+    }
+
+    cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+    display       "Work with a ROM monitor"
+        flavor        bool
+        default_value { CYG_HAL_STARTUP == "RAM" ? 1 : 0 }
+        parent        CYGPKG_HAL_ROM_MONITOR
+        requires      { CYG_HAL_STARTUP == "RAM" }
+        description   "
+            Allow coexistence with ROM monitor (CygMon or GDB stubs) by
+            only initializing interrupt vectors on startup, thus leaving
+            exception handling to the ROM monitor."
+    }
+
+    cdl_option CYGSEM_HAL_ROM_MONITOR {
+        display       "Behave as a ROM monitor"
+        flavor        bool
+        default_value 0
+        parent        CYGPKG_HAL_ROM_MONITOR
+        requires      { CYG_HAL_STARTUP == "ROM" }
+
+        description    "Enable this option if this program is to be used as
+                        a ROM monitor, i.e.  applications will be loaded  into
+                        RAM on the  board, and  this ROM  monitor may  process
+                        exceptions   or   interrupts   generated   from    the
+                        application.  This enables features such as  utilizing
+                        a  separate  interrupt   stack  when  exceptions   are
+                        generated."
+
+    }
+
+        cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+        display       "Redboot HAL options"
+        flavor        none
+        no_define
+        parent        CYGPKG_REDBOOT
+        active_if     CYGPKG_REDBOOT
+        description   "
+            This option lists the target's requirements for a valid Redboot
+            configuration."
+
+        cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+            display       "Build Redboot ROM binary image"
+            active_if     CYGBLD_BUILD_REDBOOT
+            default_value 1
+            no_define
+            description "This option enables the conversion of the Redboot ELF
+                         image to a binary image suitable for ROM programming."
+
+            make -priority 325 {
+                <PREFIX>/bin/redboot.srec : <PREFIX>/bin/redboot.elf
+                $(OBJCOPY) --strip-all $< $(@:.srec=.img)
+                $(OBJCOPY) -O srec $< $@
+            }
+        }
+    }
+
+}
diff --git a/packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_ram.h b/packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_ram.h
new file mode 100644 (file)
index 0000000..5a2ddb6
--- /dev/null
@@ -0,0 +1,17 @@
+// eCos memory layout - Fri Oct 20 05:56:24 2000
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x2000000)
+#define CYGMEM_REGION_ram_SIZE (0x800000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x03F00000 - (size_t) CYG_LABEL_NAME (__heap1))
diff --git a/packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_ram.ldi b/packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_ram.ldi
new file mode 100644 (file)
index 0000000..fb34bea
--- /dev/null
@@ -0,0 +1,28 @@
+// eCos memory layout - Fri Oct 20 05:56:24 2000
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+
+MEMORY
+{
+    ram   : ORIGIN = 0x3F000, LENGTH = 0x1000
+    sdram : ORIGIN = 0x2000000, LENGTH = 0x800000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+//    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixed_vectors (sdram, 0x2000000, LMA_EQ_VMA)
+    SECTION_text (sdram, 0x2008000, LMA_EQ_VMA)
+    SECTION_fini (sdram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (sdram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (sdram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (sdram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_data (sdram, ALIGN(0x4), FOLLOWING (.gcc_except_table))
+//    SECTION_data (sdram, ALIGN(0x4), LMA_EQ_VMA)
+    SECTION_bss (sdram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x1000);
+    SECTIONS_END
+}
diff --git a/packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_rom.h b/packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_rom.h
new file mode 100644 (file)
index 0000000..5a2ddb6
--- /dev/null
@@ -0,0 +1,17 @@
+// eCos memory layout - Fri Oct 20 05:56:24 2000
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x2000000)
+#define CYGMEM_REGION_ram_SIZE (0x800000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x03F00000 - (size_t) CYG_LABEL_NAME (__heap1))
diff --git a/packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_rom.ldi b/packages/hal/fr30/skmb91302/v2_0/include/pkgconf/mlt_fr30_skmb91302_rom.ldi
new file mode 100644 (file)
index 0000000..e6e6ed0
--- /dev/null
@@ -0,0 +1,32 @@
+// eCos memory layout - Fri Oct 20 05:56:24 2000
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+
+MEMORY
+{
+    ram   : ORIGIN = 0x18000, LENGTH = 0x1000
+    rom1  : ORIGIN = 0x80000, LENGTH = 0x7fc00 // Length = 511 kB
+    ints  : ORIGIN = 0xFFC00, LENGTH = 0x400
+    rom2  : ORIGIN = 0x1100000, LENGTH = 0x700000
+    sdram : ORIGIN = 0x2000000, LENGTH = 0x800000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    SECTION_rom_startup(rom1, 0x80000, LMA_EQ_VMA)
+    SECTION_ram_startup(ram, 0x18000, FOLLOWING(.rom_startup_trampoline))
+    SECTION_rom_vectors (ints, 0xffc00 , LMA_EQ_VMA)
+    SECTION_text (rom2, 0x1100000, AT(0x100000))
+    SECTION_fini (rom2, ALIGN (0x4), FOLLOWING (.text))
+    SECTION_rodata (rom2, ALIGN (0x4), FOLLOWING (.fini))
+    SECTION_fixup (rom2, ALIGN (0x4), FOLLOWING (.rodata))
+    SECTION_gcc_except_table (rom2, ALIGN (0x4), FOLLOWING (.fixup))
+    SECTION_fixed_vectors (sdram, 0x2000000, LMA_EQ_VMA)
+    SECTION_data (sdram, ALIGN(0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss (sdram, ALIGN (0x4), LMA_EQ_VMA)
+    CYG_LABEL_DEFN(__heap1) = ALIGN (0x1000);
+    SECTIONS_END
+}
diff --git a/packages/hal/fr30/skmb91302/v2_0/include/platform.inc b/packages/hal/fr30/skmb91302/v2_0/include/platform.inc
new file mode 100644 (file)
index 0000000..cdeac62
--- /dev/null
@@ -0,0 +1,188 @@
+#ifndef CYGONCE_HAL_PLATFORM_INC
+#define CYGONCE_HAL_PLATFORM_INC
+##=============================================================================
+##
+##     platform.inc
+##
+##     Fujitsu Starterkit MB91302 board assembler header file
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):   larsi
+## Contributors:
+## Date:        2007-07-09
+## Purpose:     Fujitsu Starterkit MB91302 board definitions.
+## Description: This file contains various definitions and macros that are
+##              useful for writing assembly code for the skmb91302 board.
+## Usage:
+##             #include <cyg/hal/platform.inc>
+##
+##
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <cyg/hal/fr30.inc>
+
+
+##------------------------------------------------------------------------------
+## ext Bus (memory controller) initialisation macros
+##
+## flash part
+
+
+#define CYGPKG_HAL_FR30_FLASH_INIT_DEFINED
+## flash init is empty for this platform because it is initialized in the
+## special hal_fr30_ram_startup_trampoline to map flash to 0x1000000
+.macro hal_flash_init
+.endm
+
+## and the following macro is used in the special
+## hal_fr30_ram_startup_trampoline for flash initialisation
+.macro hal_flash_init_from_ram
+
+    ldi:20  #FR30_MB91301_ASR0, r10 ; CS0 area starts at
+    ldi:20  0x100,   r0             ; 0x01000000
+    sth     r0,     @r10            ;
+
+    ldi:20  #FR30_MB91301_ACR0, r11 ; configuration parameters for CS0
+    ldi:20  #0x7422,    r1          ; 8MB(0x0-0x7FFFFF),16bit data bus,
+    sth     r1,     @r11            ; pre-fetch off, single access,
+                                    ; write enable, big endian,
+                                    ; normal access(asynchronous),
+                                    ; WR pin enabled for write,
+                                    ; wait by RDY pin disabled
+
+    ldi:20  #FR30_MB91301_AWR0, r12 ; first access auto-wait 3cyc
+    ldi:20  #0x3378,    r2          ; inpage access auto-wait 3cyc
+    sth     r2,     @r12            ; read/write idle 1cyc
+                                    ; write recover 3cyc
+                                    ; async write strobe outp enabled
+                                    ; CS delay enabled
+                                    ; CS read/write setup delay 0
+                                    ; RD/WR -> CS hold extension 0 cyc
+
+    ldi:20  #FR30_MB91301_PFR9, r13 ; WRn, BAAE, ASXE enable
+    ldi:8   #0x7e,  r3              ;
+    stb     r3,     @r13            ;
+
+## following would chip select enable
+## we only use cs0 until here, which is already set by reset
+
+.endm
+
+
+## sdram part
+
+
+#define CYGPKG_HAL_FR30_MEMC_INIT_DEFINED
+
+.macro hal_memc_init
+
+## The following instruction is without function. It is only to reference
+## hal_fr30_rom_startup_trampoline, because when not referenced the linker
+## does not include the file platform.S in the link. If somewhen some other
+## referenced code appears in platform.S the instruction here can be deleted
+## (including the surrounding macro)!
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+    ldi:32  #hal_fr30_rom_startup_trampoline, r10
+#endif
+
+    ldi:20  #FR30_MB91301_ASR6, r10 ; CS6 area starts at
+    ldi:20  0x200,   r0             ; 0x02000000
+    sth     r0,     @r10            ;
+
+    ldi:20  #FR30_MB91301_ACR6, r11 ; configuration parameters for CS6
+    ldi:20  #0x7868,    r1          ; 64MB(0x2000000-0x27FFFFF),32bit data bus,
+    sth     r1,     @r11            ; pre-fetch on, single access(no burst),
+                                    ; write enable, big endian,
+                                    ; FCRAM setting
+
+    ldi:20  #FR30_MB91301_AWR6, r12 ; first access auto-wait 1cyc ??
+    ldi:20  #0x1159,    r2          ; inpage access auto-wait 1cyc ??
+    sth     r2,     @r12            ; read/write idle 1cyc ??
+                                    ; write recover 1cyc ??
+                                    ; async write strobe outp enabled ??
+                                    ; CS delay disabled ??
+                                    ; CS read/write setup delay 0 ??
+                                    ; RD/WR -> CS hold extension 1 cyc ??
+                                    ; see Hardware Manual page 156ff
+
+    ldi:20  #FR30_MB91301_MCRA, r13 ; 8 columns, single write,
+    ldi:8   #0x07,  r3              ; 4 banks for burst write,
+    stb     r3,     @r13            ; 4 active banks
+
+    ldi:20  #FR30_MB91301_PFR9, r10 ; enable WRn, BAAE, ASXE,
+    ldi:8   #0x7e,  r0              ; sysclk, MCKE, MCKEE
+    stb     r0,     @r10
+
+    ldi:20  #FR30_MB91301_PFR8, r11 ; enable WR3XE, WR2XE, WR1XE
+    ldi:8   #0xe0,  r1
+    stb     r1, @r11
+
+    ldi:20  #FR30_MB91301_CSER, r12 ; switch on CS6 & CS0
+    ldi:8   #0x41,  r2
+    stb     r2,     @r12
+
+    ldi:20  #FR30_MB91301_RCR,  r13 ; power on SDRAM I/F
+    ldi:20  #0xe247,    r3          ; 0xe247 -> 0xe24f
+    sth     r3,     @r13
+    ldi:20  #0xe24f,    r3
+    sth     r3,     @r13
+
+.endm
+
+#------------------------------------------------------------------------------
+## Vector table for storage. platform.S defines a vector table and wants to
+## override the one from variant.S with this define
+
+#define CYGPKG_HAL_FR30_ROM_VECTORS_DEFINED
+
+#------------------------------------------------------------------------------
+# Difference of the flash memory from the linkers LMA (loadmemoryaddress) after
+# the new mapping in (mapping is done in hal_fr30_ram_startup_trampoline).
+
+#define CYGPKG_HAL_FR30_LMA_OFFSET  0x1000000
+
+
+
+#------------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_PLATFORM_INC
+# end of platform.inc
diff --git a/packages/hal/fr30/skmb91302/v2_0/include/plf_cache.h b/packages/hal/fr30/skmb91302/v2_0/include/plf_cache.h
new file mode 100644 (file)
index 0000000..54f058b
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef CYGONCE_PLF_CACHE_H
+#define CYGONCE_PLF_CACHE_H
+
+//=============================================================================
+//
+//      plf_cache.h
+//
+//      HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   nickg
+// Contributors:
+// Date:        2007-07-09
+// Purpose:     Cache control API
+// Description: The macros defined here provide the HAL APIs for handling
+//              cache control operations.
+// Usage:
+//              #include <cyg/hal/plf_cache.h>
+//              ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/plf_cache.h>
+
+//=============================================================================
+
+// Nothing here at present.
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_PLF_CACHE_H
+// End of plf_cache.h
+
diff --git a/packages/hal/fr30/skmb91302/v2_0/include/plf_intr.h b/packages/hal/fr30/skmb91302/v2_0/include/plf_intr.h
new file mode 100644 (file)
index 0000000..2a614a2
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef CYGONCE_HAL_PLF_INTR_H
+#define CYGONCE_HAL_PLF_INTR_H
+
+//==========================================================================
+//
+//      plf_intr.h
+//
+//      Fujitsu Starterkit MB91302 board interrupt and clock support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    nickg
+// Contributors:
+// Date:         2007-07-09
+// Purpose:      Define Interrupt support
+// Description:  The macros defined here provide the HAL APIs for handling
+//               interrupts and the clock for the Fujitsu Starterkit MB91302 board.
+//
+// Usage:
+//              #include <cyg/hal/plf_intr.h>
+//              ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Interrupt controller stuff.
+
+
+//--------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_PLF_INTR_H
+// End of plf_intr.h
diff --git a/packages/hal/fr30/skmb91302/v2_0/include/plf_io.h b/packages/hal/fr30/skmb91302/v2_0/include/plf_io.h
new file mode 100644 (file)
index 0000000..12df3df
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef CYGONCE_PLF_IO_H
+#define CYGONCE_PLF_IO_H
+
+//=============================================================================
+//
+//      plf_io.h
+//
+//      Platform specific IO support
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    hmt, jskov, nickg
+// Contributors:
+// Date:         2007-07-09
+// Purpose:      Fujitsu Starterkit MB91302 board IO support macros
+// Description: 
+// Usage:        #include <cyg/hal/plf_io.h>
+//
+// Note:         Based on information in 
+//               
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_io.h>     // IO macros
+#include <cyg/hal/hal_intr.h>   // Interrupt vectors
+
+//-----------------------------------------------------------------------------
+// end of plf_io.h
+#endif // CYGONCE_PLF_IO_H
diff --git a/packages/hal/fr30/skmb91302/v2_0/include/plf_stub.h b/packages/hal/fr30/skmb91302/v2_0/include/plf_stub.h
new file mode 100644 (file)
index 0000000..5256385
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef CYGONCE_HAL_PLF_STUB_H
+#define CYGONCE_HAL_PLF_STUB_H
+
+//=============================================================================
+//
+//      plf_stub.h
+//
+//      Platform header for GDB stub support.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   jskov
+// Contributors:
+// Date:        2007-07-09
+// Purpose:     Platform HAL stub support for Fujitsu Starterkit MB91302 boards.
+// Usage:       #include <cyg/hal/plf_stub.h>
+//              
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h>         // CYG_UNUSED_PARAM
+
+#include <cyg/hal/fr30_stub.h>          // architecture stub support
+
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+//-----------------------------------------------------------------------------
+// Syscall support.
+#ifdef CYGPKG_CYGMON
+// Cygmon provides syscall handling for this board
+#define SIGSYSCALL SIGSYS
+extern int __get_syscall_num (void);
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_PLF_STUB_H
+// End of plf_stub.h
diff --git a/packages/hal/fr30/skmb91302/v2_0/misc/redboot_RAM.ecm b/packages/hal/fr30/skmb91302/v2_0/misc/redboot_RAM.ecm
new file mode 100644 (file)
index 0000000..92c948c
--- /dev/null
@@ -0,0 +1,67 @@
+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    phytec91f364g ;
+    template    redboot ;
+    package -hardware CYGPKG_HAL_FR30 current ;
+    package -hardware CYGPKG_HAL_FR30_MB91301_SKMB91302 current ;
+    package -template CYGPKG_HAL current ;
+    package -template CYGPKG_INFRA current ;
+    package -template CYGPKG_REDBOOT current ;
+};
+
+cdl_option CYGBLD_BUILD_GDB_STUBS {
+    user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+    user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+    inferred_value 0
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+    inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT {
+    inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT {
+    inferred_value 0
+};
+
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+    inferred_value 0 0
+};
+
+cdl_component CYG_HAL_STARTUP {
+    user_value RAM
+};
+
+cdl_option CYGBLD_BUILD_REDBOOT {
+    user_value 1
+};
+
+#cdl_option CYGSEM_REDBOOT_FLASH_CONFIG {
+#    user_value 1
+#};
+
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+  user_value 1
+};
+
+cdl_option CYGBLD_REDBOOT_FLASH_BOOT_OFFSET {
+  inferred_value 0x1C00000
+};
diff --git a/packages/hal/fr30/skmb91302/v2_0/misc/redboot_ROM.ecm b/packages/hal/fr30/skmb91302/v2_0/misc/redboot_ROM.ecm
new file mode 100644 (file)
index 0000000..5f97e66
--- /dev/null
@@ -0,0 +1,68 @@
+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    phytec91f364g ;
+    template    redboot ;
+    package -hardware CYGPKG_HAL_FR30 current ;
+    package -hardware CYGPKG_HAL_FR30_MB91301_SKMB91302 current ;
+    package -template CYGPKG_HAL current ;
+    package -template CYGPKG_INFRA current ;
+    package -template CYGPKG_REDBOOT current ;
+};
+
+cdl_option CYGBLD_BUILD_GDB_STUBS {
+    user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+    user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+    inferred_value 0
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+    inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT {
+    inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT {
+    inferred_value 0
+};
+
+cdl_option CYGSEM_HAL_ROM_MONITOR {
+    user_value 1
+};
+
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+    inferred_value 0 0
+};
+
+cdl_component CYG_HAL_STARTUP {
+    user_value ROM
+};
+
+cdl_option CYGBLD_BUILD_REDBOOT {
+    user_value 1
+};
+
+
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+  user_value 1
+};
+
+cdl_option CYGBLD_REDBOOT_FLASH_BOOT_OFFSET {
+  inferred_value 0x1C00000
+};
diff --git a/packages/hal/fr30/skmb91302/v2_0/src/platform.S b/packages/hal/fr30/skmb91302/v2_0/src/platform.S
new file mode 100644 (file)
index 0000000..ebf6c0f
--- /dev/null
@@ -0,0 +1,234 @@
+##=============================================================================
+##
+##     platform.S
+##
+##     Fujitsu Starterkit MB91302 platform code
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):       larsi
+## Contributors:
+## Date:            2007-07-09
+## Purpose:         Fujitsu Starterkit MB91302 platform code
+## Description:     Platform specific code for Fujitsu Starterkit MB91302 board.
+##
+##
+##
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+#endif
+
+#include <cyg/hal/arch.inc>
+
+##-----------------------------------------------------------------------------
+## platforms special entry point.
+## it copies the code from hal_fr30_ram_startup_trampoline until
+## hal_fr30_ram_startup_trampoline_end to ram and jumps there. The code there
+## is for mapping the flash to 0x1000000 and then jumping to real entry
+## (_start).
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+    .section ".rom_startup_trampoline","ax"
+
+    .balign 4
+    .global hal_fr30_rom_startup_trampoline
+hal_fr30_rom_startup_trampoline:
+    # disable interrupts and set priority to lowest (=disable)
+    andccr  #0xef
+    stilm   #0x0
+
+    ldi:32  #__rom_trampoline_start - 4,       r11
+    ldi:32  #__ram_trampoline_start - 4,                r13
+    ldi:32  #__rom_trampoline_end - 8,   r12
+1:
+    add     #0x4,   r11
+    add     #0x4,   r13
+    ld      @r11,   r0
+    cmp     r12,    r11
+    ble:d   1b
+    st      r0,     @r13
+
+## jump to the code in ram
+    ldi:32  #hal_fr30_ram_startup_trampoline, r0
+    jmp     @r0
+
+#endif
+
+##-----------------------------------------------------------------------------
+# Platform Initialization.
+# This code is copied to a location in RAM on startup and is executed there.
+# It maps the the FLASH chip to 0x1000000 and sets the TBR to the new location
+# of the hardware vector table (hal_fr30_vector_table). So we can reach the full
+# range of the FLASH and it can be used for flashfilesystem. After that it jumps
+# to the real application.
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+    .section ".ram_startup_trampoline","ax"
+
+    .balign 4
+    .global hal_fr30_ram_startup_trampoline
+hal_fr30_ram_startup_trampoline:
+    hal_flash_init_from_ram
+
+## map TBR to the new location (for vector tables)
+    ldi:32  #0x10ffc00, r0
+    mov     r0,     tbr
+
+## jump to real startup
+    ldi:32  #_start,    r0
+    jmp     @r0
+
+#endif
+
+
+#==============================================================================
+# Vector table for storage in flash, version for skmb91302 platform.
+# it differs from variants/archs version in that uses a different reset vector
+# that points to the special startup procedure that jumps to the normal entry
+# (_start) later.
+# base address is 0x000FFC00 and 0x10ffc00 after remapping the flash.
+# This address stores the vector address for number 255
+# address 0x000FFFFC (0x10ffffc) is the last vector, the reset vector, which
+# is not alterable. Vectors 255 to 80 are used by the INT instruction and set
+# to 0 here for now ...
+
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+     .section ".rom_vectors","ax"
+
+    .balign 4
+    .global hal_fr30_vector_table
+hal_fr30_vector_table:
+    .rept   255-80 + 1
+    .long   0x0
+    .endr
+    .rept   79-67 + 1
+    .long   0x0
+    .endr
+
+    .long   0x0
+    .long   0x0
+    .long   0x0
+# number 63 first interrupt source
+    .long   hal_fr30_irq_63
+    .long   hal_fr30_irq_62
+    .long   hal_fr30_irq_61
+    .long   hal_fr30_irq_60
+    .long   hal_fr30_irq_59
+    .long   hal_fr30_irq_58
+    .long   hal_fr30_irq_57
+    .long   hal_fr30_irq_56
+    .long   hal_fr30_irq_55
+    .long   hal_fr30_irq_54
+    .long   hal_fr30_irq_53
+    .long   hal_fr30_irq_52
+    .long   hal_fr30_irq_51
+    .long   hal_fr30_irq_50
+    .long   hal_fr30_irq_49
+    .long   hal_fr30_irq_48
+    .long   hal_fr30_irq_47
+    .long   hal_fr30_irq_46
+    .long   hal_fr30_irq_45
+    .long   hal_fr30_irq_44
+    .long   hal_fr30_irq_43
+    .long   hal_fr30_irq_42
+    .long   hal_fr30_irq_41
+    .long   hal_fr30_irq_40
+    .long   hal_fr30_irq_39
+    .long   hal_fr30_irq_38
+    .long   hal_fr30_irq_37
+    .long   hal_fr30_irq_36
+    .long   hal_fr30_irq_35
+    .long   hal_fr30_irq_34
+    .long   hal_fr30_irq_33
+    .long   hal_fr30_irq_32
+    .long   hal_fr30_irq_31
+    .long   hal_fr30_irq_30
+    .long   hal_fr30_irq_29
+    .long   hal_fr30_irq_28
+    .long   hal_fr30_irq_27
+    .long   hal_fr30_irq_26
+    .long   hal_fr30_irq_25
+    .long   hal_fr30_irq_24
+    .long   hal_fr30_irq_23
+    .long   hal_fr30_irq_22
+    .long   hal_fr30_irq_21
+    .long   hal_fr30_irq_20
+    .long   hal_fr30_irq_19
+    .long   hal_fr30_irq_18
+    .long   hal_fr30_irq_17
+    .long   hal_fr30_irq_16
+    .long   hal_fr30_irq_15
+    .long   hal_fr30_exception_noerr_14
+    .long   hal_fr30_exception_noerr_13
+    .long   hal_fr30_exception_noerr_12
+    .long   hal_fr30_exception_noerr_11
+    .long   hal_fr30_exception_noerr_10
+    .long   hal_fr30_exception_noerr_9
+    .long   hal_fr30_exception_noerr_8
+    .long   hal_fr30_exception_noerr_7
+    .long   hal_fr30_exception_noerr_6
+    .long   hal_fr30_exception_noerr_5
+    .long   hal_fr30_exception_noerr_4
+    .long   hal_fr30_exception_noerr_3
+    .long   hal_fr30_exception_noerr_2
+
+# mode vector (only the first of the four byte is relevant)
+    .byte   0x1
+    .byte   0
+    .byte   0
+    .byte   0
+
+# reset vector
+    .long   hal_fr30_rom_startup_trampoline
+
+#endif /*CYG_HAL_STARTUP_ROM || CYG_HAL_STARTUP_ROMRAM*/
+
+
+##-----------------------------------------------------------------------------
+## end of platform.S
diff --git a/packages/hal/fr30/skmb91302/v2_0/src/plf_misc.c b/packages/hal/fr30/skmb91302/v2_0/src/plf_misc.c
new file mode 100644 (file)
index 0000000..e381263
--- /dev/null
@@ -0,0 +1,109 @@
+//==========================================================================
+//
+//      plf_misc.c
+//
+//      HAL platform miscellaneous functions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    nickg, larsi
+// Contributors: nickg, jlarmour, dmoseley
+// Date:         2007-07-09
+// Purpose:      HAL miscellaneous functions
+// Description:  This file contains miscellaneous functions provided by the
+//               HAL.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // Base types
+#include <cyg/infra/cyg_trac.h>         // tracing macros
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#include <cyg/hal/hal_arch.h>           // architectural definitions
+
+#include <cyg/hal/hal_intr.h>           // Interrupt handling
+
+#include <cyg/hal/hal_cache.h>          // Cache handling
+
+#include <cyg/hal/hal_if.h>
+
+
+/*------------------------------------------------------------------------*/
+
+void hal_platform_init(void)
+{
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT)
+    // Set up eCos/ROM interfaces
+    hal_if_init();
+#endif
+
+#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)      && \
+    (defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon)    || \
+     defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs))
+
+{
+    extern CYG_ADDRESS hal_virtual_vector_table[32];
+    void patch_dbg_syscalls( void * );
+    patch_dbg_syscalls( (void *)(&hal_virtual_vector_table[0]) );
+}
+#endif
+
+}
+
+/*------------------------------------------------------------------------*/
+/* Reset support                                                          */
+
+
+/*------------------------------------------------------------------------*/
+/* Syscall support                                                        */
+#ifdef CYGPKG_CYGMON
+// Cygmon provides syscall handling for this board
+#include <cyg/hal/hal_stub.h>
+int __get_syscall_num (void)
+{
+    return SIGSYS;
+}
+#endif
+
+
+/*------------------------------------------------------------------------*/
+/* End of plf_misc.c                                                      */
diff --git a/packages/hal/fr30/skmb91302/v2_0/src/plf_stub.c b/packages/hal/fr30/skmb91302/v2_0/src/plf_stub.c
new file mode 100644 (file)
index 0000000..9432168
--- /dev/null
@@ -0,0 +1,96 @@
+//=============================================================================
+//
+//      plf_stub.c
+//
+//      Platform specific code for GDB stub support.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   msalter, larsi
+// Contributors:
+// Date:        2007-07-09
+// Purpose:     Platform specific code for GDB stub support.
+//              
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/hal/hal_stub.h>
+
+#include <cyg/hal/hal_io.h>             // HAL IO macros
+#include <cyg/hal/hal_diag.h>           // diag output. FIXME
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_if.h>
+
+//-----------------------------------------------------------------------------
+// Stub init
+
+void hal_plf_stub_init(void)
+{
+//    extern CYG_ADDRESS hal_virtual_vector_table[64];
+    extern void init_thread_syscall( void *);
+    extern void install_async_breakpoint(void *epc);
+    void (*oldvsr)(void);
+    extern void __default_exception_vsr(void);
+
+    // Ensure that the breakpoint VSR points to the default VSR. This will pass
+    // it on to the stubs.
+    HAL_VSR_SET( CYGNUM_HAL_VECTOR_BREAKPOINT, __default_exception_vsr, &oldvsr );
+
+    // Install async breakpoint handler into vector table.
+    hal_virtual_vector_table[35] = (CYG_ADDRESS)install_async_breakpoint;
+
+#if !defined(CYGPKG_KERNEL) && defined(CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT)
+    // Only include this code if we do not have a kernel. Otherwise
+    // the kernel supplies the functionality for the app we are linked
+    // with.
+
+    // Prepare for application installation of thread info function in
+    // vector table.
+    hal_virtual_vector_table[15] = 0;
+    init_thread_syscall( (void *)&hal_virtual_vector_table[15] );
+#endif
+}
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+//-----------------------------------------------------------------------------
+// End of plf_stub.c
diff --git a/packages/hal/fr30/skmb91302/v2_0/src/ser.c b/packages/hal/fr30/skmb91302/v2_0/src/ser.c
new file mode 100644 (file)
index 0000000..f7fea89
--- /dev/null
@@ -0,0 +1,429 @@
+//=============================================================================
+//
+//      ser.c
+//
+//      Simple (polling) driver for the Fujitsu MB91302 on-chip serial port
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   larsi
+// Contributors:
+// Date:        2007-01-10
+// Description: Simple driver for the MB91302 internal serial port
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/system.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_if.h>             // interface API
+#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h>           // Helper functions
+#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
+
+// We have no control over baud rate
+// #if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==57600
+// #define CYG_DEV_SERIAL_BAUD_DIVISOR    BAUD_57600
+// #endif
+
+// #ifndef CYG_DEV_SERIAL_BAUD_DIVISOR
+// #error Missing/incorrect serial baud rate defined - CDL error?
+// #endif
+
+#define CYG_HAL_FR30_MB91301_SMR0     0x63
+#define CYG_HAL_FR30_MB91301_SCR0     0x62
+#define CYG_HAL_FR30_MB91301_SIDR0    0x61
+#define CYG_HAL_FR30_MB91301_SODR0    0x61
+#define CYG_HAL_FR30_MB91301_SSR0     0x60
+#define CYG_HAL_FR30_MB91301_UTIM0    0x64
+#define CYG_HAL_FR30_MB91301_UTIMR0   0x64
+#define CYG_HAL_FR30_MB91301_DRCL     0x66
+#define CYG_HAL_FR30_MB91301_UTIMC0   0x67
+
+
+#define CYG_HAL_FR30_MB91301_SER0_BASE  0x60
+#define CYG_HAL_FR30_MB91301_SER1_BASE  0x68
+#define CYG_HAL_FR30_MB91301_SER2_BASE  0x70
+
+#define CYG_HAL_FR30_MB91301_SMR_OFFSET     0x03
+#define CYG_HAL_FR30_MB91301_SCR_OFFSET     0x02
+#define CYG_HAL_FR30_MB91301_SIDR_OFFSET    0x01
+#define CYG_HAL_FR30_MB91301_SODR_OFFSET    0x01
+#define CYG_HAL_FR30_MB91301_SSR_OFFSET     0x00
+#define CYG_HAL_FR30_MB91301_UTIM_OFFSET    0x04
+#define CYG_HAL_FR30_MB91301_UTIMR_OFFSET   0x04
+#define CYG_HAL_FR30_MB91301_DRCL_OFFSET    0x06
+#define CYG_HAL_FR30_MB91301_UTIMC_OFFSET   0x07
+
+#define CYG_HAL_FR30_MB91301_PDRG     0x10
+#define CYG_HAL_FR30_MB91301_DDRG     0x400
+#define CYG_HAL_FR30_MB91301_PFRG     0x410
+#define CYG_HAL_FR30_MB91301_PDRJ     0x13
+#define CYG_HAL_FR30_MB91301_DDRJ     0x403
+#define CYG_HAL_FR30_MB91301_PFRJ     0x413
+
+
+//-----------------------------------------------------------------------------
+typedef struct {
+    cyg_uint8 base;
+    cyg_int32 msec_timeout;
+    int isr_vector;
+} channel_data_t;
+
+static channel_data_t channels[2] = {
+    {  CYG_HAL_FR30_MB91301_SER0_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART0_RX},
+    {  CYG_HAL_FR30_MB91301_SER1_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART1_RX}/*,
+    {  CYG_HAL_FR30_MB91301_SER2_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART2_RX}*/
+};
+
+//-----------------------------------------------------------------------------
+// function for calculating and setting the baudrate
+
+static void cyg_hal_plf_serial_set_baudrate_internal(cyg_uint8 port, int baudrate){
+
+    float n, nn;
+    int t, tt;
+
+    n = (CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ * 1000000 / CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER) / (float) (32 * baudrate) - 1;
+    nn = (CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ * 1000000 / CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER) / (float) (32 * baudrate) - 1.5;
+
+    /* rounding */
+    t = n;
+    tt = nn;
+    if ( (n-t) > (1 - (n-t)) ) t++;
+    if ( (nn-tt) > (1 - (nn-tt)) ) tt++;
+
+    /* check which is better t or tt */
+
+    /* back calculation of baudrate from t and tt */
+    n = (CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ * 1000000 / CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER) / (float) ((2*t+2) * 16);
+    nn = (CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ * 1000000 / CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER) / (float) ((2*tt+3) * 16);
+
+    /* taking difference between wanted baudrate and back calculated br */
+    if ((baudrate - n) < 0)
+        n = n - baudrate;
+    else
+        n = baudrate - n;
+
+    if ((baudrate - nn) < 0)
+        nn = nn - baudrate;
+    else
+        nn = baudrate - nn;
+
+    /* and finally take the best */
+    if (n < nn){
+        /* UCC1 = 0 */
+        HAL_WRITE_UINT16(port + CYG_HAL_FR30_MB91301_UTIMR_OFFSET, t);
+        HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_UTIMC_OFFSET, 0x02);
+    } else {
+        /* UCC1 = 1 */
+        HAL_WRITE_UINT16(port + CYG_HAL_FR30_MB91301_UTIMR_OFFSET, tt);
+        HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_UTIMC_OFFSET, 0x82);
+    }
+}
+
+//-----------------------------------------------------------------------------
+// The minimal init, get and put functions. All by polling.
+
+void
+cyg_hal_plf_serial_init_channel(void* __ch_data)
+{
+    cyg_uint8 port;
+    cyg_uint8 value;
+
+    port = ((channel_data_t*)__ch_data)->base;
+
+    // set the port direction and function registers to serial
+    switch (port){
+        case CYG_HAL_FR30_MB91301_SER0_BASE:
+            HAL_READ_UINT8(CYG_HAL_FR30_MB91301_DDRJ, value);
+            value |= 0x6;
+            value &= ~0x1;
+            HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_DDRJ, value);
+            HAL_READ_UINT8(CYG_HAL_FR30_MB91301_PFRJ, value);
+            HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PFRJ, value | 0x7);
+            if (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT == 0){
+                cyg_hal_plf_serial_set_baudrate_internal(port, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD);
+            } else {
+                cyg_hal_plf_serial_set_baudrate_internal(port, CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD);
+            }
+            break;
+
+        case CYG_HAL_FR30_MB91301_SER1_BASE:
+            HAL_READ_UINT8(CYG_HAL_FR30_MB91301_DDRJ, value);
+            value |= 0x30;
+            value &= ~0x8;
+            HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_DDRJ, value);
+            HAL_READ_UINT8(CYG_HAL_FR30_MB91301_PFRJ, value);
+            HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PFRJ, value | 0x38);
+            if (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT == 1){
+                cyg_hal_plf_serial_set_baudrate_internal(port, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD);
+            } else {
+                cyg_hal_plf_serial_set_baudrate_internal(port, CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD);
+            }
+            break;
+/*
+        case CYG_HAL_FR30_MB91301_SER2_BASE:
+            HAL_READ_UINT8(CYG_HAL_FR30_MB91301_DDRG, value);
+            HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_DDRG, value | 0x40);
+            HAL_READ_UINT8(CYG_HAL_FR30_MB91301_PFRG, value);
+            HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PFRG, value | 0x60);
+            break;
+*/
+    }
+
+    // set up U-Timer
+/*    HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_UTIMC_OFFSET, 0x02);
+    // 115200 bps
+    HAL_WRITE_UINT16(port + CYG_HAL_FR30_MB91301_UTIMR_OFFSET, 0x7);
+
+    cyg_hal_plf_serial_set_baudrate_internal(port, baudrate);
+*/
+    // setup UART
+    HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_SCR_OFFSET, 0x13);
+    HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_SMR_OFFSET, 0x30);
+}
+
+void
+cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 __ch)
+{
+    cyg_uint8 ssr;
+    cyg_uint8 port;
+
+    port = ((channel_data_t*)__ch_data)->base;
+    // wait for tx rdy
+    do
+    {
+        HAL_READ_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, ssr);
+    } while (!(ssr & BIT3));
+    // Now, write it
+    HAL_WRITE_UINT8( port + CYG_HAL_FR30_MB91301_SODR_OFFSET, __ch );
+}
+
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    cyg_uint8 ssr;
+    cyg_uint8 port;
+
+    port = ((channel_data_t*)__ch_data)->base;
+    HAL_READ_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, ssr);
+    if (!(ssr & BIT4))
+        return false;
+
+    HAL_READ_UINT8(port + CYG_HAL_FR30_MB91301_SIDR_OFFSET, *ch);
+//     hal_diag_led(port);
+    return true;
+}
+
+cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+
+    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+    return ch;
+}
+
+static void
+cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len)
+{
+    while(__len-- > 0)
+        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+}
+
+static void
+cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+}
+
+
+cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    int delay_count;
+    channel_data_t* chan;
+    cyg_bool res;
+
+    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
+    // Go ahead and assume it is channels[0].
+    if (__ch_data == 0)
+      __ch_data = (void*)&channels[0];
+
+    chan = (channel_data_t*)__ch_data;
+
+    delay_count = chan->msec_timeout; // delay in 1000 us steps
+    for(;;) {
+        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+        CYGACC_CALL_IF_DELAY_US(1000);
+    }
+    return res;
+}
+
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    channel_data_t* chan;
+    int ret = 0;
+    cyg_uint8 port;
+    cyg_uint8 value;
+
+    // Some of the diagnostic print code calls through here with no idea what the ch_data is.
+    // Go ahead and assume it is channels[0].
+    if (__ch_data == 0)
+      __ch_data = (void*)&channels[0];
+
+    chan = (channel_data_t*)__ch_data;
+
+    switch (__func) {
+    case __COMMCTL_IRQ_ENABLE:
+        irq_state = 1;
+        port = ((channel_data_t*)__ch_data)->base;
+        HAL_READ_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, value);
+        HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, value | BIT1);
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+        port = ((channel_data_t*)__ch_data)->base;
+        HAL_READ_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, value);
+        HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, value & ~BIT1);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = chan->isr_vector;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+    {
+        va_list ap;
+
+        va_start(ap, __func);
+
+        ret = chan->msec_timeout;
+        chan->msec_timeout = va_arg(ap, cyg_uint32);
+
+        va_end(ap);
+    }
+    break;
+    case __COMMCTL_SETBAUD:
+    {
+        cyg_uint32 baud_rate;
+        cyg_uint16 n, nn;
+        va_list ap;
+
+        va_start(ap, __func);
+        baud_rate = va_arg(ap, cyg_uint32);
+        va_end(ap);
+        port = ((channel_data_t*)__ch_data)->base;
+        cyg_hal_plf_serial_set_baudrate_internal(port, baud_rate);
+    }
+    break;
+
+    case __COMMCTL_GETBAUD:
+        break;
+    default:
+        break;
+    }
+    return ret;
+}
+
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
+                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    *__ctrlc = 0;
+    return 0;
+}
+
+static void
+cyg_hal_plf_serial_init(void)
+{
+    hal_virtual_comm_table_t* comm;
+    int i, cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+#define NUM_CHANNELS CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS
+    for (i = 0; i < NUM_CHANNELS; i++) {
+
+       // Disable interrupts.
+       HAL_INTERRUPT_MASK(channels[i].isr_vector);
+
+       // Init channels
+       cyg_hal_plf_serial_init_channel((void*)&channels[i]);
+       // Setup procs in the vector table
+
+       // Set COMM callbacks for channel
+       CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
+       comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+       CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[i]);
+       CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+       CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+       CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+       CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+       CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+       CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+       CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+    }
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+
+    initialized = 1;
+    cyg_hal_plf_serial_init();
+
+}
+
+//-----------------------------------------------------------------------------
+// end of ser.c
+
diff --git a/packages/hal/synth/arch/v2_0/tests/ftok.c b/packages/hal/synth/arch/v2_0/tests/ftok.c
new file mode 100644 (file)
index 0000000..91098eb
--- /dev/null
@@ -0,0 +1,84 @@
+/*=================================================================
+//
+//        cache.c
+//
+//        SYNTH ftok test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Andrew Lunn
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     asl
+// Contributors:  asl
+// Date:          05/11/2005
+//####DESCRIPTIONEND####
+*/
+
+#ifndef HOST
+#include <cyg/hal/hal_io.h>
+#include <cyg/infra/diag.h>
+
+#define printf diag_printf
+#define ftok cyg_hal_sys_ftok
+
+#else
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#endif
+
+int main(void)
+{
+  printf("ftok(\"/etc/passwd\",0x12)) = 0x%8x\n", 
+         ftok("/etc/passwd",0x12));
+
+  printf("ftok(\"/etc/passwd\",0x72)) = 0x%8x\n", 
+         ftok("/etc/passwd",0x72));
+
+  printf("ftok(\"/boot/vmlinuz\",0x72)) = 0x%8x\n", 
+         ftok("/boot/vmlinuz",0x72));
+
+  printf("ftok(\"/boot/vmlinuz\",0x12)) = 0x%8x\n", 
+         ftok("/boot/vmlinuz",0x12));
+
+  return 0;
+}
+
+#ifndef HOST
+
+externC void
+cyg_start( void )
+{
+    main();
+}
+#endif
diff --git a/packages/io/can/v2_0/doc/can.sgml b/packages/io/can/v2_0/doc/can.sgml
new file mode 100644 (file)
index 0000000..5914aae
--- /dev/null
@@ -0,0 +1,1980 @@
+<!-- {{{ Banner                         -->
+
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!--     can.sgml                                                    -->
+<!--                                                                 -->
+<!--     Generic CAN documentation.                                  -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN####                                          -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004 eCosCentric Limited                          -->
+<!-- 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                   -->
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!-- ####COPYRIGHTEND####                                            -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN####                                       -->
+<!--                                                                 -->
+<!-- Author(s):   Uwe Kindler                                        -->
+<!-- Date:        2006/12/04                                         -->
+<!--                                                                 -->
+<!-- ####DESCRIPTIONEND####                                          -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<PART id="io-can"><title>CAN Support</title>
+
+<CHAPTER id="io-can-overview">
+<TITLE>Overview</TITLE>
+
+<SECTION id="io-can-overview-descr">
+<TITLE>Description</TITLE>
+
+<PARA>
+The Controller Area Network, CAN, is a multicast shared, differential 
+serial bus standard especially suited for networking "intelligent" 
+devices as well as sensors and actuators within a system or sub-system. 
+The protocol was originally developed in the 1980s by Robert Bosch GmbH 
+aiming at automotive applications. Nowadays CAN has gained widespread use 
+and is used in industrial automation as well as in automotive, mobile 
+machines and in many embedded control applications.
+</PARA>
+    
+<PARA>
+The CAN protocol is defined by the ISO 11898-1 standard. The physical layer 
+uses differential transmission on a twisted pair wire.  CAN uses a 
+non-destructive bit-wise arbitration to control access to the bus.
+</PARA>
+    
+<PARA>
+There is no explicit address in the messages because in CAN networks there 
+is no addressing of subscribers or stations, but instead, each message carries 
+a prioritized identifier. A transmitter sends a message to all CAN nodes 
+(broadcasting). The identifier may serve as an identification of the contents 
+of the message and also determines the priority that the message enjoys in 
+competition for bus access. A node decides on the basis of this identifier 
+received whether it should process the message or not.
+</PARA>
+    
+<PARA>
+The CAN messages are small (at most eight data bytes) and are protected 
+by a checksum. Each CAN message consists of  an 11 bit message ID, up to 8 
+bytes of data and, a CRC checksum and a number of  control bits. These 
+short messages ensure a robust transfer of data in electromagnetically 
+noisy environments. An extended version of the CAN frame supports 29 bit 
+message identifiers.
+</PARA>
+    
+<PARA>
+Basically there are two different operational modes for CAN receivers - 
+FullCAN and BasicCAN.  The difference between these two modes is the 
+Object Storage function. The BasicCAN architecture is quite similar to a 
+simple UART. A BasicCAN device has typically one transmit buffer and two 
+receive buffers. The CAN chip handles only the transmitting and receiving 
+of the data (and the error handling) and so most of the manipulation of the 
+data has to be done by the CPU. The CPU has to request the transmitting or 
+acknowledge the receiving of the data through the interrupt flags. This will 
+burden the CPU and take up much of the CPU time. 
+</PARA>
+
+<PARA>
+The FullCAN architecture is more suitable for high-speed performance. It 
+has its own storage area on chip and works with a number of message buffers 
+or message boxes. The CAN controller has its own Acceptance Filtering Mask 
+on chip. It can thus determine which frames are to be received by examining 
+the identifiers. The CPU in this case will only receive the valid (wanted) 
+frames and hence improve the performance of the CPU.
+</PARA>
+    
+<PARA>
+You can find more information at the 
+<ulink url="http://www.can-cia.org/">CAN in Automation</ulink> website.
+</PARA>
+
+</SECTION> <!-- "io-can-description" -->
+
+<SECTION id="io-can-ecos-support">
+<TITLE>eCos Support for CAN</TITLE>
+
+<PARA>
+The eCos CAN subsystem supports the BasicCAN and FullCAN mode. The architecture 
+and the interface of the eCos CAN driver is quite similar to the eCos serial 
+driver and supports the same interface.
+</PARA>
+
+<PARA>
+The eCos CAN support for any given platform is spread over a number of different 
+packages: 
+</PARA>
+
+<itemizedlist>
+  <listitem>
+    <para>
+
+This package, <varname>CYGPKG_IO_CAN</varname>, exports a generic
+device independent CAN I/O API for accessing devices attached to a CAN
+network. This API handles issues such as locking between threads. The
+package does not contain any hardware-specific code. Instead it will
+call into a CAN device driver to handle the hardware device
+access. This package also defines the inderface that such hardware
+drivers should provide.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+Each CAN device will have its own device driver, which is implemented 
+as a separate package, for example 
+<varname>CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN</varname>. For devices that may 
+be attached to a variety of different boards the device driver will be 
+generic and a second platform specific package will be used to customize 
+it to each platform. For devices that are associated with a specific 
+chipset, only a single package may be present.
+    </para>
+  </listitem>
+</itemizedlist>
+
+<PARA>
+Typically all appropriate packages will be loaded automatically when 
+you configure eCos for a given platform. If the application does not use 
+any of the CAN I/O facilities, directly or indirectly, then linker garbage 
+collection should eliminate all unnecessary code and data. All necessary 
+initialization should happen automatically. However the exact details may 
+depend on the platform, so the platform HAL documentation should be 
+checked for further details.
+</PARA>
+    
+<PARA>
+There is an important exception to this: if the CAN devices are attached 
+to an expansion connector, such as PCI, then the platform HAL will not 
+know about these devices. Instead the necessary packages will need to be 
+added explicitly during configuration.
+</PARA>
+</SECTION>
+</CHAPTER>
+
+<CHAPTER id="io-can-api">
+<TITLE>User API</TITLE>
+
+<PARA>
+The CAN driver uses the standard eCos I/O API functions. All functions 
+except <function>cyg_io_lookup()</function> require an I/O "handle".
+</PARA>
+
+<PARA>
+All functions return a value of the type <type>Cyg_ErrNo</type>. 
+If an error condition is detected, this value will be negative and the 
+absolute value indicates the actual error, as specified in 
+<filename>cyg/error/codes.h</filename>. The only other legal return values 
+will be <varname>ENOERR</varname>, <varname>-EINTR</varname> and 
+<varname>-EAGAIN</varname>. All other function arguments are pointers 
+(references). This allows the drivers to pass information efficiently, 
+both into and out of the driver. The most striking example of this is the 
+<parameter>len</parameter> value passed to the read and write functions. 
+This parameter contains the desired length of data on input to the 
+function and the actual transferred length on return.
+</PARA>
+    
+<PROGRAMLISTING>
+// Lookup a CAN device and return its handle 
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_lookup</function>( 
+    const char <parameter>*name</parameter>,
+    cyg_io_handle_t <parameter>*handle</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function maps a CAN device name onto an appropriate handle. If the
+named device is not in the system, then the error
+<varname>-ENOENT</varname> is returned. If the device is found, then
+the handle for the device is returned by way of the handle pointer
+<parameter>*handle</parameter>.
+</PARA>
+
+<PROGRAMLISTING>
+// Send a CAN message
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_write</function>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    const void <parameter>*buf</parameter>,
+    cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function sends one single CAN message (not a buffer of CAN messages) 
+to a device. The size of data to send is contained in 
+<parameter>*len</parameter> and the actual size sent will be returned in 
+the same place.
+</PARA>
+
+<PROGRAMLISTING>
+// Read one CAN event from device
+Cyg_ErrNo <!-- <index></index> --><function>cyg_io_read</function>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    void <parameter>*buf</parameter>,
+    cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function receives one single CAN event from a device. The desired size 
+of data to receive is contained in <parameter>*len</parameter> and the 
+actual size obtained will be returned in the same place. 
+</PARA>
+
+<PROGRAMLISTING>
+// Read configuration of a CAN device
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_get_config</FUNCTION>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    cyg_uint32 <parameter>key</parameter>,
+    void *<parameter>buf</parameter>,
+    cyg_uint32 *<parameter>len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to obtain run-time configuration about a
+device. The type of information retrieved is specified by the
+<parameter>key</parameter>. The data will be returned in the given
+buffer. The value of <parameter>*len</parameter> should contain the
+amount of data requested, which must be at least as large as the size
+appropriate to the selected key. The actual size of data retrieved is
+placed in <parameter>*len</parameter>. The appropriate key values 
+are all listed in the file <filename>&lt;cyg/io/config_keys.h&gt;</filename>.
+</PARA>
+
+<PROGRAMLISTING>
+// Change configuration of a CAN device
+Cyg_ErrNo <!-- <index></index> --><function>cyg_io_set_config</function>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    cyg_uint32 <parameter>key</parameter>,
+    const void <parameter>*buf</parameter>,
+    cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to manipulate or change the run-time
+configuration of a device. The type of information is specified by the
+<parameter>key</parameter>. The data will be obtained from the given
+buffer. The value of <parameter>*len</parameter> should contain the
+amount of data provided, which must match the size appropriate to the
+selected key.  The appropriate key values are all listed in the file
+<filename>&lt;cyg/io/config_keys.h&gt;</filename>.
+</PARA> 
+</CHAPTER>   
+
+<CHAPTER id="io-can-driver-details">
+<TITLE>CAN driver details</TITLE>
+
+<PARA>
+Allow applications and other packages to access CAN devices.
+</PARA>
+
+<SECTION id="io-can-driver-description">
+<TITLE>Description</TITLE>
+
+<PARA>
+A raw CAN driver is is provided as a standard part of the eCos system.
+</PARA>
+
+<PARA>
+Use the include file <filename>&lt;cyg/io/canio.h&gt;</filename> for this driver.
+</PARA>
+    
+<PARA>
+The CAN driver is capable of sending single CAN messages to a device and 
+receiving single CAN events from a CAN device. Controls are provided to 
+configure the actual hardware, but there is no manipulation of the data by 
+this driver. 
+</PARA>
+    
+<PARA>
+There may be many instances of this driver in a given system, one for each 
+CAN channel. Each channel corresponds to a physical device and there will 
+typically be a device module created for this purpose. The device modules 
+themselves are configurable, allowing specification of the actual hardware 
+details.     
+</PARA>
+</SECTION>
+
+<SECTION id="io-can-api-details">
+<TITLE>API Details</TITLE>
+
+<SECTION>
+<TITLE>cyg_io_write</TITLE>
+  
+<PROGRAMLISTING>
+cyg_io_write(handle, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+To transmit a message an application must fill a <type>cyg_can_message</type>
+buffer and call <function>cyg_io_write()</function>.
+This function sends one single CAN message (not a buffer of CAN messages) 
+to a device. The size of data to send is contained in <parameter>*len</parameter> 
+and the actual size sent will be returned in the same place. A pointer to a
+<type>cyg_can_message</type> is contained in <parameter>*buf</parameter>. 
+The driver maintains a buffer to hold the data. The size of the intermediate
+buffer is configurable within the interface module. The data is not modified 
+at all while it is being buffered. On return, <parameter>*len</parameter> 
+contains the amount of characters actually consumed - that means 
+<parameter>*len</parameter> always contains 
+<function>sizeof(cyg_can_message)</function>.
+</PARA>
+    
+<PARA>
+It is possible to configure the write call to be blocking (default) or 
+non-blocking. Non-blocking mode requires both the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> to be enabled, and 
+the specific device to be set to non-blocking mode for writes 
+(see <function>cyg_io_set_config()</function>). In blocking mode, the 
+call will not return until there is space in the buffer and the content 
+of the CAN message has been consumed. In non-blocking mode, if there is 
+no space in buffer for the CAN message, <varname>-EAGAIN</varname> is 
+returned and the caller must try again.
+</PARA>
+    
+<PARA>
+It is possible to configure the write call to be non-blocking with timeout. 
+None-blocking mode with timeout requires the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> and 
+<varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> to be enabled, requires 
+the eCos kernel package to be included and the specific device to be set 
+to non-blocking mode for writes (see <function>cyg_io_set_config()
+</function>). 
+In non-blocking mode with timeouts, if there is no space in buffer for the 
+CAN message, the driver waits a certain amount of time (the timeout time) 
+for space in the buffer. If there is still no space in buffer after 
+expiration of the timeout time, <varname>-EINTR</varname> is returned and 
+the caller must try again.
+</PARA>
+    
+<PARA>
+If a message was sucessfully sent, the function returns <varname>ENOERR</varname>.
+</PARA>
+</SECTION>
+    
+<SECTION>  
+<TITLE>CAN Messages</TITLE>
+    
+<PARA>
+The CAN driver uses <structname>cyg_can_message</structname> structures to 
+pass messages between the application and the CAN driver. The type 
+cyg_can_message provides a device independent type of CAN message. 
+Before calling the write function this message should be setup properly.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct can_message
+{
+    cyg_uint32         id;
+    cyg_uint8          data[8];
+    cyg_can_id_type    ext;
+    cyg_can_frame_type rtr;
+    cyg_uint8          dlc;
+} cyg_can_message;
+</PROGRAMLISTING>
+
+<PARA>
+The structure contains the following fields:
+</PARA>
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>id</varname></term>
+           <listitem><para>
+Message ID. This is the ID to be transmitted with the message, or the 
+ID received. If the <structfield>ext</structfield> field is set, then 
+this will contain a 29 bit ID, otherwise it will contain an 11 bit ID.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>data</varname></term>
+           <listitem><para>
+Message data. Only the first <structfield>dlc</structfield> bytes of 
+data are valid. If the <structfield>rtr</structfield> field is set, 
+then the contents of this field are ignored.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_can_id_type</type> <varname>ext</varname></term>
+           <listitem><para>
+Extended ID. If this field is <varname>CYGNUM_CAN_ID_EXT</varname> then the 
+<structname>id</structname> field contains a 29 bit extended ID. If it 
+contains <varname>CYGNUM_CAN_ID_STD</varname> then the ID is 11 bits.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_can_frame_type</type> <varname>rtr</varname></term>
+           <listitem><para>
+Remote Transmission Request. If this field contains 
+<varname>CYGNUM_CAN_FRAME_RTR</varname> then the RTR bit on the message 
+will be set and the <structfield>data</structfield> field will be ignored. 
+If the field contains <varname>CYGNUM_CAN_FRAME_DATA</varname> then a 
+normal data frame will be send.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>dlc</varname></term>
+           <listitem><para>
+The length of the data carried in the message. This can range from 
+zero to 8. In a message with the <structfield>rtr</structfield> field set, 
+this indicates the size of data being requested.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for sending one single CAN message:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_message tx_msg;
+cyg_uint32      len;
+Cyg_ErrNo       ret;
+
+tx_msg.id  = 0x100;
+tx_msg.ext = CYGNUM_CAN_ID_EXT;
+tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
+tx_msg.dlc = 1;
+tx_msg.data[0] = 0xF1;
+
+len = sizeof(tx_msg);
+ret = cyg_io_write(hDrvCAN, &amp;tx_msg, &amp;len);
+</PROGRAMLISTING>       
+</SECTION><!-- can-cyg_can_message -->
+
+<SECTION>
+<TITLE>cyg_io_read</TITLE> 
+<PROGRAMLISTING>
+cyg_io_read(handle, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+To receive a message the application calls <function>cyg_can_recv()</function>.
+This function receives one single event from a device. The desired size 
+of data to receive is contained in <parameter>*len</parameter> and the
+actual size obtained will be returned in the same place. A pointer to 
+a <type>cyg_can_event</type> is contained in <parameter>*buf</parameter>. 
+No manipulation of the data is performed before being transferred. 
+Again, this buffering is completely configurable. On return, 
+<parameter>*len</parameter> contains <function>sizeof(cyg_can_event)</function>.
+</PARA>
+   
+<PARA>    
+It is possible to configure the read call to be blocking (default) or 
+non-blocking. Non-blocking mode requires both the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> to be enabled, 
+and the specific device to be set to non-blocking mode for reads 
+(see <function>cyg_io_set_config()</function>). In blocking mode, 
+the call will not return until one single CAN event has been read. 
+In non-blocking mode, if there is no CAN event in buffer, the call 
+returns immediately with <varname>-EAGAIN</varname> and the caller must 
+try again.
+</PARA>
+    
+<PARA>
+It is possible to configure the write call to be non-blocking with timeout. 
+None-blocking mode with timeout requires the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> and 
+<varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> to be enabled, 
+requires the eCos kernel package to be included and the specific device 
+to be set to non-blocking mode for reads (see 
+<function>cyg_io_set_config()</function>). In non-blocking mode with timeouts, 
+if there is no CAN event in receive buffer, the driver waits a certain amount 
+of time (the timeout time) for a CAN event to arrive. If there is still no 
+CAN event in buffer after expiration of the timeout time, <varname>-EINTR</varname> 
+is returned and the caller must try again.
+</PARA>
+    
+<PARA>
+If a event was sucessfully received, the function returns <varname>ENOERR</varname>.    
+</PARA>
+</SECTION><!-- cyg_io_read -->
+
+
+<SECTION>  
+<TITLE>CAN Events</TITLE>
+
+<PARA>
+The CAN driver uses <structname>cyg_can_event</structname> structures to
+pass events from hardware device driver to the generic CAN driver.
+A <structname>cyg_can_event</structname> provides a generic device 
+independent type for handling CAN events that may occur.
+</PARA> 
+
+<PROGRAMLISTING>
+typedef struct cyg_can_event_st
+{
+    cyg_uint32      timestamp;
+    cyg_can_message msg;
+    cyg_uint16      flags;
+} cyg_can_event;
+</PROGRAMLISTING>
+
+<PARA>
+The structure contains the following fields:
+</PARA>
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>timestamp</varname></term>
+           <listitem><para>
+If the hardware CAN device driver supports timestamps then this field may 
+contain a timestamp value for an event that occured.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+CAN message. The msg field contains a CAN message if an RX or TX event
+occured.  If another type of event occured,
+the <structfield>data</structfield> field of
+the <structfield>msg</structfield> may contain additional event
+specific data.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint16</type> <varname>flags</varname></term>
+           <listitem><para>
+Event flags. The <varname>flags</varname> field contains 16 bits that 
+indicate which kind of events occured. 
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+    
+<PARA>
+The following events are supported and after receiving an event the 
+application should check the flag field against these values:
+</PARA>
+    
+<PROGRAMLISTING>
+typedef enum
+{
+  CYGNUM_CAN_EVENT_RX               = 0x0001, // message received
+  CYGNUM_CAN_EVENT_TX               = 0x0002, // message transmitted
+  CYGNUM_CAN_EVENT_WARNING_RX       = 0x0004, // (TEC) reached warning level (>96)
+  CYGNUM_CAN_EVENT_WARNING_TX       = 0x0008, // (REC) reached warning level (>96)
+  CYGNUM_CAN_EVENT_ERR_PASSIVE      = 0x0010, // CAN "error passive" occured
+  CYGNUM_CAN_EVENT_BUS_OFF          = 0x0020, // CAN "bus off" error occured
+  CYGNUM_CAN_EVENT_OVERRUN_RX       = 0x0040, // overrun in RX queue or hardware 
+  CYGNUM_CAN_EVENT_OVERRUN_TX       = 0x0080, // overrun in TX queue occured
+  CYGNUM_CAN_EVENT_CAN_ERR          = 0x0100, // a CAN bit or frame error occured
+  CYGNUM_CAN_EVENT_LEAVING_STANDBY  = 0x0200, // CAN hardware leaves standby
+  CYGNUM_CAN_EVENT_ENTERING_STANDBY = 0x0400, // CAN hardware enters standby
+  CYGNUM_CAN_EVENT_ARBITRATION_LOST = 0x0800, // arbitration lost
+  CYGNUM_CAN_EVENT_FILTER_ERR       = 0x1000, // CAN message filter / acceptance filter error
+  CYGNUM_CAN_EVENT_PHY_FAULT        = 0x2000, // General failure of physical layer 
+  CYGNUM_CAN_EVENT_PHY_H            = 0x4000, // Fault on CAN-H (Low Speed CAN)
+  CYGNUM_CAN_EVENT_PHY_L            = 0x8000, // Fault on CAN-L (Low Speed CAN)
+} cyg_can_event_flags;
+</PROGRAMLISTING>
+
+<PARA>
+Often the flags field will contain only one single set flag. But it is 
+possible that a number of flags is set and so the flag field should always 
+be checked by a receiver. I.e. if the <varname>CYGNUM_CAN_EVENT_RX</varname> 
+is set then also the <varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> 
+may be set if the received message caused an RX overrun.
+</PARA>
+    
+<PARA>
+The internal receive buffers of the CAN device driver are circular buffers. 
+That means that even if the buffers are completely filled new messages 
+will be received. In this case the newest message will always overwrite 
+the oldest message in receive buffer. If this happens the 
+<varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> flag will be set for this 
+new message that caused overwriting of the old one. The 
+<varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> flag will be set also if 
+a overrun occures in hardware message buffers of the CAN device.
+</PARA>
+    
+<PARA>
+Example code for receiving one single CAN event:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_event rx_event;
+cyg_uint32    len;
+Cyg_ErrNo     ret;
+
+len = sizeof(rx_event);
+ret = cyg_io_read(hDrvCAN, &amp;rx_event, &amp;len);
+
+if (ENOERR == ret)
+{
+    if (rx_event.flags &amp; CYGNUM_CAN_EVENT_RX)
+    {
+        // handle RX event
+    }
+    
+    if (rx_event.flags &amp; ~CYGNUM_CAN_EVENT_RX)
+    {
+        // handle other events
+    }
+}
+else if (-EINTR == ret)
+{
+    // handle timeout
+}
+</PROGRAMLISTING>       
+</SECTION><!-- can-cyg_can_event -->
+
+  
+<SECTION>
+<TITLE>cyg_io_get_config</TITLE> 
+  
+<PROGRAMLISTING>
+cyg_io_get_config(handle, key, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to obtain run-time configuration about a device. 
+The type of information retrieved is specified by the <parameter>key</parameter>. 
+The data will be returned in the given buffer. The value of 
+<parameter>*len</parameter> should contain the amount of data requested, 
+which must be at least as large as the size appropriate to the selected 
+<parameter>key</parameter>. The actual size of data retrieved is placed 
+in <parameter>*len</parameter>. The appropriate key values are all listed 
+in the file <filename>&lt;cyg/io/config_keys.h&gt;</filename>.    
+</PARA>   
+    
+<PARA>
+The following config keys are currently supported:
+</PARA>  
+    
+<PROGRAMLISTING>
+CYG_IO_GET_CONFIG_READ_BLOCKING
+CYG_IO_GET_CONFIG_WRITE_BLOCKING
+CYG_IO_GET_CONFIG_CAN_INFO
+CYG_IO_GET_CONFIG_CAN_BUFFER_INFO
+CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO
+CYG_IO_GET_CONFIG_CAN_TIMEOUT
+CYG_IO_GET_CONFIG_CAN_HDI
+CYG_IO_GET_CONFIG_CAN_STATE
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-get-config -->
+  
+<SECTION>
+<TITLE>cyg_io_set_config</TITLE> 
+  
+<PROGRAMLISTING>
+cyg_io_set_config(handle, key, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to manipulate or change the run-time configuration 
+of a device. The type of information is specified by the <parameter>key</parameter>. 
+The data will be obtained from the given buffer. The value of 
+<parameter>*len</parameter> should contain the amount of data provided, 
+which must match the size appropriate to the selected <parameter>key</parameter>. 
+The appropriate key values are all listed in the file 
+<filename>&lt;cyg/io/config_keys.h&gt;</filename>.  
+</PARA>   
+    
+<PARA>
+The following config keys are currently supported:
+</PARA>  
+    
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_READ_BLOCKING
+CYG_IO_SET_CONFIG_WRITE_BLOCKING
+CYG_IO_SET_CONFIG_CAN_INFO
+CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN
+CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH
+CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH
+CYG_IO_SET_CONFIG_CAN_TIMEOUT
+CYG_IO_SET_CONFIG_CAN_MSGBUF
+CYG_IO_SET_CONFIG_CAN_MODE
+CYG_IO_SET_CONFIG_CAN_ABORT
+CYG_IO_SET_CONFIG_CAN_CALLBACK
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-set-config -->
+</SECTION><!-- io-can-api-details -->
+
+<SECTION id="io-can-runtime-cfg">  
+<TITLE>Runtime Configuration</TITLE>
+  
+<PARA>
+Runtime configuration is achieved by exchanging data structures with the 
+driver via the <function>cyg_io_set_config()</function> and 
+<function>cyg_io_get_config()</function> functions.
+</PARA>
+
+<SECTION>
+<TITLE>Device configuration</TITLE>
+  
+<PROGRAMLISTING>
+typedef struct cyg_can_info_st {
+    cyg_can_baud_rate_t baud;
+} cyg_can_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+Device configuration is achieved by by exchanging 
+<structname>cyg_can_info_t</structname> data structures with the driver 
+via the <function>cyg_io_set_config()</function> and 
+<function>cyg_io_get_config()</function> functions using the config keys 
+<varname>CYG_IO_GET_CONFIG_CAN_INFO</varname> and 
+<varname>CYG_IO_SET_CONFIG_CAN_INFO</varname>. 
+The field <structfield>baud</structfield> contains a baud rate selection. 
+This must be one of the following values:  
+</PARA>
+  
+<PROGRAMLISTING>
+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
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-set-config -->
+  
+<SECTION>
+<TITLE>Timeout configuration</TITLE>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_timeout_info_st
+{
+    cyg_uint32 rx_timeout;
+    cyg_uint32 tx_timeout;
+} cyg_can_timeout_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+Timeout configuration is achieved by by exchanging 
+<structname>cyg_can_timeout_info_t</structname> data structures with the 
+driver via the <function>cyg_io_set_config()</function> and 
+<function>cyg_io_get_config()</function> functions using the config keys 
+<varname>CYG_IO_SET_CONFIG_CAN_TIMEOUT</varname> and 
+<varname>CYG_IO_SET_CONFIG_CAN_TIMEOUT</varname>.   
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rx_timeout</varname></term>
+           <listitem><para>
+Timeout for <function>cyg_io_read</function> calls.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>tx_timeout</varname></term>
+           <listitem><para>
+Timeout for <function>cyg_io_write</function> calls.
+          </para></listitem>
+   </varlistentry>
+</variablelist>   
+
+<PARA>
+Timeout runtime configuration is supported if the configuration options 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> 
+and <varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> are enabled. 
+</PARA>
+</SECTION><!-- can-timeout-config -->
+
+<SECTION>
+<TITLE>Reading buffer configuration</TITLE>
+    
+<PROGRAMLISTING>    
+typedef struct cyg_can_buf_info_st
+{
+    cyg_int32 rx_bufsize;
+    cyg_int32 rx_count;
+    cyg_int32 tx_bufsize;
+    cyg_int32 tx_count;
+} cyg_can_buf_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_BUFFER_INFO</varname> - This function 
+retrieves the current state of the software buffers in the CAN drivers. 
+For the transmit buffer it returns the the total number of 
+<type>cyg_can_message</type> objects in buffer and the current number of 
+<type>cyg_can_message</type> objects occupied in the buffer. 
+For the receive buffer it returns the total number of 
+<type>cyg_can_event</type> objects in receive buffer and the current 
+number of <type>cyg_can_event</type> objects occupied in the buffer. 
+It does not take into account any buffering such as FIFOs or holding 
+registers that the CAN hardware device itself may have.
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rx_bufsize</varname></term>
+           <listitem><para>
+Total number of <type>cyg_can_event</type> buffers in receive queue.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rx_count</varname></term>
+           <listitem><para>
+Current number of <type>cyg_can_event</type> buffers occupied in receive queue.
+          </para></listitem>
+   </varlistentry>
+      <varlistentry>
+       <term><type>cyg_uint32</type> <varname>tx_bufsize</varname></term>
+           <listitem><para>
+Total number of <type>cyg_can_message</type> buffers in transmit queue.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rtx_count</varname></term>
+           <listitem><para>
+Current number of <type>cyg_can_message</type> buffers occupied in transmit queue.
+          </para></listitem>
+   </varlistentry>
+</variablelist>   
+</SECTION>  <!-- can-read-buffer-config -->
+  
+  
+<SECTION>
+<TITLE>Reading hardware description information</TITLE>
+    
+<PROGRAMLISTING>    
+typedef struct cyg_can_hdi_st
+{
+    cyg_uint8 support_flags;
+    cyg_uint8 controller_type;
+} cyg_can_hdi;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_HDI</varname> - This function retrieves 
+information about the used hardware. The Hardware Description Interface 
+provides a method to gather information about the CAN hardware and the 
+functionality of the driver. For this purpose the structure 
+<structname>cyg_can_hdi</structname> is defined.  
+</PARA>
+     
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>support_flags</varname></term>
+           <listitem><para>
+Contains information about the capabilities of the used CAN hardware.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>controller_type</varname></term>
+           <listitem><para>
+A number that identifies the CAN controller type.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+The following flags are available in the field <structfield>support_flags</structfield>:  
+</PARA>
+     
+<PROGRAMLISTING>    
+|   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
++-------+-------+-------+-------+-------+-------+-------+-------+
+|  res  |  res  |  res  |timest.|SW-Filt|FullCAN|   Frametype   |
+</PROGRAMLISTING>
+
+<variablelist>
+  <varlistentry>
+    <term><parameter>Frametype</parameter></term>
+    <listitem><para>
+Bit 0 and Bit 1 of the structure describe the possibilities of the CAN
+controller. The following values are defined:
+    <PROGRAMLISTING>    
+CYGNUM_CAN_HDI_FRAMETYPE_STD          // receives only standard frame
+CYGNUM_CAN_HDI_FRAMETYPE_EXT_PASSIVE  // can receive but not send extended frames
+CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE   // can send and receive extended frames
+    </PROGRAMLISTING>
+    </para></listitem>
+  </varlistentry>
+    <varlistentry>
+    <term><parameter>FullCAN</parameter></term>
+    <listitem><para>
+If the Bit 2 - <varname>CYGNUM_CAN_HDI_FULLCAN </varname> - is set to one, 
+the CAN controller supports more than one message buffer.
+    </para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>SW-Filter</parameter></term>
+    <listitem><para>
+If Bit 3 - <varname>CYGNUM_CAN_HDI_FILT_SW</varname> - is set to one then 
+the CAN driver supports some kind of software message filtering.
+    </para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>Timestamp</parameter></term>
+    <listitem><para>
+If Bit 4 - <varname>CYGNUM_CAN_HDI_TIMESTAMP</varname> - is set to one then 
+the CAN hardware supports timestamps for CAN messages
+    </para></listitem>
+  </varlistentry>
+</variablelist>
+</SECTION>  <!-- can-read-buffer-config -->
+   
+<SECTION>
+<TITLE>Reading hardware message buffer configuration</TITLE>
+<PROGRAMLISTING>    
+typedef struct cyg_can_msgbox_info_st
+{
+    cyg_uint8 count; // number of message buffers available for this device
+    cyg_uint8 free;  // number of free message buffers
+} cyg_can_msgbuf_info;
+</PROGRAMLISTING>
+   
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO</varname> - If the CAN hardware supports 
+more than one message buffer for reception of CAN messages (flag 
+<varname>CYGNUM_CAN_HDI_FULLCAN</varname> is set while reading hardware description 
+interface with <varname>CYG_IO_GET_CONFIG_CAN_HDI</varname>) then this function 
+reads the number of message buffers the CAN hardware supports and the number of 
+free message buffers.   
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>count</varname></term>
+           <listitem><para>
+Counts the number of message buffers supported by the device.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>free</varname></term>
+           <listitem><para>
+Contains the number of free message buffers. The free message buffers are 
+available for setting up remote buffers (<varname>CYG_IO_SET_CONFIG_CAN_REMOTE_BUF</varname>) 
+and message filters (<varname>CYG_IO_SET_CONFIG_CAN_FILTER_MSG</varname>).
+          </para></listitem>
+   </varlistentry>
+</variablelist>   
+</SECTION> <!-- can-read-buffer-config -->
+   
+<SECTION>
+<TITLE>Reading state of CAN hardware</TITLE>
+
+<PROGRAMLISTING>    
+typedef enum
+{
+  CYGNUM_CAN_STATE_ACTIVE,      // CAN controller active, no errors
+  CYGNUM_CAN_STATE_STOPPED,     // CAN controller in stopped mode
+  CYGNUM_CAN_STATE_STANDBY,     // CAN controller in Sleep mode
+  CYGNUM_CAN_STATE_BUS_WARN,    // CAN controller active, warning level is reached
+  CYGNUM_CAN_STATE_ERR_PASSIVE, // CAN controller went into error passive mode
+  CYGNUM_CAN_STATE_BUS_OFF,     // CAN controller went into bus off mode
+  CYGNUM_CAN_STATE_PHY_FAULT,   // General failure of physical layer 
+  CYGNUM_CAN_STATE_PHY_H,       // Fault on CAN-H detected (Low Speed CAN)
+  CYGNUM_CAN_STATE_PHY_L,       // Fault on CAN-L detected (Low Speed CAN)
+} cyg_can_state;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_STATE</varname> - This function retrieves the 
+present state of the CAN controller. Possible values are defined in the 
+<type>cyg_can_state</type> enumeration.
+</PARA>   
+</SECTION> <!-- can-read-hw-state -->
+
+
+<SECTION>
+<TITLE>Changing mode of CAN hardware</TITLE>
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_MODE</varname> - This function changes 
+the operating mode of the CAN controller. The identifiers for the different 
+operating modes are defined in the <type>cyg_can_mode</type> enumeration.
+</PARA>
+
+<PROGRAMLISTING> 
+typedef enum
+{
+  CYGNUM_CAN_MODE_STOP,   // set controller into stop mode
+  CYGNUM_CAN_MODE_START,  // set controller into operational mode
+  CYGNUM_CAN_MODE_STANDBY // set controller into standby / sleep mode
+} cyg_can_mode;
+</PROGRAMLISTING>
+<variablelist>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MODE_STOP</type></term>
+           <listitem><para>
+Set controller into stop mode
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MODE_START</type></term>
+           <listitem><para>
+Set controller into operational mode
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MODE_STANDBY</type></term>
+           <listitem><para>
+Set controller into standby / sleep mode.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Before the hardware configuration of the device is changed, that means
+if baud rate is changed or the message buffer and filter configuration
+is changed, the CAN hardware should be set into stop mode and if
+configuration is finished, then device should be set back into
+operational mode.  Before the device is set into standby mode, the
+output buffers should be flushed or drained because transmission of a
+CAN message may wake up the CAN hardware. If a received message wakes
+up the CAN hardware from standby mode then
+a <varname>CYGNUM_CAN_EVENT_LEAVING_STANDBY</varname> event will be
+inserted into receive message buffer or
+the <varname>CYGNUM_CAN_EVENT_LEAVING_STANDBY</varname> flag will be
+set for the message that caused wake up of CAN hardware.
+</PARA>
+</SECTION> <!-- can-mode-cfg -->
+   
+<SECTION>
+<TITLE>Flush or drain buffers</TITLE>
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN</varname> - This function
+waits for any buffered output to complete. This function only
+completes when there is no more data remaining to be sent to the
+device.
+</PARA>
+   
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH</varname> - This function
+discards any buffered output for the device.
+</PARA> 
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH</varname> - This function
+discards any buffered input for the device.
+</PARA>
+</SECTION>
+   
+<SECTION>
+<TITLE>Configuring blocking/non-blocking calls</TITLE>
+<PARA>
+By default all calls to <function>cyg_io_read()</function>
+and <function>cyg_io_write()</function> are blocking calls. The config
+keys
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_READ_BLOCKING
+CYG_IO_SET_CONFIG_WRITE_BLOCKING
+</PROGRAMLISTING>
+
+<PARA>
+enable switching between blocking and nonblocking calls separatly for
+read and write calls.  If blocking calls are configured then the
+read/write functions return only if a message was stored into TX
+buffer or a event was received from RX buffer. If non-blocking calls
+are enabled and there is no space in TX buffer or RX buffer is empty
+then the function returns immediately
+with <varname>-EAGAIN</varname>.
+</PARA>
+   
+<PARA>
+If non-blocking calls are enabled and additionally timeouts are
+supported by driver, then the read/write functions wait until timeout
+value is expired and then return with <varname>-EINTR</varname>.  If
+the read/write operation succeeds during the timed wait then the
+functions return succesfully with
+<varname>ENOERR</varname>.
+</PARA>
+
+<PARA>
+To query if <function>cyg_io_read()</function>
+and <function>cyg_io_write()</function> are blocking or non-blocking
+you can use the config keys
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_GET_CONFIG_READ_BLOCKING
+CYG_IO_GET_CONFIG_WRITE_BLOCKING
+</PROGRAMLISTING>
+</SECTION> <!-- can-cfg-unblock -->
+   
+<SECTION>
+<TITLE>Message buffer management</TITLE>
+
+<PARA>
+Full CAN controllers often support more the one message buffer. These
+message buffers are often configurable for transmission or reception
+of certain CAN messages or as a remote buffers.  If a CAN hardware
+supports more than one message buffer then it is possible to configure
+the CAN hardware to receive only CAN messages with certain identifiers
+or to configure hardware support for remote buffers. If message
+filtering is done by hardware, the number of received CAN messages
+decreases and so also the time for processing received CAN messages
+and the memory required for buffering received messages
+decreases. This saves valuable memory and processing time.
+</PARA>
+
+<PARA>
+The eCos CAN driver supports a generic way of adding message filters
+or remote buffers. By default the CAN driver is configured for
+reception of any kind of CAN standard and extended
+frames. Configuration of message buffers is done by
+calling <function>cyg_io_set_config()</function> with the config key
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_CAN_MSGBUF
+</PROGRAMLISTING>
+
+<PARA>
+and by exchanging <type>cyg_can_msgbuf_cfg</type> data structures.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_msgbox_cfg_st
+{
+    cyg_can_msgbuf_cfg_id cfg_id; // configuration id
+    cyg_can_msgbuf_handle handle; // handle to message buffer
+    cyg_can_message msg;          // CAN message - for configuration of buffer
+} cyg_can_msgbuf_cfg;
+</PROGRAMLISTING>
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+           <listitem><para> The <varname>cfg_id</varname> field
+contains the configuration ID that tells the driver what to do with a
+message buffer.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+           <listitem><para>
+Contains a reference to a certain message buffer.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+Required for configuration of message buffer parameters.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+The following configuration identifiers are supported:
+</PARA>
+
+<PROGRAMLISTING>
+CYGNUM_CAN_MSGBUF_RESET_ALL        // clears alle message buffers
+CYGNUM_CAN_MSGBUF_RX_FILTER_ALL    // cfg driver for reception of all can messages
+CYGNUM_CAN_MSGBUF_RX_FILTER_ADD    // add single message filter
+CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD   // add new remote response buffer
+CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE // stores data into existing remote buffer 
+</PROGRAMLISTING>
+
+<variablelist>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_RESET_ALL</type></term>
+           <listitem><para>
+Clears alle message buffers - no message will be received and all remote buffers are deleted.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_RX_FILTER_ALL</type></term>
+           <listitem><para>
+Configure driver for reception of all can messages
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_RX_FILTER_ADD</type></term>
+           <listitem><para>
+Add single message filter.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD</type></term>
+           <listitem><para>
+Add new remote response buffer.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE</type></term>
+           <listitem><para>
+Stores data into existing remote buffer (remote buffer handle required).
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for resetting all message buffers:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_msgbuf_cfg msgbox_cfg;
+
+msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+len = sizeof(msgbox_cfg);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;msgbox_cfg, &amp;len))
+{
+    // handle configuration error
+}
+</PROGRAMLISTING> 
+</SECTION> <!-- can-msgbuf-cfg -->
+   
+   
+<SECTION>
+<TITLE>Remote frame response buffer configuration</TITLE>
+
+<PARA>
+The remote frame is a message frame which is transmitted to request a
+data frame. Some CAN hardware generates receive interrupts when a
+remote transmission request arrives. Other CAN hardware, i.e.  the
+Motorola FlexCAN module, does not generate any receive
+interrupt. These CAN hardware chips like the FlexCAN module can be
+configured to transmit a data frame automatically in response to a
+remote frame. In order to support any kind of CAN hardware the eCos CAN
+driver provides a generic handling of remote transmission requests.
+</PARA>
+
+<PARA>
+The transmission of the data frame in response to a remote frame is
+completely handled by the CAN driver.  If the hardware driver, like
+the driver for the FlexCAN module, supports hardware message buffers,
+then the response frame is automatically transmitted if a remote
+transmission request with a matching ID arrives.  If a CAN hardware
+does not provide hardware support for sending data frames in response
+to a remote frame, then this need to be implemented in software by the
+hardware device driver.
+</PARA>
+
+<PARA>
+It is always possible to add remote response buffers. It does not
+matter if the driver is configured for reception of all CAN messages
+or if message filtering is used. As long as there are free message
+buffers available, it is possible to add remote response buffers.
+</PARA>
+   
+<PARA>
+In order to respond to a remote frame, a remote frame response buffer
+need to be initialized before a data frame can be sent in response to
+a remote frame. This is achieved by by
+exchanging <type>cyg_can_remote_buf</type> data structures with the
+driver via the <function>cyg_io_set_config()</function> function using
+the config key <varname>CYG_IO_SET_CONFIG_CAN_MSGBUF</varname>. Once
+the buffer is initialized, the CAN data can be changed at any time by
+the application.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_msgbuf_cfg_st
+{
+    cyg_can_msgbuf_cfg_id cfg_id; // configuration id 
+    cyg_can_msgbuf_handle handle; // handle to message buffer
+    cyg_can_message msg;          // CAN message - for configuration of buffer
+} cyg_can_remote_buf;
+</PROGRAMLISTING> 
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+           <listitem><para>
+The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with 
+a message buffer (<varname>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD</varname> or 
+<varname>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE</varname>).
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+           <listitem><para>
+If there is no buffer initialized for this data, the value of the handle field need to be set to 
+<varname>CYGNUM_CAN_MSGBUF_INIT</varname>. After the call to <function>cyg_io_set_config()</function> 
+the handle field contains a valid remote buffer handle ( &gt;= 0) or the value 
+<varname>CYGNUM_CAN_MSGBUF_NA</varname> ( &lt; 0) if no free buffer is available.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+The CAN frame that should be transmitted in response to a remote frame.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for setting up a remote response buffer:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_remote_buf rtr_buf;
+
+// prepare the remote response buffer
+rtr_buf.cfg_id  = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
+rtr_buf.handle  = CYGNUM_CAN_MSGBUF_INIT;
+rtr_buf.msg.id  = 0x7FF;
+rtr_buf.msg.ext = CYGNUM_CAN_ID_STD;
+rtr_buf.msg.rtr = CYGNUM_CAN_FRAME_DATA;
+rtr_buf.msg.dlc = 1;
+rtr_buf.msg.data[0] = 0xAB;
+
+len = sizeof(rtr_buf);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rtr_buf, &amp;len))
+{
+    // handle configuration error
+}
+
+if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA)
+{
+    // no free message buffer available - handle this problem here
+}
+
+
+// change CAN data for a buffer that is already initialized
+rtr_buf.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE;
+rtr_buf.msg.data[0] = 0x11;
+
+len = sizeof(rtr_buf);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rtr_buf, &amp;len))
+{
+    // handle configuration error
+} 
+</PROGRAMLISTING> 
+</SECTION> <!-- can-rtrbuf-cfg -->
+    
+
+<SECTION>
+<TITLE>Message filter configuration</TITLE>
+
+<PARA>
+If message filtering is done by hardware the number of received CAN
+messages decreases and so also the time for processing received CAN
+messages and the memory required for buffering received messages
+decreases.  This saves valuable memory and processing time. The eCos
+CAN driver supports a generic way of adding message filters. By
+default the CAN driver is configured for reception of any kind of CAN
+standard and extended frames. As soon as a message filter is added,
+the CAN driver will only receive the CAN frames with the identifier of
+the CAN filter. By adding a number of message filters it is possible
+for the CAN hardware to receive an number of different CAN messages.
+</PARA>
+
+<PARA>
+Adding message filters is only possible if driver is not configured
+for reception of all available CAN messages. If the driver is
+configured for reception of all CAN messages then message buffers need
+to be reset before adding single message filters.
+</PARA>
+    
+<PARA>
+In order to add a message filter, a message buffer need to be
+initialized. This is achieved by
+exchanging <type>cyg_can_filter</type> data structures with the driver
+via the <function>cyg_io_set_config()</function> function using the
+config key <varname>CYG_IO_SET_CONFIG_CAN_MSGBUF</varname>. Once the
+buffer is initialized, the CAN hardware can receive messages with the
+identifier of the filter.
+</PARA>
+
+<PROGRAMLISTING> 
+typedef struct cyg_can_msgbox_cfg_st
+{
+    cyg_can_msgbuf_cfg_id cfg_id;
+    cyg_can_msgbuf_handle handle;
+    cyg_can_message       msg;
+} cyg_can_filter;
+</PROGRAMLISTING> 
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+           <listitem><para>
+The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with 
+a message buffer.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+           <listitem><para>
+After the call to <function>cyg_io_set_config()</function> the handle field contains a valid value 
+( &gt;= 0) or the value <varname>CYGNUM_CAN_MSGBUF_NA</varname> ( &lt; 0) if no free buffer is available. 
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+The fields <structfield>id</structfield> and <structfield>ext</structfield> of the <structfield>msg</structfield>
+configure the type of message to receive by a certain message filter.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Before adding message filters the device should be stopped and after
+configuration it should be set into operational mode again.
+</PARA>
+
+<PARA>
+Example code for setting up a message filter:   
+</PARA>
+
+<PROGRAMLISTING> 
+cyg_can_msgbuf_cfg msgbox_cfg;
+cyg_can_filter rx_filter;
+
+// reset all message buffers
+msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+len = sizeof(msgbox_cfg);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN, 
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;msgbox_cfg, &amp;len))
+{
+    // handle configuration error
+}
+
+// prepare the message filter
+rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
+rx_filter.msg.id  = 0x800;
+rx_filter.msg.ext = CYGNUM_CAN_ID_EXT;
+
+len = sizeof(rx_filter);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rx_filter, &amp;len))
+{
+    // handle configuration error;
+}
+else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle)
+{
+    // no free message buffer available - handle this problem here
+}
+</PROGRAMLISTING> 
+</SECTION> <!-- can-msgfilt-cfg -->
+  
+  
+<SECTION id="can-msgfilt-deact">
+<TITLE>Message filter deactivation</TITLE>
+
+<PARA>
+After startup of your device the CAN driver is configured for
+reception of all available CAN messages.  If you change this
+configuration by adding single message filters then you can reset this
+default state with the configuration ID:
+</PARA> 
+
+<PROGRAMLISTING> 
+CYGNUM_CAN_MSGBUF_RX_FILTER_ALL
+</PROGRAMLISTING> 
+
+<PARA>
+This message buffer configuration id will clear all message filters
+and remote buffers and prepares the CAN hardware for reception of any
+kind of CAN standard and extended frames. It is not necessary to reset
+the message buffer configuration before this configuration step is
+executed because this should be done by device driver.
+</PARA> 
+   
+<PARA>
+Example code for deactivation of message filtering:
+</PARA>
+
+<PROGRAMLISTING> 
+cyg_can_filter rx_filter;
+
+// now setup a RX all configuration
+rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ALL;
+len = sizeof(rx_filter);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rx_filter, &amp;len))
+{
+    CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+}
+</PROGRAMLISTING> 
+</SECTION> <!-- can-msgfilt-deact -->
+
+<SECTION id="can-event-callback">
+<TITLE>Configuring a callback on events</TITLE>
+
+<PARA>
+By default application cannot get information about an event arriving
+in the RX buffer until it calls
+the <function>cyg_io_read()</function>.  Usually this leads applications
+to use accessory threads to wait for new CAN events.
+</PARA>
+
+<PARA>
+The CDL option <varname>CYGOPT_IO_CAN_SUPPORT_CALLBACK</varname>
+allows application to use a callback on event arrival. It is
+configured by passing a <structname>cyg_can_callback_cfg</structname>
+data structure to the driver via
+the <function>cyg_io_set_config()</function> function using the config
+key
+<varname>CYG_IO_SET_CONFIG_CAN_CALLBACK</varname>.
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_CAN_CALLBACK
+</PROGRAMLISTING>
+
+<PROGRAMLISTING>
+typedef void (*cyg_can_event_cb_t)(cyg_uint16, CYG_ADDRWORD);
+
+typedef struct cyg_can_callback_cfg_st
+{
+    cyg_can_event_cb_t callback_func;   // callback function
+    cyg_uint16  flag_mask;              // flags mask
+    CYG_ADDRWORD data;                  // data passed to callback
+} cyg_can_callback_cfg;
+</PROGRAMLISTING>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_event_cb_t</type> <varname>callback_func</varname></term>
+           <listitem><para> 
+Pointer to the callback function. The function will be called from DSR context so
+you should be careful to only call API functions that are safe in DSR
+context.  The First parameter is a combination of event flags for events that have 
+occurred. Second parameter is a user defined data pointer or value.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYG_ADDRWORD</type> <varname>data</varname></term>
+           <listitem><para>
+Additional user data that will be passed to callback function as a second parameter.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint16</type> <varname>flag_mask</varname></term>
+           <listitem><para>
+Should be set with a combination
+of <varname>CYGNUM_CAN_EVENT_*</varname> flags.  If one of these
+events happens, the callback function will be called, with the
+actually event flags passed as a parameter.  To disable the callback
+function from being called set <varname>flag_mask</varname> to 0.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+</SECTION> <!-- can-event-callback -->
+
+</SECTION>  
+</CHAPTER>
+
+<CHAPTER id="io-can-configuration">
+<TITLE>Configuration</TITLE>
+
+<PARA>
+The CAN subsystem has a number of configuration options.
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cdl_interface CYGINT_IO_CAN_TIMESTAMP</type></term>
+           <listitem><para>
+A hardware device driver that supports timestamps should implement this interface.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_TIMESTAMP</type></term>
+           <listitem><para>
+If the CAN hardware driver supports some kind of timestamps then this option enables 
+propagation of timestamps to higher layers. This may add some extra code to hardware 
+drivers.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_TX_EVENT_SUPPORT</type></term>
+           <listitem>
+<para> This option enables support for TX
+events. If a CAN message is transmitted successfully a TX event will
+be inserted into the receive event queue and propagated to higher
+layers.  If this option is enabled the RX event queue will be filled
+faster.
+</para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</type></term>
+           <listitem>
+<para>
+This option enables extra code in the generic CAN driver which allows
+clients to switch read() and write() call semantics from blocking to
+non-blocking.
+</para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_CALLBACK</type></term>
+           <listitem>
+<para>
+This option enables extra code in the generic CAN driver which allows
+an application to register a callback for events. The callback function
+is called from DSR context so you should be careful to only call API
+functions that are safe in DSR context.
+</para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGNUM_IO_CAN_DEFAULT_TIMEOUT_READ</type></term>
+           <listitem><para>
+The initial timeout value in clock ticks for <FUNCTION>cyg_io_read()</FUNCTION> calls.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGNUM_IO_CAN_DEFAULT_TIMEOUT_WRITE</type></term>
+           <listitem><para> The initial timeout value in clock ticks
+for <FUNCTION>cyg_io_write()</FUNCTION> calls.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+</CHAPTER>
+
+
+<CHAPTER id="io-can-device-drivers">
+<TITLE>Writing a CAN hardware device driver</TITLE>
+
+<PARA>
+A CAN driver is nothing more than a named entity that supports the
+basic I/O functions - read, write, get config, and set config. The
+device driver uses and manages interrupts from the device. While the
+interface is generic and device driver independent, the actual driver
+implementation is completely up to the device driver designer.
+</PARA>
+
+<PARA>
+That said, the reason for using a device driver is to provide access
+to a CAN device from application code in as general purpose a fashion
+as reasonable. Most driver writers are also concerned with making this
+access as simple as possible while being as efficient as possible.
+</PARA>
+
+<PARA>
+Like other device drivers the CAN device driver is concerned with the
+movement of information - the CAN messages. In order to make the most
+efficient use of system resources, interrupts are used.  This will
+allow other application processing to take place while the data
+transfers are under way, with interrupts used to indicate when various
+events have occurred. For example, a CAN device typically generates an
+interrupt after a CAN message has been sent or a CAN message has been
+received by a CAN hardware message buffer. It makes sense to allow
+further application processing while the data is being sent since this
+can take quite a long time. The interrupt can be used to allow the
+driver to send a CAN message as soon as the current one is complete,
+without any active participation by the application code.
+</PARA>
+
+<PARA>
+The main building blocks for CAN device drivers are found in the
+include files
+<filename>&lt;cyg/io/devtab.h&gt;</filename> and <filename>&lt;cyg/io/can.h&gt;</filename>
+</PARA>
+
+<PARA>
+Like many other device drivers in eCos, CAN device drivers are described by a device 
+table entry, using the <type>cyg_devtab_entry_t</type> type. The entry should be created using 
+the <varname>DEVTAB_ENTRY()</varname> macro.
+</PARA>
+
+
+<SECTION id="io-can-how-to-write-interface-driver">
+<TITLE>How to Write a CAN Hardware Interface Driver</TITLE>
+
+<PARA>
+The standard CAN driver supplied with eCos is structured as a hardware
+independent portion and a hardware dependent interface module. To add
+support for a new CAN device, the user should be able to use the
+existing hardware independent portion and just add their own interface
+driver which handles the details of the actual device. The user should
+have no need to change the hardware independent portion.
+</PARA>
+
+<PARA>
+The interfaces used by the CAN driver and CAN implementation modules
+are contained in the file <filename>&lt;cyg/io/can.h&gt;</filename>.
+</PARA>
+
+<SECTION>
+<title>DevTab Entry</TITLE>
+
+<PARA>
+The interface module contains the devtab entry (or entries if a single
+module supports more than one interface). This entry should have the
+form:
+</PARA>
+
+<PROGRAMLISTING> 
+DEVTAB_ENTRY(&lt;&lt;module_name&gt;&gt;, 
+             &lt;&lt;device_name&gt;&gt;,
+             0,
+             &amp;can_devio, 
+             &lt;&lt;module_init&gt;&gt;, 
+             &lt;&lt;module_lookup&gt;&gt;,
+             &amp;&lt;&lt;can_channel&gt;&gt;
+            );
+</PROGRAMLISTING> 
+
+<variablelist>
+<title>Arguments</title>
+  <varlistentry>
+    <term><parameter>module_name</parameter></term>
+    <listitem><para>The "C" label for this devtab entry</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>device_name</parameter></term>
+    <listitem><para>The "C" string for the
+    device. E.g. <filename>/dev/can0</filename>.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>can_devio</parameter></term>
+    <listitem><para>The table of I/O functions. This set is defined in
+    the hardware independent CAN driver and should be used.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>module_init</parameter></term>
+    <listitem><para>The hardware module initialization function.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>module_lookup</parameter></term>
+    <listitem><para>The device lookup function. This function
+    typically sets up the CAN device for actual use, turning on
+    interrupts, configuring the message buffers, etc.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>can_channel</parameter></term>
+    <listitem><para>This table (defined below) contains the interface
+    between the interface module and the CAN driver proper.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<PARA>
+Example devtab entry for Motorola FlexCAN device driver:
+</PARA>
+
+<PROGRAMLISTING>
+DEVTAB_ENTRY(flexcan_devtab, 
+             CYGDAT_DEVS_CAN_MCF52xx_FLEXCAN0_NAME,
+             0,                     // Does not depend on a lower level interface
+             &amp;cyg_io_can_devio, 
+             flexcan_init, 
+             flexcan_lookup,        // CAN driver may need initializing
+             &amp;flexcan_can0_chan
+    );
+</PROGRAMLISTING>
+</SECTION>
+
+
+<SECTION>
+<title>CAN Channel Structure</TITLE>
+
+<PARA>
+Each CAN device must have a &ldquo;CAN channel&rdquo;.
+This is a set of data which describes all operations on the device.
+It also contains buffers, etc. The CAN channel is created by the macro: 
+</PARA>
+
+<PROGRAMLISTING>
+CAN_CHANNEL_USING_INTERRUPTS(l, funs, dev_priv, baud,
+                             out_buf, out_buflen,
+                             in_buf,  in_buflen)
+</PROGRAMLISTING>
+
+<variablelist>
+  <title>Arguments</title>
+  <varlistentry>
+    <term><parameter>l</parameter></term>
+    <listitem><para>The "C" label for this structure.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>funs</parameter></term>
+    <listitem><para>The set of interface functions (see below).</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>dev_priv</structfield></term>
+    <listitem><para>A placeholder for any device specific data for
+    this channel.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>baud</structfield></term>
+    <listitem><para>The initial baud rate value
+    (<type>cyg_can_baud_rate_t</type>).</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>out_buf</structfield></term>
+    <listitem><para>Pointer to the output buffer</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>out_buflen</structfield></term>
+    <listitem><para>The length of the output buffer.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>in_buf</structfield></term>
+    <listitem><para>pointer to the input buffer.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>in_buflen</structfield></term>
+    <listitem><para>The length of the input buffer.</PARA></listitem>
+  </varlistentry>
+</variablelist>
+
+<PARA>
+Example CAN channel implementation for Motorola FlexCAN device driver:
+</PARA>
+
+<PROGRAMLISTING>
+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
+);
+</PROGRAMLISTING>
+
+<PARA>
+The interface from the hardware independent driver into the hardware
+interface module is contained in the <structfield>funs</structfield>
+table.  This is defined by the macro:
+</PARA>
+</SECTION>
+
+<SECTION>
+<TITLE>CAN Lowlevel Functions Structure</TITLE>
+
+<PROGRAMLISTING>
+CAN_LOWLEVEL_FUNS(l, putmsg, getevent, get_config, set_config, start_xmit, stop_xmit)
+</PROGRAMLISTING>
+
+<variablelist>
+  <title>Arguments</title>
+  <varlistentry>
+    <term><structfield>l</structfield></term>
+    <listitem><para>The "C" label for this structure.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>putmsg</structfield></term>
+    <listitem>
+      <para><literal>
+      bool (*putmsg)(can_channel *priv, cyg_can_message *pmsg, void *pdata)
+      </literal></para>
+      <para>
+      This function sends one CAN message to the interface. It should
+      return <literal>true</literal> if the message is actually
+      consumed. It should return <literal>false</literal> if there is
+      no space in the interface
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>getevent</structfield></term>
+    <listitem>
+      <para><literal>
+      bool (*getevent)(can_channel *priv, cyg_can_event *pevent, void *pdata)
+      </literal></para>
+      <para>
+      This function fetches one event from the interface.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>get_config</structfield></term>
+    <listitem>
+      <para><literal> 
+      Cyg_ErrNo (*get_config)(can_channel *priv, cyg_uint32 key, const void *xbuf, cyg_uint32 *len)
+      </literal></para>
+      <para>
+        This function is used to query the configuration of a CAN channel.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>set_config</structfield></term>
+    <listitem>
+      <para><literal> 
+      Cyg_ErrNo (*set_config)(can_channel *priv, cyg_uint32 key, const void *xbuf, cyg_uint32 *len)
+      </literal></para>
+      <para>
+        This function is used to change configuration of a CAN channel.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>start_xmit</parameter></term>
+    <listitem><para><literal>void (*start_xmit)(can_channel *priv)</literal></para>
+      <para>
+        Enable the transmit channel and turn on transmit interrupts.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>stop_xmit</parameter></term>
+    <listitem>
+      <para><literal>void (*stop_xmit)(can_channel *priv)</literal></para>
+      <para>Disable the transmit channel and turn transmit interrupts off.</PARA>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<PARA>
+Example implementation of low level function structure for Motorola FlexCAN 
+device driver:
+</PARA>
+
+<PROGRAMLISTING>
+CAN_LOWLEVEL_FUNS(flexcan_lowlevel_funs,
+                  flexcan_putmsg,
+                  flexcan_getevent,
+                  flexcan_get_config,
+                  flexcan_set_config,
+                  flexcan_start_xmit,
+                  flexcan_stop_xmit
+     );
+</PROGRAMLISTING>
+</SECTION>
+
+<SECTION>
+<TITLE>Callbacks</TITLE>
+
+<PARA>
+The device interface module can execute functions in the
+hardware independent driver via <literal>chan-&gt;callbacks</literal>.
+These functions are available:
+</PARA>
+
+<PROGRAMLISTING>
+void (*can_init)(can_channel *chan)
+</PROGRAMLISTING>
+
+<PARA>This function is used to initialize the CAN channel.</PARA>
+
+<PROGRAMLISTING>
+void (*xmt_msg)(can_channel *chan, void *pdata)
+</PROGRAMLISTING>
+
+<PARA>
+This function would be called from an interrupt handler after a
+transmit interrupt indicating that additional messages may be
+sent. The upper driver will call the <function>putmsg</function>
+function as appropriate to send more data to the device.
+</PARA>
+
+<PROGRAMLISTING>
+void (*rcv_event)(can_channel *chan, void *pdata)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to tell the driver that a message has arrived
+at the interface or that an event has occurred. This function is typically 
+called from the interrupt handler. 
+</PARA>
+</SECTION><!-- Callbacks -->
+
+</SECTION><!-- id="io-can-how-to-write-interface-driver" -->
+</CHAPTER>
+
+</PART>
diff --git a/packages/io/can/v2_0/tests/can_filter.c b/packages/io/can/v2_0/tests/can_filter.c
new file mode 100644 (file)
index 0000000..c1145f0
--- /dev/null
@@ -0,0 +1,307 @@
+//==========================================================================
+//
+//        can_filter.c
+//
+//        CAN message filter test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Uwe Kindler
+// Contributors:  Uwe Kindler
+// Date:          2007-03-21
+// Description:   CAN hardware filter 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_STD_CAN_ID)
+
+
+//===========================================================================
+//                               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;
+
+
+//===========================================================================
+//                          LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// Main thread
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+    cyg_uint32             len;
+    cyg_can_event          rx_event;
+    cyg_uint16             i;
+    cyg_can_hdi            hdi;
+    cyg_can_msgbuf_info    msgbox_info;
+    cyg_can_msgbuf_cfg     msgbox_cfg;
+
+    
+    len = sizeof(hdi);
+    if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_HDI ,&hdi, &len))
+    {
+        CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+    } 
+    
+    //
+    // Normally the CAN modul should support message filters. So the
+    // FULLCAN flag should be set - if it is not, we treat this as an error
+    //
+    if (!(hdi.support_flags & CYGNUM_CAN_HDI_FULLCAN))
+    {
+        CYG_TEST_FAIL_FINISH("/dev/can0 does not support message buffers");
+    }
+    
+    
+    //
+    // Now reset message buffer configuration - this is mandatory bevore starting
+    // message buffer runtime configuration
+    //
+    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 query number of available and free message boxes
+    //
+    len = sizeof(msgbox_info);
+    if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+    {
+        CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+    } 
+    
+    //
+    // if there are no free message boxes available then this is a failure
+    //
+    if (!msgbox_info.free)
+    {
+        CYG_TEST_FAIL_FINISH("No free message boxes available for /dev/can0");
+    }
+    
+    //
+    // We setup as many standard CAN message filters as there are free
+    // message buffers available.
+    //
+    for (i = 0; i < msgbox_info.free; ++i)
+    {
+        cyg_can_filter rx_filter;
+        
+        rx_filter.cfg_id  = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD;
+        rx_filter.msg.id  = i;
+        rx_filter.msg.ext = CYGNUM_CAN_ID_STD;
+  
+        len = sizeof(rx_filter); 
+        if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len))
+        {
+            CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+        }
+        else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle)
+        {
+            CYG_TEST_FAIL_FINISH("Error setting up message filter for /dev/can0");
+        }
+    }
+    
+    
+    diag_printf("\n\nNow try to send CAN messages. The device should only\n"
+                "receive messages identifiers in the range of 0x00 to 0x%X.\n"
+                "As soon as a standard message with ID 0x000 arrives, all\n"
+                "message filters will be cleared\n\n", (msgbox_info.free - 1));
+    
+    //
+    // Now receive messages until a message arrives with largest ID of all
+    // available message filters
+    //
+    rx_event.msg.id = 1;
+    while(rx_event.msg.id != 0)
+    {
+        len = sizeof(rx_event); 
+            
+        if (ENOERR != cyg_io_read(hCAN0, &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 (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+        else
+        {
+               print_can_flags(rx_event.flags, "");
+               rx_event.msg.id = 1;
+        }
+    } // while(1)
+    
+    
+    //
+    // Now enable reception of all available CAN messages
+    //
+    cyg_can_filter rx_filter;
+    rx_filter.cfg_id  = CYGNUM_CAN_MSGBUF_RX_FILTER_ALL;
+    len = sizeof(rx_filter);
+    if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF , &rx_filter, &len))
+    {
+        CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+    }
+    
+    
+    diag_printf("\n\nAll message filters have been cleared an now the device\n"
+                "will receive any available CAN message identifiers.\n"
+                "Send a CAN message with ID 0x100 to stop this test.\n\n");
+    
+    //
+    // Now receive messages until a message arrives with largest ID of all
+    // available message filters
+    //
+    rx_event.msg.id = 1;
+    while(rx_event.msg.id != 0x100)
+    {
+        len = sizeof(rx_event); 
+            
+        if (ENOERR != cyg_io_read(hCAN0, &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 (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+    } // while(1)
+    
+    CYG_TEST_PASS_FINISH("can_filter test OK");
+}
+
+
+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 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 // CYGOPT_IO_CAN_STD_CAN_ID
+#define N_A_MSG "Needs support for standard CAN identifiers"
+#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_filter.c
diff --git a/packages/io/can/v2_0/tests/can_hdi.c b/packages/io/can/v2_0/tests/can_hdi.c
new file mode 100644 (file)
index 0000000..1aba373
--- /dev/null
@@ -0,0 +1,235 @@
+//==========================================================================
+//
+//        can_hdi.c
+//
+//        CAN hardware description information test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Uwe Kindler
+// Contributors:  Uwe Kindler
+// Date:          2007-03-22
+// Description:   CAN hardware desciption information 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>
+
+
+//===========================================================================
+//                               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;
+
+
+//===========================================================================
+//                          LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// Main thread
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+    cyg_uint32             len;
+    cyg_can_hdi            hdi;
+    cyg_can_msgbuf_info    msgbox_info;
+
+    
+    //
+    // Query information about hardware of CAN controller
+    //
+    len = sizeof(hdi);
+    if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_HDI ,&hdi, &len))
+    {
+        CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+    } 
+    
+    //
+    // Check type of CAN controller - type of supported CAN frames
+    //
+    diag_printf("\n\nSupported message formats:\n");
+    if (hdi.support_flags & CYGNUM_CAN_HDI_FRAMETYPE_STD)
+    {
+        diag_printf("  Standard CAN (2.0A):         yes\n");
+        diag_printf("  Extended CAN (2.0B):         no\n");
+    } 
+    else if (hdi.support_flags & CYGNUM_CAN_HDI_FRAMETYPE_EXT_PASSIVE)
+    {
+       diag_printf("  Standard CAN (2.0A):         yes\n");
+        diag_printf("  Extended CAN (2.0B):         passive\n"); 
+    }
+    else if (hdi.support_flags & CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE)
+    {
+       diag_printf("  Standard CAN (2.0A):         yes\n");
+        diag_printf("  Extended CAN (2.0B):         yes\n"); 
+    }
+    
+    //
+    // Check if this is a FullCAN controller
+    //
+    diag_printf("\nController type:               ");
+    if (hdi.support_flags & CYGNUM_CAN_HDI_FULLCAN)
+    {
+        diag_printf("FullCAN\n");
+        //
+        // FullCAN means the controller supports a number of message buffers.
+        // Now query number of available and free message buffers
+        //
+        len = sizeof(msgbox_info);
+        if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+        {
+             CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+        } 
+    
+        diag_printf("  Message buffers:             %d\n", msgbox_info.count);
+        diag_printf("  Message buffers free:        %d\n", msgbox_info.free);
+    }
+    else
+    {
+       diag_printf("BasicCAN\n");      
+    }
+       
+    //
+    // Check if automatic baudrate detection is supported
+    //
+    if (hdi.support_flags & CYGNUM_CAN_HDI_AUTBAUD)
+    {
+       diag_printf("\nAutomatic baudrate detection:  supported\n"); 
+    }
+    
+    //
+    // Check if driver supports timestamps
+    //
+    if (hdi.support_flags & CYGNUM_CAN_HDI_TIMESTAMP)
+    {
+       diag_printf("Timestamps:                    supported\n"); 
+    }
+    
+    diag_printf("\n\n"); 
+    CYG_TEST_PASS_FINISH("can_hdi test OK");
+}
+
+
+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 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 can_hdi.c
diff --git a/packages/io/can/v2_0/tests/can_load.c b/packages/io/can/v2_0/tests/can_load.c
new file mode 100644 (file)
index 0000000..60d5d02
--- /dev/null
@@ -0,0 +1,308 @@
+//==========================================================================
+//
+//        can_load.c
+//
+//        CAN load test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Uwe Kindler
+// Contributors:  Uwe Kindler
+// Date:          2005-08-14
+// Description:  CAN 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>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_STD_CAN_ID) && defined(CYGOPT_IO_CAN_EXT_CAN_ID)
+
+
+//===========================================================================
+//                               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_io_handle_t    hCAN0;
+
+
+//===========================================================================
+//                          LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// Main thread
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+    cyg_uint32             len;
+    cyg_can_event          rx_event;
+    cyg_can_timeout_info_t timeouts;
+
+#if defined(CYGOPT_IO_CAN_SUPPORT_TIMEOUTS)   
+    //
+    // setup large timeout values because we do not need timeouts here
+    //
+    timeouts.rx_timeout = 100000;
+    timeouts.tx_timeout = 100000;
+    
+    len = sizeof(timeouts);
+    if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_TIMEOUT ,&timeouts, &len))
+    {
+        CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+    }
+#endif // defined(CYGOPT_IO_CAN_SUPPORT_TIMEOUTS)  
+    
+    //
+    // This thread simply receives all CAN events and prints the event flags and the
+    // CAN message if it was a TX or RX event. You can use this test in order to check
+    // when a RX overrun occurs
+    //
+    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) || (rx_event.flags & CYGNUM_CAN_EVENT_TX))
+            {
+                print_can_msg(&rx_event.msg, "");
+            }
+        }    
+    }             
+}
+
+
+//===========================================================================
+//                            WRITER THREAD
+//===========================================================================
+void can1_thread(cyg_addrword_t data)
+{
+    cyg_uint16      i = 0;
+    cyg_uint32      len;
+    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
+    };
+    
+    //
+    // This thread simply sends CAN messages. It increments the ID for each new CAN messsage
+    // and sends a remote frame after seven data frames. In the first byte of each data frame
+    // the number (0 - 7) of the data frame is stored and the length of the data frame grows
+    // from 1 - 8 data bytes.
+    //
+    // The received pattern should look like this way:
+    // ID    Length    Data
+    // ----------------------------------------------
+    // 000   1         00
+    // 001   2         01 F1
+    // 002   3         02 F1 F2
+    // 003   4         03 F1 F2 F3
+    // 004   5         04 F1 F2 F3 F4
+    // 005   6         05 F1 F2 F3 F4 F5
+    // 006   7         06 F1 F2 F3 F4 F5 F6
+    // 007   8         Remote Request
+    // 008   1         00
+    // 009   2         01 F1
+    // 00A   3         02 F1 F2
+    // ...
+    //
+    while (1)
+    {
+        tx_msg.id            = i;
+        tx_msg.dlc           = (i % 8) + 1;
+        tx_msg.data.bytes[0] = (i % 8);
+        i = (i + 1) % 0x7FF;
+        
+        //
+        // the 6th frame is a remote frame
+        //
+        if ((i % 8) == 6)
+        {
+            tx_msg.rtr =  CYGNUM_CAN_FRAME_RTR;
+            tx_msg.ext =  CYGNUM_CAN_ID_STD;
+        }
+        //
+        // the 7th frame is a extended frame
+        //
+        else if ((i % 8) == 7)
+        {
+            tx_msg.ext =  CYGNUM_CAN_ID_EXT;
+            tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
+        }
+        //
+        // the 8th frame is a extended remote frame
+        //
+        else if (!(i % 8))
+        {
+            tx_msg.ext =  CYGNUM_CAN_ID_EXT;
+            tx_msg.rtr = CYGNUM_CAN_FRAME_RTR;
+        }
+        //
+        // all other frames are standard data frames
+        //
+        else
+        {
+            tx_msg.ext =  CYGNUM_CAN_ID_STD;
+            tx_msg.rtr =  CYGNUM_CAN_FRAME_DATA;
+        }
+        
+        len = sizeof(tx_msg);
+        if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len))
+        {
+            CYG_TEST_FAIL_FINISH("Error writing to /dev/can0");
+        }
+        
+        cyg_thread_delay(50);          
+    } // 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 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_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 // defined(CYGOPT_IO_CAN_STD_CAN_ID) && defined(CYGOPT_IO_CAN_EXT_CAN_ID)
+#define N_A_MSG "Needs support for standard and extended CAN identifiers"
+#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_load.c
diff --git a/packages/io/can/v2_0/tests/can_remote.c b/packages/io/can/v2_0/tests/can_remote.c
new file mode 100644 (file)
index 0000000..0c223f0
--- /dev/null
@@ -0,0 +1,312 @@
+//==========================================================================
+//
+//        can_remote.c
+//
+//        CAN remote response buffer test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Uwe Kindler
+// Contributors:  Uwe Kindler
+// Date:          2005-08-14
+// Description:   CAN 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>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_RUNTIME_MBOX_CFG)
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_REMOTE_BUF)
+
+
+//===========================================================================
+//                               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;
+
+
+//===========================================================================
+//                          LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// Main thread
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+    cyg_uint32             len;
+    cyg_can_event          rx_event;
+    cyg_can_remote_buf     rtr_buf;
+    cyg_can_filter         rx_filter;
+    cyg_can_msgbuf_info    msgbox_info; 
+    cyg_can_msgbuf_cfg     msgbox_cfg;
+
+    //
+    // We would like to setup 2 remote buffers - check if we have enough
+    // free message buffers
+    //
+    len = sizeof(msgbox_info);
+    if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+    {
+        CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+    } 
+    else
+    {
+        diag_printf("\n\n\nMessage boxes available: %d    free: %d\n", 
+                    msgbox_info.count, msgbox_info.free);
+    }
+    
+    //
+    // We have not enougth free message buffers, so we clear all message buffers now
+    // and try again
+    //
+    if (msgbox_info.free < 2)
+    {
+        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 clearing message buffers of /dev/can0");    
+        }
+        
+        //
+        // Now query number of free message boxes again. We need 3 free message boxes.
+        // 2 message boxes for setup of remote response buffers and 1 message box for
+        // setup of receive message box for CAN identifier 0x100
+        //
+        len = sizeof(msgbox_info);
+        if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+        {
+            CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+        } 
+        else
+        {
+            diag_printf("Message boxes available: %d    free: %d\n", 
+                        msgbox_info.count, msgbox_info.free);    
+        }
+        
+        if (msgbox_info.free < 3)
+        {
+            CYG_TEST_FAIL_FINISH("Not enough free message buffers available for /dev/can0");    
+        }
+        else
+        {
+            rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD;
+            CYG_CAN_MSG_SET_STD_ID(rx_filter.msg, 0x100);
+            
+            len = sizeof(rx_filter);
+            if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len))
+            {
+                CYG_TEST_FAIL_FINISH("Error adding rx filter for CAN ID 0x100 for /dev/can0");
+            } 
+        } // if (msgbox_info.free < 3)
+    } // if (msgbox_info.free < 2)
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+    //
+    // Setup the first remote response buffer for resception of standard
+    // remote frames
+    //
+    rtr_buf.cfg_id      = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
+    CYG_CAN_MSG_SET_PARAM(rtr_buf.msg, 0x7FF, CYGNUM_CAN_ID_STD, 1, CYGNUM_CAN_FRAME_DATA);
+    CYG_CAN_MSG_SET_DATA(rtr_buf.msg, 0, 0xAB);
+   
+    len = sizeof(rtr_buf);
+    if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf, &len))
+    {
+        CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+    } 
+#endif
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+    cyg_can_remote_buf     rtr_buf2;
+    //
+    // setup the second remote response buffer for reception of extended
+    // remote frames
+    // 
+    rtr_buf2.cfg_id      = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
+    CYG_CAN_MSG_SET_PARAM(rtr_buf2.msg, 0x800, CYGNUM_CAN_ID_EXT, 4, CYGNUM_CAN_FRAME_DATA);
+    CYG_CAN_MSG_SET_DATA(rtr_buf2.msg, 0, 0xCD);
+   
+    len = sizeof(rtr_buf2);
+    if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf2, &len))
+    {
+        CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+    } 
+    
+    if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA)
+    {
+        CYG_TEST_FAIL_FINISH("No free message buffer available for /dev/can0");
+    }
+#endif
+      
+    diag_printf("\nTest of CAN remote response buffer configuration\n"
+                "If a CAN node sends a remote request with ID 0x7FF (std. ID)\n"
+                "or 0x800 (ext. ID) then the CAN driver should respond with\n"
+                "data frames.\n\n");
+    diag_printf("!!! This test can be stopped by sending a data frame\n"
+                "with ID 0x100 !!!\n\n");
+    
+    len = sizeof(msgbox_info);
+    if (ENOERR != cyg_io_get_config(hCAN0, 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)
+    {
+        len = sizeof(rx_event); 
+            
+        if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+        {
+            CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+        }
+        
+        if (0x100 == rx_event.msg.id)
+        {
+            CYG_TEST_PASS_FINISH("can_remote test OK"); 
+        }
+        else
+        {
+            print_can_flags(rx_event.flags, "");
+            
+            if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+            {
+                print_can_msg(&rx_event.msg, "");   
+            }
+        }
+    }         
+}
+
+
+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_IO_CAN_REMOTE_BUF
+#define N_A_MSG "Needs support for CAN remote response buffers"
+#endif
+
+#else // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+#define N_A_MSG "Needs support for CAN message buffer runtime configuration"
+#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_remote.c
diff --git a/packages/io/can/v2_0/tests/can_test_aux.inl b/packages/io/can/v2_0/tests/can_test_aux.inl
new file mode 100644 (file)
index 0000000..2946b8f
--- /dev/null
@@ -0,0 +1,148 @@
+//==========================================================================
+//
+//        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 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-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/packages/io/can/v2_0/tests/can_tx.c b/packages/io/can/v2_0/tests/can_tx.c
new file mode 100644 (file)
index 0000000..ceea6ef
--- /dev/null
@@ -0,0 +1,230 @@
+//==========================================================================
+//
+//        can_tx.c
+//
+//        Simple CAN TX test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Uwe Kindler
+// Contributors:  Uwe Kindler
+// Date:          2007-01-08
+// Description:   Simple 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>
+#include <cyg/hal/hal_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;
+
+
+//===========================================================================
+//                          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      i;
+    cyg_uint32      len;
+    CYG_CAN_MSG_INIT(tx_msg, 0x001, CYGNUM_CAN_ID_STD, 1, CYGNUM_CAN_FRAME_DATA);
+    
+    //
+    // Open device and check return value
+    //
+    if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0)) 
+    {
+        CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+    }
+
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID    
+    //
+    // Now send 1000 messages with standard identifier.
+    // Each message contains the message number in its identifier 
+    // and in the first data byte
+    //
+    for (i = 0; i < 1000; ++i)
+    {
+        CYG_CAN_MSG_SET_STD_ID(tx_msg, i);
+        CYG_CAN_MSG_SET_DATA(tx_msg, 0, i);
+        len = sizeof(tx_msg);
+        
+        //
+        // Each message with an odd identifier should be a remote request message
+        //
+        if (i % 2)
+        {
+            CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_RTR); 
+        }
+        else
+        {
+            CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_DATA); 
+        }
+        
+        //
+        // Sending CAN messages is blocking so the thread waits until there is
+        // space in the tx queue
+        //
+        if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len))
+        {
+            CYG_TEST_FAIL_FINISH("Error writing to /dev/can0");
+        }    
+    }
+#endif
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID    
+    //
+    // Now send 1000 messages with extended identifier.
+    // Each message contains the message number in its identifier 
+    // and in the first data byte
+    //
+    for (i = 0; i < 1000; ++i)
+    {
+        CYG_CAN_MSG_SET_EXT_ID(tx_msg, i + 0x800);
+        CYG_CAN_MSG_SET_DATA(tx_msg, 0, i);
+        CYG_CAN_MSG_SET_DATA_LEN(tx_msg, 8);
+        len = sizeof(tx_msg);
+        
+        //
+        // Each message with an odd identifier should be a remote request message
+        //
+        if (i % 2)
+        {
+            CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_RTR); 
+        }
+        else
+        {
+            CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_DATA); 
+        }
+        
+        //
+        // Sending CAN messages is blocking so the thread waits until there is
+        // space in the tx queue
+        //
+        if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len))
+        {
+            CYG_TEST_FAIL_FINISH("Error writing to /dev/can0");
+        }    
+    }
+#endif
+
+    
+    CYG_TEST_PASS_FINISH("CAN TX test OK");
+}
+
+
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    
+    //
+    // create the threads that 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 // 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_tx.c
diff --git a/packages/io/fileio/v2_0/include/fnmatch.h b/packages/io/fileio/v2_0/include/fnmatch.h
new file mode 100644 (file)
index 0000000..c14318b
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef CYGONCE_FILEIO_FNMATCH_H
+#define CYGONCE_FILEIO_FNMATCH_H
+
+//==========================================================================
+//
+//      fnmatch.h
+//
+//==========================================================================
+//####BSDCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from NetBSD, and are
+// covered by the appropriate copyright disclaimers included herein.
+//
+// -------------------------------------------
+//
+//####BSDCOPYRIGHTEND####
+
+/*     $NetBSD: fnmatch.h,v 1.12 2005/02/03 04:39:32 perry Exp $       */
+
+/*-
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)fnmatch.h   8.1 (Berkeley) 6/2/93
+ */
+
+#include <cyg/infra/cyg_type.h> // common type definitions and support
+
+#define        FNM_NOMATCH     (1)     /* Match failed. */
+#define        FNM_NOSYS       (2)     /* Function not implemented. */
+
+#define        FNM_NOESCAPE    (0x01)  /* Disable backslash escaping. */
+#define        FNM_PATHNAME    (0x02)  /* Slash must be matched by slash. */
+#define        FNM_PERIOD      (0x04)  /* Period must be matched by period. */
+#define        FNM_CASEFOLD    (0x08)  /* Pattern is matched case-insensitive */
+#define        FNM_LEADING_DIR (0x10)  /* Ignore /<tail> after Imatch. */
+
+__externC int
+fnmatch(const char *, const char *, int);
+
+#endif /* !CYGONCE_FILEIO_FNMATCH_H */
diff --git a/packages/io/fileio/v2_0/src/fnmatch.c b/packages/io/fileio/v2_0/src/fnmatch.c
new file mode 100644 (file)
index 0000000..0c3db47
--- /dev/null
@@ -0,0 +1,185 @@
+/*     $NetBSD: fnmatch.c,v 1.21 2005/12/24 21:11:16 perry Exp $       */
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ * Compares a filename or pathname to a pattern.
+ */
+
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+#include <ctype.h>
+#include <fnmatch.h>
+#include <string.h>
+
+#define        EOS     '\0'
+
+static const char *rangematch(const char *, int, int);
+
+static inline int
+foldcase(int ch, int flags)
+{
+
+       if ((flags & FNM_CASEFOLD) != 0 && isupper(ch))
+               return (tolower(ch));
+       return (ch);
+}
+
+#define        FOLDCASE(ch, flags)     foldcase((unsigned char)(ch), (flags))
+
+int
+fnmatch(const char *pattern, const char *string, int flags)
+{
+       const char *stringstart;
+       char c, test;
+
+       CYG_ASSERT(pattern != NULL, "pattern NULL pointer!");
+       CYG_ASSERT(string != NULL, "string NULL pointer!");
+
+       for (stringstart = string;;)
+               switch (c = FOLDCASE(*pattern++, flags)) {
+               case EOS:
+                       if ((flags & FNM_LEADING_DIR) && *string == '/')
+                               return (0);
+                       return (*string == EOS ? 0 : FNM_NOMATCH);
+               case '?':
+                       if (*string == EOS)
+                               return (FNM_NOMATCH);
+                       if (*string == '/' && (flags & FNM_PATHNAME))
+                               return (FNM_NOMATCH);
+                       if (*string == '.' && (flags & FNM_PERIOD) &&
+                           (string == stringstart ||
+                           ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                               return (FNM_NOMATCH);
+                       ++string;
+                       break;
+               case '*':
+                       c = FOLDCASE(*pattern, flags);
+                       /* Collapse multiple stars. */
+                       while (c == '*')
+                               c = FOLDCASE(*++pattern, flags);
+
+                       if (*string == '.' && (flags & FNM_PERIOD) &&
+                           (string == stringstart ||
+                           ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+                               return (FNM_NOMATCH);
+
+                       /* Optimize for pattern with * at end or before /. */
+                       if (c == EOS) {
+                               if (flags & FNM_PATHNAME)
+                                       return ((flags & FNM_LEADING_DIR) ||
+                                           strchr(string, '/') == NULL ?
+                                           0 : FNM_NOMATCH);
+                               else
+                                       return (0);
+                       } else if (c == '/' && flags & FNM_PATHNAME) {
+                               if ((string = strchr(string, '/')) == NULL)
+                                       return (FNM_NOMATCH);
+                               break;
+                       }
+
+                       /* General case, use recursion. */
+                       while ((test = FOLDCASE(*string, flags)) != EOS) {
+                               if (!fnmatch(pattern, string,
+                                            flags & ~FNM_PERIOD))
+                                       return (0);
+                               if (test == '/' && flags & FNM_PATHNAME)
+                                       break;
+                               ++string;
+                       }
+                       return (FNM_NOMATCH);
+               case '[':
+                       if (*string == EOS)
+                               return (FNM_NOMATCH);
+                       if (*string == '/' && flags & FNM_PATHNAME)
+                               return (FNM_NOMATCH);
+                       if ((pattern =
+                           rangematch(pattern, FOLDCASE(*string, flags),
+                                      flags)) == NULL)
+                               return (FNM_NOMATCH);
+                       ++string;
+                       break;
+               case '\\':
+                       if (!(flags & FNM_NOESCAPE)) {
+                               if ((c = FOLDCASE(*pattern++, flags)) == EOS) {
+                                       c = '\\';
+                                       --pattern;
+                               }
+                       }
+                       /* FALLTHROUGH */
+               default:
+                       if (c != FOLDCASE(*string++, flags))
+                               return (FNM_NOMATCH);
+                       break;
+               }
+       /* NOTREACHED */
+}
+
+static const char *
+rangematch(const char *pattern, int test, int flags)
+{
+       int negate, ok;
+       char c, c2;
+
+       CYG_ASSERT(pattern != NULL, "pattern NULL pointer!");
+
+       /*
+        * A bracket expression starting with an unquoted circumflex
+        * character produces unspecified results (IEEE 1003.2-1992,
+        * 3.13.2).  This implementation treats it like '!', for
+        * consistency with the regular expression syntax.
+        * J.T. Conklin (conklin@ngai.kaleida.com)
+        */
+       if ((negate = (*pattern == '!' || *pattern == '^')) != 0)
+               ++pattern;
+
+       for (ok = 0; (c = FOLDCASE(*pattern++, flags)) != ']';) {
+               if (c == '\\' && !(flags & FNM_NOESCAPE))
+                       c = FOLDCASE(*pattern++, flags);
+               if (c == EOS)
+                       return (NULL);
+               if (*pattern == '-'
+                   && (c2 = FOLDCASE(*(pattern+1), flags)) != EOS &&
+                       c2 != ']') {
+                       pattern += 2;
+                       if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+                               c2 = FOLDCASE(*pattern++, flags);
+                       if (c2 == EOS)
+                               return (NULL);
+                       if (c <= test && test <= c2)
+                               ok = 1;
+               } else if (c == test)
+                       ok = 1;
+       }
+       return (ok == negate ? NULL : pattern);
+}
diff --git a/packages/io/fileio/v2_0/tests/fnmatch.c b/packages/io/fileio/v2_0/tests/fnmatch.c
new file mode 100644 (file)
index 0000000..75667be
--- /dev/null
@@ -0,0 +1,152 @@
+//==========================================================================
+//
+//      fnmatch.c
+//
+//      Test fnmatch function
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2007 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           asl
+// Contributors:        asl
+// Date:                2007-01-27
+// Purpose:             Test fnmatch function.
+// Description:         //              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/io_fileio.h>
+
+#ifndef CYGPKG_FILEIO_FNMATCH
+# define NA_MSG "FNMATCH function not available"
+#endif
+
+#include <cyg/infra/testcase.h>
+
+#ifndef NA_MSG
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+
+#include <fnmatch.h>
+
+//==========================================================================
+// main
+
+int main( int argc, char **argv )
+{
+  int i;
+  cyg_bool failed = false;
+  
+  struct 
+  {
+    const int result;
+    const int flags;
+    const char * string;
+    const char * pattern;
+  } test_case[] = {
+    { 0,           0, "abc", "abc" },               /*  0 */
+    { FNM_NOMATCH, 0, "cba", "abc" },
+    { 0,           0, "abc", "a*"  },
+    { FNM_NOMATCH, 0, "abc", "b*"  },
+    { 0,           0, "abc", "[abc]*" },
+    { FNM_NOMATCH, 0, "abc", "[def]*" },
+    { FNM_NOMATCH, 0, "abc", "*[def]*" },
+    { 0,           0, "a/b", "a/b" },
+    { FNM_NOMATCH, 0, "a/b", "a/a" },
+    { FNM_NOMATCH, 0, "a/b", "b/b" },
+
+    { 0,           0,            "a b", "a\\ b"},  /* 10 */
+    { FNM_NOMATCH, FNM_NOESCAPE, "a b", "a\\ b"},
+
+    { 0,           0,            "a/b", "a*b" },
+    { 0,           0,            "a/b", "a?b" },
+    { 0,           0,            "a/b", "a[/]b" },
+    { FNM_NOMATCH, FNM_PATHNAME, "a/b", "a*b"},
+    { FNM_NOMATCH, FNM_PATHNAME, "a/b", "a?b"},
+    { FNM_NOMATCH, FNM_PATHNAME, "a/b", "a[/]b"},
+    { 0,           FNM_PATHNAME, "a/b", "a/b"},
+
+    { 0,           0,          ".abc", "?abc" },
+    { 0,           0,          ".abc", "*abc" },  /* 20 */
+    { 0,           0,          ".abc", "[.]abc" },
+    { 0,           0,          ".abc", ".abc" },
+    { FNM_NOMATCH, FNM_PERIOD, ".abc", "?abc" },
+    { FNM_NOMATCH, FNM_PERIOD, ".abc", "*abc" },
+    { 0,           FNM_PERIOD, ".abc", "[.]abc" },       
+    { 0,           FNM_PERIOD, ".abc", ".abc" },
+
+    { 0,           0,                       "/.abc", "/?abc" },
+    { 0,           0,                       "/.abc", "/*abc" },
+    { 0,           0,                       "/.abc", "/[.]abc" },
+    { 0,           0,                       "/.abc", "/.abc" },  /* 30 */
+    { FNM_NOMATCH, FNM_PERIOD|FNM_PATHNAME, "/.abc", "/?abc" },
+    { FNM_NOMATCH, FNM_PERIOD|FNM_PATHNAME, "/.abc", "/*abc" },
+    { 0,           FNM_PERIOD|FNM_PATHNAME, "/.abc", "/[.]abc" },       
+    { 0,           FNM_PERIOD|FNM_PATHNAME, "/.abc", "/.abc" }
+  };
+  
+  for (i=0; i < CYG_NELEM(test_case); i++) {
+    if (test_case[i].result != 
+        fnmatch(test_case[i].pattern,
+                test_case[i].string,
+                test_case[i].flags)) {
+      diag_printf("<INFO>: test number %d failed\n", i);
+      failed = true;
+    }
+  }
+  
+  if (failed) {
+    CYG_TEST_FAIL_FINISH("fnmatch failed");
+  } else {
+    CYG_TEST_PASS_FINISH("fnmatch passed");
+  }
+}
+
+#else 
+
+//==========================================================================
+// main
+
+int main( int argc, char **argv )
+{
+    CYG_TEST_INIT();
+
+    CYG_TEST_NA(NA_MSG);
+}
+
+#endif
+
+// -------------------------------------------------------------------------
+// EOF fnmatch.c
diff --git a/packages/io/usb/serial/slave/v2_0/ChangeLog b/packages/io/usb/serial/slave/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..ccf3798
--- /dev/null
@@ -0,0 +1,37 @@
+2008-07-12  Frank Pagliughi <fpagliughi@mindspring.com>
+
+       * Generic USB Serial package created.  
+         Some files were rearranged during the import and the Documentation
+         written Andrew Lunn.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 FSF
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/io/usb/serial/slave/v2_0/cdl/usbs_serial.cdl b/packages/io/usb/serial/slave/v2_0/cdl/usbs_serial.cdl
new file mode 100644 (file)
index 0000000..de6a8e7
--- /dev/null
@@ -0,0 +1,260 @@
+# ====================================================================
+#
+#      usbs_serial.cdl
+#
+#      USB slave-side serial package.
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not 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:           2008-06-04
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_IO_USB_SLAVE_SERIAL {
+    display     "USB slave serial support"
+    include_dir "cyg/io/usb"
+    parent      CYGPKG_IO_USB_SLAVE
+    requires    { CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS >= 1 }
+    requires    { CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS >= 1 }
+    compile     usbs_serial.c
+    implements  CYGINT_IO_USB_SLAVE_CLIENTS
+#    doc         ref/io-usb-slave-eth.html
+    
+    description "
+        The USB slave serial package supports the development of USB
+        peripherals which mimic a serial connection to the host
+        machine. Such a device creates a relatively simple upgrade to
+        USB from a legacy serial connection, especially from the
+        perspective of the host software and device drivers."
+
+    cdl_option CYGDAT_IO_USB_SLAVE_CLASS_TYPE {
+        display         "Serial USB Class"
+        flavor          data
+        default_value   { "ACM" }
+        legal_values    { "ACM" "generic" }
+        description     "
+            The USB serial module can enumerate as either a generic
+            (vendor-specific) usb device or a communications class ACM
+            device. The generic device requires a pair of Bulk
+            endpoints, while the ACM device also requires an Interrupt
+            IN endpoint.  For a Windows host, the ACM configuration is
+            required to use the standard 'usbser.sys' device driver,
+            but for a Linux host, the generic configuration works, and
+            saves the additional endpoint."
+    }
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_EP0 {
+        display       "Name of EP0 structure"
+        flavor        data               
+        default_value { "usbs_at91_ep0" }
+        description   "
+            The name of the variable that contains the endpoint 0
+            structure.  This should be set to the EP0 structure for
+            the desired USB device driver such as usbs_at91_ep0,
+            usbs_sa11x0_ep0, etc"
+    }
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_EP0_MAX_PACKET_SIZE {
+        display       "The size of EP0"
+        flavor        data
+        default_value 8
+        legal_values  { 8 16 64 } 
+        description   "
+            The size of the EP0 hardware buffer on the specific USB
+            chip used."
+    } 
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_TX_EP_NUM {
+        display       "Tx (USB IN) endpoint number"
+        flavor        data
+        default_value 1
+        description   "
+            The endpoint that should be used for the device-side
+            transmitter, which is the USB IN direction."
+    }
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP {
+        display         "The Tx (USB IN) endpoint structure"
+         flavor         data               
+         default_value  { "usbs_at91_ep1" }
+         description    "
+             The endpoint structure that corresponds to the selected
+             Tx endpoint number. This is dependent on the USBS device
+             driver selected, and could be usbs_at91_ep1,
+             usbs_sa11x0_ep1, etc"
+
+    }
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_RX_EP_NUM {
+        display         "Rx (USB OUT) endpoint number"
+        flavor          data
+        default_value   2
+        description     "
+            The endpoint that should be used for the device-side
+            receiver, which is the USB OUT direction."
+    } 
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP {
+        display         "The Rx (USB OUT) endpoint structure"
+         flavor         data               
+         default_value  { "usbs_at91_ep2" }
+         description    "
+             The endpoint structure that corresponds to the selected
+             Rx endpoint number. This is dependent on the USBS device
+             driver selected, and could be usbs_at91_ep2,
+             usbs_sa11x0_ep2, etc"
+    }
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_INTR_EP_NUM {
+        display         "Interrupt IN endpoint number"
+        flavor          data
+        default_value   3
+        active_if       { CYGDAT_IO_USB_SLAVE_CLASS_TYPE == "ACM" }
+        description     "
+            The endpoint that should be used for the ACM Interrupt IN"
+    }
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_INTR_EP {
+        display         "Interrupt IN endpoint structure"
+         flavor         data               
+         default_value  { "usbs_at91_ep3" }
+         active_if      { CYGDAT_IO_USB_SLAVE_CLASS_TYPE == "ACM" }
+         description    "
+             The endpoint structure that corresponds to the selected ACM
+             Interrupt IN endpoint."
+    }
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_VENDOR_ID {
+        display       "USB Forum Vendor ID"
+        flavor        data
+        default_value 0xFFFF
+        legal_values  1 to 0xFFFF
+        description   "
+            Each USB vendor has an Vendor ID allocated to it by the
+            USB-IF organization.  Any arbitrary value can be selected
+            for testing provided that it doesn't conflict with devices
+            on the development host, but a device should NEVER be
+            released publicly without a valid Vendor ID"
+
+    }
+    cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_PRODUCT_ID {
+        display       "USB product ID"
+        flavor        data
+        default_value 1
+        legal_values  1 to 0xFFFF
+        description   "
+            You are free to select an arbitrary 16-bit Product ID for
+            a device. The combination of Vendor ID and Product ID
+            uniquely identified a USB device."
+    }
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_MFG_STR {
+        display       "The Device Vendor's Name (Manufacturer String)"
+        flavor        data
+        default_value { "\"eCos\"" }
+        description "
+                The standard USB enumeration allows for a
+                manufacturer's name which is normally reported to the
+                user when the device is first plugged into the host."
+    }
+    cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_PRODUCT_STR {
+        display       "The Device Product Name"
+        flavor        data
+        default_value { "\"eCos USB Serial Device\"" }
+        description "
+                The standard USB enumeration allows for a product name
+                which is normally reported to the user when the device
+                is first plugged into the host."
+    }
+
+    cdl_option  CYGBLD_IO_USB_SLAVE_SERIAL_DEBUG {
+        display       "Enable debug output from the driver"
+        default_value 0
+        flavor        bool
+        description   "
+            The driver may produce debug output which can be
+            useful to work out why it is not working as expected."
+    }
+
+    cdl_component CYGPKG_IO_USB_SLAVE_SERIAL_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_IO_USB_SLAVE_SERIAL_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_IO_USB_SLAVE_SERIAL_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."
+        }
+    
+
+        cdl_component CYGBLD_IO_USB_SLAVE_SERIAL_EXAMPLES {
+            display "Build example programs"
+            no_define
+            requires    { CYGPKG_IO_FILEIO }         
+            requires    { CYGPKG_IO_SERIAL_DEVICES }         
+            description "
+                Enabling this option will cause the example programs
+                to be built using the normal test case infrastructure.
+                They are however not test cases and should not be used
+                with any automatic test farm running all the
+                tests. Hence this option is disabled by default."
+            
+             cdl_option CYGPKG_IO_USB_SLAVE_SERIAL_TESTS {
+                 display "USBS serial example/test programs"
+                 no_define
+                 flavor data
+                 calculated { "tests/usbserial_echo.c tests/usb2serial.c" }
+                 description "
+                     usbserial_echo will echo charactors received
+                     over the usb serial port back to the sender.
+                     usb2serial acts as a bridge between a USB serial
+                     slave and a real serial port. It is hard coded to use
+                     /dev/ser0."
+             }
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/io/usb/serial/slave/v2_0/doc/usbs_serial.sgml b/packages/io/usb/serial/slave/v2_0/doc/usbs_serial.sgml
new file mode 100644 (file)
index 0000000..ef8a22a
--- /dev/null
@@ -0,0 +1,391 @@
+<!-- DOCTYPE reference  PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner                         -->
+
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!--     usbs_serial.sgml                                            -->
+<!--                                                                 -->
+<!--     USB slave-side serial port package.                         -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN####                                          -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2008 FSF                                          -->
+<!-- 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                   -->
+<!-- =============================================================== -->
+<!--                                                                 -->      
+<!-- ####COPYRIGHTEND####                                            -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN####                                       -->
+<!--                                                                 -->
+<!-- Author(s):   Andrew Lunn, Frank Pagliughi                       -->
+<!-- Contact(s):  asl                                                -->
+<!-- Date:        2008/06/18                                         -->
+<!-- Version:     0.01                                               -->
+<!--                                                                 -->
+<!-- ####DESCRIPTIONEND####                                          -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="io-usb-slave-serial">
+  <!-- reference id="io-usb-slave-serial" -->
+  <title>eCos Support for USB Serial like Peripherals</title>
+  
+  <!-- {{{ Intro                          -->
+  
+  <refentry id="usbs-serial-intro">
+    <refmeta>
+      <refentrytitle>Introduction</refentrytitle>
+    </refmeta>
+    <refnamediv>
+      <refname>Introduction</refname>
+      <refpurpose>
+        eCos support for USB Serial like Peripherals
+      </refpurpose>
+    </refnamediv>
+    
+    <refsect1><title>Introduction</title>
+      <para>
+        The eCos USB-Serial package provides additional support for
+        USB peripherals that look like a serial port to the
+        host. These can follow the ACM communication device
+        specification or simpler devices which just have two bulk
+        endpoints. Microsoft Windows requires ACM mode. Linux should
+        operate with both modes, however ACM may cause problems since
+        the eCos driver does not implement all the class descriptors,
+        so generic mode is recommended.
+      </para>
+      <para>
+        The USB-Serial package is not tied to any specific
+        hardware. It requires the presence of USB hardware on the
+        target and a suitable device driver to make endpoints
+        available for this code to use.  The configuration system
+        cannot load the eCos package automatically for specific
+        targets, in the way that a USB device driver or an ethernet
+        driver can be loaded automatically. Instead, the package has
+        to be added explicitly. When using the command line tools this
+        will involve an operation like the following:
+      </para>
+      <screen width=72 format=linespecific>
+        $ ecosconfig add usbs_serial
+      </screen>
+      <para>
+        Typically, this will automatically cause the USB device driver
+        to become active. 
+      </para>
+    </refsect1>
+  </refentry>
+  
+  <!-- }}} -->
+  <!-- {{{ Config                          -->
+  
+  <refentry id="usbs-serial-config">
+    <refmeta>
+      <refentrytitle>Configuration</refentrytitle>
+    </refmeta>
+    <refnamediv>
+      <refname>Configuration</refname>
+      <refpurpose>Configuration USB Serial like Peripherals</refpurpose>
+    </refnamediv>
+    
+    <refsect1><title>Configuration</title>
+      <para>
+        The package requires a few basic configurations plus
+        optionally some additional configuration options.
+      </para>
+      <para>
+        The driver needs two or three endpoints, depending if ACM
+        communications or a more generic model is used. This is
+        configured
+        with <literal>CYGDAT_IO_USB_SLAVE_CLASS_TYPE</literal> which
+        can take the value <literal>ACM</literal>
+        or <literal>generic</literal>.
+      </para>
+      <para>
+        The <literal>CYGDAT_IO_USB_SLAVE_SERIAL_EP0</literal> must be
+        configured with the control end point of the USB
+        device. <literal>CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP</literal>
+        must be configured with the endpoint to be used for
+        transmission and  
+        <literal>CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP</literal> must be
+        configured with the end point used for reception. Associated
+        with these
+        are <literal>CYGNUM_IO_USB_SLAVE_SERIAL_RX_EP_NUM</literal>
+        and <literal>CYGNUM_IO_USB_SLAVE_SERIAL_TX_EP_NUM</literal>
+        which are the endpoint numbers and are used during enumeration
+        of the device. The TX and RX endpoints must operate in BULK
+        mode.
+      </para>
+      <para>
+        If operation mode ACM is selected a third endpoint is
+        needed. This must operate in interrupt mode and should be
+        configured
+        in <literal>CYGNUM_IO_USB_SLAVE_SERIAL_INTR_EP</literal>
+        and <literal>
+        CYGNUM_IO_USB_SLAVE_SERIAL_INTR_EP_NUM</literal>.
+      </para>
+      <para>
+        The USB serial device will make its vendor:product ID known to
+        the host. This should be configured
+        with <literal>CYGNUM_IO_USB_SLAVE_SERIAL_VENDOR_ID</literal>
+        and <literal>CYGNUM_IO_USB_SLAVE_SERIAL_PRODUCT_ID</literal>. NOTE:
+        The default configurations are not valid for products, but
+        should work for testing.
+      </para>
+      <para>
+        The USB enumeration also contains text strings to describe the
+        device. This text string can be set
+        with <literal>CYGDAT_IO_USB_SLAVE_SERIAL_PRODUCT_STR</literal>.
+      </para>
+      <para>
+        The last configuration option of interest
+        is <literal>CYGPKG_IO_USB_SLAVE_SERIAL_EXAMPLES</literal>. When
+        true example programs will be built when the eCos tests are
+        built. These are not pass/fail test like other eCos tests, but
+        examples of how the eCos USB serial class can be used.
+      </para>
+    </refsect1>
+  </refentry>
+  
+  <!-- }}} -->
+  <!-- {{{ Host Config                          -->
+  
+  <refentry id="usbs-serial-host-config">
+    <refmeta>
+      <refentrytitle>Host Configuration</refentrytitle>
+    </refmeta>
+    <refnamediv>
+      <refname>Host Configuration</refname>
+      <refpurpose>Host Configuration for USB Serial like Peripherals
+      </refpurpose>
+    </refnamediv>
+    
+    <refsect1>
+      <title>Host Configuration</title>
+      <para>
+        Configuration for two hosts are listed here, Microsoft Windows
+        and Linux. It should also be possible to use the eCos USB
+        serial like peripheral driver with other hosts.
+      </para>
+      <refsect2><title>Linux</title>
+        <para>
+          The eCos USB serial like peripheral driver can be used in
+          Linux in one of two ways.
+          <itemizedlist>
+            <listitem>
+              <para>
+                Using the generic usbserial kernel module passing the
+                vendor and product ID as module parameters. e.g.
+              </para>
+              <programlisting width=72>
+                modprobe usbserial vendor=0xabcd product=0x1234
+              </programlisting>
+              <para>
+                would load the kernel module so that it would use a
+                USB device abcd:1234 as a serial device.
+              </para>
+            </listitem>
+            <listitem>
+              <para>
+                Using the mini driver provided with eCos in the
+                <filename class=directory>host/linux</filename>
+                directory. This driver must be edited and the correct
+                vendor and product ID set to match the vendor and
+                product ID used by the device. Once compiled this
+                driver can be loaded with:
+              </para>
+              <programlisting width=72>
+                modprobe usbserial
+                modprobe ecos_usbserial
+              </programlisting>
+              <para>
+                This driver is known to compile with kernel versions
+                2.6.18 and probably works fine with other
+                kernels. However it fails to compile with kernels
+                after 2.6.25.
+              </para>
+            </listitem>
+          </itemizedlist>
+          Both of these methods will result in the Linux Kernel making
+          a new serial device available. This is typically
+          named <filename>/dev/ttyUSB0</filename>.
+        </para>
+      </refsect2>
+      <refsect2><title>Microsoft Windows</title>
+        <para>
+          To install the device in a Microsoft Windows system make use
+          of the INF file
+          in <filename>host/windows/eCosUsbSerial.inf</filename>. Copy
+          this INF file and <filename>usbser.sys</filename> from your
+          version of Windows into an empty directory. Then plug in the
+          USB device. When prompted to load a driver navigate to the
+          INF file and select it.
+        </para>
+      </refsect2>
+    </refsect1>
+    
+  </refentry>
+  
+  <!-- }}} -->
+  <!-- {{{ Using                         -->
+  <refentry id="usbs-serial-using">
+    <refmeta>
+      <refentrytitle>API Function</refentrytitle>
+    </refmeta>
+    <refnamediv>
+      <refname>usbs_serial_start</refname>
+      <refname>usbs_serial_init</refname>
+      <refname>usbs_serial_start</refname>
+      <refname>usbs_serial_wait_until_configured</refname>
+      <refname>usbs_serial_is_configured</refname>
+      <refname>usbs_serial_start_tx</refname>
+      <refname>usbs_serial_wait_for_tx</refname>
+      <refname>usbs_serial_tx</refname>
+      <refname>usbs_serial_start_rx</refname>
+      <refname>usbs_serial_wait_for_rx</refname>
+      <refname>usbs_serial_rx</refname>
+      <refname>usbs_serial_state_change_handler</refname>
+      <refpurpose>
+        eCos USB Serial like Peripherals API
+      </refpurpose>
+    </refnamediv>
+    
+    <refsynopsisdiv>
+      <funcsynopsis>
+        <funcsynopsisinfo>
+#include &lt;cyg/io/usb/usbs_serial.h&gt;
+        </funcsynopsisinfo>
+        <funcprototype>
+          <funcdef>void 
+            <function>usbs_serial_start</function>
+          </funcdef>
+          <paramdef>void</paramdef>
+        </funcprototype>
+        <funcprototype>
+          <funcdef>void 
+            <function>usbs_serial_init</function>
+          </funcdef>
+          <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+          <paramdef>usbs_tx_endpoint * <parameter>tx_ep</parameter></paramdef>
+          <paramdef>usbs_rx_endpoint * <parameter>rx_ep</parameter></paramdef>
+        </funcprototype>
+        <funcprototype>
+          <funcdef>void 
+            <function>usbs_serial_wait_until_configured</function>
+          </funcdef>
+          <paramdef>void></paramdef>
+        </funcprototype>
+        <funcprototype>
+          <funcdef>cyg_bool
+            <function>usbs_serial_is_configured</function>
+          </funcdef>
+          <paramdef>void</paramdef>
+        </funcprototype>
+        <funcprototype>
+          <funcdef>void 
+            <function>usbs_serial_start_tx</function>
+          </funcdef>
+          <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+          <paramdef>const void *<parameter>buf</parameter></paramdef>
+          <paramdef>int * <parameter>n</parameter></paramdef>
+        </funcprototype>
+        <funcprototype>
+          <funcdef>int 
+            <function>usbs_serial_wait_for_tx</function>
+          </funcdef>
+          <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+        </funcprototype>
+        <funcprototype>
+          <funcdef>void 
+            <function>usbs_serial_start_rx</function>
+          </funcdef>
+          <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+          <paramdef>const void *<parameter>buf</parameter></paramdef>
+          <paramdef>int * <parameter>n</parameter></paramdef>
+        </funcprototype>
+        <funcprototype>
+          <funcdef>int 
+            <function>usbs_serial_wait_for_rx</function>
+          </funcdef>
+          <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+        </funcprototype>
+        <funcprototype>
+          <funcdef>int 
+            <function>usbs_serial_rx</function>
+          </funcdef>
+          <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+          <paramdef>const void *<parameter>buf</parameter></paramdef>
+          <paramdef>int * <parameter>n</parameter></paramdef>
+        </funcprototype>
+        <funcprototype>
+          <funcdef>void 
+            <function>usbs_serial_state_change_handler</function>
+          </funcdef>
+          <paramdef>usbs_control_endpoint * <parameter>ep</parameter></paramdef>
+          <paramdef>void * <parameter>data</parameter></paramdef>
+          <paramdef>usbs_state_change <parameter>change</parameter></paramdef>
+          <paramdef>int <parameter>prev_state</parameter></paramdef>
+        </funcprototype>
+      </funcsynopsis>
+    </refsynopsisdiv>
+    
+    <refsect1 id="usbs-serial-api-description">
+      <title>Description</title>
+      <para>
+        For examples of how to use this API see the
+        files <filename>.../tests/usbserial_echo.c</filename>
+        and <filename>.../tests/usb2serial.c</filename>
+      </para>
+      
+      <para>
+        The first function that needs calling
+        is <function>usbs_serial_start()</function>. This will initialise
+        the eCos USB slave layer, creating all the enumeration data and
+        then let the host know that the device exists.
+      </para>
+      <para>
+        Once the USB subsystem has been started it is necessary to wait
+        for the host to configure the device using the
+        function <function>usbs_serial_wait_until_configured()</function>. The
+        host will assign the device an ID and then load the appropriate
+        device driver in the host in order to make use the device.
+      </para>
+      <para>
+        Once the device is configured it is then possible to make use of
+        it, i.e. send and receive data. This transfer of data can be
+        accomplished either asynchronously or synchronously. It is also
+        possible to mix asynchronously and synchronously between
+        receiving and sending data.
+      </para>
+      <para>
+        To perform asynchronous operations the
+        functions <function>usbs_serial_start_rx()</function>
+        and <function>usbs_serial_start_tx()</function> is used to
+        start the operation. These functions start the necessary
+        actions and then return immediately. At a later time the
+        functions <function>usbs_serial_wait_for_tx()</function>
+        or <function>usbs_serial_wait_for_rx()</function> should be
+        called. These will, if necessary, block and then return the
+        status and any data for the previously started asynchronous
+        call.
+      </para>
+      <para>
+        To perform synchronous operations the
+        functions <function>usbs_serial_rx()</function>
+        and <function>usbs_serial_tx()</function> are used. These
+        functions will block until the requested action is complete.
+      </para>
+    </refsect1>
+  </refentry>    
+  <!-- }}} -->
+</part>
+<!-- /reference -->
diff --git a/packages/io/usb/serial/slave/v2_0/host/linux/.cvsignore b/packages/io/usb/serial/slave/v2_0/host/linux/.cvsignore
new file mode 100644 (file)
index 0000000..88c404a
--- /dev/null
@@ -0,0 +1,3 @@
+.ecos_usbserial.o.d
+.tmp_versions
+*.ko
\ No newline at end of file
diff --git a/packages/io/usb/serial/slave/v2_0/host/linux/Makefile b/packages/io/usb/serial/slave/v2_0/host/linux/Makefile
new file mode 100644 (file)
index 0000000..e3f4d0b
--- /dev/null
@@ -0,0 +1,11 @@
+# Makefile for ecos_usbserial Linux kernel module
+
+ifneq ($(KERNELRELEASE),)
+       obj-m := ecos_usbserial.o
+else
+       KDIR ?= /lib/modules/$(shell uname -r)/build
+       PWD := $(shell pwd)
+default:
+       $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+endif
+
diff --git a/packages/io/usb/serial/slave/v2_0/host/linux/ecos_usbserial.c b/packages/io/usb/serial/slave/v2_0/host/linux/ecos_usbserial.c
new file mode 100644 (file)
index 0000000..1170897
--- /dev/null
@@ -0,0 +1,111 @@
+//==========================================================================
+//
+//      ecos_usbserial.c
+//
+//      Kernel driver for the eCos USB serial driver
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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:         2008-06-02
+// Description:  Kernel driver for the eCos USB serial driver
+//
+//####DESCRIPTIONEND####
+//===========================================================================
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+#define VENDOR_ID      0xFFFF
+#define PRODUCT_ID     1
+
+static struct usb_device_id id_table[] = {
+       { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
+       { }
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver ecos_usbserial_driver = {
+       .name           = "ecos_usbserial",
+       .probe          = usb_serial_probe,
+       .disconnect     = usb_serial_disconnect,
+       .id_table       = id_table
+};
+
+static struct usb_serial_driver ecos_usbserial_device = {
+       .driver = {
+               .owner                  = THIS_MODULE,
+               .name                   = "ecos_usbserial",
+       },
+       .id_table                       = id_table, 
+       .num_interrupt_in       = NUM_DONT_CARE,
+       .num_bulk_in            = NUM_DONT_CARE,
+       .num_bulk_out           = NUM_DONT_CARE,
+       .num_ports                      = 1
+};
+
+static int __init ecos_usbserial_init(void)
+{
+       int retval;
+
+       retval = usb_serial_register(&ecos_usbserial_device);
+       if (retval)
+               return retval;
+
+       retval = usb_register(&ecos_usbserial_driver);
+       if (retval) {
+               usb_serial_deregister(&ecos_usbserial_device);
+               return retval;
+       }
+
+       return 0;
+}
+
+static void __exit ecos_usbserial_exit(void)
+{
+       usb_deregister(&ecos_usbserial_driver);
+       usb_serial_deregister(&ecos_usbserial_device);
+}
+
+module_init(ecos_usbserial_init);
+module_exit(ecos_usbserial_exit);
+
+MODULE_LICENSE("GPL");
+
diff --git a/packages/io/usb/serial/slave/v2_0/host/windows/eCosUsbSerial.inf b/packages/io/usb/serial/slave/v2_0/host/windows/eCosUsbSerial.inf
new file mode 100644 (file)
index 0000000..f96e116
--- /dev/null
@@ -0,0 +1,49 @@
+; eCos USB Serial INF file for Windows
+; This can be used for any USB device that emulates a serial port connection.
+; Simply set the VID & PID numbers in this file to the proper values for the
+; device, copy this file and the 'usbser.sys' file from your version of Windows
+; into the same directory, and load these when prompted by the Windows device
+; manager.
+
+[Version]
+Signature="$Windows NT$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=eCosUsbSerial
+DriverVer=06/02/2008,0.0.0.1
+
+[DestinationDirs]
+DefaultDestDir=12      ; %windir$\System32\drivers
+
+[Manufacturer]
+eCosUsbSerial=eCosDevices
+
+[eCosDevices]
+"eCosUsbSerial"=InstalleCosUsbSerial,USB\VID_FFFF&PID_0001
+
+[InstalleCosUsbSerial]
+CopyFiles=CopyeCosUsbFiles
+AddReg=eCosUsbReg
+
+[CopyeCosUsbFiles]
+usbser.sys                     ; The standard Windows USB serial driver
+
+[eCosUsbReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[InstalleCosUsbSerial.Services]
+AddService = usbser,2,eCosUsbSerialService
+
+[eCosUsbSerialService]
+DisplayName = ECOS_USB_SERIAL_NAME
+ServiceType = 1                                ; driver
+StartType = 3                          ; on-demand or manual
+ErrorControl = 1                       ; report errors
+ServiceBinary = %12%\usbser.sys                ; Driver path: %windir%\System32\drivers
+LoadOrderGroup = Base
+
+[Strings]
+ECOS_USB_SERIAL_NAME = "eCos USB Serial Driver"
+
diff --git a/packages/io/usb/serial/slave/v2_0/include/usbs_serial.h b/packages/io/usb/serial/slave/v2_0/include/usbs_serial.h
new file mode 100644 (file)
index 0000000..9e7f84c
--- /dev/null
@@ -0,0 +1,184 @@
+#ifndef CYGONCE_USBS_SERIAL_H
+#define CYGONCE_USBS_SERIAL_H
+//==========================================================================
+//
+//      include/usbs_serial.h
+//
+//      Description of the USB slave-side serial device support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+// Contributors: 
+// Date:         2008-06-02
+// Purpose:
+// Description:  USB slave-side serial support
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    
+//
+// The primary purpose of the USB slave-side serial code is to provide a 
+// simple USB connection to the host, especially for embedded systems that
+// are upgrading from RS-232 serial connections. The host would see the 
+// device as if through a serial port, and thus the host software would
+// remain unchanged. It would also eliminate the need for a new device
+// driver on the host.
+// 
+// On this side (the eCos USB slave side), the application sees the host
+// through a normal USB slave connection with two Bulk endpoints - one in 
+// the IN direction and one in the OUT direction. This module provides the
+// necessary USB descriptors to enumerate the device for a single serial
+// port, but then the application is free to communicate with the host
+// using any desired API:
+//  - The standard eCos USB slave API
+//  - The low-level File I/O layer (if USB devtab entries configured)
+//  - The C stdio functions (again, if USB devtab entries configured)
+//  - The USB serial API defined here.
+// 
+// The USB serial API is a thin layer over the standard eCos USB functions
+// to provide common synchronous and asynchronous transfers over the assigned
+// Bulk endpoints.
+//
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/io/usb/usbs.h>
+
+// ----------------------------------------------------------------------------
+// The ACM class requests
+// 
+
+#define USBS_SERIAL_SEND_ENCAPSULATED_COMMAND   0x00
+#define USBS_SERIAL_GET_ENCAPSULATED_RESPONSE   0x01
+#define USBS_SERIAL_SET_COMM_FEATURE            0x02
+#define USBS_SERIAL_GET_COMM_FEATURE            0x03
+#define USBS_SERIAL_CLEAR_COMM_FEATURE          0x04
+
+#define USBS_SERIAL_SET_LINE_CODING             0x20
+#define USBS_SERIAL_GET_LINE_CODING             0x21
+#define USBS_SERIAL_SET_CONTROL_LINE_STATE      0x22
+#define USBS_SERIAL_SEND_BREAK                  0x23
+
+// ----------------------------------------------------------------------------
+// Data structure to manage the pair of USB endpoints that comprise a single
+// serial port connection. Each "port" requires one Bulk IN endpoint and one
+// Bulk OUT endpoint.
+
+typedef struct usbs_serial {
+    // The communication endpoints. For the first (default) channel, these
+    // are normally set by the configuration, but can be changed by the
+    // application, if desired.
+    usbs_tx_endpoint*   tx_ep;
+    usbs_rx_endpoint*   rx_ep;
+
+    // The signal that a transmit operation is complete, and it's result.
+    cyg_sem_t   tx_ready;
+    int         tx_result;
+
+    // The signal that a receive operation is complete, and it's result.
+    cyg_sem_t   rx_ready;
+    int         rx_result;
+
+} usbs_serial;
+
+// The package contains one USB serial device.
+extern usbs_serial usbs_ser0;
+
+// It's assumed that there's a single USB slave chip in the system, with a
+// single control endpoint 0. The actual variable is contained in the device
+// driver, but the USB serial code keeps a pointer to it for driver 
+// independence. The application might find it useful for overriding low-level
+// code or callbacks.
+extern usbs_control_endpoint* usbs_serial_ep0;
+
+// ----------------------------------------------------------------------------
+// A C interface to the serial USB code.
+// The application can use this interface, the standard (low-level) USB slave
+// API, the standard Unix-like I/O API, or C stdio API.
+    
+// Initialize support for a particular USB serial "port"
+// This associates a usbs_serial structure with specific endpoints and 
+// initializes the structure for communications.
+void usbs_serial_init(usbs_serial*, usbs_tx_endpoint*, usbs_rx_endpoint*);
+
+// Block the calling thread until the host configures the USB device.
+void usbs_serial_wait_until_configured(void);
+
+// Determines if the USB subsystem is configured
+cyg_bool usbs_serial_is_configured(void);
+
+// Start an asynchronous transmit of a single buffer.
+void usbs_serial_start_tx(usbs_serial*, const void* buf, int n);
+
+// Block the calling thread until the transmit completes.
+// Returns the result code for the transfer
+int usbs_serial_wait_for_tx(usbs_serial*);
+
+// Blocking, synchronous transmit of a single buffer.
+int usbs_serial_tx(usbs_serial*, const void* buf, int n);
+
+// Start an asynchronous receive of a buffer.
+void usbs_serial_start_rx(usbs_serial*, void* buf, int n);
+
+// Block the calling thread until the receive completes.
+// Returns the result code for the transfer
+int usbs_serial_wait_for_rx(usbs_serial*);
+
+// Blocking, synchronous receive of a single buffer.
+int usbs_serial_rx(usbs_serial*, void* buf, int n);
+
+// The default USB-serial state change handler paces the functions
+// usbs_serial_wait_until_configured() and usbs_serial_is_configured().
+// The application can override the state chain handler, but chain to 
+// this function to keep the full USB-serial system working.
+void usbs_serial_state_change_handler(usbs_control_endpoint*, void*, 
+                                      usbs_state_change, int);
+
+// Starts the USB subsystem
+void usbs_serial_start(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // CYGONCE_USBS_SERIAL_H
+
diff --git a/packages/io/usb/serial/slave/v2_0/src/usbs_serial.c b/packages/io/usb/serial/slave/v2_0/src/usbs_serial.c
new file mode 100644 (file)
index 0000000..52b464d
--- /dev/null
@@ -0,0 +1,545 @@
+//==========================================================================
+//
+//      usbs_serial.c
+//
+//      Support for slave-side USB serial devices.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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.
+// Date:         2008-06-02
+//
+//####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 <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/kernel/kapi.h>
+
+#include <pkgconf/io_usb_slave_serial.h>
+#include <cyg/io/usb/usbs_serial.h>
+#include <string.h>
+
+#if defined(CYGBLD_IO_USB_SLAVE_SERIAL_DEBUG)
+#define DBG diag_printf
+#else
+#define DBG (1) ? (void)0 : diag_printf
+#endif
+
+#define EP0_MAX_PACKET_SIZE     CYGNUM_IO_USB_SLAVE_SERIAL_EP0_MAX_PACKET_SIZE
+
+extern usbs_control_endpoint    CYGDAT_IO_USB_SLAVE_SERIAL_EP0;
+extern usbs_tx_endpoint         CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP;
+extern usbs_rx_endpoint         CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP;
+
+#define TX_EP_NUM               CYGNUM_IO_USB_SLAVE_SERIAL_TX_EP_NUM
+#define RX_EP_NUM               CYGNUM_IO_USB_SLAVE_SERIAL_RX_EP_NUM
+#define INTR_EP_NUM             CYGNUM_IO_USB_SLAVE_SERIAL_INTR_EP_NUM
+#define EP0                     (&CYGDAT_IO_USB_SLAVE_SERIAL_EP0)
+#define TX_EP                   (&CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP)
+#define RX_EP                   (&CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP)
+#define INTR_EP                 (&CYGDAT_IO_USB_SLAVE_SERIAL_INTR_EP)
+
+
+#define VENDOR_ID               CYGNUM_IO_USB_SLAVE_SERIAL_VENDOR_ID
+#define PRODUCT_ID              CYGNUM_IO_USB_SLAVE_SERIAL_PRODUCT_ID
+
+#define USB_MAX_STR_LEN         256
+
+#define LO_BYTE_16(word16)      ((cyg_uint8) ((word16) & 0xFF))
+#define HI_BYTE_16(word16)      ((cyg_uint8) (((word16) >> 8) & 0xFF))
+
+#define BYTE0_32(word32)        ((cyg_uint8) ((word32) & 0xFF))
+#define BYTE1_32(word32)        ((cyg_uint8) (((word32) >>  8) & 0xFF))
+#define BYTE2_32(word32)        ((cyg_uint8) (((word32) >> 16) & 0xFF))
+#define BYTE3_32(word32)        ((cyg_uint8) (((word32) >> 24) & 0xFF))
+
+
+#define MFG_STR_INDEX           '\x01'
+#define PRODUCT_STR_INDEX       '\x02'
+
+#define USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH(interfaces, endpoints) \
+            (USB_CONFIGURATION_DESCRIPTOR_LENGTH +            \
+            ((interfaces) * USB_INTERFACE_DESCRIPTOR_LENGTH) +  \
+            ((endpoints)  * USB_ENDPOINT_DESCRIPTOR_LENGTH))
+
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+    #define USBS_SERIAL_DEVICE_CLASS        2
+    #define USBS_SERIAL_NUM_IFACE           2
+    #define USBS_SERIAL_NUM_ENDP            3
+    #define USBS_SERIAL_DATA_IFACE_CLASS    0x0A    // Data
+#else
+    #define USBS_SERIAL_DEVICE_CLASS        0
+    #define USBS_SERIAL_NUM_IFACE           1
+    #define USBS_SERIAL_NUM_ENDP            2
+    #define USBS_SERIAL_DATA_IFACE_CLASS    0xFF    // Vendor
+#endif
+
+// ----- Configuration Descriptor -----
+
+static const usb_configuration_descriptor usb_configuration = {
+    length:             sizeof(usb_configuration_descriptor),
+    type:               USB_CONFIGURATION_DESCRIPTOR_TYPE,
+    total_length_lo:    
+        USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_LO(USBS_SERIAL_NUM_IFACE, 
+                                                     USBS_SERIAL_NUM_ENDP),
+    total_length_hi:    
+        USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_HI(USBS_SERIAL_NUM_IFACE, 
+                                                     USBS_SERIAL_NUM_ENDP),
+    number_interfaces:  USBS_SERIAL_NUM_IFACE,
+    configuration_id:   1,
+    configuration_str:  0,
+    attributes:         (USB_CONFIGURATION_DESCRIPTOR_ATTR_REQUIRED |
+                         USB_CONFIGURATION_DESCRIPTOR_ATTR_SELF_POWERED),
+    max_power:          50
+};
+
+// ----- Interface Descriptor -----
+
+static const usb_interface_descriptor usb_interface[] = {
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+    {
+        length:             sizeof(usb_interface_descriptor),
+        type:               USB_INTERFACE_DESCRIPTOR_TYPE,
+        interface_id:       0,
+        alternate_setting:  0,
+        number_endpoints:   1,
+        interface_class:    0x02,   // Comm class
+        interface_subclass: 0x02,
+        interface_protocol: 0x01,
+        interface_str:      0x00
+    },
+    {
+        length:             sizeof(usb_interface_descriptor),
+        type:               USB_INTERFACE_DESCRIPTOR_TYPE,
+        interface_id:       1,
+        alternate_setting:  0,
+        number_endpoints:   2,
+        interface_class:    USBS_SERIAL_DATA_IFACE_CLASS,
+        interface_subclass: 0x00,
+        interface_protocol: 0x00,
+        interface_str:      0x00
+    }
+#else
+    {
+        length:             sizeof(usb_interface_descriptor),
+        type:               USB_INTERFACE_DESCRIPTOR_TYPE,
+        interface_id:       0,
+        alternate_setting:  0,
+        number_endpoints:   2,
+        interface_class:    USBS_SERIAL_DATA_IFACE_CLASS,
+        interface_subclass: 0x00,
+        interface_protocol: 0x00,
+        interface_str:      0x00
+    }
+#endif
+};
+
+// ----- Endpoint Descriptors -----
+
+static const usb_endpoint_descriptor usb_endpoints[] =
+{ 
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+    // Interrupt in endpoint
+    {
+        sizeof(usb_endpoint_descriptor),
+        USB_ENDPOINT_DESCRIPTOR_TYPE,
+        USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN | INTR_EP_NUM,
+        USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
+        0x40,
+        0,
+        255
+    },
+#endif
+
+    // Tx (Bulk IN) Endpoint Descriptor
+    {
+        sizeof(usb_endpoint_descriptor),
+        USB_ENDPOINT_DESCRIPTOR_TYPE,
+        USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN | TX_EP_NUM,
+        USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+        0x40,
+        0,
+        0
+    },
+
+    // Rx (Bulk OUT) Endpoint Descriptor
+    {
+        sizeof(usb_endpoint_descriptor),
+        USB_ENDPOINT_DESCRIPTOR_TYPE,
+        USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT | RX_EP_NUM,
+        USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+        0x40,
+        0,
+        0
+    }
+};
+
+// ----- String Descriptors -----
+
+static char mfg_str_descr[USB_MAX_STR_LEN],
+            product_str_descr[USB_MAX_STR_LEN];
+
+
+static const char* usb_strings[] = {
+    "\x04\x03\x09\x04",
+    mfg_str_descr,
+    product_str_descr
+};
+
+// ----- Enumeration Data w/ Device Descriptor -----
+
+static usbs_enumeration_data usb_enum_data = {
+    {
+        length:                 sizeof(usb_device_descriptor),
+        type:                   USB_DEVICE_DESCRIPTOR_TYPE,
+        usb_spec_lo:            0x00, 
+        usb_spec_hi:            0x02,
+        device_class:           USBS_SERIAL_DEVICE_CLASS,
+        device_subclass:        0,
+        device_protocol:        0,
+        max_packet_size:        EP0_MAX_PACKET_SIZE,
+        vendor_lo:              LO_BYTE_16(VENDOR_ID),
+        vendor_hi:              HI_BYTE_16(VENDOR_ID),
+        product_lo:             LO_BYTE_16(PRODUCT_ID),
+        product_hi:             HI_BYTE_16(PRODUCT_ID),
+        device_lo:              0x00,
+        device_hi:              0x00,
+        manufacturer_str:       MFG_STR_INDEX,
+        product_str:            PRODUCT_STR_INDEX,
+        serial_number_str:      0,
+        number_configurations:  1
+    },
+
+    total_number_interfaces:    USBS_SERIAL_NUM_IFACE,
+    total_number_endpoints:     USBS_SERIAL_NUM_ENDP,
+    total_number_strings:       3,
+    configurations:             &usb_configuration,
+    interfaces:                 usb_interface,
+    endpoints:                  usb_endpoints,
+    strings:                    (const unsigned char **) usb_strings
+};
+
+// --------------------------------------------------------------------------
+// USBS Serial Data
+// --------------------------------------------------------------------------
+
+usbs_control_endpoint* usbs_serial_ep0 = EP0;
+
+// Lock for the state.
+cyg_mutex_t usbs_serial_lock;   
+
+// Condition variable for state changes
+cyg_cond_t  usbs_serial_state_cond;
+
+int usbs_serial_state;
+
+usbs_serial usbs_ser0 = {
+    tx_ep:      TX_EP,
+    rx_ep:      RX_EP,
+    tx_result:  0,    
+    rx_result:  0,    
+};
+
+static void (*usbs_serial_app_state_change_fn)(struct usbs_control_endpoint*, 
+                                               void*, usbs_state_change, int) 
+= 0;
+
+// --------------------------------------------------------------------------
+// Create a USB String Descriptor from a C string.
+
+void
+usbs_serial_create_str_descriptor(char descr[], const char *str)
+{
+    int i, n = strlen(str);
+
+    if (n > (USB_MAX_STR_LEN/2 - 2))
+        n = USB_MAX_STR_LEN/2 - 2;
+
+    descr[0] = (cyg_uint8) (2*n + 2);
+    descr[1] = USB_DEVREQ_DESCRIPTOR_TYPE_STRING;
+
+    for (i=0; i<n; i++) {
+        descr[i*2+2] = str[i];
+        descr[i*2+3] = '\x00';
+    }
+}
+
+// --------------------------------------------------------------------------
+// ACM Class Handler
+//
+// For a Windows host, the device must, at least, respond to a SetLineCoding
+// request (0x20), otherwise Windows will report that it's unable to open the 
+// port. This request normally sets the standard serial parameters:
+//          baud rate, # stop bits, parity, and # data bits
+// If we're just making believe that we're a serial port to communicate with
+// the host via USB, then these values don't matter. So we ACK the request,
+// but ignore the parameters.
+// If we were actually creating a USB-serial converter, then we would need to
+// read these values and configure the serial port accordingly.
+// 
+// Similarly, the host can request the current settings through a 
+// GetLineCoding request (0x21). Since we're just faking it, we return some
+// arbitrary values: 38400,1,N,8
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+static usbs_control_return 
+usbs_serial_acm_class_handler(usbs_control_endpoint* ep0, void* data)
+{
+  usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+  usb_devreq      *req = (usb_devreq *) ep0->control_buffer;
+  static cyg_uint8 rsp_buf[32];
+  cyg_uint32 baud = 38400;  // Arbitrary, fake value to return to the host.
+
+  DBG("USB Serial ACM Class Handler: ");
+  
+  switch (req->request) {
+    
+    case USBS_SERIAL_SET_LINE_CODING :
+      DBG("ACM Request: Set Line Coding\n");
+      result = USBS_CONTROL_RETURN_HANDLED;
+      break;
+      
+    case USBS_SERIAL_GET_LINE_CODING :
+      DBG("ACM Request: Get Line Coding\n");
+      rsp_buf[0] = BYTE0_32(baud);
+      rsp_buf[1] = BYTE1_32(baud);
+      rsp_buf[2] = BYTE2_32(baud);
+      rsp_buf[3] = BYTE3_32(baud);
+      rsp_buf[4] = 0; // One stop bit
+      rsp_buf[5] = 0; // No parity
+      rsp_buf[6] = 8; // 8 data bits
+      ep0->buffer = rsp_buf;
+      ep0->buffer_size = 7;
+      result = USBS_CONTROL_RETURN_HANDLED;
+      break;
+      
+    default :
+      DBG("*** Unhandled ACM Request: 0x%02X ***\n",
+          (unsigned) req->request);
+  }
+  
+  return result;
+}
+#endif      // CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+// --------------------------------------------------------------------------
+// Callback for a USB state change
+
+void
+usbs_serial_state_change_handler(usbs_control_endpoint* ep, void* data,
+                                 usbs_state_change change, int prev_state)
+{
+#if defined(CYGBLD_IO_USB_SLAVE_SERIAL_DEBUG)
+  const char *STATE_CHG_STR[] = { "Detached", "Attached", "Powered", "Reset",
+                                  "Addressed", "Configured", "Deconfigured",
+                                  "Suspended", "Resumed" };
+  
+  if (change > 0) {
+    DBG("### %d:%s ###\n", change, STATE_CHG_STR[(int) change-1]);
+  }
+#endif
+  
+  // Called from DSR, cond broadcast should be ok without mutex lock
+  usbs_serial_state = usbs_serial_ep0->state;
+  cyg_cond_broadcast(&usbs_serial_state_cond);
+  
+  if (usbs_serial_app_state_change_fn)
+    (*usbs_serial_app_state_change_fn)(ep, data, change, prev_state);
+}
+
+// --------------------------------------------------------------------------
+// Block the calling thread until the USB is configured.
+void
+usbs_serial_wait_until_configured(void)
+{
+  cyg_mutex_lock(&usbs_serial_lock);
+  while (usbs_serial_state != USBS_STATE_CONFIGURED)
+    cyg_cond_wait(&usbs_serial_state_cond);
+  cyg_mutex_unlock(&usbs_serial_lock);
+}
+
+// --------------------------------------------------------------------------
+// Determine if the device is currently configured.
+
+cyg_bool
+usbs_serial_is_configured(void)
+{
+  return usbs_serial_state == USBS_STATE_CONFIGURED;
+}
+
+// --------------------------------------------------------------------------
+// Callback for when a transmit is complete
+
+static void 
+usbs_serial_tx_complete(void *p, int result)
+{
+  usbs_serial* ser = (usbs_serial*) p;
+  ser->tx_result = result;
+  cyg_semaphore_post(&ser->tx_ready);
+}
+
+// --------------------------------------------------------------------------
+// Callback for when a receive is complete
+
+static void 
+usbs_serial_rx_complete(void *p, int result)
+{
+  usbs_serial* ser = (usbs_serial*) p;
+  ser->rx_result = result;
+  cyg_semaphore_post(&ser->rx_ready);
+}
+
+// --------------------------------------------------------------------------
+// Start an asynchronous transmit of a buffer.
+// 
+void
+usbs_serial_start_tx(usbs_serial* ser, const void* buf, int n)
+{
+  usbs_start_tx_buffer(ser->tx_ep, (unsigned char*) buf, n,
+                       usbs_serial_tx_complete, ser);
+}
+
+// --------------------------------------------------------------------------
+// Block the caller until the transmit is complete
+
+int
+usbs_serial_wait_for_tx(usbs_serial* ser)
+{
+  cyg_semaphore_wait(&ser->tx_ready);
+  return ser->tx_result;
+}
+
+// --------------------------------------------------------------------------
+// Perform a synchronous transmit and wait for it to complete.
+
+int
+usbs_serial_tx(usbs_serial* ser, const void* buf, int n)
+{
+  usbs_serial_start_tx(ser, buf, n);
+  return usbs_serial_wait_for_tx(ser);
+}
+
+// --------------------------------------------------------------------------
+// Start an asynchronous receive of a buffer.
+
+void
+usbs_serial_start_rx(usbs_serial* ser, void* buf, int n)
+{
+  usbs_start_rx_buffer(ser->rx_ep, (unsigned char*) buf, n,
+                       usbs_serial_rx_complete, ser);
+}
+
+// --------------------------------------------------------------------------
+// Block the caller until the receive is complete
+
+int
+usbs_serial_wait_for_rx(usbs_serial* ser)
+{
+  cyg_semaphore_wait(&ser->rx_ready);
+  return ser->rx_result;
+}
+
+// --------------------------------------------------------------------------
+// Perform a synchronous receive and wait for it to complete.
+
+int
+usbs_serial_rx(usbs_serial* ser, void* buf, int n)
+{
+  usbs_serial_start_rx(ser, buf, n);
+  return usbs_serial_wait_for_rx(ser);
+}
+
+// --------------------------------------------------------------------------
+// Initialize a serial port structure.
+
+void
+usbs_serial_init(usbs_serial* ser, usbs_tx_endpoint* tx_ep, 
+                 usbs_rx_endpoint* rx_ep)
+{
+  ser->tx_ep = tx_ep;
+  ser->rx_ep = rx_ep;
+  
+  cyg_semaphore_init(&ser->tx_ready, 0);
+  cyg_semaphore_init(&ser->rx_ready, 0);
+}
+
+// --------------------------------------------------------------------------
+// Start the USB subsystem
+
+void
+usbs_serial_start(void)
+{
+  usbs_serial_init(&usbs_ser0, TX_EP, RX_EP);
+  
+  cyg_mutex_init(&usbs_serial_lock);
+  cyg_cond_init(&usbs_serial_state_cond, &usbs_serial_lock);
+  
+  // Make the mfg & product names into USB string descriptors
+  
+  usbs_serial_create_str_descriptor(mfg_str_descr, 
+                                    CYGDAT_IO_USB_SLAVE_SERIAL_MFG_STR);
+  usbs_serial_create_str_descriptor(product_str_descr, 
+                                    CYGDAT_IO_USB_SLAVE_SERIAL_PRODUCT_STR);
+  
+  // ----- Set up enumeration & USB callbacks -----
+  
+  usbs_serial_state = usbs_serial_ep0->state;
+  
+  usbs_serial_ep0->enumeration_data   = &usb_enum_data;
+  
+  if (usbs_serial_ep0->state_change_fn)
+    usbs_serial_app_state_change_fn = usbs_serial_ep0->state_change_fn;
+  
+  usbs_serial_ep0->state_change_fn = usbs_serial_state_change_handler;
+  
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+  if (!usbs_serial_ep0->class_control_fn)
+    usbs_serial_ep0->class_control_fn = usbs_serial_acm_class_handler;
+#endif
+  
+  // ----- Start USB subsystem -----
+  
+  usbs_start(usbs_serial_ep0);
+}
diff --git a/packages/io/usb/serial/slave/v2_0/tests/usb2serial.c b/packages/io/usb/serial/slave/v2_0/tests/usb2serial.c
new file mode 100644 (file)
index 0000000..78f2f22
--- /dev/null
@@ -0,0 +1,358 @@
+//==========================================================================
+//
+//      usb2serial.c
+//
+//      Example application for the USB serial layer in eCos.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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:         2008-06-02
+// Description:  USB serial example application.
+//
+//####DESCRIPTIONEND####
+//===========================================================================
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <pkgconf/kernel.h>
+#include <cyg/io/serialio.h>
+
+// Replace this with any other USB driver desired.
+#include <cyg/io/usb/usbs_at91.h>
+#include <cyg/io/usb/usbs_serial.h>
+#include <pkgconf/io_usb_slave_serial.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+// This application creates a USB-serial converter. To the host it will appear
+// as a single serial USB port, such as /dev/ttyUSB0 for a Linux host.
+// Any characters received from the USB host will be sent out the serial port
+// and visa-verse. It creates a separate, dedicated thread for each direction.
+// 
+// It uses the eCos USB-serial layer to enumerate with the USB host and monitor
+// the connection, but then uses standard C I/O functions to perform the 
+// communications.
+// 
+// The USB serial module can be configured as a generic adapter or an an ACM
+// communications class device. For the latter, the application handles the
+// USB communications class requests which allows it to receive requests from
+// the host to set serial parameters, like the baud rate. This actually turns
+// this example into a more realistic USB-serial adapter that can be configured
+// dynamically by the host.
+// 
+// The eCos library must be configured with the packages for USB slave, USB 
+// serial, and File I/O. It also requires the proper serial port driver for the
+// target platform.
+// 
+// This example was tested with the AT91SAM7S-EK board, but should work with any
+// board that has a USB slave and serial port, and the necessary drivers.
+
+
+// Comment this line out to remove debug output.
+#define DEBUG_OUTPUT
+
+#if defined(DEBUG_OUTPUT)
+#define DBG diag_printf
+#else
+#define DBG (1) ? (void)0 : diag_printf
+#endif
+
+// Set these to the USB devtab entries for the Tx and Rx Bulk endpoints 
+// selected in the configuration of the USB serial subsystem.
+#define USB_TX_DEV  "/dev/usbs1"
+#define USB_RX_DEV  "/dev/usbs2"
+
+// Set this for any available serial port on the target.
+#define SER_DEV     "/dev/ser0"
+
+// Buffer for incoming USB bulk data. The local USB driver can probably split
+// packets, but just in case, making this the page size of the host might be
+// helpful.
+#define BUF_SIZE 4096
+static char usb2ser_buf[BUF_SIZE];
+
+// The threads
+cyg_thread thread[2];
+
+// Space for two 4K stacks
+#define THREAD_STACK_SIZE 4096
+char stack[2][THREAD_STACK_SIZE];
+
+// The handles for the threads
+cyg_handle_t    usb2ser_thread, 
+                ser2usb_thread;
+
+// --------------------------------------------------------------------------
+// For an ACM serial device we can handle the USB class messages to deal with
+// requests from the host like setting the serial parameters (baud rate, 
+// etc).
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+static cyg_uint8    acm_buf[32];
+static cyg_uint32   baud = 34800;
+
+// --------------------------------------------------------------------------
+// Handler for the completion of a SetLineCoding request from the host.
+// The 'acm_buf' should contain the 7-byte request OUT packet from the
+// host. This contains a request to change the serial parameters.
+// In this example function, we will accept a few different baud rates.
+// To keep the example relatively simple, though, we keep the other serial
+// parameters to 1 stop bit, no parity, 8 data bits.
+
+static usbs_control_return
+acm_set_line_coding(usbs_control_endpoint* ep0, int n)
+{
+  int err;
+  cyg_uint32 req_baud;
+  cyg_io_handle_t handle;
+  
+  // Get the requested baud rate from the received ctrl OUT packet
+  req_baud = ((acm_buf[3] << 24) | (acm_buf[2] << 16) | 
+              (acm_buf[1] << 8) | acm_buf[0]);
+  
+  DBG("Set Baud: %u\n", (unsigned) baud);
+  
+  // Look up the serial handle and attempt to set the baud rate.
+  if (cyg_io_lookup(SER_DEV, &handle) == 0) {
+    cyg_serial_info_t ser_info;
+    cyg_uint32 len = sizeof(ser_info);
+    
+    switch (baud) {
+      case   9600 : ser_info.baud = CYGNUM_SERIAL_BAUD_9600;      break;
+      case  38400 : ser_info.baud = CYGNUM_SERIAL_BAUD_38400;     break;
+      case 115200 : ser_info.baud = CYGNUM_SERIAL_BAUD_115200;    break;
+      default:
+        DBG("Unsupported baud rate\n");
+        return USBS_CONTROL_RETURN_HANDLED;
+    }
+    ser_info.stop = CYGNUM_SERIAL_STOP_1;
+    ser_info.parity = CYGNUM_SERIAL_PARITY_NONE;
+    ser_info.word_length = CYGNUM_SERIAL_WORD_LENGTH_8;
+    ser_info.flags = 0;
+    
+    err = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, 
+                            &ser_info, &len);
+    if (err == 0)
+      baud = req_baud;
+    else {
+      DBG("Error setting serial params\n");
+    }
+  }
+  else {
+    DBG("Error looking up serial device: %s\n", SER_DEV);
+  }
+  return USBS_CONTROL_RETURN_HANDLED;
+}
+
+// --------------------------------------------------------------------------
+// Handler for the ACM class messages.
+// 
+static usbs_control_return 
+acm_class_handler(usbs_control_endpoint* ep0, void* data)
+{
+  usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+  
+  usb_devreq  *req = (usb_devreq *) ep0->control_buffer;
+  
+  static cyg_uint8 rsp_buf[32];
+  
+  DBG("ACM Class Handler\n");
+  
+  switch (req->request) {
+    
+    case USBS_SERIAL_SET_LINE_CODING :
+      DBG("Set Line Coding\n");
+      memset(acm_buf, 0, 32);
+      ep0->buffer = acm_buf;
+      ep0->buffer_size = 7;
+      ep0->complete_fn = acm_set_line_coding;
+      result = USBS_CONTROL_RETURN_HANDLED;
+      break;
+      
+    case USBS_SERIAL_GET_LINE_CODING :
+      DBG("Get Line Coding\n");
+      rsp_buf[0] = baud & 0xFF;
+      rsp_buf[1] = (baud >>  8) & 0xFF;
+      rsp_buf[2] = (baud >> 16) & 0xFF;
+      rsp_buf[3] = (baud >> 24) & 0xFF;
+      rsp_buf[4] = 0; // One stop bit
+      rsp_buf[5] = 0; // No parity
+      rsp_buf[6] = 8; // 8 data bits
+      ep0->buffer = rsp_buf;
+      ep0->buffer_size = 7;
+      result = USBS_CONTROL_RETURN_HANDLED;
+      break;
+      
+    default :
+      DBG("*** Unhandled ACM Request: 0x%02X ***\n",
+          (unsigned) req->request);
+  }
+  
+  return result;
+}
+
+#endif      // CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+// --------------------------------------------------------------------------
+// Thread receives packets from the USB and sends them out the serial port
+// It uses a buffered stdio input, an un-buffered low-level file output.
+// This isn't terribly efficient, but rather an example of both methods.
+
+void usb2ser_func(cyg_addrword_t data)
+{
+  int  c;
+  FILE *rxf = fopen(USB_RX_DEV, "r");
+  int   txh = open(SER_DEV, O_WRONLY, 0);
+  
+  DBG("Usb2Ser: Thread starting\n");
+  
+  if (!rxf) {
+    DBG("Error opening USB rx port\n");
+    return;
+  }
+  
+  if (txh < 0) {
+    DBG("Error opening serial tx port\n");
+    return;
+  }
+  
+  // Give the USB receiver an adequate buffer.
+  setvbuf(rxf, usb2ser_buf, _IOFBF, BUF_SIZE);
+  
+  while (1) {
+    
+    // ----- Wait for the host to configure -----
+    
+    DBG("Usb2Ser: Waiting for USB configuration\n");
+    usbs_serial_wait_until_configured();
+    cyg_thread_delay((cyg_tick_count_t) 10);
+    
+    // ----- While configured read data & send out serial port -----
+    
+    DBG("Usb2Ser: USB configured\n");
+    while (usbs_serial_is_configured()) {
+      if ((c = getc(rxf)) < 0) {
+        DBG("*** USB Read Error: %d ***\n", c);
+      }
+      else {
+        char ch = (char) c;
+        write(txh, &ch, 1);
+      }
+    }
+  }
+}
+
+// --------------------------------------------------------------------------
+// Thread receives packets from the serial port and sends them out the USB
+// It uses a buffered stdio input, an un-buffered low-level file output.
+// This isn't terribly efficient, but rather an example of both methods.
+
+void ser2usb_func(cyg_addrword_t data)
+{
+  int  c;
+  FILE *rxf = fopen(SER_DEV, "r");
+  int  txh = open(USB_TX_DEV, O_WRONLY, 0);
+  
+  DBG("Ser2Usb: Thread starting\n");
+  
+  if (!rxf) {
+    DBG("Error opening serial rx port\n");
+    return;
+  }
+  
+  if (txh < 0) {
+    DBG("Error opening USB tx port\n");
+    return;
+  }
+  
+  while (1) {
+    
+    // ----- Wait for the host to configure -----
+    
+    DBG("Ser2Usb: Waiting for USB configuration\n");
+    usbs_serial_wait_until_configured();
+    cyg_thread_delay((cyg_tick_count_t) 10);
+    
+    // ----- While configured read data & send out serial port -----
+    
+    DBG("Ser2Usb: USB configured\n");
+    while (usbs_serial_is_configured()) {
+      if ((c = getc(rxf)) < 0) {
+        DBG("*** Console Read Error: %d ***\n", c);
+      }
+      else {
+        char ch = (char) c;
+        write(txh, &ch, 1);
+      }
+    }
+  }
+}
+
+// --------------------------------------------------------------------------
+//  Application Startup
+// --------------------------------------------------------------------------
+
+void cyg_user_start(void)
+{
+  DBG("Entering cyg_user_start() function\n");
+  
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+  // Override the class handler to use ours.
+  usbs_serial_ep0->class_control_fn = acm_class_handler;
+#endif
+  
+  cyg_thread_create(4, usb2ser_func, (cyg_addrword_t) 0,
+                    "Usb2Serial", (void *) stack[0], THREAD_STACK_SIZE,
+                    &usb2ser_thread, &thread[0]);
+  
+  cyg_thread_create(4, ser2usb_func, (cyg_addrword_t) 1,
+                    "Serial2Usb", (void *) stack[1], THREAD_STACK_SIZE,
+                    &ser2usb_thread, &thread[1]);
+  
+  // Start USB subsystem
+  usbs_serial_start();
+  
+  // Start the threads running.
+  cyg_thread_resume(usb2ser_thread);
+  cyg_thread_resume(ser2usb_thread);
+}
+
diff --git a/packages/io/usb/serial/slave/v2_0/tests/usbserial_echo.c b/packages/io/usb/serial/slave/v2_0/tests/usbserial_echo.c
new file mode 100644 (file)
index 0000000..9ffab93
--- /dev/null
@@ -0,0 +1,126 @@
+//==========================================================================
+//
+//      usb_serial_echo.c
+//
+//      Example application for the USB serial layer in eCos.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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:         2008-06-02
+// Description:  USB serial example application.
+//
+//####DESCRIPTIONEND####
+//===========================================================================
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <pkgconf/kernel.h>
+#include <cyg/io/usb/usbs_at91.h>
+#include <cyg/io/usb/usbs_serial.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DEBUG_OUTPUT
+
+#if defined(DEBUG_OUTPUT)
+#define DBG diag_printf
+#else
+#define DBG (1) ? (void)0 : diag_printf
+#endif
+
+typedef unsigned char byte;
+
+// --------------------------------------------------------------------------
+//                                                         Data & Callback(s)
+// --------------------------------------------------------------------------
+
+#define BUF_SIZE        4096
+
+static byte     rx_buf[2][BUF_SIZE+1], tx_buf[BUF_SIZE+1];
+
+// --------------------------------------------------------------------------
+//                                                              Main Routine
+// --------------------------------------------------------------------------
+
+int main(void)
+{
+  int             n;
+  unsigned        ibuf, next_buf;
+  
+  // ----- Start USB subsystem -----
+  
+  usbs_serial_start();
+  
+  // ----- Get data from host and send it back -----
+  
+  while (1) {
+    ibuf = 0;
+    
+    // ----- Wait for the host to configure -----
+    
+    usbs_serial_wait_until_configured();
+    cyg_thread_delay((cyg_tick_count_t) 10);
+    
+    // ----- While configured read data & print to screen -----
+    
+    usbs_serial_start_rx(&usbs_ser0, rx_buf[ibuf], BUF_SIZE);
+    
+    while (usbs_serial_is_configured()) {
+      
+      n = usbs_serial_wait_for_rx(&usbs_ser0);
+      next_buf = ibuf ^ 1;
+      
+      usbs_serial_start_rx(&usbs_ser0, rx_buf[next_buf], BUF_SIZE);
+      
+      if (n < 0) {
+        DBG("*** I/O Error: %d ***\n", n);
+      }
+      else {
+        memcpy(tx_buf, rx_buf[ibuf], n);
+        usbs_serial_tx(&usbs_ser0, tx_buf, n);
+        rx_buf[ibuf][n] = '\0';
+        DBG("%s", rx_buf[ibuf]);
+      }
+      
+      ibuf = next_buf;
+    }
+  }
+  
+  return 0;
+}
+
diff --git a/packages/io/usb/slave/v2_0/host/bulk-boundaries.tcl b/packages/io/usb/slave/v2_0/host/bulk-boundaries.tcl
new file mode 100644 (file)
index 0000000..deceb1c
--- /dev/null
@@ -0,0 +1,105 @@
+#===============================================================================
+#
+#    bulk-boundaries.tcl
+#
+#    Support for USB testing
+#
+#===============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+#===============================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):   asl
+# Date:                2006-04-21
+# Purpose:      Test the bulk endpoints with different sizes of packets
+#               at the important boundaries.
+#
+#####DESCRIPTIONEND####
+#===============================================================================
+
+set pktsizes { 1 2 3 4 5 7 8 9 15 16 17 31 32 33 63 64 65 127 128 129 \
+               255 256 257 511 512 513 1023 1024 1025 2047 2048 2049 \
+               4095 4096 4097 }
+
+ if { 0 != [llength $usbtest::bulk_in_endpoints] } {
+     puts "Bulk IN endpoints: $usbtest::bulk_in_endpoints"
+     foreach ep $usbtest::bulk_in_endpoints {
+       puts [format "  %2d: packet sizes %d to %d, padding %d" $ep \
+                   $usbtest::bulk_in($ep,min_size) \
+                   $usbtest::bulk_in($ep,max_size) \
+                   $usbtest::bulk_in($ep,max_in_padding)]
+         foreach pktsize $pktsizes {
+             if { $pktsize <=  $usbtest::bulk_in($ep,max_size) } {
+                 puts [format "Testing IN endpoint %d with packet size %4d" \
+                           $ep $pktsize]
+                 usbtest::reset
+                 usbtest::bulktest $ep in 5 txsize1=$pktsize format=byteseq \
+                     data1=42 data* $usbtest::MULTIPLIER \
+                     data+ $usbtest::INCREMENT
+                 if { [usbtest::start 10] } {
+                     puts "Passed"
+                 } else {
+                     puts "Failed"
+                     foreach result $usbtest::results {
+                         puts $result
+                     }
+                 }
+             }
+         }
+     }
+ }
+
+if { 0 != [llength $usbtest::bulk_out_endpoints] } {
+    puts "Bulk OUT endpoints: $usbtest::bulk_out_endpoints"
+    foreach ep $usbtest::bulk_out_endpoints {
+       puts [format "  %2d: packet sizes %d to %d" $ep \
+                  $usbtest::bulk_out($ep,min_size) \
+                  $usbtest::bulk_out($ep,max_size)]
+        foreach pktsize $pktsizes {
+            if { $pktsize <=  $usbtest::bulk_out($ep,max_size) } {
+                puts [format "Testing OUT endpoint %d with packet size %4d" \
+                          $ep $pktsize]
+                usbtest::reset
+                usbtest::bulktest $ep out 5 txsize1=$pktsize format=byteseq \
+                    data1=42 data* $usbtest::MULTIPLIER \
+                    data+ $usbtest::INCREMENT rxsize1=4096 
+                if { [usbtest::start 10] } {
+                    puts "Passed"
+                } else {
+                    puts "Failed"
+                    foreach result $usbtest::results {
+                        puts $result
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/packages/isoinfra/v2_0/include/fnmatch.h b/packages/isoinfra/v2_0/include/fnmatch.h
new file mode 100644 (file)
index 0000000..61c7a97
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef CYGONCE_ISO_FNMATCH_H
+#define CYGONCE_ISO_FNMATCH_H
+/*========================================================================
+//
+//      fnmatch.h
+//
+//      fnmatch()
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2007 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Peter Korsgaard <peter.korsgaard@barco.com>
+// Contributors:
+// Date:          2007-01-24
+// Purpose:       This file provides the fnmatch() function
+//                required by POSIX 1003.2-1992, section B.6.
+// Description:   The real contents of this file get set from the
+//                configuration (set by the implementation)
+// Usage:         #include <fnmatch.h>
+//
+//####DESCRIPTIONEND####
+//
+//======================================================================
+*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/isoinfra.h>          /* Configuration header */
+
+/* INCLUDES */
+
+#ifdef CYGBLD_ISO_FNMATCH_HEADER
+# include CYGBLD_ISO_FNMATCH_HEADER
+#endif
+
+#endif /* CYGONCE_ISO_FNMATCH_H multiple inclusion protection */
+
+/* EOF fnmatch.h */
diff --git a/packages/isoinfra/v2_0/include/sys/time.h b/packages/isoinfra/v2_0/include/sys/time.h
new file mode 100644 (file)
index 0000000..6e547f9
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef CYGONCE_ISO_SYS_TIME_H
+#define CYGONCE_ISO_SYS_TIME_H
+/*========================================================================
+//
+//      sys/time.h
+//
+//      struct timeval and gettimeofday()
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005  eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Alexander Neundorf <neundorf@kde.org>
+// Contributors:  
+// Date:          2005-10-04
+// Purpose:       This file provides the time macros, types and functions
+//                required by ISO C and POSIX 1003.1.
+// Description:   The real contents of this file get set from the
+//                configuration (set by the implementation)
+// Usage:         #include <sys/time.h>
+//
+//####DESCRIPTIONEND####
+//
+//======================================================================
+*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/isoinfra.h>          /* Configuration header */
+
+/* INCLUDES */
+
+/* This is the "standard" way to get NULL and size_t from stddef.h,
+ * which is the canonical location of the definitions.
+ */
+#define __need_NULL
+#define __need_size_t
+#include <stddef.h>
+
+#include <time.h>
+#ifdef CYGBLD_ISO_STRUCTTIMEVAL_HEADER
+# include CYGBLD_ISO_STRUCTTIMEVAL_HEADER
+#else
+
+/*
+ * Structure returned by gettimeofday(2),
+ * and used in other calls such as select(2).
+ */
+struct timeval {
+       time_t  tv_sec;         /* seconds */
+       time_t  tv_usec;        /* and microseconds */
+};
+
+#endif
+
+
+#endif /* CYGONCE_ISO_SYS_TIME_H multiple inclusion protection */
+
+/* EOF sys/time.h */
diff --git a/packages/kernel/v2_0/tests/timeslice2.c b/packages/kernel/v2_0/tests/timeslice2.c
new file mode 100644 (file)
index 0000000..b71fd0f
--- /dev/null
@@ -0,0 +1,307 @@
+//==========================================================================
+//
+//        timeslice2.c
+//
+//        Timeslice 2 test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2001-06-18
+// Description:   An additional timeslicing test.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/kernel/smp.hxx>
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+//==========================================================================
+
+#if defined(CYGSEM_KERNEL_SCHED_TIMESLICE) &&   \
+    defined(CYGFUN_KERNEL_API_C) &&             \
+    defined(CYGSEM_KERNEL_SCHED_MLQUEUE) &&     \
+    defined(CYGVAR_KERNEL_COUNTERS_CLOCK) &&    \
+    !defined(CYGDBG_INFRA_DIAG_USE_DEVICE) &&   \
+    (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)
+
+//==========================================================================
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#define NTHREADS_MAX (CYGNUM_KERNEL_CPU_MAX*6)
+
+static int ncpus = CYGNUM_KERNEL_CPU_MAX;
+
+static char test_stack[STACK_SIZE];
+static cyg_thread test_thread;
+static cyg_handle_t main_thread;
+
+static char hipri_stack[STACK_SIZE];
+static cyg_thread hipri_thread_obj;
+static cyg_handle_t hipri_thread;
+
+static char stacks[NTHREADS_MAX][STACK_SIZE];
+static cyg_thread test_threads[NTHREADS_MAX];
+static cyg_handle_t threads[NTHREADS_MAX];
+
+static volatile int failed = false;
+
+static volatile cyg_uint32 slicerun[NTHREADS_MAX][CYGNUM_KERNEL_CPU_MAX];
+
+//==========================================================================
+
+void 
+test_thread_timeslice(CYG_ADDRESS id)
+{
+    for(;;)
+        slicerun[id][CYG_KERNEL_CPU_THIS()]++;
+}
+
+//==========================================================================
+
+void run_test_timeslice(int nthread)
+{
+    int i,j;
+    cyg_uint32 cpu_total[CYGNUM_KERNEL_CPU_MAX];
+    cyg_uint32 cpu_threads[CYGNUM_KERNEL_CPU_MAX];
+    cyg_uint32 thread_total[NTHREADS_MAX];
+
+    CYG_TEST_INFO( "Timeslice2 Test: Check timeslicing works under preemption");
+    
+    // Init flags.
+    for (i = 0;  i < nthread;  i++)
+        for( j = 0; j < ncpus; j++ )
+            slicerun[i][j] = 0;
+    
+    // Set my priority higher than any I plan to create
+    cyg_thread_set_priority(cyg_thread_self(), 2);
+
+    for (i = 0;  i < nthread;  i++) {
+        cyg_thread_create(10,              // Priority - just a number
+                          test_thread_timeslice, // entry
+                          i,               // index
+                          "test_thread",     // Name
+                          &stacks[i][0],   // Stack
+                          STACK_SIZE,      // Size
+                          &threads[i],     // Handle
+                          &test_threads[i] // Thread data structure
+            );
+        cyg_thread_resume( threads[i]);
+    }
+
+    // Just wait a while, until the threads have all run for a bit.
+    cyg_thread_delay( CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS*100 );
+
+    // Suspend all the threads
+    for (i = 0;  i < nthread;  i++) {
+        cyg_thread_suspend(threads[i]);
+    }
+
+    
+    // And check that a thread ran on each CPU, and that each thread
+    // ran.
+    
+    
+    diag_printf(" Thread ");
+    for( j = 0; j < ncpus; j++ )
+    {
+        cpu_total[j] = 0;
+        cpu_threads[j] = 0;
+        // "  %11d"  __123456789ab"
+        diag_printf("       CPU %2d",j);
+    }
+    // "  %11d"  __123456789ab"
+    diag_printf("        Total\n");
+    for (i = 0;  i < nthread;  i++)
+    {
+        thread_total[i] = 0;
+        diag_printf("     %2d ",i);
+        for( j = 0; j < ncpus; j++ )
+        {
+            thread_total[i] += slicerun[i][j];
+            cpu_total[j] += slicerun[i][j];
+            if( slicerun[i][j] > 0 )
+                cpu_threads[j]++;
+            diag_printf("  %11d",slicerun[i][j]);
+        }
+        diag_printf("  %11d\n",thread_total[i]);
+        if( thread_total[i] == 0 )
+            failed++;
+    }
+    
+    diag_printf(" Total  ");
+    for( j = 0; j < ncpus; j++ )
+        diag_printf("  %11d",cpu_total[j]);
+    diag_printf("\n");
+    diag_printf("Threads ");
+    for( j = 0; j < ncpus; j++ )
+    {
+        diag_printf("  %11d",cpu_threads[j]);
+        if( cpu_threads[j] < 2 )
+            failed++;
+    }
+    diag_printf("\n");
+
+    // Delete all the threads
+    for (i = 0;  i < nthread;  i++) {
+        cyg_thread_delete(threads[i]);
+    }
+
+    CYG_TEST_INFO( "Timeslice2 Test: done");
+}
+
+
+//==========================================================================
+
+void 
+hipri_test(CYG_ADDRESS id)
+{
+    while( 1 )
+    {
+        cyg_thread_delay( CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS/2 );
+    }
+}
+
+//==========================================================================
+
+void 
+run_tests(CYG_ADDRESS id)
+{
+    int step;
+    int nthread;
+    
+    // Try to run about 10 times in total, with varying numbers of threads
+    // from only one extra up to the full set:
+
+    step = (NTHREADS_MAX - (1 + CYG_KERNEL_CPU_COUNT()))/10;
+    if( step == 0 ) step = 1;
+    
+    for( nthread = 1 + CYG_KERNEL_CPU_COUNT() ;
+         nthread <= NTHREADS_MAX ;
+         nthread += step )
+            run_test_timeslice(nthread);
+
+    if( failed )
+        CYG_TEST_FAIL_FINISH("Timeslice2 test failed\n");
+    
+    CYG_TEST_PASS_FINISH("Timeslice2 test OK");    
+}
+
+//==========================================================================
+
+void timeslice_main( void )
+{
+    CYG_TEST_INIT();
+
+    // Work out how many CPUs we actually have.
+    ncpus = CYG_KERNEL_CPU_COUNT();
+
+    cyg_thread_create(0,              // Priority - just a number
+                      run_tests, // entry
+                      0,               // index
+                      "run_tests",     // Name
+                      test_stack,   // Stack
+                      STACK_SIZE,      // Size
+                      &main_thread,     // Handle
+                      &test_thread // Thread data structure
+        );
+    cyg_thread_resume( main_thread);
+
+    cyg_thread_create(5,               // Priority - just a number
+                      hipri_test,      // entry
+                      0,               // index
+                      "hipri_run",     // Name
+                      hipri_stack,   // Stack
+                      STACK_SIZE,      // Size
+                      &hipri_thread,     // Handle
+                      &hipri_thread_obj // Thread data structure
+        );
+    cyg_thread_resume( hipri_thread);
+    
+    cyg_scheduler_start();
+}
+
+//==========================================================================
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+    cyg_hal_invoke_constructors();
+#endif
+    timeslice_main();
+}   
+
+//==========================================================================
+
+#else // CYGSEM_KERNEL_SCHED_TIMESLICE etc
+
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO("Timeslice test requires:\n"
+                "CYGSEM_KERNEL_SCHED_TIMESLICE &&\n"
+                "CYGFUN_KERNEL_API_C && \n"
+                "CYGSEM_KERNEL_SCHED_MLQUEUE &&\n"
+                "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n"
+                "!CYGDBG_INFRA_DIAG_USE_DEVICE &&\n"
+                "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n");
+    CYG_TEST_NA("Timeslice test requirements");
+}
+
+#endif // CYGSEM_KERNEL_SCHED_TIMESLICE etc.
+
+//==========================================================================
+// EOF timeslice2.c
diff --git a/packages/redboot/v2_0/doc/.cvsignore b/packages/redboot/v2_0/doc/.cvsignore
new file mode 100644 (file)
index 0000000..8a8c385
--- /dev/null
@@ -0,0 +1,11 @@
+redboot-guide-a4.aux
+redboot-guide-a4.log
+redboot-guide-a4.out
+redboot-guide-a4.pdf
+redboot-guide-a4.tex
+redboot-guide-letter.aux
+redboot-guide-letter.log
+redboot-guide-letter.out
+redboot-guide-letter.pdf
+redboot-guide-letter.tex
+*.html
\ No newline at end of file
diff --git a/packages/redboot/v2_0/src/flash_load.c b/packages/redboot/v2_0/src/flash_load.c
new file mode 100644 (file)
index 0000000..9082502
--- /dev/null
@@ -0,0 +1,183 @@
+//==========================================================================
+//
+//      flash_load.c
+//
+//      RedBoot file/image loader into flash
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric LTD
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Oliver Munz
+// Contributors: om, asl
+// Date:         2006-02-21
+// Purpose:      
+// Description:  
+//              
+// This code is part of RedBoot (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <redboot.h>
+#include <flash_load.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/infra/cyg_ass.h>
+
+static int flash_block_size;
+
+static cyg_uint8 * current_flash_page;
+
+/* Allocation of the flash-sector size RAM-buffer is done */
+static bool init_done = false; 
+
+/* We have initialized the current page ready for writing */
+static bool flash_page_init = false; 
+
+static cyg_uint8 *flash_buffer;
+
+// If the io flash code outputs when erasing/writing it will upset the
+// download over the communications channel. So we install a dummy
+// print function.
+static int dummy_printf(const char *fmt, ...){ 
+  return 0;
+}
+
+// Calculate the address of the first byte in a flash block
+static cyg_uint8 * flash_block_begin(cyg_uint32 addr) 
+{
+  return (cyg_uint8 *)
+    ((addr / flash_block_size) * flash_block_size);
+}
+
+// Initialize the loading process
+void flash_load_start(void)
+{
+  flash_init(dummy_printf);
+  
+  init_done = true;
+  flash_page_init = false;
+}
+
+// Write a byte into flash. We maintain a copy in RAM of the FLASH
+// page we are currently "writing" into. This copy is loaded with the
+// current contents of the FLASH page when the first byte is "written"
+// to the page. The "writes" are then made into the RAM copy. We only
+// write to FLASH when there is a "write" outside of the current page,
+// or the flash_load_finish function is called.
+void flash_load_write(cyg_uint8 *flash_addr, cyg_uint8 value)
+{
+  
+  cyg_uint32 retcode = FLASH_ERR_OK;
+  void * err_addr;
+  cyg_uint32 addr = (cyg_uint32)flash_addr;
+  cyg_uint32 offset;
+  
+  if (!flash_page_init) { 
+    /* First Byte for the current flash block. Read the current contents */
+    current_flash_page = flash_block_begin(addr);
+    flash_read(flash_buffer, current_flash_page, flash_block_size, &err_addr); 
+    flash_page_init = true;
+  } 
+  if (flash_block_begin(addr) != current_flash_page) { 
+    /* We have moved into the next flash page. Write the current
+       page so we can move on */
+    retcode = flash_erase(current_flash_page, flash_block_size, &err_addr);
+    if (retcode != FLASH_ERR_OK){ /* Flash ERROR */
+      diag_printf("Error erase at %p: %s\n", err_addr, flash_errmsg(retcode));
+      return;
+    }
+    
+    retcode = flash_program(current_flash_page, flash_buffer, 
+                            flash_block_size, &err_addr); 
+    if (retcode != FLASH_ERR_OK){ 
+      diag_printf("Error writing at %p: %s\n", 
+                  err_addr, flash_errmsg(retcode));
+      return;
+    }
+    current_flash_page = flash_block_begin(addr);
+    flash_read(flash_buffer, current_flash_page, flash_block_size, &err_addr);
+  }
+  
+  offset = flash_addr - current_flash_page;
+  CYG_ASSERT(offset < flash_block_size, "offset not inside flash block");
+  
+  flash_buffer[offset] = value;
+}
+
+// Program the current page into flash.
+void flash_load_finish(void)
+{
+  cyg_uint32 retcode = FLASH_ERR_OK;
+  void * err_addr;
+  
+  if (init_done && flash_page_init) {
+    flash_page_init = false;
+    
+    retcode = flash_erase(current_flash_page, flash_block_size, &err_addr);
+    if (retcode != FLASH_ERR_OK){
+      diag_printf("Error erase at %p: %s\n", err_addr, flash_errmsg(retcode));
+    } else {
+      retcode = flash_program(current_flash_page, flash_buffer, 
+                              flash_block_size, &err_addr);
+      if (retcode != FLASH_ERR_OK){ 
+        diag_printf("Error writing at %p: %s\n", 
+                    err_addr, flash_errmsg(retcode));
+      }
+    }
+  }
+  flash_init(diag_printf);
+}
+
+// This is called during redboot start up. We allocate a buffer the
+// size of the flash page.
+void
+flash_load_init(void)
+{
+  int flash_blocks;
+
+  flash_get_block_info(&flash_block_size, &flash_blocks);
+  workspace_end -= flash_block_size;
+  
+  flash_buffer = workspace_end;
+}
+
+// Register this initialization function in the table
+RedBoot_init(flash_load_init, RedBoot_INIT_LAST);
+
+
+    
diff --git a/packages/redboot/v2_0/src/flash_load.h b/packages/redboot/v2_0/src/flash_load.h
new file mode 100644 (file)
index 0000000..8b95596
--- /dev/null
@@ -0,0 +1,67 @@
+//==========================================================================
+//
+//      flash_load.h
+//
+//      Interfaces to byte writing into FLASH during load
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not 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: om, asl
+// Date:         2005-02-21
+// Purpose:      
+// Description:  
+//              
+// This code is part of RedBoot (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef FLASH_LOAD_H
+#define FLASH_LOAd_H
+
+// Prepare a write to flash.
+void flash_load_start(void);
+
+// Finish a write to flash
+void flash_load_finish(void);
+
+// Write a single byte. This will be buffered until either a full page
+// is available or flash_write_finish is called.
+void flash_load_write(cyg_uint8 *addr, cyg_uint8 value);
+
+#endif // FLASH_LOAD_H
+
diff --git a/packages/redboot/v2_0/src/gunzip.c b/packages/redboot/v2_0/src/gunzip.c
new file mode 100644 (file)
index 0000000..c241433
--- /dev/null
@@ -0,0 +1,117 @@
+//==========================================================================
+//
+//      gunzip.c
+//
+//      RedBoot GZIP uncompress command
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Peter Korsgaard
+// Contributors: Peter Korsgaard
+// Date:         2005-04-04
+// Purpose:      
+// Description:  
+//              
+// This code is part of RedBoot (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <redboot.h>
+
+RedBoot_cmd("gunzip",
+           "Uncompress GZIP compressed data",
+           "-s <location> -d <location>",
+           do_gunzip
+    );
+
+void
+do_gunzip(int argc, char *argv[])
+{
+    struct option_info opts[2];
+    unsigned long src, dst;
+    bool src_set, dst_set;
+    _pipe_t pipe;
+    _pipe_t* p = &pipe;
+    int err;
+
+    init_opts(&opts[0], 's', true, OPTION_ARG_TYPE_NUM, 
+              (void *)&src, (bool *)&src_set, "source address");
+    init_opts(&opts[1], 'd', true, OPTION_ARG_TYPE_NUM, 
+              (void *)&dst, (bool *)&dst_set, "destination address");
+    if (!scan_opts(argc, argv, 1, opts, 2, 0, 0, "")) {
+        return;
+    }
+
+    // Must have src and dst
+    if (!src_set || !dst_set) {
+        // try to use load_address for src 
+        if (dst_set 
+            && load_address >= (CYG_ADDRESS)ram_start 
+            && load_address < load_address_end) {
+            src = load_address;
+            diag_printf("Decompressing from %p to %p\n",
+                       (void*)src, (void*)dst);
+        }
+        else
+        {
+            diag_printf("usage: gunzip -s <addr> -d <addr>\n");
+            return;
+        }
+    }
+
+    p->out_buf = (unsigned char*)dst;
+    p->out_max = p->out_size = -1;
+    p->in_buf = (unsigned char*)src;
+    p->in_avail = -1;
+
+    err = (*_dc_init)(p);
+
+    if (0 == err)
+        err = (*_dc_inflate)(p);
+
+    // Free used resources, do final translation of error value.
+    err = (*_dc_close)(p, err);
+
+    if (0 != err && p->msg) {
+       entry_address = (CYG_ADDRESS)NO_MEMORY;
+       diag_printf("Decompression error: %s\n", p->msg);
+    } else {
+        load_address     = entry_address = (CYG_ADDRESS)dst;
+        load_address_end = (CYG_ADDRESS)p->out_buf;
+        diag_printf("Decompressed %lu bytes\n", 
+                    load_address_end - load_address);
+    }
+}