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&