From 58ff370dd6640883d31915bbaf8b9c27a2eca84b Mon Sep 17 00:00:00 2001 From: schneider Date: Sun, 12 Jun 2011 04:18:11 +0200 Subject: [PATCH] added code from openbeacon.org --- openbeacon/lpc13xx/.gitignore | 11 + openbeacon/lpc13xx/core/Makefile.rules | 94 + .../lpc13xx/core/cmsis/cmsis_readme.txt | 28 + .../lpc13xx/core/cmsis/docs/CMSIS changes.htm | 320 +++ .../core/cmsis/docs/CMSIS debug support.htm | 243 ++ .../lpc13xx/core/cmsis/docs/CMSIS_Core.htm | 1337 ++++++++++ .../lpc13xx/core/cmsis/docs/License.doc | Bin 0 -> 39936 bytes openbeacon/lpc13xx/core/cmsis/history.txt | 8 + openbeacon/lpc13xx/core/cmsis/inc/LPC13xx.h | 532 ++++ openbeacon/lpc13xx/core/cmsis/inc/core_cm3.h | 1838 +++++++++++++ .../lpc13xx/core/cmsis/inc/system_LPC13xx.h | 63 + openbeacon/lpc13xx/core/cmsis/src/core_cm3.c | 784 ++++++ .../lpc13xx/core/cmsis/src/system_LPC13xx.c | 487 ++++ .../lpc13xx/core/freertos/inc/FreeRTOS.h | 424 +++ .../lpc13xx/core/freertos/inc/StackMacros.h | 173 ++ .../lpc13xx/core/freertos/inc/croutine.h | 749 ++++++ openbeacon/lpc13xx/core/freertos/inc/list.h | 305 +++ .../lpc13xx/core/freertos/inc/mpu_wrappers.h | 135 + .../lpc13xx/core/freertos/inc/portable.h | 390 +++ .../lpc13xx/core/freertos/inc/portmacro.h | 156 ++ .../lpc13xx/core/freertos/inc/projdefs.h | 77 + openbeacon/lpc13xx/core/freertos/inc/queue.h | 1261 +++++++++ openbeacon/lpc13xx/core/freertos/inc/semphr.h | 711 +++++ openbeacon/lpc13xx/core/freertos/inc/task.h | 1279 +++++++++ openbeacon/lpc13xx/core/freertos/src/heap_2.c | 283 ++ openbeacon/lpc13xx/core/freertos/src/list.c | 193 ++ openbeacon/lpc13xx/core/freertos/src/port.c | 292 ++ openbeacon/lpc13xx/core/freertos/src/queue.c | 1632 ++++++++++++ openbeacon/lpc13xx/core/freertos/src/tasks.c | 2347 +++++++++++++++++ openbeacon/lpc13xx/core/linker/LPC1342.ld | 9 + openbeacon/lpc13xx/core/linker/LPC1343.ld | 9 + openbeacon/lpc13xx/core/linker/LPC13xx.ld | 55 + .../lpc13xx/core/openbeacon/inc/crc16.h | 29 + .../core/openbeacon/inc/debug_printf.h | 20 + openbeacon/lpc13xx/core/openbeacon/inc/hid.h | 30 + openbeacon/lpc13xx/core/openbeacon/inc/iap.h | 32 + openbeacon/lpc13xx/core/openbeacon/inc/msd.h | 52 + .../lpc13xx/core/openbeacon/inc/openbeacon.h | 113 + openbeacon/lpc13xx/core/openbeacon/inc/spi.h | 43 + openbeacon/lpc13xx/core/openbeacon/inc/vfs.h | 70 + .../lpc13xx/core/openbeacon/inc/xxtea.h | 37 + .../lpc13xx/core/openbeacon/src/crc16.c | 43 + .../core/openbeacon/src/debug_printf.c | 367 +++ openbeacon/lpc13xx/core/openbeacon/src/hid.c | 112 + openbeacon/lpc13xx/core/openbeacon/src/iap.c | 45 + openbeacon/lpc13xx/core/openbeacon/src/msd.c | 117 + openbeacon/lpc13xx/core/openbeacon/src/spi.c | 128 + openbeacon/lpc13xx/core/openbeacon/src/vfs.c | 533 ++++ .../lpc13xx/core/openbeacon/src/xxtea.c | 102 + .../lpc13xx/core/peripherals/inc/gpio.h | 70 + .../core/peripherals/inc/rom_drivers.h | 62 + .../lpc13xx/core/peripherals/inc/uart.h | 60 + openbeacon/lpc13xx/core/peripherals/inc/usb.h | 237 ++ .../lpc13xx/core/peripherals/inc/usb/cdc.h | 241 ++ .../lpc13xx/core/peripherals/inc/usb/cdcusb.h | 240 ++ .../core/peripherals/inc/usb/cdcusbdesc.h | 35 + .../core/peripherals/inc/usb/cdcuser.h | 60 + .../core/peripherals/inc/usb/usbcore.h | 57 + .../lpc13xx/core/peripherals/inc/usb/usbhw.h | 95 + .../lpc13xx/core/peripherals/inc/usb/usbreg.h | 134 + .../core/peripherals/inc/usb/usbuser.h | 57 + .../lpc13xx/core/peripherals/inc/usbdesc.h | 42 + .../lpc13xx/core/peripherals/src/gpio.c | 42 + .../lpc13xx/core/peripherals/src/uart.c | 190 ++ .../core/peripherals/src/usb/cdcusbdesc.c | 204 ++ .../core/peripherals/src/usb/cdcuser.c | 372 +++ .../core/peripherals/src/usb/usbcore.c | 1291 +++++++++ .../lpc13xx/core/peripherals/src/usb/usbhw.c | 687 +++++ .../core/peripherals/src/usb/usbuser.c | 234 ++ openbeacon/lpc13xx/core/startup/LPC13xx.c | 368 +++ openbeacon/lpc13xx/drivers/bitmanufaktur.inf | 60 + openbeacon/lpc13xx/hid-client/Makefile | 68 + openbeacon/lpc13xx/hid-client/hid_listen.c | 65 + openbeacon/lpc13xx/hid-client/rawhid.c | 152 ++ openbeacon/lpc13xx/hid-client/rawhid.h | 12 + openbeacon/lpc13xx/lpc-flash/.gitignore | 21 + openbeacon/lpc13xx/lpc-flash/AUTHORS | 1 + openbeacon/lpc13xx/lpc-flash/COPYING | 674 +++++ openbeacon/lpc13xx/lpc-flash/Makefile.am | 1 + openbeacon/lpc13xx/lpc-flash/NEWS | 0 openbeacon/lpc13xx/lpc-flash/README | 0 openbeacon/lpc13xx/lpc-flash/bootstrap | 5 + openbeacon/lpc13xx/lpc-flash/configure.ac | 16 + openbeacon/lpc13xx/lpc-flash/src/Makefile.am | 4 + openbeacon/lpc13xx/lpc-flash/src/lpc-flash.c | 165 ++ openbeacon/lpc13xx/openbeacon-sensor/Makefile | 32 + .../openbeacon-sensor/inc/3d_acceleration.h | 32 + .../lpc13xx/openbeacon-sensor/inc/config.h | 44 + .../lpc13xx/openbeacon-sensor/inc/nRF_API.h | 60 + .../lpc13xx/openbeacon-sensor/inc/nRF_CMD.h | 45 + .../lpc13xx/openbeacon-sensor/inc/nRF_HW.h | 109 + .../openbeacon-sensor/inc/openbeacon-proto.h | 109 + .../lpc13xx/openbeacon-sensor/inc/pmu.h | 31 + .../lpc13xx/openbeacon-sensor/inc/sound.h | 33 + .../openbeacon-sensor/src/3d_acceleration.c | 100 + .../lpc13xx/openbeacon-sensor/src/main.c | 346 +++ .../lpc13xx/openbeacon-sensor/src/nRF_API.c | 330 +++ .../lpc13xx/openbeacon-sensor/src/nRF_CMD.c | 238 ++ .../lpc13xx/openbeacon-sensor/src/pmu.c | 160 ++ .../lpc13xx/openbeacon-sensor/src/sound.c | 93 + openbeacon/lpc13xx/openbeacon-usb2/.gitignore | 2 + openbeacon/lpc13xx/openbeacon-usb2/Makefile | 32 + .../openbeacon-usb2/inc/3d_acceleration.h | 31 + .../openbeacon-usb2/inc/FreeRTOSConfig.h | 103 + .../lpc13xx/openbeacon-usb2/inc/bluetooth.h | 29 + .../lpc13xx/openbeacon-usb2/inc/config.h | 47 + .../lpc13xx/openbeacon-usb2/inc/nRF_API.h | 63 + .../lpc13xx/openbeacon-usb2/inc/nRF_CMD.h | 46 + .../lpc13xx/openbeacon-usb2/inc/nRF_HW.h | 109 + .../openbeacon-usb2/inc/openbeacon-proto.h | 109 + openbeacon/lpc13xx/openbeacon-usb2/inc/pin.h | 36 + openbeacon/lpc13xx/openbeacon-usb2/inc/pmu.h | 49 + .../lpc13xx/openbeacon-usb2/inc/storage.h | 32 + .../openbeacon-usb2/src/3d_acceleration.c | 100 + .../lpc13xx/openbeacon-usb2/src/bluetooth.c | 87 + openbeacon/lpc13xx/openbeacon-usb2/src/main.c | 379 +++ .../lpc13xx/openbeacon-usb2/src/nRF_API.c | 329 +++ .../lpc13xx/openbeacon-usb2/src/nRF_CMD.c | 226 ++ openbeacon/lpc13xx/openbeacon-usb2/src/pin.c | 78 + openbeacon/lpc13xx/openbeacon-usb2/src/pmu.c | 78 + .../lpc13xx/openbeacon-usb2/src/storage.c | 110 + openbeacon/lpc13xx/openpcd2/Makefile | 22 + .../lpc13xx/openpcd2/inc/FreeRTOSConfig.h | 104 + openbeacon/lpc13xx/openpcd2/inc/config.h | 50 + openbeacon/lpc13xx/openpcd2/inc/pn532.h | 71 + openbeacon/lpc13xx/openpcd2/inc/rfid.h | 30 + openbeacon/lpc13xx/openpcd2/inc/usbcfg.h | 157 ++ openbeacon/lpc13xx/openpcd2/src/main.c | 72 + openbeacon/lpc13xx/openpcd2/src/rfid.c | 359 +++ openbeacon/lpc13xx/rtos-simple-demo/Makefile | 21 + .../rtos-simple-demo/inc/FreeRTOSConfig.h | 104 + .../lpc13xx/rtos-simple-demo/inc/config.h | 9 + .../lpc13xx/rtos-simple-demo/src/main.c | 190 ++ openbeacon/lpc13xx/sound/Makefile | 21 + openbeacon/lpc13xx/sound/inc/config.h | 9 + openbeacon/lpc13xx/sound/src/soundtest.c | 143 + openbeacon/lpc13xx/uart/Makefile | 21 + openbeacon/lpc13xx/uart/inc/config.h | 43 + openbeacon/lpc13xx/uart/src/uarttest.c | 52 + openbeacon/lpc13xx/usbcdc-storage/Makefile | 28 + openbeacon/lpc13xx/usbcdc-storage/inc/cdc.h | 241 ++ .../lpc13xx/usbcdc-storage/inc/cdcuser.h | 62 + .../lpc13xx/usbcdc-storage/inc/clkconfig.h | 28 + .../lpc13xx/usbcdc-storage/inc/compusb.h | 252 ++ .../lpc13xx/usbcdc-storage/inc/compusbdesc.h | 34 + .../lpc13xx/usbcdc-storage/inc/config.h | 40 + .../lpc13xx/usbcdc-storage/inc/memory.h | 20 + openbeacon/lpc13xx/usbcdc-storage/inc/msc.h | 103 + .../lpc13xx/usbcdc-storage/inc/mscuser.h | 47 + openbeacon/lpc13xx/usbcdc-storage/inc/type.h | 46 + .../lpc13xx/usbcdc-storage/inc/usbcfg.h | 157 ++ .../lpc13xx/usbcdc-storage/inc/usbcore.h | 56 + openbeacon/lpc13xx/usbcdc-storage/inc/usbhw.h | 62 + .../lpc13xx/usbcdc-storage/inc/usbreg.h | 134 + .../lpc13xx/usbcdc-storage/inc/usbuser.h | 57 + .../lpc13xx/usbcdc-storage/inc/vcomdemo.h | 30 + .../lpc13xx/usbcdc-storage/lpc134x-vcom.inf | 60 + openbeacon/lpc13xx/usbcdc-storage/readme.txt | 40 + .../lpc13xx/usbcdc-storage/src/DiskImg.c | 166 ++ .../lpc13xx/usbcdc-storage/src/cdcuser.c | 392 +++ .../lpc13xx/usbcdc-storage/src/clkconfig.c | 61 + .../lpc13xx/usbcdc-storage/src/compusbdesc.c | 273 ++ openbeacon/lpc13xx/usbcdc-storage/src/main.c | 163 ++ .../lpc13xx/usbcdc-storage/src/mscuser.c | 795 ++++++ .../lpc13xx/usbcdc-storage/src/usbcore.c | 1267 +++++++++ openbeacon/lpc13xx/usbcdc-storage/src/usbhw.c | 630 +++++ .../lpc13xx/usbcdc-storage/src/usbuser.c | 242 ++ openbeacon/lpc13xx/usbcdc/Makefile | 20 + .../lpc13xx/usbcdc/inc/FreeRTOSConfig.h | 104 + openbeacon/lpc13xx/usbcdc/inc/config.h | 43 + openbeacon/lpc13xx/usbcdc/inc/usbcfg.h | 157 ++ openbeacon/lpc13xx/usbcdc/lpc134x-vcom.inf | 65 + openbeacon/lpc13xx/usbcdc/readme.txt | 36 + openbeacon/lpc13xx/usbcdc/src/main.c | 102 + 174 files changed, 35448 insertions(+) create mode 100644 openbeacon/lpc13xx/.gitignore create mode 100644 openbeacon/lpc13xx/core/Makefile.rules create mode 100644 openbeacon/lpc13xx/core/cmsis/cmsis_readme.txt create mode 100644 openbeacon/lpc13xx/core/cmsis/docs/CMSIS changes.htm create mode 100644 openbeacon/lpc13xx/core/cmsis/docs/CMSIS debug support.htm create mode 100644 openbeacon/lpc13xx/core/cmsis/docs/CMSIS_Core.htm create mode 100644 openbeacon/lpc13xx/core/cmsis/docs/License.doc create mode 100644 openbeacon/lpc13xx/core/cmsis/history.txt create mode 100644 openbeacon/lpc13xx/core/cmsis/inc/LPC13xx.h create mode 100644 openbeacon/lpc13xx/core/cmsis/inc/core_cm3.h create mode 100644 openbeacon/lpc13xx/core/cmsis/inc/system_LPC13xx.h create mode 100644 openbeacon/lpc13xx/core/cmsis/src/core_cm3.c create mode 100644 openbeacon/lpc13xx/core/cmsis/src/system_LPC13xx.c create mode 100644 openbeacon/lpc13xx/core/freertos/inc/FreeRTOS.h create mode 100644 openbeacon/lpc13xx/core/freertos/inc/StackMacros.h create mode 100644 openbeacon/lpc13xx/core/freertos/inc/croutine.h create mode 100644 openbeacon/lpc13xx/core/freertos/inc/list.h create mode 100644 openbeacon/lpc13xx/core/freertos/inc/mpu_wrappers.h create mode 100644 openbeacon/lpc13xx/core/freertos/inc/portable.h create mode 100644 openbeacon/lpc13xx/core/freertos/inc/portmacro.h create mode 100644 openbeacon/lpc13xx/core/freertos/inc/projdefs.h create mode 100644 openbeacon/lpc13xx/core/freertos/inc/queue.h create mode 100644 openbeacon/lpc13xx/core/freertos/inc/semphr.h create mode 100644 openbeacon/lpc13xx/core/freertos/inc/task.h create mode 100644 openbeacon/lpc13xx/core/freertos/src/heap_2.c create mode 100644 openbeacon/lpc13xx/core/freertos/src/list.c create mode 100644 openbeacon/lpc13xx/core/freertos/src/port.c create mode 100644 openbeacon/lpc13xx/core/freertos/src/queue.c create mode 100644 openbeacon/lpc13xx/core/freertos/src/tasks.c create mode 100644 openbeacon/lpc13xx/core/linker/LPC1342.ld create mode 100644 openbeacon/lpc13xx/core/linker/LPC1343.ld create mode 100644 openbeacon/lpc13xx/core/linker/LPC13xx.ld create mode 100644 openbeacon/lpc13xx/core/openbeacon/inc/crc16.h create mode 100644 openbeacon/lpc13xx/core/openbeacon/inc/debug_printf.h create mode 100644 openbeacon/lpc13xx/core/openbeacon/inc/hid.h create mode 100644 openbeacon/lpc13xx/core/openbeacon/inc/iap.h create mode 100644 openbeacon/lpc13xx/core/openbeacon/inc/msd.h create mode 100644 openbeacon/lpc13xx/core/openbeacon/inc/openbeacon.h create mode 100644 openbeacon/lpc13xx/core/openbeacon/inc/spi.h create mode 100644 openbeacon/lpc13xx/core/openbeacon/inc/vfs.h create mode 100644 openbeacon/lpc13xx/core/openbeacon/inc/xxtea.h create mode 100644 openbeacon/lpc13xx/core/openbeacon/src/crc16.c create mode 100644 openbeacon/lpc13xx/core/openbeacon/src/debug_printf.c create mode 100644 openbeacon/lpc13xx/core/openbeacon/src/hid.c create mode 100644 openbeacon/lpc13xx/core/openbeacon/src/iap.c create mode 100644 openbeacon/lpc13xx/core/openbeacon/src/msd.c create mode 100644 openbeacon/lpc13xx/core/openbeacon/src/spi.c create mode 100644 openbeacon/lpc13xx/core/openbeacon/src/vfs.c create mode 100644 openbeacon/lpc13xx/core/openbeacon/src/xxtea.c create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/gpio.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/rom_drivers.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/uart.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/usb.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/usb/cdc.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusb.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusbdesc.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/usb/cdcuser.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/usb/usbcore.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/usb/usbhw.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/usb/usbreg.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/usb/usbuser.h create mode 100644 openbeacon/lpc13xx/core/peripherals/inc/usbdesc.h create mode 100644 openbeacon/lpc13xx/core/peripherals/src/gpio.c create mode 100644 openbeacon/lpc13xx/core/peripherals/src/uart.c create mode 100644 openbeacon/lpc13xx/core/peripherals/src/usb/cdcusbdesc.c create mode 100644 openbeacon/lpc13xx/core/peripherals/src/usb/cdcuser.c create mode 100644 openbeacon/lpc13xx/core/peripherals/src/usb/usbcore.c create mode 100644 openbeacon/lpc13xx/core/peripherals/src/usb/usbhw.c create mode 100644 openbeacon/lpc13xx/core/peripherals/src/usb/usbuser.c create mode 100644 openbeacon/lpc13xx/core/startup/LPC13xx.c create mode 100644 openbeacon/lpc13xx/drivers/bitmanufaktur.inf create mode 100644 openbeacon/lpc13xx/hid-client/Makefile create mode 100644 openbeacon/lpc13xx/hid-client/hid_listen.c create mode 100644 openbeacon/lpc13xx/hid-client/rawhid.c create mode 100644 openbeacon/lpc13xx/hid-client/rawhid.h create mode 100644 openbeacon/lpc13xx/lpc-flash/.gitignore create mode 100644 openbeacon/lpc13xx/lpc-flash/AUTHORS create mode 100644 openbeacon/lpc13xx/lpc-flash/COPYING create mode 100644 openbeacon/lpc13xx/lpc-flash/Makefile.am create mode 100644 openbeacon/lpc13xx/lpc-flash/NEWS create mode 100644 openbeacon/lpc13xx/lpc-flash/README create mode 100755 openbeacon/lpc13xx/lpc-flash/bootstrap create mode 100644 openbeacon/lpc13xx/lpc-flash/configure.ac create mode 100644 openbeacon/lpc13xx/lpc-flash/src/Makefile.am create mode 100644 openbeacon/lpc13xx/lpc-flash/src/lpc-flash.c create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/Makefile create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/inc/3d_acceleration.h create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/inc/config.h create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_API.h create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_CMD.h create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_HW.h create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/inc/openbeacon-proto.h create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/inc/pmu.h create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/inc/sound.h create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/src/3d_acceleration.c create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/src/main.c create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/src/nRF_API.c create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/src/nRF_CMD.c create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/src/pmu.c create mode 100644 openbeacon/lpc13xx/openbeacon-sensor/src/sound.c create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/.gitignore create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/Makefile create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/3d_acceleration.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/FreeRTOSConfig.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/bluetooth.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/config.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_API.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_CMD.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_HW.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/openbeacon-proto.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/pin.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/pmu.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/inc/storage.h create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/src/3d_acceleration.c create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/src/bluetooth.c create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/src/main.c create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/src/nRF_API.c create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/src/nRF_CMD.c create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/src/pin.c create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/src/pmu.c create mode 100644 openbeacon/lpc13xx/openbeacon-usb2/src/storage.c create mode 100644 openbeacon/lpc13xx/openpcd2/Makefile create mode 100644 openbeacon/lpc13xx/openpcd2/inc/FreeRTOSConfig.h create mode 100644 openbeacon/lpc13xx/openpcd2/inc/config.h create mode 100644 openbeacon/lpc13xx/openpcd2/inc/pn532.h create mode 100644 openbeacon/lpc13xx/openpcd2/inc/rfid.h create mode 100644 openbeacon/lpc13xx/openpcd2/inc/usbcfg.h create mode 100644 openbeacon/lpc13xx/openpcd2/src/main.c create mode 100644 openbeacon/lpc13xx/openpcd2/src/rfid.c create mode 100644 openbeacon/lpc13xx/rtos-simple-demo/Makefile create mode 100644 openbeacon/lpc13xx/rtos-simple-demo/inc/FreeRTOSConfig.h create mode 100644 openbeacon/lpc13xx/rtos-simple-demo/inc/config.h create mode 100644 openbeacon/lpc13xx/rtos-simple-demo/src/main.c create mode 100644 openbeacon/lpc13xx/sound/Makefile create mode 100644 openbeacon/lpc13xx/sound/inc/config.h create mode 100644 openbeacon/lpc13xx/sound/src/soundtest.c create mode 100644 openbeacon/lpc13xx/uart/Makefile create mode 100644 openbeacon/lpc13xx/uart/inc/config.h create mode 100644 openbeacon/lpc13xx/uart/src/uarttest.c create mode 100644 openbeacon/lpc13xx/usbcdc-storage/Makefile create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/cdc.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/cdcuser.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/clkconfig.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/compusb.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/compusbdesc.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/config.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/memory.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/msc.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/mscuser.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/type.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/usbcfg.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/usbcore.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/usbhw.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/usbreg.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/usbuser.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/inc/vcomdemo.h create mode 100644 openbeacon/lpc13xx/usbcdc-storage/lpc134x-vcom.inf create mode 100644 openbeacon/lpc13xx/usbcdc-storage/readme.txt create mode 100644 openbeacon/lpc13xx/usbcdc-storage/src/DiskImg.c create mode 100644 openbeacon/lpc13xx/usbcdc-storage/src/cdcuser.c create mode 100644 openbeacon/lpc13xx/usbcdc-storage/src/clkconfig.c create mode 100644 openbeacon/lpc13xx/usbcdc-storage/src/compusbdesc.c create mode 100644 openbeacon/lpc13xx/usbcdc-storage/src/main.c create mode 100644 openbeacon/lpc13xx/usbcdc-storage/src/mscuser.c create mode 100644 openbeacon/lpc13xx/usbcdc-storage/src/usbcore.c create mode 100644 openbeacon/lpc13xx/usbcdc-storage/src/usbhw.c create mode 100644 openbeacon/lpc13xx/usbcdc-storage/src/usbuser.c create mode 100644 openbeacon/lpc13xx/usbcdc/Makefile create mode 100644 openbeacon/lpc13xx/usbcdc/inc/FreeRTOSConfig.h create mode 100644 openbeacon/lpc13xx/usbcdc/inc/config.h create mode 100644 openbeacon/lpc13xx/usbcdc/inc/usbcfg.h create mode 100644 openbeacon/lpc13xx/usbcdc/lpc134x-vcom.inf create mode 100644 openbeacon/lpc13xx/usbcdc/readme.txt create mode 100644 openbeacon/lpc13xx/usbcdc/src/main.c diff --git a/openbeacon/lpc13xx/.gitignore b/openbeacon/lpc13xx/.gitignore new file mode 100644 index 0000000..22e9940 --- /dev/null +++ b/openbeacon/lpc13xx/.gitignore @@ -0,0 +1,11 @@ +*.o +*.asm +*.bin +*.elf +*.map +*~ +.cproject +.project +.settings +Default +ignore diff --git a/openbeacon/lpc13xx/core/Makefile.rules b/openbeacon/lpc13xx/core/Makefile.rules new file mode 100644 index 0000000..fe92014 --- /dev/null +++ b/openbeacon/lpc13xx/core/Makefile.rules @@ -0,0 +1,94 @@ +CROSS=arm-none-eabi- +CC=$(CROSS)gcc +LD=$(CROSS)ld +OBJCOPY=$(CROSS)objcopy +OBJDUMP=$(CROSS)objdump +AR=$(CROSS)ar +LDSCRIPT=$(CORE)linker/$(CPU).ld + +CORE=../core/ + +# +# CFLAGS common to both the THUMB and ARM mode builds +# +CFLAGS= \ +-D __$(CPU)__ \ +-D __$(ARCH)xx__ \ +-Iconfig \ +-I$(CORE)cmsis/inc \ +-I$(CORE)openbeacon/inc \ +-I$(CORE)peripherals/inc \ +-I$(CORE)peripherals/inc/usb \ +-I$(CORE)freertos/inc \ +-Wall \ +-Werror \ +-Wextra \ +-Wno-multichar \ +-Wstrict-prototypes \ +-Wno-strict-aliasing \ +-D CORTEXM3_GCC \ +-mcpu=cortex-m3 \ +-msoft-float \ +-mthumb \ +-fno-common \ +-T$(LDSCRIPT) \ +$(DEBUG) \ +$(OPTIM) \ +-fomit-frame-pointer \ +-ffunction-sections \ +-fdata-sections \ +$(APP_CFLAGS) + +LINKER_FLAGS=$(APP_LDFLAGS) -Xlinker --gc-sections -Xlinker -o$(TARGET).elf -Xlinker -M -Xlinker -Map=$(TARGET).map + +ARM_SRC= \ + $(APP_SRC) \ + $(CORE)cmsis/src/core_cm3.c \ + $(CORE)cmsis/src/system_$(ARCH)xx.c \ + $(CORE)startup/$(ARCH)xx.c \ + $(CORE)peripherals/src/uart.c \ + $(CORE)peripherals/src/gpio.c \ + $(CORE)peripherals/src/usb/cdcusbdesc.c \ + $(CORE)peripherals/src/usb/cdcuser.c \ + $(CORE)peripherals/src/usb/usbcore.c \ + $(CORE)peripherals/src/usb/usbhw.c \ + $(CORE)peripherals/src/usb/usbuser.c \ + $(CORE)freertos/src/heap_2.c \ + $(CORE)freertos/src/list.c \ + $(CORE)freertos/src/port.c \ + $(CORE)freertos/src/queue.c \ + $(CORE)freertos/src/tasks.c \ + $(CORE)openbeacon/src/msd.c \ + $(CORE)openbeacon/src/vfs.c \ + $(CORE)openbeacon/src/hid.c \ + $(CORE)openbeacon/src/spi.c \ + $(CORE)openbeacon/src/iap.c \ + $(CORE)openbeacon/src/crc16.c \ + $(CORE)openbeacon/src/xxtea.c \ + $(CORE)openbeacon/src/debug_printf.c + +# +# Define all object files. +# +ARM_OBJ = $(ARM_SRC:.c=.o) +APP_ADDITIONAL?= + +$(TARGET).bin : $(TARGET).elf + $(OBJCOPY) $(TARGET).elf -O binary $(TARGET).bin + +$(TARGET).hex : $(TARGET).elf + $(OBJCOPY) $(TARGET).elf -O ihex $(TARGET).hex + +$(TARGET).elf : $(ARM_OBJ) $(CRT0) $(BOOTLOADER) $(APP_ADDITIONAL) Makefile + $(CC) $(CFLAGS) $(ARM_OBJ) $(BOOTLOADER) $(APP_ADDITIONAL) -nostartfiles $(CRT0) $(LINKER_FLAGS) + $(OBJDUMP) -d $(TARGET).elf > $(TARGET).asm + +$(ARM_OBJ) : %.o : %.c $(LDSCRIPT) Makefile + $(CC) -c $(CFLAGS) $< -o $@ + +flash : $(TARGET).bin + ../lpc-flash/src/lpc-flash $(TARGET).bin /media/CRP\ DISABLD/firmware.bin + +clean : app_clean + find $(CORE) -name '*.o' -exec rm \{\} \; + rm -f $(TARGET).bin $(TARGET).elf $(TARGET).map $(TARGET).asm diff --git a/openbeacon/lpc13xx/core/cmsis/cmsis_readme.txt b/openbeacon/lpc13xx/core/cmsis/cmsis_readme.txt new file mode 100644 index 0000000..d345055 --- /dev/null +++ b/openbeacon/lpc13xx/core/cmsis/cmsis_readme.txt @@ -0,0 +1,28 @@ +CMSIS : Cortex Microcontroller Software Interface Standard +========================================================== +CMSIS defines for a Cortex-M Microcontroller System: + + * A common way to access peripheral registers and a + common way to define exception vectors. + * The register names of the Core Peripherals and the + names of the Core Exception Vectors. + * An device independent interface for RTOS Kernels + including a debug channel. + +By using CMSIS compliant software components, the user can +easier re-use template code. CMSIS is intended to enable the +combination of software components from multiple middleware +vendors. + +This project contains appropriate files for this MCU family +taken from CMSIS. A full copy of the CMSIS files can be found +within your tools installation directory. More information on +CMSIS can be found at: + + http://www.onarm.com/ + http://www.arm.com/ + + + + + diff --git a/openbeacon/lpc13xx/core/cmsis/docs/CMSIS changes.htm b/openbeacon/lpc13xx/core/cmsis/docs/CMSIS changes.htm new file mode 100644 index 0000000..5a17f1a --- /dev/null +++ b/openbeacon/lpc13xx/core/cmsis/docs/CMSIS changes.htm @@ -0,0 +1,320 @@ + + + +CMSIS Changes + + + + + + + + +

Changes to CMSIS version V1.20

+ +
+ +

1. Removed CMSIS Middelware packages

+

+ CMSIS Middleware is on hold from ARM side until a agreement between all CMSIS partners is found. +

+ +

2. SystemFrequency renamed to SystemCoreClock

+

+ The variable name SystemCoreClock is more precise than SystemFrequency + because the variable holds the clock value at which the core is running. +

+ +

3. Changed startup concept

+

+ The old startup concept (calling SystemInit_ExtMemCtl from startup file and calling SystemInit + from main) has the weakness that it does not work for controllers which need a already + configuerd clock system to configure the external memory controller. +

+ +

Changed startup concept

+ + + +

4. Advanced Debug Functions

+

+ ITM communication channel is only capable for OUT direction. To allow also communication for + IN direction a simple concept is provided. +

+ + +

+ For detailed explanation see file CMSIS debug support.htm. +

+ + +

5. Core Register Bit Definitions

+

+ Files core_cm3.h and core_cm0.h contain now bit definitions for Core Registers. The name for the + defines correspond with the Cortex-M Technical Reference Manual. +

+

+ e.g. SysTick structure with bit definitions +

+
+/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick
+  memory mapped structure for SysTick
+  @{
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                         /*!< Offset: 0x00  SysTick Control and Status Register */
+  __IO uint32_t LOAD;                         /*!< Offset: 0x04  SysTick Reload Value Register       */
+  __IO uint32_t VAL;                          /*!< Offset: 0x08  SysTick Current Value Register      */
+  __I  uint32_t CALIB;                        /*!< Offset: 0x0C  SysTick Calibration Register        */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1ul << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1ul << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1ul << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */
+/*@}*/ /* end of group CMSIS_CM3_SysTick */
+ +

7. DoxyGen Tags

+

+ DoxyGen tags in files core_cm3.[c,h] and core_cm0.[c,h] are reworked to create proper documentation + using DoxyGen. +

+ +

8. Folder Structure

+

+ The folder structure is changed to differentiate the single support packages. +

+ + + +

9. Open Points

+

+ Following points need to be clarified and solved: +

+ + + +

10. Limitations

+

+ The following limitations are not covered with the current CMSIS version: +

+ diff --git a/openbeacon/lpc13xx/core/cmsis/docs/CMSIS debug support.htm b/openbeacon/lpc13xx/core/cmsis/docs/CMSIS debug support.htm new file mode 100644 index 0000000..36e0446 --- /dev/null +++ b/openbeacon/lpc13xx/core/cmsis/docs/CMSIS debug support.htm @@ -0,0 +1,243 @@ + + + +CMSIS Debug Support + + + + + + + + +

CMSIS Debug Support

+ +
+ +

Cortex-M3 ITM Debug Access

+

+ The Cortex-M3 incorporates the Instrumented Trace Macrocell (ITM) that provides together with + the Serial Viewer Output trace capabilities for the microcontroller system. The ITM has + 32 communication channels which are able to transmit 32 / 16 / 8 bit values; two ITM + communication channels are used by CMSIS to output the following information: +

+ + +

Debug IN / OUT functions

+

CMSIS provides following debug functions:

+ + +

ITM_SendChar

+

+ ITM_SendChar is used to transmit a character over ITM channel 0 from + the microcontroller system to the debug system.
+ Only a 8 bit value is transmitted. +

+
+static __INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  /* check if debugger connected and ITM channel enabled for tracing */
+  if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA)  &&
+      (ITM->TCR & ITM_TCR_ITMENA)                  &&
+      (ITM->TER & (1UL << 0))  ) 
+  {
+    while (ITM->PORT[0].u32 == 0);
+    ITM->PORT[0].u8 = (uint8_t)ch;
+  }  
+  return (ch);
+}
+ +

ITM_ReceiveChar

+

+ ITM communication channel is only capable for OUT direction. For IN direction + a globel variable is used. A simple mechansim detects if a character is received. + The project to test need to be build with debug information. +

+ +

+ The globale variable ITM_RxBuffer is used to transmit a 8 bit value from debug system + to microcontroller system. ITM_RxBuffer is 32 bit wide to enshure a proper handshake. +

+
+extern volatile int ITM_RxBuffer;                    /* variable to receive characters                             */
+
+

+ A dedicated bit pattern is used to determin if ITM_RxBuffer is empty + or contains a valid value. +

+
+#define             ITM_RXBUFFER_EMPTY    0x5AA55AA5 /* value identifying ITM_RxBuffer is ready for next character */
+
+

+ ITM_ReceiveChar is used to receive a 8 bit value from the debug system. The function is nonblocking. + It returns the received character or '-1' if no character was available. +

+
+static __INLINE int ITM_ReceiveChar (void) {
+  int ch = -1;                               /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+  
+  return (ch); 
+}
+
+ +

ITM_CheckChar

+

+ ITM_CheckChar is used to check if a character is received. +

+
+static __INLINE int ITM_CheckChar (void) {
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+    return (0);                                 /* no character available */
+  } else {
+    return (1);                                 /*    character available */
+  }
+}
+ + +

ITM Debug Support in uVision

+

+ uVision uses in a debug session the Debug (printf) Viewer window to + display the debug data. +

+

Direction microcontroller system -> uVision:

+ + +

Direction uVision -> microcontroller system:

+ + +

Note

+ + +

RTX Kernel awareness in uVision

+

+ uVision / RTX are using a simple and efficient solution for RTX Kernel awareness. + No format overhead is necessary.
+ uVsion debugger decodes the RTX events via the 32 / 16 / 8 bit ITM write access + to ITM communication channel 31. +

+ +

Following RTX events are traced:

+ + +

Note

+ + + +

 

+ +
+ +

Copyright © KEIL - An ARM Company.
+All rights reserved.
+Visit our web site at www.keil.com. +

+ + + + \ No newline at end of file diff --git a/openbeacon/lpc13xx/core/cmsis/docs/CMSIS_Core.htm b/openbeacon/lpc13xx/core/cmsis/docs/CMSIS_Core.htm new file mode 100644 index 0000000..b8acb53 --- /dev/null +++ b/openbeacon/lpc13xx/core/cmsis/docs/CMSIS_Core.htm @@ -0,0 +1,1337 @@ + + + + CMSIS: Cortex Microcontroller Software Interface Standard + + + +

Cortex Microcontroller Software Interface Standard

+ +

This file describes the Cortex Microcontroller Software Interface Standard (CMSIS).

+

Version: 1.30 - 30. October 2009

+ +

Information in this file, the accompany manuals, and software is
+ Copyright © ARM Ltd.
All rights reserved. +

+ +
+ +

Revision History

+ + +
+ +

Contents

+ +
    +
  1. About
  2. +
  3. Coding Rules and Conventions
  4. +
  5. CMSIS Files
  6. +
  7. Core Peripheral Access Layer
  8. +
  9. CMSIS Example
  10. +
+ +

About

+ +

+ The Cortex Microcontroller Software Interface Standard (CMSIS) answers the challenges + that are faced when software components are deployed to physical microcontroller devices based on a + Cortex-M0 or Cortex-M3 processor. The CMSIS will be also expanded to future Cortex-M + processor cores (the term Cortex-M is used to indicate that). The CMSIS is defined in close co-operation + with various silicon and software vendors and provides a common approach to interface to peripherals, + real-time operating systems, and middleware components. +

+ +

ARM provides as part of the CMSIS the following software layers that are +available for various compiler implementations:

+ + +

These software layers are expanded by Silicon partners with:

+ + +

CMSIS defines for a Cortex-M Microcontroller System:

+ + +

+ By using CMSIS compliant software components, the user can easier re-use template code. + CMSIS is intended to enable the combination of software components from multiple middleware vendors. +

+ +

Coding Rules and Conventions

+ +

+ The following section describes the coding rules and conventions used in the CMSIS + implementation. It contains also information about data types and version number information. +

+ +

Essentials

+ + +

Recommendations

+ +

The CMSIS recommends the following conventions for identifiers.

+ + +Comments + + + +

Data Types and IO Type Qualifiers

+ +

+ The Cortex-M HAL uses the standard types from the standard ANSI C header file + <stdint.h>. IO Type Qualifiers are used to specify the access + to peripheral variables. IO Type Qualifiers are indented to be used for automatic generation of + debug information of peripheral registers. +

+ + + + + + + + + + + + + + + + + + + + + + + + +
IO Type Qualifier#defineDescription
__Ivolatile constRead access only
__OvolatileWrite access only
__IOvolatileRead and write access
+ +

CMSIS Version Number

+

+ File core_cm3.h contains the version number of the CMSIS with the following define: +

+ +
+#define __CM3_CMSIS_VERSION_MAIN  (0x01)      /* [31:16] main version       */
+#define __CM3_CMSIS_VERSION_SUB   (0x30)      /* [15:0]  sub version        */
+#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB)
+ +

+ File core_cm0.h contains the version number of the CMSIS with the following define: +

+ +
+#define __CM0_CMSIS_VERSION_MAIN  (0x01)      /* [31:16] main version       */
+#define __CM0_CMSIS_VERSION_SUB   (0x30)      /* [15:0]  sub version        */
+#define __CM0_CMSIS_VERSION       ((__CM0_CMSIS_VERSION_MAIN << 16) | __CM0_CMSIS_VERSION_SUB)
+ + +

CMSIS Cortex Core

+

+ File core_cm3.h contains the type of the CMSIS Cortex-M with the following define: +

+ +
+#define __CORTEX_M                (0x03)
+ +

+ File core_cm0.h contains the type of the CMSIS Cortex-M with the following define: +

+ +
+#define __CORTEX_M                (0x00)
+ + +

CMSIS Files

+

+ This section describes the Files provided in context with the CMSIS to access the Cortex-M + hardware and peripherals. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileProviderDescription
device.hDevice specific (provided by silicon partner)Defines the peripherals for the actual device. The file may use + several other include files to define the peripherals of the actual device.
core_cm0.hARM (for RealView ARMCC, IAR, and GNU GCC)Defines the core peripherals for the Cortex-M0 CPU and core peripherals.
core_cm3.hARM (for RealView ARMCC, IAR, and GNU GCC)Defines the core peripherals for the Cortex-M3 CPU and core peripherals.
core_cm0.cARM (for RealView ARMCC, IAR, and GNU GCC)Provides helper functions that access core registers.
core_cm3.cARM (for RealView ARMCC, IAR, and GNU GCC)Provides helper functions that access core registers.
startup_deviceARM (adapted by compiler partner / silicon partner)Provides the Cortex-M startup code and the complete (device specific) Interrupt Vector Table
system_deviceARM (adapted by silicon partner)Provides a device specific configuration file for the device. It configures the device initializes + typically the oscillator (PLL) that is part of the microcontroller device
+ +

device.h

+ +

+ The file device.h is provided by the silicon vendor and is the + central include file that the application programmer is using in + the C source code. This file contains: +

+ + + +

Interrupt Number Definition

+ +

To access the device specific interrupts the device.h file defines IRQn +numbers for the complete device using a enum typedef as shown below:

+
+typedef enum IRQn
+{
+/******  Cortex-M3 Processor Exceptions/Interrupt Numbers ************************************************/
+  NonMaskableInt_IRQn             = -14,      /*!< 2 Non Maskable Interrupt                              */
+  HardFault_IRQn                  = -13,      /*!< 3 Cortex-M3 Hard Fault Interrupt                      */
+  MemoryManagement_IRQn           = -12,      /*!< 4 Cortex-M3 Memory Management Interrupt               */
+  BusFault_IRQn                   = -11,      /*!< 5 Cortex-M3 Bus Fault Interrupt                       */
+  UsageFault_IRQn                 = -10,      /*!< 6 Cortex-M3 Usage Fault Interrupt                     */
+  SVCall_IRQn                     = -5,       /*!< 11 Cortex-M3 SV Call Interrupt                        */
+  DebugMonitor_IRQn               = -4,       /*!< 12 Cortex-M3 Debug Monitor Interrupt                  */
+  PendSV_IRQn                     = -2,       /*!< 14 Cortex-M3 Pend SV Interrupt                        */
+  SysTick_IRQn                    = -1,       /*!< 15 Cortex-M3 System Tick Interrupt                    */
+/******  STM32 specific Interrupt Numbers ****************************************************************/
+  WWDG_STM_IRQn                   = 0,        /*!< Window WatchDog Interrupt                             */
+  PVD_STM_IRQn                    = 1,        /*!< PVD through EXTI Line detection Interrupt             */
+  :
+  :
+  } IRQn_Type;
+ + +

Configuration for core_cm0.h / core_cm3.h

+

+ The Cortex-M core configuration options which are defined for each device implementation. Some + configuration options are reflected in the CMSIS layer using the #define settings described below. +

+

+ To access core peripherals file device.h includes file core_cm0.h / core_cm3.h. + Several features in core_cm0.h / core_cm3.h are configured by the following defines that must be + defined before #include <core_cm0.h> / #include <core_cm3.h> + preprocessor command. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#defineFileValueDescription
__NVIC_PRIO_BITScore_cm0.h(2)Number of priority bits implemented in the NVIC (device specific)
__NVIC_PRIO_BITScore_cm3.h(2 ... 8)Number of priority bits implemented in the NVIC (device specific)
__MPU_PRESENTcore_cm0.h, core_cm3.h(0, 1)Defines if an MPU is present or not
__Vendor_SysTickConfigcore_cm0.h, core_cm3.h(1)When this define is setup to 1, the SysTickConfig function + in core_cm3.h is excluded. In this case the device.h + file must contain a vendor specific implementation of this function.
+ + +

Device Peripheral Access Layer

+

+ Each peripheral uses a prefix which consists of <device abbreviation>_ + and <peripheral name>_ to identify peripheral registers that access this + specific peripheral. The intention of this is to avoid name collisions caused + due to short names. If more than one peripheral of the same type exists, + identifiers have a postfix (digit or letter). For example: +

+ + +
Minimal Requiements
+

+ To access the peripheral registers and related function in a device the files device.h + and core_cm0.h / core_cm3.h defines as a minimum: +

+ + +

+ These definitions allow to access the peripheral registers from user code with simple assignments like: +

+
SysTick->CTRL = 0;
+ +
Optional Features
+

In addition the device.h file may define:

+ + +

core_cm0.h and core_cm0.c

+

+ File core_cm0.h describes the data structures for the Cortex-M0 core peripherals and does + the address mapping of this structures. It also provides basic access to the Cortex-M0 core registers + and core peripherals with efficient functions (defined as static inline). +

+

+ File core_cm0.c defines several helper functions that access processor registers. +

+

Together these files implement the Core Peripheral Access Layer for a Cortex-M0.

+ +

core_cm3.h and core_cm3.c

+

+ File core_cm3.h describes the data structures for the Cortex-M3 core peripherals and does + the address mapping of this structures. It also provides basic access to the Cortex-M3 core registers + and core peripherals with efficient functions (defined as static inline). +

+

+ File core_cm3.c defines several helper functions that access processor registers. +

+

Together these files implement the Core Peripheral Access Layer for a Cortex-M3.

+ +

startup_device

+

+ A template file for startup_device is provided by ARM for each supported + compiler. It is adapted by the silicon vendor to include interrupt vectors for all device specific + interrupt handlers. Each interrupt handler is defined as weak function + to an dummy handler. Therefore the interrupt handler can be directly used in application software + without any requirements to adapt the startup_device file. +

+

+ The following exception names are fixed and define the start of the vector table for a Cortex-M0: +

+
+__Vectors       DCD     __initial_sp              ; Top of Stack
+                DCD     Reset_Handler             ; Reset Handler
+                DCD     NMI_Handler               ; NMI Handler
+                DCD     HardFault_Handler         ; Hard Fault Handler
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     SVC_Handler               ; SVCall Handler
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     PendSV_Handler            ; PendSV Handler
+                DCD     SysTick_Handler           ; SysTick Handler
+ +

+ The following exception names are fixed and define the start of the vector table for a Cortex-M3: +

+
+__Vectors       DCD     __initial_sp              ; Top of Stack
+                DCD     Reset_Handler             ; Reset Handler
+                DCD     NMI_Handler               ; NMI Handler
+                DCD     HardFault_Handler         ; Hard Fault Handler
+                DCD     MemManage_Handler         ; MPU Fault Handler
+                DCD     BusFault_Handler          ; Bus Fault Handler
+                DCD     UsageFault_Handler        ; Usage Fault Handler
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     SVC_Handler               ; SVCall Handler
+                DCD     DebugMon_Handler          ; Debug Monitor Handler
+                DCD     0                         ; Reserved
+                DCD     PendSV_Handler            ; PendSV Handler
+                DCD     SysTick_Handler           ; SysTick Handler
+ +

+ In the following examples for device specific interrupts are shown: +

+
+; External Interrupts
+                DCD     WWDG_IRQHandler           ; Window Watchdog
+                DCD     PVD_IRQHandler            ; PVD through EXTI Line detect
+                DCD     TAMPER_IRQHandler         ; Tamper
+ +

+ Device specific interrupts must have a dummy function that can be overwritten in user code. + Below is an example for this dummy function. +

+
+Default_Handler PROC
+                EXPORT WWDG_IRQHandler   [WEAK]
+                EXPORT PVD_IRQHandler    [WEAK]
+                EXPORT TAMPER_IRQHandler [WEAK]
+                :
+                :
+                WWDG_IRQHandler
+                PVD_IRQHandler
+                TAMPER_IRQHandler
+                :
+                :
+                B .
+                ENDP
+ +

+ The user application may simply define an interrupt handler function by using the handler name + as shown below. +

+
+void WWDG_IRQHandler(void)
+{
+  :
+  :
+}
+ + +

system_device.c

+

+ A template file for system_device.c is provided by ARM but adapted by + the silicon vendor to match their actual device. As a minimum requirement + this file must provide a device specific system configuration function and a global variable + that contains the system frequency. It configures the device and initializes typically the + oscillator (PLL) that is part of the microcontroller device. +

+

+ The file system_device.c must provide + as a minimum requirement the SystemInit function as shown below. +

+ + + + + + + + + + + + + + + + +
Function DefinitionDescription
void SystemInit (void)Setup the microcontroller system. Typically this function configures the + oscillator (PLL) that is part of the microcontroller device. For systems + with variable clock speed it also updates the variable SystemCoreClock.
+ SystemInit is called from startup_device file.
void SystemCoreClockUpdate (void)Updates the variable SystemCoreClock and must be called whenever the + core clock is changed during program execution. SystemCoreClockUpdate() + evaluates the clock register settings and calculates the current core clock. +
+ +

+ Also part of the file system_device.c + is the variable SystemCoreClock which contains the current CPU clock speed shown below. +

+ + + + + + + + + + + + +
Variable DefinitionDescription
uint32_t SystemCoreClockContains the system core clock (which is the system clock frequency supplied + to the SysTick timer and the processor core clock). This variable can be + used by the user application to setup the SysTick timer or configure other + parameters. It may also be used by debugger to query the frequency of the + debug timer or configure the trace clock speed.
+ SystemCoreClock is initialized with a correct predefined value.

+ The compiler must be configured to avoid the removal of this variable in + case that the application program is not using it. It is important for + debug systems that the variable is physically present in memory so that + it can be examined to configure the debugger.
+ +

Note

+ + + +

Core Peripheral Access Layer

+ +

Cortex-M Core Register Access

+

+ The following functions are defined in core_cm0.h / core_cm3.h + and provide access to Cortex-M core registers. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Function DefinitionCoreCore RegisterDescription
void __enable_irq (void)M0, M3PRIMASK = 0Global Interrupt enable (using the instruction CPSIE + i)
void __disable_irq (void)M0, M3PRIMASK = 1Global Interrupt disable (using the instruction + CPSID i)
void __set_PRIMASK (uint32_t value)M0, M3PRIMASK = valueAssign value to Priority Mask Register (using the instruction + MSR)
uint32_t __get_PRIMASK (void)M0, M3return PRIMASKReturn Priority Mask Register (using the instruction + MRS)
void __enable_fault_irq (void)M3FAULTMASK = 0Global Fault exception and Interrupt enable (using the + instruction CPSIE + f)
void __disable_fault_irq (void)M3FAULTMASK = 1Global Fault exception and Interrupt disable (using the + instruction CPSID f)
void __set_FAULTMASK (uint32_t value)M3FAULTMASK = valueAssign value to Fault Mask Register (using the instruction + MSR)
uint32_t __get_FAULTMASK (void)M3return FAULTMASKReturn Fault Mask Register (using the instruction MRS)
void __set_BASEPRI (uint32_t value)M3BASEPRI = valueSet Base Priority (using the instruction MSR)
uiuint32_t __get_BASEPRI (void)M3return BASEPRIReturn Base Priority (using the instruction MRS)
void __set_CONTROL (uint32_t value)M0, M3CONTROL = valueSet CONTROL register value (using the instruction MSR)
uint32_t __get_CONTROL (void)M0, M3return CONTROLReturn Control Register Value (using the instruction + MRS)
void __set_PSP (uint32_t TopOfProcStack)M0, M3PSP = TopOfProcStackSet Process Stack Pointer value (using the instruction + MSR)
uint32_t __get_PSP (void)M0, M3return PSPReturn Process Stack Pointer (using the instruction MRS)
void __set_MSP (uint32_t TopOfMainStack)M0, M3MSP = TopOfMainStackSet Main Stack Pointer (using the instruction MSR)
uint32_t __get_MSP (void)M0, M3return MSPReturn Main Stack Pointer (using the instruction MRS)
+ +

Cortex-M Instruction Access

+

+ The following functions are defined in core_cm0.h / core_cm3.hand + generate specific Cortex-M instructions. The functions are implemented in the file + core_cm0.c / core_cm3.c. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameCoreGenerated CPU InstructionDescription
void __NOP (void)M0, M3NOPNo Operation
void __WFI (void)M0, M3WFIWait for Interrupt
void __WFE (void)M0, M3WFEWait for Event
void __SEV (void)M0, M3SEVSet Event
void __ISB (void)M0, M3ISBInstruction Synchronization Barrier
void __DSB (void)M0, M3DSBData Synchronization Barrier
void __DMB (void)M0, M3DMBData Memory Barrier
uint32_t __REV (uint32_t value)M0, M3REVReverse byte order in integer value.
uint32_t __REV16 (uint16_t value)M0, M3REV16Reverse byte order in unsigned short value.
sint32_t __REVSH (sint16_t value)M0, M3REVSHReverse byte order in signed short value with sign extension to integer.
uint32_t __RBIT (uint32_t value)M3RBITReverse bit order of value
uint8_t __LDREXB (uint8_t *addr)M3LDREXBLoad exclusive byte
uint16_t __LDREXH (uint16_t *addr)M3LDREXHLoad exclusive half-word
uint32_t __LDREXW (uint32_t *addr)M3LDREXWLoad exclusive word
uint32_t __STREXB (uint8_t value, uint8_t *addr)M3STREXBStore exclusive byte
uint32_t __STREXB (uint16_t value, uint16_t *addr)M3STREXHStore exclusive half-word
uint32_t __STREXB (uint32_t value, uint32_t *addr)M3STREXWStore exclusive word
void __CLREX (void)M3CLREXRemove the exclusive lock created by __LDREXB, __LDREXH, or __LDREXW
+ + +

NVIC Access Functions

+

+ The CMSIS provides access to the NVIC via the register interface structure and several helper + functions that simplify the setup of the NVIC. The CMSIS HAL uses IRQ numbers (IRQn) to + identify the interrupts. The first device interrupt has the IRQn value 0. Therefore negative + IRQn values are used for processor core exceptions. +

+

+ For the IRQn values of core exceptions the file device.h provides + the following enum names. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Core Exception enum ValueCoreIRQnDescription
NonMaskableInt_IRQnM0, M3-14Cortex-M Non Maskable Interrupt
HardFault_IRQnM0, M3-13Cortex-M Hard Fault Interrupt
MemoryManagement_IRQnM3-12Cortex-M Memory Management Interrupt
BusFault_IRQnM3-11Cortex-M Bus Fault Interrupt
UsageFault_IRQnM3-10Cortex-M Usage Fault Interrupt
SVCall_IRQnM0, M3-5Cortex-M SV Call Interrupt
DebugMonitor_IRQnM3-4Cortex-M Debug Monitor Interrupt
PendSV_IRQnM0, M3-2Cortex-M Pend SV Interrupt
SysTick_IRQnM0, M3-1Cortex-M System Tick Interrupt
+ +

The following functions simplify the setup of the NVIC. +The functions are defined as static inline.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameCoreParameterDescription
void NVIC_SetPriorityGrouping (uint32_t PriorityGroup)M3Priority Grouping ValueSet the Priority Grouping (Groups . Subgroups)
uint32_t NVIC_GetPriorityGrouping (void)M3(void)Get the Priority Grouping (Groups . Subgroups)
void NVIC_EnableIRQ (IRQn_Type IRQn)M0, M3IRQ NumberEnable IRQn
void NVIC_DisableIRQ (IRQn_Type IRQn)M0, M3IRQ NumberDisable IRQn
uint32_t NVIC_GetPendingIRQ (IRQn_Type IRQn)M0, M3IRQ NumberReturn 1 if IRQn is pending else 0
void NVIC_SetPendingIRQ (IRQn_Type IRQn)M0, M3IRQ NumberSet IRQn Pending
void NVIC_ClearPendingIRQ (IRQn_Type IRQn)M0, M3IRQ NumberClear IRQn Pending Status
uint32_t NVIC_GetActive (IRQn_Type IRQn)M3IRQ NumberReturn 1 if IRQn is active else 0
void NVIC_SetPriority (IRQn_Type IRQn, uint32_t priority)M0, M3IRQ Number, PrioritySet Priority for IRQn
+ (not threadsafe for Cortex-M0)
uint32_t NVIC_GetPriority (IRQn_Type IRQn)M0, M3IRQ NumberGet Priority for IRQn
uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)M3IRQ Number, Priority Group, Preemptive Priority, Sub PriorityEncode priority for given group, preemptive and sub priority
NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)M3IRQ Number, Priority, pointer to Priority Group, pointer to Preemptive Priority, pointer to Sub PriorityDeccode given priority to group, preemptive and sub priority
void NVIC_SystemReset (void)M0, M3(void)Resets the System
+

Note

+ + + +

SysTick Configuration Function

+ +

The following function is used to configure the SysTick timer and start the +SysTick interrupt.

+ + + + + + + + + + + + + + +
NameParameterDescription
uint32_t SysTickConfig + (uint32_t ticks)ticks is SysTick counter reload valueSetup the SysTick timer and enable the SysTick interrupt. After this + call the SysTick timer creates interrupts with the specified time + interval.
+
+ Return: 0 when successful, 1 on failure.
+
+ + +

Cortex-M3 ITM Debug Access

+ +

The Cortex-M3 incorporates the Instrumented Trace Macrocell (ITM) that +provides together with the Serial Viewer Output trace capabilities for the +microcontroller system. The ITM has 32 communication channels; two ITM +communication channels are used by CMSIS to output the following information:

+ +

Note

+ + +

The prototype of the ITM_SendChar routine is shown in the +table below.

+ + + + + + + + + + + + + + +
NameParameterDescription
void uint32_t ITM_SendChar(uint32_t chr)character to outputThe function outputs a character via the ITM channel 0. The + function returns when no debugger is connected that has booked the + output. It is blocking when a debugger is connected, but the + previous character send is not transmitted.

+ Return: the input character 'chr'.
+ +

+ Example for the usage of the ITM Channel 31 for RTOS Kernels: +

+
+  // check if debugger connected and ITM channel enabled for tracing
+  if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA) &&
+  (ITM->TCR & ITM_TCR_ITMENA) &&
+  (ITM->TER & (1UL << 31))) {
+    // transmit trace data
+    while (ITM->PORT31_U32 == 0);
+    ITM->PORT[31].u8 = task_id;      // id of next task
+    while (ITM->PORT[31].u32 == 0);
+    ITM->PORT[31].u32 = task_status; // status information
+  }
+ + +

Cortex-M3 additional Debug Access

+ +

CMSIS provides additional debug functions to enlarge the Cortex-M3 Debug Access. +Data can be transmitted via a certain global buffer variable towards the target system.

+ +

The buffer variable and the prototypes of the additional functions are shown in the +table below.

+ + + + + + + + + + + + + + + + + + + + + + + + +
NameParameterDescription
extern volatile int ITM_RxBuffer Buffer to transmit data towards debug system.

+ Value 0x5AA55AA5 indicates that buffer is empty.
int ITM_ReceiveChar (void)noneThe nonblocking functions returns the character stored in + ITM_RxBuffer.

+ Return: -1 indicates that no character was received.
int ITM_CheckChar (void)noneThe function checks if a character is available in ITM_RxBuffer.

+ Return: 1 indicates that a character is available, 0 indicates that + no character is available.
+ + +

CMSIS Example

+

+ The following section shows a typical example for using the CMSIS layer in user applications. + The example is based on a STM32F10x Device. +

+
+#include "stm32f10x.h"
+
+volatile uint32_t msTicks;                       /* timeTicks counter */
+
+void SysTick_Handler(void) {
+  msTicks++;                                     /* increment timeTicks counter */
+}
+
+__INLINE static void Delay (uint32_t dlyTicks) {
+  uint32_t curTicks = msTicks;
+
+  while ((msTicks - curTicks) < dlyTicks);
+}
+
+__INLINE static void LED_Config(void) {
+  ;                                              /* Configure the LEDs */
+}
+
+__INLINE static void LED_On (uint32_t led) {
+  ;                                              /* Turn On  LED */
+}
+
+__INLINE static void LED_Off (uint32_t led) {
+  ;                                              /* Turn Off LED */
+}
+
+int main (void) {
+  if (SysTick_Config (SystemCoreClock / 1000)) { /* Setup SysTick for 1 msec interrupts */
+    ;                                            /* Handle Error */
+    while (1);
+  }
+  
+  LED_Config();                                  /* configure the LEDs */                            
+ 
+  while(1) {
+    LED_On (0x100);                              /* Turn  on the LED   */
+    Delay (100);                                 /* delay  100 Msec    */
+    LED_Off (0x100);                             /* Turn off the LED   */
+    Delay (100);                                 /* delay  100 Msec    */
+  }
+}
+ + + \ No newline at end of file diff --git a/openbeacon/lpc13xx/core/cmsis/docs/License.doc b/openbeacon/lpc13xx/core/cmsis/docs/License.doc new file mode 100644 index 0000000000000000000000000000000000000000..b6b8acecc137bca709444106cba045d3d01daedd GIT binary patch literal 39936 zcmeI53w&Hvz3*2ZZBuBVr4Jqg-IP)q2qBafkZ1Flwy9}S@}SfrFqxSo(8g!^moP(odvq z?1-P~rSnWxy)k$1Uu5y=1Ks4`kH|Iruxr=e*@t}heulg3&0El=OJVTdj~gA%QG|Cj zO)+Lpu`#RnaU+7^2}E5={8@zmi%^7jOmp+yxSuhvaXWRk`>gP6Zlm7w=Y;hFFQKlHfxaQ}ERf8S{OfPon%>RWR!E`Qf)aD%tq)`9jqjy!`t7(C??8 zN6#+|{a z7IHL08H+OOzPDoR@5VzOOM$dFX^6)r68iU4Fg?y;)TbzaJ;w zfA-UD=0C%aU$0-4&mXn(2YTc4*$@5p{bxV)%jXOIe4|5O9{n(1c|ZOc=#m^xbd7Gu zfA;z8Kj#bm`hEQn3@<~+{E9)35(eW{#(!42uD!^k`MrctL%f<0wU(VHKEEdlwYX3W z-7+I9V|p%J1rF>!2i7P1Q%++%5=%s4PA2KJrwO`aPAl=m)Fq=aC!B~nt$ndbyfYpN zXX43()0s@!Ty@D*Cbq>{6OW{lkz^v1O7`@`QWWmY41`lLry-Gvr8>h@)S97|a4LFY zd3oEahE^xkRPVI6hFYA)hPqHwUC60f*%At^2{pAjq}Di%p_Mg_fyl+zdl|P?IJKd+ zb)is`v%b0ASsZF;TSYZBPHRKc%Epk>&{W@WMnipjO=G3g+~UW&)lqvx+xiNphQ@1J z*3kBvhPF_>vv>hd3o4uy6reT{<}|Ocx2?_XEl^k2Tn~v9Yh4?vYgo}xSJT$e+~m~M z)itkKThp|jw#g3V9+g#&ZGed8rpEQox`xI^o2A*!K>ccG{L0&!Z4YUtu9;5R2HRHE zwAol%4y|o-Y8o4TO4~v$Yg+04C^~A_J9QBC5jB5(gUiuv;tUB5O|5Ozpd=!i#mIFH z(AF+qDypt|t?in}WR)VQ>1Yg>?)HYB1Y)Yjgjv6_SwAe>cBdHMB$Il0a0jfE3wI|wV_iv}DxJ|Jq`SjCJx(H-apH+cPd`0e9Ivp2 z;=O%6vEEoB<7%X2r;|i)rJTP0j-GhBI~H})L88-6D%KfGNzFy6%T_U>yC+dIRfiLU zPAn0o4iOiNbSIKM$*y=ztPW?K-teH)5pxo;NGzQWrv{}md&8Sz4hpd!)v4lrsbsW2 zl2KG2`ce8)l*J&?))7fUx@r_7#u8HLbo6H&X-{>VlD+9z&t|g6w)CZFwP(;t$1)lO zO52{q)1%b$;#gHzm7{jzQpcSsR5QJbrYnhrhh4EmEEUcqQ$%!xBb&Umo_I$poDyY_ z?sC(wqtXed)3M$TRYxM+*~DFtKPNex!#(k+HySA?8tdrqa?<`vK%s8bzgC5loNylu zaF-G&NcM>s@jE@3&cu4vKr|KKOap%Llbn`@);gFH>5kKAreC$dXN>~6d$s-q6D#a! zGMv5P^rnGiYE#-SVtw6%Y1-{^dcuRr{tW%>goBw_7wsb!k$5W7AJ0H~I^LB?pCm#S z$2V6vEp3g%Ea{GSbvr$=&9NRtN+aUS-~`n%!OH!`Ze>eNQ(J5KF)S0U{T&!|xWY*eB`cXC2o)m|OQezfm_xl<9wnc!$>|FZYNDx;{zSO5 zGu{)o{K|C4Q&CcpacGp4u(+ebiBSq75SC;#?oKu@inclsD_7*lvo9oVzK}oq!ov8InkN-=GR)6$F&|m1#1josM`yQ&%izL>aK$-GP)72AS3N+YE1V}@Z!qhG|nN+*>Z4EMlpakkPy{(7PVaps+6v9+^K zEJu$`cQporCz3V#BQ#Q0&-V4F`jRLYq%|tJOZHh^*&W`jN#jMuqLoN{q91FE=@HB@ z9IHIZPRLX_ScPJtJNmWx)BViLL8ZYyJO2mbG#iblGpRUANhzLkLwR+_Bi&ZVAUnA= z*-3OVUU7$e(N}4ozCp-DFggdVz@(+EJ>zqf)w!7A^_Dh~tw&<(uXum2 zOsaIJd=z=Mvs2U9YL(PxmJ=2~@hpYT$!I-*S7`*-E``JE*zjDEov;M0(l&~jV@-H1 zFs=&lX1k^gn#5HDEDd&il#3yk&V@j74pY+;9&q#6d6ck2k?zMd*M zrqXKCaOAxHxLt!C%lt|w6VIR;#U<&DSXw5@#HvgM^6TTQl9bAf#S>L{O!UHGmZOYZ z<41bIn=S%3=4?M1;ecHtGK@(w6|+oLbB3vA#n^B)ZkIIF7UiLFS-?fz*$$* zqBXoBge!aI+LlmjYo*h$W^H2wrQ`*))wH#@HMguMwyCbMy&i|E5;w37H=xb+JFN#< zX({px1}eo5S`%uiTSXf+wGEB9t(8tIMOs(X)Tv(QbUa)e+tl3D(6pk323+@<)>kyN zH9?W}XKS3bH7#uob?uEcEza8ZmbJ~Tp-C}9j*m-w$O*NyG`F;RY@oBDmNV$MnAy^> za#fpLIsuJswHR(4#tD;#I)%KUQ8ylgQH<&pN*Kz9<8T8o5h zd1vP+=6>c4WbF{w? zS10U5dcyJE>|%xqO<`0IdeCP<1xBO#D^qmXu7i2QHrp7YtZEESXqosG&Vp>E3p|%t zbWwL4p8H!;*1GW@AQZI+O|Fi>_UnagFV$TNu=ebj$pn!-rQF=IKvg=M7=4>QFhB(Ezd01)hM7RMvJ$qUxSO&mCRh3W?u0ScFLs>xw~6 zr>r=)MbQ@PV)3QPa1?g5dAkD%zf(}&i;b&+p?DN~ zEu89zb89Oexy*N6;cr5Z~NOO^(1jBrsPB2P<8 z50-l@C38l$y`&?Sip1giAnsl`oz&g{3GxBFCRF19`vP(%{Y{D7tsw5363~eUEN4ls zWr)FMyF#*MBSqRqq$(YaN9@*tJH@j3B1|OogsXkzN82q3*@+zU4mU?w2DDz?j3aNdpLvhvULhXC!s;OSYtM1$} zX^0;7#oPK9vdJOdZuCfs$N2pT1c;p~_Mkd#*J!{O{7Lj>TQFTDD;x&Ov^V{ zCs=8$E>Nf7WDbh6f-how!&~CL{k_y;RTmT{2V5oZ?K5dhgZae<%<&#;$0ydxudLFs zR-^++!PUiLtOCEZuQdNyf|?UUoYy5@%`iG>v*avVOZ+#AI?eqqGsi zIKQZ8 zTJ9`}Mx8ZWxaM37oU@LQbF?zV`?@t)@pGz=L$ztq`LZqxzndlpY7B)*WnJV z4YjnbcNWwk@BNHYlO<$m{UO?I1i*i8hiyj1QzXK%rbEIp2mC?+zY+| zUjFgR-@5DitsA$l+q&X}!$p`gxBJ$zkD7Vivris0b*uL=&8v&e>ELV-=Gh!Dulvhq zY|EWSX{C*m{q2F|Yfe;&oA8IIum2K;+aF5mOR8}FjFmx5(} z5PbM%@Zo{H51$XFjCcqp1n=QR$-u%s*cwSgmz z;anlP?DJOhm@#mY=e;jGuz1#GzkK^_!gC32`kNKo?V+YX`p82H)YyHY40p?ZstAe!qC>1tRF&;Xv zTT^D-Jggv^CP4-3SEAKLVxBV%9e(@;r=T0#omX<_pmgcQFXm3mmd;y$R;Me+s2+@6 z0jN(Ca2$G}ChsarTk3_|mkHaVrhIGeEREe)!G8e{g0F+e!H>Ydfqw^o1kIcZUkhR& z13nIJ05^g!fv7*>25~FJ5rw z__fiZte{cSF_IVNAdN*DWI#W-0DKDE0{%O=mUVs`coIAX{sm;$f9_ufe**s>%*P&B z0PX{ig6{y?2s?kd^XZ+B?R@$hPv8CYV>f+bAiiPshSmHGkL}32?A*|DnR70~=}({Y z^So)lKKa{u)AH6i8Qnu3l^>U<(6(kpYu@%H1^N1vSF*Ak$(w^#mt?+?x8}R{cqV7s zej1-SoTQ!$_64VbCeRGR;5G0DXv4-k2b>4e;0ACHxDPxHehPj8ehpp)vI*Y+zXxxD zU0@a`-46qcz~Nvi*aU6@H-lTiz2H&sZSc?F8Sv_}+h2X?)jMB(_SI+Yk8WPw{_IuH zUUlbH7kK|VFX+4~JAXE;`0V&hivCtKTuvxwRxapOt_d7eDvt_kx@xcX7gg!E)7 zpRhKwSo|&HIQjwLXfTbxJ}Cp!!CG)SXa{G30dPLJ99#je2KR!Oz#HHl@cIj{KmPE2 zw|(ZKzS}Ok?K9`x)^yP+BPVzEDJ#<(KK!$svN^1AkDhhj1UY`aWJm5C6KIOO+8|5a zU9*qOU2`@^-c_2mrKR)D_Iy6-aKH2Bn54u_C@E&P=BdWJ>|kTApU?O?#{3pE;}fg} zr-M&|E5WCLe1)sPXTde#T5vts25tm5frIfS=7SyCvF7HL;KOslhY=|w9{wemZN$Tf zZ13jb$zav*;{*QQ@b&2MZT7BoZ_^dM;iF5;9($Ye?PaET+pNWh78Sd3_RlLv`*3+Z zJ_*|x4=-`C*aU6{KLalUhrdWW1bhsf4L%QU2mc$q1PJ&&_F^6Ck+z{FbS6X^>ks6Vfk$x@J4 zk3zveCzs`{-x2>G1&1;BD?k`r3#1Ef0;f2}EC&r>JxGHL_^;rfz-z$Q89TXu6TJG9 zNBQ@)&+Fe+{JU_|$5xt2UF^xpd&=(>1@`3VRbF2#%M(qkoccGL<42YMBX15@I`WPz zb+|dk8yh!AUP`ml`e&5uY@KR*T&u*)(RdXff(`)ZEx`T{vm+|MI_H=pF(0kZ?-_h+_G@{|iIX|& z%(j|W(#Dfh`Xb3NyCe7PZWk?z=A6r)fMd02hL-KzqUZ z+y4>U!N1q^^snFgHws5&8}aa~V79{j`_6%YrD%8eOK1AF<;*;`tJ=!`#X08+y8pYy`+*tPe7E=mG*lmuu3la|*X)Cvc`L6aOS63*zRN}x zZVDWDA33lbQ}K7Zip_E}BP)DUO_NEQl<75L(?i=*Kl@=E?PtzeRa6=#>|HgzEDbVX zEOGUwX8F!tUoiD%#uPtw9#1jTNsax~nK6!8%Y6!T+220XP239FO^~Xq#l+3;cYU33 zxRx2FjS?Ny5F__UDi1XKzKMIX^rurz(HVG zAOW_5!RhRxajNRa2*lHR3(s5j47+u|0jj@@o!RU6Wp{;L`QL(OcGcE`)4?afmEcq0 zCU7wQaKHsXJ8zmQDTnVcNfID0drv#r`(S*&duZIP{BR?ipT1}B>3{Y<*jBzgLHe25 z*|MBK$leF*4BiLp&q4oH_m1L8F#o%}SDnQ<%G$OVj=!`_=u2!@fzN_#z_s9dunpV@ ze3_Xakeds+-|ETF&CqN=Mx}7bgYLNsX)YfMeDV13L6Hegwb*NjU%|bK#+eT#|0rpD zS9`r3A{5-q_B~J9czVL}W#%|_=1Ci;&Y_Z9e5w=<2`>&*nOn@c_MO=KuY-eY@_W_4 zwlBH)GwuCI+xTfyJopme;{F4&M1!Ze9=B zn|2pOJ=usO`7OCFx{>-cG;ixNi@&Q?0iWnxD8v zMss*SAYCP$gjs9k`cTC1;@TVnRJTsJ=q-oJY94Y>!8kx^defnKEBZbRJ_4G-Mc`WS zIdCVq3)~GJ0{;ZQ34RUq9z=bZJukEChN0Q*_V*C`d%$oE9oumNxoC2SC@#jM!3VK^ zqqMD{=jG<$-)RE4-}l^QhK7dpcNH^n?TdF@N5V`~wnO_Iwh(h;Z&R{E63o`!4z?1A zpT5JNK|E%!VzY-WXDBm;Smm!J+{cSABA!15!P(w(huHTB4a_u8s2PJNY|2b&iH7sE zk|NvotQ{&~lL?b>{t|F0xB_VLlY{XLcpe#a+_;Nrgwr6@ z4TtY(NaS1h_uaN~;w0M80G$f@JY0=zT?a0rCl>>`-0Gpf#QSbmK37XzcosYdd~V29 zAI%ZD?mjn4=;=s^BgGTI<(l%byTIj-i#7yY-VP8e9!iG(4d~horqF4$_tAM^OYZ1eK@b4)|~T=O-~R9}7Ee&(qI_BZoW2bv9==bLjY9rMTehnPb)Ei}cv zK|FuO;pWAXBaBW<=-lDG$!fb*^@~%EHT$nS*60Mv_YXMHJkxoy(K-A#SJasM!YfQI zf3$Vil+{LWt98moXJ_@-PKow)M(1)uQ`Z}923=aZ!E88TgPGd3!9>qL+vvQ++_S>w zbG02t@53+LZTg_xV)mW9H3;+l@|y>&)+~XMNA;&5qvh zu0H#5^U8)FnR{!VG9_pH*tB2twE5-v|7wnQerj}5_jKo36FL4_qZ2(Z)x2o*R|z_S zaAfx{%qe^P%IN&M-XZJ6LVM$D=IQd+%}e#K8=ZpeDEXb4y5%kNO3&M-YVj^R#&@Ha zwH0+Un#kWavfD(YY8DF>33RV_?OJYz{Ml{HnIAe~&*3LO4=T%7HQGg6E{(yDcFrVj z?d}-0e}wiFu~vF=e0J&+K@r zm@mKEEaxnJ;&S1|6F;+}*bYxEENNhx7E4c4qGaZ=gd<}WqwA0oW0wK9H8-yCJ6R5t zO}k^tL#*_dTypSI{ej&6_N(o(GPa_^h26PEj{!sMU1i69{5*}5FVBAb$Z*w}dY-;x z*WN6>ry280Q2`Z`|JORie0<>30`B?BYpiyuKTtj!mLRc{W|Qn zC;4q>Hn~sTHf&`%jFH2gY1+|mV6ODp_aB;jdRGz#aY`rbOic2QMYXx*LuQMuzb~7| zrEHqHkobFfC-M@KU60;KP_N$kXjY|t@(bbn#({Uxx~Rr6^%oKI(kE`;`KRXYnfF{< zW{y1k>(5ma_b>^PBc-aDs@ymf(@ts2zEZ5JXvv)TC?7Kzw{?27d z{a+@6_ZkE7L7`R#g<3Nd`t)&IxC$I7aG=0}0tX5lC~%;_fdU5#94K(0z<~k>K7bs^ z=l{!(EdI$4e{yTphh|=X6aIhYpYE$CZpx^*K78*=Ab*{J{T|mx?^9kd1hfb6Nx-2- za}Cg&JMA6F*S`bEm;VZoFMmJK+r9q=pY7_V5-K*zq`u_%4TGWR6CBEpY28z=w7?rpP zh~`^>{Piz;&q~w2$H-3@+N@%sAKlnuOVNBb%KHSNt=-=p(L2zw-#T>ZRjYjQFuQA^ z4;2zsxC$I7aG=0}0tX5lC~%;_fdU5#94K(0z<~k>{_Z&-|5N^@{7!j)@=fKn>V3U@ zY`v$~yLma9^26nm%g2^KDo;~Bz24!=cb8|W)3oy6N1x8ssaqYL;i#DPF6R?E;1I9? zyu$&Og@lKJMc{C-7*v2Gz>%O590jU?+*0|^#{iX;|Icw9vkV*ujt3_Io$6KkNrWeZ zQ^2W!qcmnYr~yiU8`OLEdKNwimrly*?|~f?vZr`boPyh(YaXXZd_GBrrcReMx%)N* zE9`^!^VFQxm*~ubB8R-VW9(@-_b;ivsND+o;_oiizT{TnWC|ZjrU$)qTMTBZw*JR68N!YliaPCm8>a?PG-@qtzTACE&pQv*4=K5Vs z`{H;hm~8txd*YveoHC~8yGPFn9{+9UC)t0UTl3p5GIjJ;XUUrRTkVZX*{y3Iw3pxZ zWc#lM&fBe4#?Sn2+8@8h-AjEh?Mrq)D7r4lr^3C zU;jHIYZ|O+)p<3d?3~tpm7iX9g89RTAN+I9wcVQ;h1?Ty;4iuU4^_6tk7NCBgs4Yd zGXeW;_)97i(V8p0u>QZd^_G g!+ZG+YJlCX=dW%57tSBCAIe6m^l&ZsOP@db55$o82LJ#7 literal 0 HcmV?d00001 diff --git a/openbeacon/lpc13xx/core/cmsis/history.txt b/openbeacon/lpc13xx/core/cmsis/history.txt new file mode 100644 index 0000000..6bb4084 --- /dev/null +++ b/openbeacon/lpc13xx/core/cmsis/history.txt @@ -0,0 +1,8 @@ +History of updates to CMSISv1p30_LPC13xx +======================================== + +18 February 2010 +---------------- +system_LPC13xx.c updated to new version (dated 18 February 2010), +changing value of SYSPLLCTRL_Val from 0x05 to 0x25 + diff --git a/openbeacon/lpc13xx/core/cmsis/inc/LPC13xx.h b/openbeacon/lpc13xx/core/cmsis/inc/LPC13xx.h new file mode 100644 index 0000000..3a2cb36 --- /dev/null +++ b/openbeacon/lpc13xx/core/cmsis/inc/LPC13xx.h @@ -0,0 +1,532 @@ +/**************************************************************************//** + * @file lpc13xx.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File for + * NXP LPC13xx Device Series + * @version V1.01 + * @date 19. October 2009 + * + * @note + * Copyright (C) 2009 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + + +#ifndef __LPC13xx_H__ +#define __LPC13xx_H__ + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ + +typedef enum IRQn { +/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ + +/****** LPC13xx Specific Interrupt Numbers *******************************************************/ + WAKEUP_PIO0_0_IRQn = 0, /*!< All I/O pins can be used as wakeup source. */ + WAKEUP_PIO0_1_IRQn = 1, /*!< There are 40 pins in total for LPC17xx */ + WAKEUP_PIO0_2_IRQn = 2, + WAKEUP_PIO0_3_IRQn = 3, + WAKEUP_PIO0_4_IRQn = 4, + WAKEUP_PIO0_5_IRQn = 5, + WAKEUP_PIO0_6_IRQn = 6, + WAKEUP_PIO0_7_IRQn = 7, + WAKEUP_PIO0_8_IRQn = 8, + WAKEUP_PIO0_9_IRQn = 9, + WAKEUP_PIO0_10_IRQn = 10, + WAKEUP_PIO0_11_IRQn = 11, + + WAKEUP_PIO1_0_IRQn = 12, + WAKEUP_PIO1_1_IRQn = 13, + WAKEUP_PIO1_2_IRQn = 14, + WAKEUP_PIO1_3_IRQn = 15, + WAKEUP_PIO1_4_IRQn = 16, + WAKEUP_PIO1_5_IRQn = 17, + WAKEUP_PIO1_6_IRQn = 18, + WAKEUP_PIO1_7_IRQn = 19, + WAKEUP_PIO1_8_IRQn = 20, + WAKEUP_PIO1_9_IRQn = 21, + WAKEUP_PIO1_10_IRQn = 22, + WAKEUP_PIO1_11_IRQn = 23, + + WAKEUP_PIO2_0_IRQn = 24, + WAKEUP_PIO2_1_IRQn = 25, + WAKEUP_PIO2_2_IRQn = 26, + WAKEUP_PIO2_3_IRQn = 27, + WAKEUP_PIO2_4_IRQn = 28, + WAKEUP_PIO2_5_IRQn = 29, + WAKEUP_PIO2_6_IRQn = 30, + WAKEUP_PIO2_7_IRQn = 31, + WAKEUP_PIO2_8_IRQn = 31, + WAKEUP_PIO2_9_IRQn = 33, + WAKEUP_PIO2_10_IRQn = 34, + WAKEUP_PIO2_11_IRQn = 35, + + WAKEUP_PIO3_0_IRQn = 36, + WAKEUP_PIO3_1_IRQn = 37, + WAKEUP_PIO3_2_IRQn = 38, + WAKEUP_PIO3_3_IRQn = 39, + + I2C_IRQn = 40, /*!< I2C Interrupt */ + TIMER_16_0_IRQn = 41, /*!< 16-bit Timer0 Interrupt */ + TIMER_16_1_IRQn = 42, /*!< 16-bit Timer1 Interrupt */ + TIMER_32_0_IRQn = 43, /*!< 32-bit Timer0 Interrupt */ + TIMER_32_1_IRQn = 44, /*!< 32-bit Timer1 Interrupt */ + SSP_IRQn = 45, /*!< SSP Interrupt */ + UART_IRQn = 46, /*!< UART Interrupt */ + USB_IRQn = 47, /*!< USB Regular Interrupt */ + USB_FIQn = 48, /*!< USB Fast Interrupt */ + ADC_IRQn = 49, /*!< A/D Converter Interrupt */ + WDT_IRQn = 50, /*!< Watchdog timer Interrupt */ + BOD_IRQn = 51, /*!< Brown Out Detect(BOD) Interrupt */ + EINT3_IRQn = 53, /*!< External Interrupt 3 Interrupt */ + EINT2_IRQn = 54, /*!< External Interrupt 2 Interrupt */ + EINT1_IRQn = 55, /*!< External Interrupt 1 Interrupt */ + EINT0_IRQn = 56, /*!< External Interrupt 0 Interrupt */ +} IRQn_Type; + + +/* + * ========================================================================== + * ----------- Processor and Core Peripheral Section ------------------------ + * ========================================================================== + */ + +/* Configuration of the Cortex-M3 Processor and Core Peripherals */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + + +#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */ +#include "system_LPC13xx.h" /* System Header */ + + +/******************************************************************************/ +/* Device Specific Peripheral registers structures */ +/******************************************************************************/ + +#if defined ( __CC_ARM ) +#pragma anon_unions +#endif + +/*------------- System Control (SYSCON) --------------------------------------*/ +typedef struct { + __IO uint32_t SYSMEMREMAP; /* Sys mem. Remap, Offset 0x0 */ + __IO uint32_t PRESETCTRL; + __IO uint32_t SYSPLLCTRL; /* Sys PLL control */ + __IO uint32_t SYSPLLSTAT; + __IO uint32_t USBPLLCTRL; /* USB PLL control, offset 0x10 */ + __IO uint32_t USBPLLSTAT; + uint32_t RESERVED0[2]; + + __IO uint32_t SYSOSCCTRL; /* Offset 0x20 */ + __IO uint32_t WDTOSCCTRL; + __IO uint32_t IRCCTRL; + uint32_t RESERVED1[1]; + __IO uint32_t SYSRESSTAT; /* Offset 0x30 */ + uint32_t RESERVED2[3]; + __IO uint32_t SYSPLLCLKSEL; /* Offset 0x40 */ + __IO uint32_t SYSPLLCLKUEN; + __IO uint32_t USBPLLCLKSEL; + __IO uint32_t USBPLLCLKUEN; + uint32_t RESERVED3[8]; + + __IO uint32_t MAINCLKSEL; /* Offset 0x70 */ + __IO uint32_t MAINCLKUEN; + __IO uint32_t SYSAHBCLKDIV; + uint32_t RESERVED4[1]; + + __IO uint32_t SYSAHBCLKCTRL; /* Offset 0x80 */ + uint32_t RESERVED5[4]; + __IO uint32_t SSPCLKDIV; + __IO uint32_t UARTCLKDIV; + uint32_t RESERVED6[4]; + __IO uint32_t TRACECLKDIV; + + __IO uint32_t SYSTICKCLKDIV; /* Offset 0xB0 */ + uint32_t RESERVED7[3]; + + __IO uint32_t USBCLKSEL; /* Offset 0xC0 */ + __IO uint32_t USBCLKUEN; + __IO uint32_t USBCLKDIV; + uint32_t RESERVED8[1]; + __IO uint32_t WDTCLKSEL; /* Offset 0xD0 */ + __IO uint32_t WDTCLKUEN; + __IO uint32_t WDTCLKDIV; + uint32_t RESERVED9[1]; + __IO uint32_t CLKOUTCLKSEL; /* Offset 0xE0 */ + __IO uint32_t CLKOUTUEN; + __IO uint32_t CLKOUTDIV; + uint32_t RESERVED10[5]; + + __IO uint32_t PIOPORCAP0; /* Offset 0x100 */ + __IO uint32_t PIOPORCAP1; + uint32_t RESERVED11[18]; + + __IO uint32_t BODCTRL; /* Offset 0x150 */ + uint32_t RESERVED12[1]; + __IO uint32_t SYSTCKCAL; + uint32_t RESERVED13[41]; + + __IO uint32_t STARTAPRP0; /* Offset 0x200 */ + __IO uint32_t STARTERP0; + __IO uint32_t STARTRSRP0CLR; + __IO uint32_t STARTSRP0; + __IO uint32_t STARTAPRP1; + __IO uint32_t STARTERP1; + __IO uint32_t STARTRSRP1CLR; + __IO uint32_t STARTSRP1; + uint32_t RESERVED14[4]; + + __IO uint32_t PDSLEEPCFG; /* Offset 0x230 */ + __IO uint32_t PDAWAKECFG; + __IO uint32_t PDRUNCFG; + uint32_t RESERVED15[110]; + __I uint32_t DEVICE_ID; +} LPC_SYSCON_TypeDef; + + +/*------------- Pin Connect Block (IOCON) --------------------------------*/ +typedef struct { + __IO uint32_t PIO2_6; + uint32_t RESERVED0[1]; + __IO uint32_t PIO2_0; + __IO uint32_t RESET_PIO0_0; + __IO uint32_t PIO0_1; + __IO uint32_t PIO1_8; + uint32_t RESERVED1[1]; + __IO uint32_t PIO0_2; + + __IO uint32_t PIO2_7; + __IO uint32_t PIO2_8; + __IO uint32_t PIO2_1; + __IO uint32_t PIO0_3; + __IO uint32_t PIO0_4; + __IO uint32_t PIO0_5; + __IO uint32_t PIO1_9; + __IO uint32_t PIO3_4; + + __IO uint32_t PIO2_4; + __IO uint32_t PIO2_5; + __IO uint32_t PIO3_5; + __IO uint32_t PIO0_6; + __IO uint32_t PIO0_7; + __IO uint32_t PIO2_9; + __IO uint32_t PIO2_10; + __IO uint32_t PIO2_2; + + __IO uint32_t PIO0_8; + __IO uint32_t PIO0_9; + __IO uint32_t JTAG_TCK_PIO0_10; + __IO uint32_t PIO1_10; + __IO uint32_t PIO2_11; + __IO uint32_t JTAG_TDI_PIO0_11; + __IO uint32_t JTAG_TMS_PIO1_0; + __IO uint32_t JTAG_TDO_PIO1_1; + + __IO uint32_t JTAG_nTRST_PIO1_2; + __IO uint32_t PIO3_0; + __IO uint32_t PIO3_1; + __IO uint32_t PIO2_3; + __IO uint32_t ARM_SWDIO_PIO1_3; + __IO uint32_t PIO1_4; + __IO uint32_t PIO1_11; + __IO uint32_t PIO3_2; + + __IO uint32_t PIO1_5; + __IO uint32_t PIO1_6; + __IO uint32_t PIO1_7; + __IO uint32_t PIO3_3; + __IO uint32_t SCKLOC; /* For HB1 only, new feature */ +} LPC_IOCON_TypeDef; + + +/*------------- Power Management Unit (PMU) --------------------------*/ +typedef struct { + __IO uint32_t PCON; + __IO uint32_t GPREG0; + __IO uint32_t GPREG1; + __IO uint32_t GPREG2; + __IO uint32_t GPREG3; + __IO uint32_t GPREG4; +} LPC_PMU_TypeDef; + + +/*------------- General Purpose Input/Output (GPIO) --------------------------*/ +typedef struct { + union { + __IO uint32_t MASKED_ACCESS[4096]; + struct { + uint32_t RESERVED0[4095]; + __IO uint32_t DATA; + }; + }; + uint32_t RESERVED1[4096]; + __IO uint32_t DIR; + __IO uint32_t IS; + __IO uint32_t IBE; + __IO uint32_t IEV; + __IO uint32_t IE; + __IO uint32_t RIS; + __IO uint32_t MIS; + __IO uint32_t IC; +} LPC_GPIO_TypeDef; + + +/*------------- Timer (TMR) --------------------------------------------------*/ +typedef struct { + __IO uint32_t IR; + __IO uint32_t TCR; + __IO uint32_t TC; + __IO uint32_t PR; + __IO uint32_t PC; + __IO uint32_t MCR; + __IO uint32_t MR0; + __IO uint32_t MR1; + __IO uint32_t MR2; + __IO uint32_t MR3; + __IO uint32_t CCR; + __I uint32_t CR0; + uint32_t RESERVED1[3]; + __IO uint32_t EMR; + uint32_t RESERVED2[12]; + __IO uint32_t CTCR; + __IO uint32_t PWMC; +} LPC_TMR_TypeDef; + +/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/ +typedef struct { + union { + __I uint32_t RBR; + __O uint32_t THR; + __IO uint32_t DLL; + }; + union { + __IO uint32_t DLM; + __IO uint32_t IER; + }; + union { + __I uint32_t IIR; + __O uint32_t FCR; + }; + __IO uint32_t LCR; + __IO uint32_t MCR; + __I uint32_t LSR; + __I uint32_t MSR; + __IO uint32_t SCR; + __IO uint32_t ACR; + __IO uint32_t ICR; + __IO uint32_t FDR; + uint32_t RESERVED0; + __IO uint32_t TER; + uint32_t RESERVED1[6]; + __IO uint32_t RS485CTRL; + __IO uint32_t ADRMATCH; + __IO uint32_t RS485DLY; + __I uint32_t FIFOLVL; +} LPC_UART_TypeDef; + +/*------------- Synchronous Serial Communication (SSP) -----------------------*/ +typedef struct { + __IO uint32_t CR0; + __IO uint32_t CR1; + __IO uint32_t DR; + __I uint32_t SR; + __IO uint32_t CPSR; + __IO uint32_t IMSC; + __IO uint32_t RIS; + __IO uint32_t MIS; + __IO uint32_t ICR; +} LPC_SSP_TypeDef; + +/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/ +typedef struct { + __IO uint32_t CONSET; + __I uint32_t STAT; + __IO uint32_t DAT; + __IO uint32_t ADR0; + __IO uint32_t SCLH; + __IO uint32_t SCLL; + __O uint32_t CONCLR; + __IO uint32_t MMCTRL; + __IO uint32_t ADR1; + __IO uint32_t ADR2; + __IO uint32_t ADR3; + __I uint32_t DATA_BUFFER; + __IO uint32_t MASK0; + __IO uint32_t MASK1; + __IO uint32_t MASK2; + __IO uint32_t MASK3; +} LPC_I2C_TypeDef; + +/*------------- Watchdog Timer (WDT) -----------------------------------------*/ +typedef struct { + __IO uint32_t MOD; + __IO uint32_t TC; + __O uint32_t FEED; + __I uint32_t TV; +} LPC_WDT_TypeDef; + +/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/ +typedef struct { + __IO uint32_t CR; + __IO uint32_t GDR; + uint32_t RESERVED0; + __IO uint32_t INTEN; + __I uint32_t DR0; + __I uint32_t DR1; + __I uint32_t DR2; + __I uint32_t DR3; + __I uint32_t DR4; + __I uint32_t DR5; + __I uint32_t DR6; + __I uint32_t DR7; + __I uint32_t STAT; +} LPC_ADC_TypeDef; + + +/*------------- Universal Serial Bus (USB) -----------------------------------*/ +typedef struct { + __I uint32_t DevIntSt; /* USB Device Interrupt Registers */ + __IO uint32_t DevIntEn; + __O uint32_t DevIntClr; + __O uint32_t DevIntSet; + + __O uint32_t CmdCode; /* USB Device SIE Command Registers */ + __I uint32_t CmdData; + + __I uint32_t RxData; /* USB Device Transfer Registers */ + __O uint32_t TxData; + __I uint32_t RxPLen; + __O uint32_t TxPLen; + __IO uint32_t Ctrl; + __O uint32_t DevFIQSel; +} LPC_USB_TypeDef; + +#if defined ( __CC_ARM ) +#pragma no_anon_unions +#endif + + +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ +/* Base addresses */ +#define LPC_FLASH_BASE (0x00000000UL) +#define LPC_RAM_BASE (0x10000000UL) +#define LPC_APB0_BASE (0x40000000UL) +#define LPC_AHB_BASE (0x50000000UL) + +/* APB0 peripherals */ +#define LPC_I2C_BASE (LPC_APB0_BASE + 0x00000) +#define LPC_WDT_BASE (LPC_APB0_BASE + 0x04000) +#define LPC_UART_BASE (LPC_APB0_BASE + 0x08000) +#define LPC_CT16B0_BASE (LPC_APB0_BASE + 0x0C000) +#define LPC_CT16B1_BASE (LPC_APB0_BASE + 0x10000) +#define LPC_CT32B0_BASE (LPC_APB0_BASE + 0x14000) +#define LPC_CT32B1_BASE (LPC_APB0_BASE + 0x18000) +#define LPC_ADC_BASE (LPC_APB0_BASE + 0x1C000) +#define LPC_USB_BASE (LPC_APB0_BASE + 0x20000) +#define LPC_PMU_BASE (LPC_APB0_BASE + 0x38000) +#define LPC_SSP_BASE (LPC_APB0_BASE + 0x40000) +#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000) +#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000) + +/* AHB peripherals */ +#define LPC_GPIO_BASE (LPC_AHB_BASE + 0x00000) +#define LPC_GPIO0_BASE (LPC_AHB_BASE + 0x00000) +#define LPC_GPIO1_BASE (LPC_AHB_BASE + 0x10000) +#define LPC_GPIO2_BASE (LPC_AHB_BASE + 0x20000) +#define LPC_GPIO3_BASE (LPC_AHB_BASE + 0x30000) + +/******************************************************************************/ +/* Peripheral declaration */ +/******************************************************************************/ +#define LPC_I2C ((LPC_I2C_TypeDef *) LPC_I2C_BASE ) +#define LPC_WDT ((LPC_WDT_TypeDef *) LPC_WDT_BASE ) +#define LPC_UART ((LPC_UART_TypeDef *) LPC_UART_BASE ) +#define LPC_TMR16B0 ((LPC_TMR_TypeDef *) LPC_CT16B0_BASE) +#define LPC_TMR16B1 ((LPC_TMR_TypeDef *) LPC_CT16B1_BASE) +#define LPC_TMR32B0 ((LPC_TMR_TypeDef *) LPC_CT32B0_BASE) +#define LPC_TMR32B1 ((LPC_TMR_TypeDef *) LPC_CT32B1_BASE) +#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE ) +#define LPC_PMU ((LPC_PMU_TypeDef *) LPC_PMU_BASE ) +#define LPC_SSP ((LPC_SSP_TypeDef *) LPC_SSP_BASE ) +#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE ) +#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE) +#define LPC_USB ((LPC_USB_TypeDef *) LPC_USB_BASE ) +#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE ) +#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE ) +#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE ) +#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE ) + + + +/******************************************************************************/ +/* IO Start logic Register Delcaration */ +/******************************************************************************/ +#define STARTxPRP0_PIO0_0 (1UL<<0) +#define STARTxPRP0_PIO0_1 (1UL<<1) +#define STARTxPRP0_PIO0_2 (1UL<<2) +#define STARTxPRP0_PIO0_3 (1UL<<3) +#define STARTxPRP0_PIO0_4 (1UL<<4) +#define STARTxPRP0_PIO0_5 (1UL<<5) +#define STARTxPRP0_PIO0_6 (1UL<<6) +#define STARTxPRP0_PIO0_7 (1UL<<7) +#define STARTxPRP0_PIO0_8 (1UL<<8) +#define STARTxPRP0_PIO0_9 (1UL<<9) +#define STARTxPRP0_PIO0_10 (1UL<<10) +#define STARTxPRP0_PIO0_11 (1UL<<11) +#define STARTxPRP0_PIO1_0 (1UL<<12) +#define STARTxPRP0_PIO1_1 (1UL<<13) +#define STARTxPRP0_PIO1_2 (1UL<<14) +#define STARTxPRP0_PIO1_3 (1UL<<15) +#define STARTxPRP0_PIO1_4 (1UL<<16) +#define STARTxPRP0_PIO1_5 (1UL<<17) +#define STARTxPRP0_PIO1_6 (1UL<<18) +#define STARTxPRP0_PIO1_7 (1UL<<19) +#define STARTxPRP0_PIO1_8 (1UL<<20) +#define STARTxPRP0_PIO1_9 (1UL<<21) +#define STARTxPRP0_PIO1_10 (1UL<<22) +#define STARTxPRP0_PIO1_11 (1UL<<23) +#define STARTxPRP0_PIO2_0 (1UL<<24) +#define STARTxPRP0_PIO2_1 (1UL<<25) +#define STARTxPRP0_PIO2_2 (1UL<<26) +#define STARTxPRP0_PIO2_3 (1UL<<27) +#define STARTxPRP0_PIO2_4 (1UL<<28) +#define STARTxPRP0_PIO2_5 (1UL<<29) +#define STARTxPRP0_PIO2_6 (1UL<<30) +#define STARTxPRP0_PIO2_7 (1UL<<31) + +#define STARTxPRP1_PIO2_8 (1UL<<0) +#define STARTxPRP1_PIO2_9 (1UL<<1) +#define STARTxPRP1_PIO2_10 (1UL<<2) +#define STARTxPRP1_PIO2_11 (1UL<<3) +#define STARTxPRP1_PIO3_0 (1UL<<4) +#define STARTxPRP1_PIO3_1 (1UL<<4) +#define STARTxPRP1_PIO3_2 (1UL<<6) +#define STARTxPRP1_PIO3_3 (1UL<<7) + +#endif // __LPC13xx_H__ diff --git a/openbeacon/lpc13xx/core/cmsis/inc/core_cm3.h b/openbeacon/lpc13xx/core/cmsis/inc/core_cm3.h new file mode 100644 index 0000000..34fc8b4 --- /dev/null +++ b/openbeacon/lpc13xx/core/cmsis/inc/core_cm3.h @@ -0,0 +1,1838 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V1.30 + * @date 30. October 2009 + * + * @note + * Copyright (C) 2009 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#ifndef __CM3_CORE_H__ +#define __CM3_CORE_H__ + +/** @addtogroup CMSIS_CM3_core_LintCinfiguration CMSIS CM3 Core Lint Configuration + * + * List of Lint messages which will be suppressed and not shown: + * - Error 10: \n + * register uint32_t __regBasePri __asm("basepri"); \n + * Error 10: Expecting ';' + * . + * - Error 530: \n + * return(__regBasePri); \n + * Warning 530: Symbol '__regBasePri' (line 264) not initialized + * . + * - Error 550: \n + * __regBasePri = (basePri & 0x1ff); \n + * Warning 550: Symbol '__regBasePri' (line 271) not accessed + * . + * - Error 754: \n + * uint32_t RESERVED0[24]; \n + * Info 754: local structure member '' (line 109, file ./cm3_core.h) not referenced + * . + * - Error 750: \n + * #define __CM3_CORE_H__ \n + * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced + * . + * - Error 528: \n + * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n + * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced + * . + * - Error 751: \n + * } InterruptType_Type; \n + * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced + * . + * Note: To re-enable a Message, insert a space before 'lint' * + * + */ + +/*lint -save */ +/*lint -e10 */ +/*lint -e530 */ +/*lint -e550 */ +/*lint -e754 */ +/*lint -e750 */ +/*lint -e528 */ +/*lint -e751 */ + + +/** @addtogroup CMSIS_CM3_core_definitions CM3 Core Definitions + This file defines all structures and symbols for CMSIS core: + - CMSIS version number + - Cortex-M core registers and bitfields + - Cortex-M core peripheral base address + @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x03) /*!< Cortex core */ + +#include /* Include standard types */ + +#if defined (__ICCARM__) +#include /* IAR Intrinsics */ +#endif + + +#ifndef __NVIC_PRIO_BITS +#define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */ +#endif + + + + +/** + * IO definitions + * + * define access restrictions to peripheral registers + */ + +#ifdef __cplusplus +#define __I volatile /*!< defines 'read only' permissions */ +#else +#define __I volatile const /*!< defines 'read only' permissions */ +#endif +#define __O volatile /*!< defines 'write only' permissions */ +#define __IO volatile /*!< defines 'read / write' permissions */ + + + +/******************************************************************************* + * Register Abstraction + ******************************************************************************/ +/** @addtogroup CMSIS_CM3_core_register CMSIS CM3 Core Register + @{ +*/ + + +/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC + memory mapped structure for Nested Vectored Interrupt Controller (NVIC) + @{ + */ + typedef struct { + __IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */ + } NVIC_Type; + /*@}*//* end of group CMSIS_CM3_NVIC */ + + +/** @addtogroup CMSIS_CM3_SCB CMSIS CM3 SCB + memory mapped structure for System Control Block (SCB) + @{ + */ + typedef struct { + __I uint32_t CPUID; /*!< Offset: 0x00 CPU ID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x04 Interrupt Control State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x08 Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x0C Application Interrupt / Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x10 System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x14 Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x18 System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x24 System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x28 Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x2C Hard Fault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x30 Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x34 Mem Manage Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x38 Bus Fault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x3C Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x40 Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x48 Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x4C Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x50 Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x60 ISA Feature Register */ + } SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFul << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFul << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFul << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFul << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1ul << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1ul << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1ul << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1ul << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1ul << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1ul << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1ul << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFul << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1ul << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFul << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (0x1FFul << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFul << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFul << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFul << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1ul << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7ul << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1ul << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1ul << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1ul << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1ul << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1ul << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1ul << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1ul << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1ul << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1ul << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1ul << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1ul << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1ul << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1ul << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1ul << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1ul << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1ul << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1ul << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1ul << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1ul << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1ul << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1ul << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1ul << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1ul << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1ul << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1ul << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1ul << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFul << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFul << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFul << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1ul << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1ul << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1ul << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1ul << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1ul << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1ul << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1ul << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1ul << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + /*@}*//* end of group CMSIS_CM3_SCB */ + + +/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick + memory mapped structure for SysTick + @{ + */ + typedef struct { + __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */ + } SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + /*@}*//* end of group CMSIS_CM3_SysTick */ + + +/** @addtogroup CMSIS_CM3_ITM CMSIS CM3 ITM + memory mapped structure for Instrumentation Trace Macrocell (ITM) + @{ + */ + typedef struct { + __O union { + __O uint8_t u8; /*!< Offset: ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: ITM Stimulus Port 32-bit */ + } PORT[32]; /*!< Offset: 0x00 ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __IO uint32_t IWR; /*!< Offset: ITM Integration Write Register */ + __IO uint32_t IRR; /*!< Offset: ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __IO uint32_t LAR; /*!< Offset: ITM Lock Access Register */ + __IO uint32_t LSR; /*!< Offset: ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: ITM Component Identification Register #3 */ + } ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFul << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1ul << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_ATBID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_ATBID_Msk (0x7Ful << ITM_TCR_ATBID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3ul << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1ul << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1ul << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1ul << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1ul << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1ul << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1ul << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1ul << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1ul << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1ul << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1ul << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1ul << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + /*@}*//* end of group CMSIS_CM3_ITM */ + + +/** @addtogroup CMSIS_CM3_InterruptType CMSIS CM3 Interrupt Type + memory mapped structure for Interrupt Type + @{ + */ + typedef struct { + uint32_t RESERVED0; + __I uint32_t ICTR; /*!< Offset: 0x04 Interrupt Control Type Register */ +#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) + __IO uint32_t ACTLR; /*!< Offset: 0x08 Auxiliary Control Register */ +#else + uint32_t RESERVED1; +#endif + } InterruptType_Type; + +/* Interrupt Controller Type Register Definitions */ +#define InterruptType_ICTR_INTLINESNUM_Pos 0 /*!< InterruptType ICTR: INTLINESNUM Position */ +#define InterruptType_ICTR_INTLINESNUM_Msk (0x1Ful << InterruptType_ICTR_INTLINESNUM_Pos) /*!< InterruptType ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define InterruptType_ACTLR_DISFOLD_Pos 2 /*!< InterruptType ACTLR: DISFOLD Position */ +#define InterruptType_ACTLR_DISFOLD_Msk (1ul << InterruptType_ACTLR_DISFOLD_Pos) /*!< InterruptType ACTLR: DISFOLD Mask */ + +#define InterruptType_ACTLR_DISDEFWBUF_Pos 1 /*!< InterruptType ACTLR: DISDEFWBUF Position */ +#define InterruptType_ACTLR_DISDEFWBUF_Msk (1ul << InterruptType_ACTLR_DISDEFWBUF_Pos) /*!< InterruptType ACTLR: DISDEFWBUF Mask */ + +#define InterruptType_ACTLR_DISMCYCINT_Pos 0 /*!< InterruptType ACTLR: DISMCYCINT Position */ +#define InterruptType_ACTLR_DISMCYCINT_Msk (1ul << InterruptType_ACTLR_DISMCYCINT_Pos) /*!< InterruptType ACTLR: DISMCYCINT Mask */ + /*@}*//* end of group CMSIS_CM3_InterruptType */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1) +/** @addtogroup CMSIS_CM3_MPU CMSIS CM3 MPU + memory mapped structure for Memory Protection Unit (MPU) + @{ + */ + typedef struct { + __I uint32_t TYPE; /*!< Offset: 0x00 MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x04 MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x08 MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x0C MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x10 MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x14 MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x18 MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x1C MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x20 MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x24 MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x28 MPU Alias 3 Region Attribute and Size Register */ + } MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFul << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFul << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1ul << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1ul << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1ul << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1ul << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFul << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFul << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1ul << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFul << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: XN Position */ +#define MPU_RASR_XN_Msk (1ul << MPU_RASR_XN_Pos) /*!< MPU RASR: XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: AP Position */ +#define MPU_RASR_AP_Msk (7ul << MPU_RASR_AP_Pos) /*!< MPU RASR: AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: TEX Position */ +#define MPU_RASR_TEX_Msk (7ul << MPU_RASR_TEX_Pos) /*!< MPU RASR: TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: Shareable bit Position */ +#define MPU_RASR_S_Msk (1ul << MPU_RASR_S_Pos) /*!< MPU RASR: Shareable bit Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: Cacheable bit Position */ +#define MPU_RASR_C_Msk (1ul << MPU_RASR_C_Pos) /*!< MPU RASR: Cacheable bit Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: Bufferable bit Position */ +#define MPU_RASR_B_Msk (1ul << MPU_RASR_B_Pos) /*!< MPU RASR: Bufferable bit Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFul << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1Ful << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENA_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENA_Msk (0x1Ful << MPU_RASR_ENA_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + + /*@}*//* end of group CMSIS_CM3_MPU */ +#endif + + +/** @addtogroup CMSIS_CM3_CoreDebug CMSIS CM3 Core Debug + memory mapped structure for Core Debug Register + @{ + */ + typedef struct { + __IO uint32_t DHCSR; /*!< Offset: 0x00 Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x04 Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x08 Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x0C Debug Exception and Monitor Control Register */ + } CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFul << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1ul << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1ul << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1ul << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1ul << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1ul << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1ul << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1ul << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1ul << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1ul << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1ul << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1ul << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1ul << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1Ful << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1ul << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1ul << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1ul << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1ul << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1ul << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1ul << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1ul << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1ul << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1ul << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1ul << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1ul << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1ul << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1ul << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + /*@}*//* end of group CMSIS_CM3_CoreDebug */ + + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000) /*!< ITM Base Address */ +#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */ + +#define InterruptType ((InterruptType_Type *) SCS_BASE) /*!< Interrupt Type Register */ +#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE) /*!< ITM configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1) +#define MPU_BASE (SCS_BASE + 0x0D90) /*!< Memory Protection Unit */ +#define MPU ((MPU_Type*) MPU_BASE) /*!< Memory Protection Unit */ +#endif + + /*@}*//* end of group CMSIS_CM3_core_register */ + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ + +#if defined ( __CC_ARM ) +#define __ASM __asm /*!< asm keyword for ARM Compiler */ +#define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) +#define __ASM __asm /*!< asm keyword for IAR Compiler */ +#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */ + +#elif defined ( __GNUC__ ) +#define __ASM __asm /*!< asm keyword for GNU Compiler */ +#define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) +#define __ASM __asm /*!< asm keyword for TASKING Compiler */ +#define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + + +/* ################### Compiler specific Intrinsics ########################### */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#define __enable_fault_irq __enable_fiq +#define __disable_fault_irq __disable_fiq + +#define __NOP __nop +#define __WFI __wfi +#define __WFE __wfe +#define __SEV __sev +#define __ISB() __isb(0) +#define __DSB() __dsb(0) +#define __DMB() __dmb(0) +#define __REV __rev +#define __RBIT __rbit +#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr)) +#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr)) +#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr)) +#define __STREXB(value, ptr) __strex(value, ptr) +#define __STREXH(value, ptr) __strex(value, ptr) +#define __STREXW(value, ptr) __strex(value, ptr) + + +/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */ +/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */ +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + + +/** + * @brief Return the Process Stack Pointer + * + * @return ProcessStackPointer + * + * Return the actual process stack pointer + */ + extern uint32_t __get_PSP(void); + +/** + * @brief Set the Process Stack Pointer + * + * @param topOfProcStack Process Stack Pointer + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ + extern void __set_PSP(uint32_t topOfProcStack); + +/** + * @brief Return the Main Stack Pointer + * + * @return Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ + extern uint32_t __get_MSP(void); + +/** + * @brief Set the Main Stack Pointer + * + * @param topOfMainStack Main Stack Pointer + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ + extern void __set_MSP(uint32_t topOfMainStack); + +/** + * @brief Reverse byte order in unsigned short value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in unsigned short value + */ + extern uint32_t __REV16(uint16_t value); + +/** + * @brief Reverse byte order in signed short value with sign extension to integer + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in signed short value with sign extension to integer + */ + extern int32_t __REVSH(int16_t value); + + +#if (__ARMCC_VERSION < 400000) + +/** + * @brief Remove the exclusive lock created by ldrex + * + * Removes the exclusive lock which is created by ldrex. + */ + extern void __CLREX(void); + +/** + * @brief Return the Base Priority value + * + * @return BasePriority + * + * Return the content of the base priority register + */ + extern uint32_t __get_BASEPRI(void); + +/** + * @brief Set the Base Priority value + * + * @param basePri BasePriority + * + * Set the base priority register + */ + extern void __set_BASEPRI(uint32_t basePri); + +/** + * @brief Return the Priority Mask value + * + * @return PriMask + * + * Return state of the priority mask bit from the priority mask register + */ + extern uint32_t __get_PRIMASK(void); + +/** + * @brief Set the Priority Mask value + * + * @param priMask PriMask + * + * Set the priority mask bit in the priority mask register + */ + extern void __set_PRIMASK(uint32_t priMask); + +/** + * @brief Return the Fault Mask value + * + * @return FaultMask + * + * Return the content of the fault mask register + */ + extern uint32_t __get_FAULTMASK(void); + +/** + * @brief Set the Fault Mask value + * + * @param faultMask faultMask value + * + * Set the fault mask register + */ + extern void __set_FAULTMASK(uint32_t faultMask); + +/** + * @brief Return the Control Register value + * + * @return Control value + * + * Return the content of the control register + */ + extern uint32_t __get_CONTROL(void); + +/** + * @brief Set the Control Register value + * + * @param control Control value + * + * Set the control register + */ + extern void __set_CONTROL(uint32_t control); + +#else /* (__ARMCC_VERSION >= 400000) */ + +/** + * @brief Remove the exclusive lock created by ldrex + * + * Removes the exclusive lock which is created by ldrex. + */ +#define __CLREX __clrex + +/** + * @brief Return the Base Priority value + * + * @return BasePriority + * + * Return the content of the base priority register + */ + static __INLINE uint32_t __get_BASEPRI(void) { + register uint32_t __regBasePri __ASM("basepri"); + return (__regBasePri); + } +/** + * @brief Set the Base Priority value + * + * @param basePri BasePriority + * + * Set the base priority register + */ static __INLINE void __set_BASEPRI(uint32_t basePri) { + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xff); + } + +/** + * @brief Return the Priority Mask value + * + * @return PriMask + * + * Return state of the priority mask bit from the priority mask register + */ + static __INLINE uint32_t __get_PRIMASK(void) { + register uint32_t __regPriMask __ASM("primask"); + return (__regPriMask); + } + +/** + * @brief Set the Priority Mask value + * + * @param priMask PriMask + * + * Set the priority mask bit in the priority mask register + */ + static __INLINE void __set_PRIMASK(uint32_t priMask) { + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); + } + +/** + * @brief Return the Fault Mask value + * + * @return FaultMask + * + * Return the content of the fault mask register + */ + static __INLINE uint32_t __get_FAULTMASK(void) { + register uint32_t __regFaultMask __ASM("faultmask"); + return (__regFaultMask); + } + +/** + * @brief Set the Fault Mask value + * + * @param faultMask faultMask value + * + * Set the fault mask register + */ + static __INLINE void __set_FAULTMASK(uint32_t faultMask) { + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & 1); + } + +/** + * @brief Return the Control Register value + * + * @return Control value + * + * Return the content of the control register + */ + static __INLINE uint32_t __get_CONTROL(void) { + register uint32_t __regControl __ASM("control"); + return (__regControl); + } + +/** + * @brief Set the Control Register value + * + * @param control Control value + * + * Set the control register + */ + static __INLINE void __set_CONTROL(uint32_t control) { + register uint32_t __regControl __ASM("control"); + __regControl = control; + } + +#endif /* __ARMCC_VERSION */ + + + +#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#define __enable_irq __enable_interrupt /*!< global Interrupt enable */ +#define __disable_irq __disable_interrupt /*!< global Interrupt disable */ + + static __INLINE void __enable_fault_irq() { + __ASM("cpsie f"); + } static __INLINE void __disable_fault_irq() { + __ASM("cpsid f"); + } + +#define __NOP __no_operation /*!< no operation intrinsic in IAR Compiler */ + static __INLINE void __WFI() { + __ASM("wfi"); + } + static __INLINE void __WFE() { + __ASM("wfe"); + } + static __INLINE void __SEV() { + __ASM("sev"); + } + static __INLINE void __CLREX() { + __ASM("clrex"); + } + +/* intrinsic void __ISB(void) */ +/* intrinsic void __DSB(void) */ +/* intrinsic void __DMB(void) */ +/* intrinsic void __set_PRIMASK(); */ +/* intrinsic void __get_PRIMASK(); */ +/* intrinsic void __set_FAULTMASK(); */ +/* intrinsic void __get_FAULTMASK(); */ +/* intrinsic uint32_t __REV(uint32_t value); */ +/* intrinsic uint32_t __REVSH(uint32_t value); */ +/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */ +/* intrinsic unsigned long __LDREX(unsigned long *); */ + + +/** + * @brief Return the Process Stack Pointer + * + * @return ProcessStackPointer + * + * Return the actual process stack pointer + */ + extern uint32_t __get_PSP(void); + +/** + * @brief Set the Process Stack Pointer + * + * @param topOfProcStack Process Stack Pointer + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ + extern void __set_PSP(uint32_t topOfProcStack); + +/** + * @brief Return the Main Stack Pointer + * + * @return Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ + extern uint32_t __get_MSP(void); + +/** + * @brief Set the Main Stack Pointer + * + * @param topOfMainStack Main Stack Pointer + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ + extern void __set_MSP(uint32_t topOfMainStack); + +/** + * @brief Reverse byte order in unsigned short value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in unsigned short value + */ + extern uint32_t __REV16(uint16_t value); + +/** + * @brief Reverse bit order of value + * + * @param value value to reverse + * @return reversed value + * + * Reverse bit order of value + */ + extern uint32_t __RBIT(uint32_t value); + +/** + * @brief LDR Exclusive (8 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 8 bit values) + */ + extern uint8_t __LDREXB(uint8_t * addr); + +/** + * @brief LDR Exclusive (16 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 16 bit values + */ + extern uint16_t __LDREXH(uint16_t * addr); + +/** + * @brief LDR Exclusive (32 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 32 bit values + */ + extern uint32_t __LDREXW(uint32_t * addr); + +/** + * @brief STR Exclusive (8 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 8 bit values + */ + extern uint32_t __STREXB(uint8_t value, uint8_t * addr); + +/** + * @brief STR Exclusive (16 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 16 bit values + */ + extern uint32_t __STREXH(uint16_t value, uint16_t * addr); + +/** + * @brief STR Exclusive (32 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 32 bit values + */ + extern uint32_t __STREXW(uint32_t value, uint32_t * addr); + + + +#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + + static __INLINE void __enable_irq(void) { + __ASM volatile ("cpsie i"); + } static __INLINE void __disable_irq(void) { + __ASM volatile ("cpsid i"); + } + + static __INLINE void __enable_fault_irq(void) { + __ASM volatile ("cpsie f"); + } + static __INLINE void __disable_fault_irq(void) { + __ASM volatile ("cpsid f"); + } + + static __INLINE void __NOP(void) { + __ASM volatile ("nop"); + } + static __INLINE void __WFI(void) { + __ASM volatile ("wfi"); + } + static __INLINE void __WFE(void) { + __ASM volatile ("wfe"); + } + static __INLINE void __SEV(void) { + __ASM volatile ("sev"); + } + static __INLINE void __ISB(void) { + __ASM volatile ("isb"); + } + static __INLINE void __DSB(void) { + __ASM volatile ("dsb"); + } + static __INLINE void __DMB(void) { + __ASM volatile ("dmb"); + } + static __INLINE void __CLREX(void) { + __ASM volatile ("clrex"); + } + + +/** + * @brief Return the Process Stack Pointer + * + * @return ProcessStackPointer + * + * Return the actual process stack pointer + */ + extern uint32_t __get_PSP(void); + +/** + * @brief Set the Process Stack Pointer + * + * @param topOfProcStack Process Stack Pointer + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ + extern void __set_PSP(uint32_t topOfProcStack); + +/** + * @brief Return the Main Stack Pointer + * + * @return Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ + extern uint32_t __get_MSP(void); + +/** + * @brief Set the Main Stack Pointer + * + * @param topOfMainStack Main Stack Pointer + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ + extern void __set_MSP(uint32_t topOfMainStack); + +/** + * @brief Return the Base Priority value + * + * @return BasePriority + * + * Return the content of the base priority register + */ + extern uint32_t __get_BASEPRI(void); + +/** + * @brief Set the Base Priority value + * + * @param basePri BasePriority + * + * Set the base priority register + */ + extern void __set_BASEPRI(uint32_t basePri); + +/** + * @brief Return the Priority Mask value + * + * @return PriMask + * + * Return state of the priority mask bit from the priority mask register + */ + extern uint32_t __get_PRIMASK(void); + +/** + * @brief Set the Priority Mask value + * + * @param priMask PriMask + * + * Set the priority mask bit in the priority mask register + */ + extern void __set_PRIMASK(uint32_t priMask); + +/** + * @brief Return the Fault Mask value + * + * @return FaultMask + * + * Return the content of the fault mask register + */ + extern uint32_t __get_FAULTMASK(void); + +/** + * @brief Set the Fault Mask value + * + * @param faultMask faultMask value + * + * Set the fault mask register + */ + extern void __set_FAULTMASK(uint32_t faultMask); + +/** + * @brief Return the Control Register value +* +* @return Control value + * + * Return the content of the control register + */ + extern uint32_t __get_CONTROL(void); + +/** + * @brief Set the Control Register value + * + * @param control Control value + * + * Set the control register + */ + extern void __set_CONTROL(uint32_t control); + +/** + * @brief Reverse byte order in integer value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in integer value + */ + extern uint32_t __REV(uint32_t value); + +/** + * @brief Reverse byte order in unsigned short value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in unsigned short value + */ + extern uint32_t __REV16(uint16_t value); + +/** + * @brief Reverse byte order in signed short value with sign extension to integer + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in signed short value with sign extension to integer + */ + extern int32_t __REVSH(int16_t value); + +/** + * @brief Reverse bit order of value + * + * @param value value to reverse + * @return reversed value + * + * Reverse bit order of value + */ + extern uint32_t __RBIT(uint32_t value); + +/** + * @brief LDR Exclusive (8 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 8 bit value + */ + extern uint8_t __LDREXB(uint8_t * addr); + +/** + * @brief LDR Exclusive (16 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 16 bit values + */ + extern uint16_t __LDREXH(uint16_t * addr); + +/** + * @brief LDR Exclusive (32 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 32 bit values + */ + extern uint32_t __LDREXW(uint32_t * addr); + +/** + * @brief STR Exclusive (8 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 8 bit values + */ + extern uint32_t __STREXB(uint8_t value, uint8_t * addr); + +/** + * @brief STR Exclusive (16 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 16 bit values + */ + extern uint32_t __STREXH(uint16_t value, uint16_t * addr); + +/** + * @brief STR Exclusive (32 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 32 bit values + */ + extern uint32_t __STREXW(uint32_t value, uint32_t * addr); + + +#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif + + +/** @addtogroup CMSIS_CM3_Core_FunctionInterface CMSIS CM3 Core Function Interface + Core Function Interface containing: + - Core NVIC Functions + - Core SysTick Functions + - Core Reset Functions +*/ +/*@{*/ + +/* ########################## NVIC functions #################################### */ + +/** + * @brief Set the Priority Grouping in NVIC Interrupt Controller + * + * @param PriorityGroup is priority grouping field + * + * Set the priority grouping field using the required unlock sequence. + * The parameter priority_grouping is assigned to the field + * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. + * In case of a conflict between priority grouping and available + * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + */ + static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | (0x5FA << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; + } +/** + * @brief Get the Priority Grouping from NVIC Interrupt Controller + * + * @return priority grouping field + * + * Get the priority grouping from NVIC Interrupt Controller. + * priority grouping is SCB->AIRCR [10:8] PRIGROUP field. + */ static __INLINE uint32_t NVIC_GetPriorityGrouping(void) { + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ + } + +/** + * @brief Enable Interrupt in NVIC Interrupt Controller + * + * @param IRQn The positive number of the external interrupt to enable + * + * Enable a device specific interupt in the NVIC interrupt controller. + * The interrupt number cannot be a negative value. + */ + static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) { + NVIC->ISER[((uint32_t) (IRQn) >> 5)] = (1 << ((uint32_t) (IRQn) & 0x1F)); /* enable interrupt */ + } + +/** + * @brief Disable the interrupt line for external interrupt specified + * + * @param IRQn The positive number of the external interrupt to disable + * + * Disable a device specific interupt in the NVIC interrupt controller. + * The interrupt number cannot be a negative value. + */ + static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) { + NVIC->ICER[((uint32_t) (IRQn) >> 5)] = (1 << ((uint32_t) (IRQn) & 0x1F)); /* disable interrupt */ + } + +/** + * @brief Read the interrupt pending bit for a device specific interrupt source + * + * @param IRQn The number of the device specifc interrupt + * @return 1 = interrupt pending, 0 = interrupt not pending + * + * Read the pending register in NVIC and return 1 if its status is pending, + * otherwise it returns 0 + */ + static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) { + return ((uint32_t) ((NVIC->ISPR[(uint32_t) (IRQn) >> 5] & (1 << ((uint32_t) (IRQn) & 0x1F))) ? 1 : 0)); /* Return 1 if pending else 0 */ + } + +/** + * @brief Set the pending bit for an external interrupt + * + * @param IRQn The number of the interrupt for set pending + * + * Set the pending bit for the specified interrupt. + * The interrupt number cannot be a negative value. + */ + static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) { + NVIC->ISPR[((uint32_t) (IRQn) >> 5)] = (1 << ((uint32_t) (IRQn) & 0x1F)); /* set interrupt pending */ + } + +/** + * @brief Clear the pending bit for an external interrupt + * + * @param IRQn The number of the interrupt for clear pending + * + * Clear the pending bit for the specified interrupt. + * The interrupt number cannot be a negative value. + */ + static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) { + NVIC->ICPR[((uint32_t) (IRQn) >> 5)] = (1 << ((uint32_t) (IRQn) & 0x1F)); /* Clear pending interrupt */ + } + +/** + * @brief Read the active bit for an external interrupt + * + * @param IRQn The number of the interrupt for read active bit + * @return 1 = interrupt active, 0 = interrupt not active + * + * Read the active register in NVIC and returns 1 if its status is active, + * otherwise it returns 0. + */ + static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) { + return ((uint32_t) ((NVIC->IABR[(uint32_t) (IRQn) >> 5] & (1 << ((uint32_t) (IRQn) & 0x1F))) ? 1 : 0)); /* Return 1 if active else 0 */ + } + +/** + * @brief Set the priority for an interrupt + * + * @param IRQn The number of the interrupt for set priority + * @param priority The priority to set + * + * Set the priority for the specified interrupt. The interrupt + * number can be positive to specify an external (device specific) + * interrupt, or negative to specify an internal (core) interrupt. + * + * Note: The priority cannot be set for every core interrupt. + */ + static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, + uint32_t priority) { + if (IRQn < 0) { + SCB->SHP[((uint32_t) (IRQn) & 0xF) - 4] = + ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); + } /* set Priority for Cortex-M3 System Interrupts */ + else { + NVIC->IP[(uint32_t) (IRQn)] = + ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); + } /* set Priority for device specific Interrupts */ + } + +/** + * @brief Read the priority for an interrupt + * + * @param IRQn The number of the interrupt for get priority + * @return The priority for the interrupt + * + * Read the priority for the specified interrupt. The interrupt + * number can be positive to specify an external (device specific) + * interrupt, or negative to specify an internal (core) interrupt. + * + * The returned priority value is automatically aligned to the implemented + * priority bits of the microcontroller. + * + * Note: The priority cannot be set for every core interrupt. + */ + static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) { + + if (IRQn < 0) { + return ((uint32_t) + (SCB-> + SHP[((uint32_t) (IRQn) & 0xF) - 4] >> (8 - + __NVIC_PRIO_BITS))); + } /* get priority for Cortex-M3 system interrupts */ + else { + return ((uint32_t) + (NVIC-> + IP[(uint32_t) (IRQn)] >> (8 - __NVIC_PRIO_BITS))); + } /* get priority for device specific interrupts */ + } + + +/** + * @brief Encode the priority for an interrupt + * + * @param PriorityGroup The used priority group + * @param PreemptPriority The preemptive priority value (starting from 0) + * @param SubPriority The sub priority value (starting from 0) + * @return The encoded priority for the interrupt + * + * Encode the priority for an interrupt with the given priority group, + * preemptive priority value and sub priority value. + * In case of a conflict between priority grouping and available + * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + * + * The returned priority value can be used for NVIC_SetPriority(...) function + */ + static __INLINE uint32_t NVIC_EncodePriority(uint32_t PriorityGroup, + uint32_t PreemptPriority, + uint32_t SubPriority) { + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = + ((7 - PriorityGroupTmp) > + __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = + ((PriorityGroupTmp + __NVIC_PRIO_BITS) < + 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return (((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << + SubPriorityBits) | ((SubPriority & + ((1 << (SubPriorityBits)) - 1))) + ); + } + + +/** + * @brief Decode the priority of an interrupt + * + * @param Priority The priority for the interrupt + * @param PriorityGroup The used priority group + * @param pPreemptPriority The preemptive priority value (starting from 0) + * @param pSubPriority The sub priority value (starting from 0) + * + * Decode an interrupt priority value with the given priority group to + * preemptive priority value and sub priority value. + * In case of a conflict between priority grouping and available + * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + * + * The priority value can be retrieved with NVIC_GetPriority(...) function + */ + static __INLINE void NVIC_DecodePriority(uint32_t Priority, + uint32_t PriorityGroup, + uint32_t * pPreemptPriority, + uint32_t * pSubPriority) { + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = + ((7 - PriorityGroupTmp) > + __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = + ((PriorityGroupTmp + __NVIC_PRIO_BITS) < + 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = + (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - + 1); + *pSubPriority = (Priority) & ((1 << (SubPriorityBits)) - 1); + } + + + +/* ################################## SysTick function ############################################ */ + +#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0) + +/** + * @brief Initialize and start the SysTick counter and its interrupt. + * + * @param ticks number of ticks between two interrupts + * @return 1 = failed, 0 = successful + * + * Initialise the system tick timer and its interrupt and start the + * system tick timer / counter in free running mode to generate + * periodical interrupts. + */ + static __INLINE uint32_t SysTick_Config(uint32_t ticks) { + if (ticks > SysTick_LOAD_RELOAD_Msk) + return (1); /* Reload value impossible */ + + SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ + NVIC_SetPriority(SysTick_IRQn, (1 << __NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ + } + +#endif + + + + +/* ################################## Reset function ############################################ */ + +/** + * @brief Initiate a system reset request. + * + * Initiate a system reset request to reset the MCU + */ + static __INLINE void NVIC_SystemReset(void) { + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while (1); /* wait until reset */ + } + + /*@}*//* end of group CMSIS_CM3_Core_FunctionInterface */ + + + +/* ##################################### Debug In/Output function ########################################### */ + +/** @addtogroup CMSIS_CM3_CoreDebugInterface CMSIS CM3 Core Debug Interface + Core Debug Interface containing: + - Core Debug Receive / Transmit Functions + - Core Debug Defines + - Core Debug Variables +*/ +/*@{*/ + + extern volatile int ITM_RxBuffer; /*!< variable to receive characters */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */ + + +/** + * @brief Outputs a character via the ITM channel 0 + * + * @param ch character to output + * @return character to output + * + * The function outputs a character via the ITM channel 0. + * The function returns when no debugger is connected that has booked the output. + * It is blocking when a debugger is connected, but the previous character send is not transmitted. + */ + static __INLINE uint32_t ITM_SendChar(uint32_t ch) { + if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */ + (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1ul << 0))) { /* ITM Port #0 enabled */ + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); + } + + +/** + * @brief Inputs a character via variable ITM_RxBuffer + * + * @return received character, -1 = no character received + * + * The function inputs a character via variable ITM_RxBuffer. + * The function returns when no debugger is connected that has booked the output. + * It is blocking when a debugger is connected, but the previous character send is not transmitted. + */ + static __INLINE int ITM_ReceiveChar(void) { + int ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); + } + + +/** + * @brief Check if a character via variable ITM_RxBuffer is available + * + * @return 1 = character available, 0 = no character available + * + * The function checks variable ITM_RxBuffer whether a character is available or not. + * The function returns '1' if a character is available and '0' if no character is available. + */ + static __INLINE int ITM_CheckChar(void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } + } + + /*@}*//* end of group CMSIS_CM3_core_DebugInterface */ + + +#ifdef __cplusplus +} +#endif + + /*@}*//* end of group CMSIS_CM3_core_definitions */ + +#endif /* __CM3_CORE_H__ */ + +/*lint -restore */ diff --git a/openbeacon/lpc13xx/core/cmsis/inc/system_LPC13xx.h b/openbeacon/lpc13xx/core/cmsis/inc/system_LPC13xx.h new file mode 100644 index 0000000..4fa62d7 --- /dev/null +++ b/openbeacon/lpc13xx/core/cmsis/inc/system_LPC13xx.h @@ -0,0 +1,63 @@ +/**************************************************************************//** + * @file system_lpc13xx.h + * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File + * for the NXP LPC13xx Device Series + * @version V1.01 + * @date 19. October 2009 + * + * @note + * Copyright (C) 2009 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + + +#ifndef __SYSTEM_LPC13xx_H +#define __SYSTEM_LPC13xx_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ + extern void SystemInit(void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ + extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif +#endif /* __SYSTEM_LPC13x_H */ diff --git a/openbeacon/lpc13xx/core/cmsis/src/core_cm3.c b/openbeacon/lpc13xx/core/cmsis/src/core_cm3.c new file mode 100644 index 0000000..fcff0d1 --- /dev/null +++ b/openbeacon/lpc13xx/core/cmsis/src/core_cm3.c @@ -0,0 +1,784 @@ +/**************************************************************************//** + * @file core_cm3.c + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File + * @version V1.30 + * @date 30. October 2009 + * + * @note + * Copyright (C) 2009 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#include + +/* define compiler specific symbols */ +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */ + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + + +/* ################### Compiler specific Intrinsics ########################### */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +/** + * @brief Return the Process Stack Pointer + * + * @return ProcessStackPointer + * + * Return the actual process stack pointer + */ +__ASM uint32_t __get_PSP(void) +{ + mrs r0, psp + bx lr +} + +/** + * @brief Set the Process Stack Pointer + * + * @param topOfProcStack Process Stack Pointer + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +__ASM void __set_PSP(uint32_t topOfProcStack) +{ + msr psp, r0 + bx lr +} + +/** + * @brief Return the Main Stack Pointer + * + * @return Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +__ASM uint32_t __get_MSP(void) +{ + mrs r0, msp + bx lr +} + +/** + * @brief Set the Main Stack Pointer + * + * @param topOfMainStack Main Stack Pointer + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +__ASM void __set_MSP(uint32_t mainStackPointer) +{ + msr msp, r0 + bx lr +} + +/** + * @brief Reverse byte order in unsigned short value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in unsigned short value + */ +__ASM uint32_t __REV16(uint16_t value) +{ + rev16 r0, r0 + bx lr +} + +/** + * @brief Reverse byte order in signed short value with sign extension to integer + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in signed short value with sign extension to integer + */ +__ASM int32_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} + + +#if (__ARMCC_VERSION < 400000) + +/** + * @brief Remove the exclusive lock created by ldrex + * + * Removes the exclusive lock which is created by ldrex. + */ +__ASM void __CLREX(void) +{ + clrex +} + +/** + * @brief Return the Base Priority value + * + * @return BasePriority + * + * Return the content of the base priority register + */ +__ASM uint32_t __get_BASEPRI(void) +{ + mrs r0, basepri + bx lr +} + +/** + * @brief Set the Base Priority value + * + * @param basePri BasePriority + * + * Set the base priority register + */ +__ASM void __set_BASEPRI(uint32_t basePri) +{ + msr basepri, r0 + bx lr +} + +/** + * @brief Return the Priority Mask value + * + * @return PriMask + * + * Return state of the priority mask bit from the priority mask register + */ +__ASM uint32_t __get_PRIMASK(void) +{ + mrs r0, primask + bx lr +} + +/** + * @brief Set the Priority Mask value + * + * @param priMask PriMask + * + * Set the priority mask bit in the priority mask register + */ +__ASM void __set_PRIMASK(uint32_t priMask) +{ + msr primask, r0 + bx lr +} + +/** + * @brief Return the Fault Mask value + * + * @return FaultMask + * + * Return the content of the fault mask register + */ +__ASM uint32_t __get_FAULTMASK(void) +{ + mrs r0, faultmask + bx lr +} + +/** + * @brief Set the Fault Mask value + * + * @param faultMask faultMask value + * + * Set the fault mask register + */ +__ASM void __set_FAULTMASK(uint32_t faultMask) +{ + msr faultmask, r0 + bx lr +} + +/** + * @brief Return the Control Register value + * + * @return Control value + * + * Return the content of the control register + */ +__ASM uint32_t __get_CONTROL(void) +{ + mrs r0, control + bx lr +} + +/** + * @brief Set the Control Register value + * + * @param control Control value + * + * Set the control register + */ +__ASM void __set_CONTROL(uint32_t control) +{ + msr control, r0 + bx lr +} + +#endif /* __ARMCC_VERSION */ + + + +#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#pragma diag_suppress=Pe940 + +/** + * @brief Return the Process Stack Pointer + * + * @return ProcessStackPointer + * + * Return the actual process stack pointer + */ +uint32_t __get_PSP(void) +{ + __ASM("mrs r0, psp"); + __ASM("bx lr"); +} + +/** + * @brief Set the Process Stack Pointer + * + * @param topOfProcStack Process Stack Pointer + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +void __set_PSP(uint32_t topOfProcStack) +{ + __ASM("msr psp, r0"); + __ASM("bx lr"); +} + +/** + * @brief Return the Main Stack Pointer + * + * @return Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +uint32_t __get_MSP(void) +{ + __ASM("mrs r0, msp"); + __ASM("bx lr"); +} + +/** + * @brief Set the Main Stack Pointer + * + * @param topOfMainStack Main Stack Pointer + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +void __set_MSP(uint32_t topOfMainStack) +{ + __ASM("msr msp, r0"); + __ASM("bx lr"); +} + +/** + * @brief Reverse byte order in unsigned short value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in unsigned short value + */ +uint32_t __REV16(uint16_t value) +{ + __ASM("rev16 r0, r0"); + __ASM("bx lr"); +} + +/** + * @brief Reverse bit order of value + * + * @param value value to reverse + * @return reversed value + * + * Reverse bit order of value + */ +uint32_t __RBIT(uint32_t value) +{ + __ASM("rbit r0, r0"); + __ASM("bx lr"); +} + +/** + * @brief LDR Exclusive (8 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 8 bit values) + */ +uint8_t __LDREXB(uint8_t *addr) +{ + __ASM("ldrexb r0, [r0]"); + __ASM("bx lr"); +} + +/** + * @brief LDR Exclusive (16 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 16 bit values + */ +uint16_t __LDREXH(uint16_t *addr) +{ + __ASM("ldrexh r0, [r0]"); + __ASM("bx lr"); +} + +/** + * @brief LDR Exclusive (32 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 32 bit values + */ +uint32_t __LDREXW(uint32_t *addr) +{ + __ASM("ldrex r0, [r0]"); + __ASM("bx lr"); +} + +/** + * @brief STR Exclusive (8 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 8 bit values + */ +uint32_t __STREXB(uint8_t value, uint8_t *addr) +{ + __ASM("strexb r0, r0, [r1]"); + __ASM("bx lr"); +} + +/** + * @brief STR Exclusive (16 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 16 bit values + */ +uint32_t __STREXH(uint16_t value, uint16_t *addr) +{ + __ASM("strexh r0, r0, [r1]"); + __ASM("bx lr"); +} + +/** + * @brief STR Exclusive (32 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 32 bit values + */ +uint32_t __STREXW(uint32_t value, uint32_t *addr) +{ + __ASM("strex r0, r0, [r1]"); + __ASM("bx lr"); +} + +#pragma diag_default=Pe940 + + +#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** + * @brief Return the Process Stack Pointer + * + * @return ProcessStackPointer + * + * Return the actual process stack pointer + */ +uint32_t __get_PSP(void) __attribute__( ( naked ) ); +uint32_t __get_PSP(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, psp\n\t" + "MOV r0, %0 \n\t" + "BX lr \n\t" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Process Stack Pointer + * + * @param topOfProcStack Process Stack Pointer + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) ); +void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n\t" + "BX lr \n\t" : : "r" (topOfProcStack) ); +} + +/** + * @brief Return the Main Stack Pointer + * + * @return Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +uint32_t __get_MSP(void) __attribute__( ( naked ) ); +uint32_t __get_MSP(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, msp\n\t" + "MOV r0, %0 \n\t" + "BX lr \n\t" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Main Stack Pointer + * + * @param topOfMainStack Main Stack Pointer + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) ); +void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n\t" + "BX lr \n\t" : : "r" (topOfMainStack) ); +} + +/** + * @brief Return the Base Priority value + * + * @return BasePriority + * + * Return the content of the base priority register + */ +uint32_t __get_BASEPRI(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Base Priority value + * + * @param basePri BasePriority + * + * Set the base priority register + */ +void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) ); +} + +/** + * @brief Return the Priority Mask value + * + * @return PriMask + * + * Return state of the priority mask bit from the priority mask register + */ +uint32_t __get_PRIMASK(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Priority Mask value + * + * @param priMask PriMask + * + * Set the priority mask bit in the priority mask register + */ +void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); +} + +/** + * @brief Return the Fault Mask value + * + * @return FaultMask + * + * Return the content of the fault mask register + */ +uint32_t __get_FAULTMASK(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Fault Mask value + * + * @param faultMask faultMask value + * + * Set the fault mask register + */ +void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); +} + +/** + * @brief Return the Control Register value +* +* @return Control value + * + * Return the content of the control register + */ +uint32_t __get_CONTROL(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Control Register value + * + * @param control Control value + * + * Set the control register + */ +void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) ); +} + + +/** + * @brief Reverse byte order in integer value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in integer value + */ +uint32_t __REV(uint32_t value) +{ + uint32_t result=0; + + __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +/** + * @brief Reverse byte order in unsigned short value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in unsigned short value + */ +uint32_t __REV16(uint16_t value) +{ + uint32_t result=0; + + __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +/** + * @brief Reverse byte order in signed short value with sign extension to integer + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in signed short value with sign extension to integer + */ +int32_t __REVSH(int16_t value) +{ + uint32_t result=0; + + __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +/** + * @brief Reverse bit order of value + * + * @param value value to reverse + * @return reversed value + * + * Reverse bit order of value + */ +uint32_t __RBIT(uint32_t value) +{ + uint32_t result=0; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +/** + * @brief LDR Exclusive (8 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 8 bit value + */ +uint8_t __LDREXB(uint8_t *addr) +{ + uint8_t result=0; + + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + +/** + * @brief LDR Exclusive (16 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 16 bit values + */ +uint16_t __LDREXH(uint16_t *addr) +{ + uint16_t result=0; + + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + +/** + * @brief LDR Exclusive (32 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 32 bit values + */ +uint32_t __LDREXW(uint32_t *addr) +{ + uint32_t result=0; + + __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + +/** + * @brief STR Exclusive (8 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 8 bit values + */ +uint32_t __STREXB(uint8_t value, uint8_t *addr) +{ + uint32_t result=0; + + __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + +/** + * @brief STR Exclusive (16 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 16 bit values + */ +uint32_t __STREXH(uint16_t value, uint16_t *addr) +{ + uint32_t result=0; + + __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + +/** + * @brief STR Exclusive (32 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 32 bit values + */ +uint32_t __STREXW(uint32_t value, uint32_t *addr) +{ + uint32_t result=0; + + __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif diff --git a/openbeacon/lpc13xx/core/cmsis/src/system_LPC13xx.c b/openbeacon/lpc13xx/core/cmsis/src/system_LPC13xx.c new file mode 100644 index 0000000..fec287a --- /dev/null +++ b/openbeacon/lpc13xx/core/cmsis/src/system_LPC13xx.c @@ -0,0 +1,487 @@ +/**************************************************************************//** + * @file system_LPC13xx.c + * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File + * for the NXP LPC13xx Device Series + * @version V1.02 + * @date 18. February 2010 + * + * @note + * Copyright (C) 2009 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +// ******** Code Red ************** +// * Changed USBCLK_SETUP to 1 +// * Changed SYSPLLCTRL_Val to 0x25 +// ******************************** + +#include +#include "LPC13xx.h" + +/* +//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +*/ + +/*--------------------- Clock Configuration ---------------------------------- +// +// Clock Configuration +// System Clock Setup +// System Oscillator Enable +// Select System Oscillator Frequency Range +// <0=> 1 - 20 MHz +// <1=> 15 - 25 MHz +// +// Watchdog Oscillator Enable +// Select Divider for Fclkana +// <0=> 2 <1=> 4 <2=> 6 <3=> 8 +// <4=> 10 <5=> 12 <6=> 14 <7=> 16 +// <8=> 18 <9=> 20 <10=> 22 <11=> 24 +// <12=> 26 <13=> 28 <14=> 30 <15=> 32 +// <16=> 34 <17=> 36 <18=> 38 <19=> 40 +// <20=> 42 <21=> 44 <22=> 46 <23=> 48 +// <24=> 50 <25=> 52 <26=> 54 <27=> 56 +// <28=> 58 <29=> 60 <30=> 62 <31=> 64 +// Select Watchdog Oscillator Analog Frequency (Fclkana) +// <0=> Disabled +// <1=> 0.5 MHz +// <2=> 0.8 MHz +// <3=> 1.1 MHz +// <4=> 1.4 MHz +// <5=> 1.6 MHz +// <6=> 1.8 MHz +// <7=> 2.0 MHz +// <8=> 2.2 MHz +// <9=> 2.4 MHz +// <10=> 2.6 MHz +// <11=> 2.7 MHz +// <12=> 2.9 MHz +// <13=> 3.1 MHz +// <14=> 3.2 MHz +// <15=> 3.4 MHz +// +// Select Input Clock for sys_pllclkin (Register: SYSPLLCLKSEL) +// <0=> IRC Oscillator +// <1=> System Oscillator +// <2=> WDT Oscillator +// <3=> Invalid +// Use System PLL +// F_pll = M * F_in +// F_in must be in the range of 10 MHz to 25 MHz +// M: PLL Multiplier Selection +// <1-32><#-1> +// P: PLL Divider Selection +// <0=> 2 +// <1=> 4 +// <2=> 8 +// <3=> 16 +// DIRECT: Direct CCO Clock Output Enable +// BYPASS: PLL Bypass Enable +// +// Select Input Clock for Main clock (Register: MAINCLKSEL) +// <0=> IRC Oscillator +// <1=> Input Clock to System PLL +// <2=> WDT Oscillator +// <3=> System PLL Clock Out +// +// USB Clock Setup +// Use USB PLL +// F_pll = M * F_in +// F_in must be in the range of 10 MHz to 25 MHz +// Select Input Clock for usb_pllclkin (Register: USBPLLCLKSEL) +// <0=> IRC Oscillator +// <1=> System Oscillator +// M: PLL Multiplier Selection +// <1-32><#-1> +// P: PLL Divider Selection +// <0=> 2 +// <1=> 4 +// <2=> 8 +// <3=> 16 +// DIRECT: Direct CCO Clock Output Enable +// BYPASS: PLL Bypass Enable +// +// +// System AHB Divider <0-255> +// 0 = is disabled +// SYS Clock Enable +// ROM Clock Enable +// RAM Clock Enable +// FLASH1 Clock Enable +// FLASH2 Clock Enable +// I2C Clock Enable +// GPIO Clock Enable +// CT16B0 Clock Enable +// CT16B1 Clock Enable +// CT32B0 Clock Enable +// CT32B1 Clock Enable +// SSP Clock Enable +// UART Clock Enable +// ADC Clock Enable +// USB_REG Clock Enable +// SWDT Clock Enable +// IOCON Clock Enable +// +*/ +#define CLOCK_SETUP 1 +#define SYSCLK_SETUP 1 +#define SYSOSC_SETUP 1 +#define SYSOSCCTRL_Val 0x00000000 +#define WDTOSC_SETUP 0 +#define WDTOSCCTRL_Val 0x000000A0 +#define SYSPLLCLKSEL_Val 0x00000001 +#define SYSPLL_SETUP 1 +#define SYSPLLCTRL_Val 0x00000025 +#define MAINCLKSEL_Val 0x00000003 + +// ******** Code Red ********* +// * Changed USBCLK_SETUP to 1 +// *************************** +#define USBCLK_SETUP 1 +#define USBPLL_SETUP 1 +#define USBPLLCLKSEL_Val 0x00000001 +#define USBPLLCTRL_Val 0x00000003 +#define SYSAHBCLKDIV_Val 0x00000001 +#define AHBCLKCTRL_Val 0x0001005F + +/*--------------------- Memory Mapping Configuration ------------------------- +// +// Memory Mapping +// System Memory Remap (Register: SYSMEMREMAP) +// <0=> Bootloader mapped to address 0 +// <1=> RAM mapped to address 0 +// <2=> Flash mapped to address 0 +// <3=> Flash mapped to address 0 +// +*/ +#define MEMMAP_SETUP 0 +#define SYSMEMREMAP_Val 0x00000001 + +/* +//-------- <<< end of configuration section >>> ------------------------------ +*/ + +/*---------------------------------------------------------------------------- + Check the register settings + *----------------------------------------------------------------------------*/ +#define CHECK_RANGE(val, min, max) ((val < min) || (val > max)) +#define CHECK_RSVD(val, mask) (val & mask) + +/* Clock Configuration -------------------------------------------------------*/ +#if (CHECK_RSVD((SYSOSCCTRL_Val), ~0x00000003)) + #error "SYSOSCCTRL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((WDTOSCCTRL_Val), ~0x000001FF)) + #error "WDTOSCCTRL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 2)) + #error "SYSPLLCLKSEL: Value out of range!" +#endif + +#if (CHECK_RSVD((SYSPLLCTRL_Val), ~0x000001FF)) + #error "SYSPLLCTRL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((MAINCLKSEL_Val), ~0x00000003)) + #error "MAINCLKSEL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RANGE((USBPLLCLKSEL_Val), 0, 1)) + #error "USBPLLCLKSEL: Value out of range!" +#endif + +#if (CHECK_RSVD((USBPLLCTRL_Val), ~0x000001FF)) + #error "USBPLLCTRL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((USBPLLUEN_Val), ~0x00000001)) + #error "USBPLLUEN: Invalid values of reserved bits!" +#endif + +#if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255)) + #error "SYSAHBCLKDIV: Value out of range!" +#endif + +#if (CHECK_RSVD((AHBCLKCTRL_Val), ~0x0001FFFF)) + #error "AHBCLKCTRL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((SYSMEMREMAP_Val), ~0x00000003)) + #error "SYSMEMREMAP: Invalid values of reserved bits!" +#endif + + +/*---------------------------------------------------------------------------- + DEFINES + *----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ +#define __XTAL (12000000UL) /* Oscillator frequency */ +#define __SYS_OSC_CLK ( __XTAL) /* Main oscillator frequency */ +#define __IRC_OSC_CLK (12000000UL) /* Internal RC oscillator frequency */ + + +#define __FREQSEL ((WDTOSCCTRL_Val >> 5) & 0x0F) +#define __DIVSEL (((WDTOSCCTRL_Val & 0x1F) << 1) + 2) + +#if (CLOCK_SETUP) /* Clock Setup */ + #if (SYSCLK_SETUP) /* System Clock Setup */ + #if (WDTOSC_SETUP) /* Watchdog Oscillator Setup*/ + #if (__FREQSEL == 0) + #define __WDT_OSC_CLK ( 400000 / __DIVSEL) + #elif (__FREQSEL == 1) + #define __WDT_OSC_CLK ( 500000 / __DIVSEL) + #elif (__FREQSEL == 2) + #define __WDT_OSC_CLK ( 800000 / __DIVSEL) + #elif (__FREQSEL == 3) + #define __WDT_OSC_CLK (1100000 / __DIVSEL) + #elif (__FREQSEL == 4) + #define __WDT_OSC_CLK (1400000 / __DIVSEL) + #elif (__FREQSEL == 5) + #define __WDT_OSC_CLK (1600000 / __DIVSEL) + #elif (__FREQSEL == 6) + #define __WDT_OSC_CLK (1800000 / __DIVSEL) + #elif (__FREQSEL == 7) + #define __WDT_OSC_CLK (2000000 / __DIVSEL) + #elif (__FREQSEL == 8) + #define __WDT_OSC_CLK (2200000 / __DIVSEL) + #elif (__FREQSEL == 9) + #define __WDT_OSC_CLK (2400000 / __DIVSEL) + #elif (__FREQSEL == 10) + #define __WDT_OSC_CLK (2600000 / __DIVSEL) + #elif (__FREQSEL == 11) + #define __WDT_OSC_CLK (2700000 / __DIVSEL) + #elif (__FREQSEL == 12) + #define __WDT_OSC_CLK (2900000 / __DIVSEL) + #elif (__FREQSEL == 13) + #define __WDT_OSC_CLK (3100000 / __DIVSEL) + #elif (__FREQSEL == 14) + #define __WDT_OSC_CLK (3200000 / __DIVSEL) + #else + #define __WDT_OSC_CLK (3400000 / __DIVSEL) + #endif + #else + #define __WDT_OSC_CLK (1600000 / 2) + #endif // WDTOSC_SETUP + + /* sys_pllclkin calculation */ + #if ((SYSPLLCLKSEL_Val & 0x03) == 0) + #define __SYS_PLLCLKIN (__IRC_OSC_CLK) + #elif ((SYSPLLCLKSEL_Val & 0x03) == 1) + #define __SYS_PLLCLKIN (__SYS_OSC_CLK) + #elif ((SYSPLLCLKSEL_Val & 0x03) == 2) + #define __SYS_PLLCLKIN (__WDT_OSC_CLK) + #else + #define __SYS_PLLCLKIN (0) + #endif + + #if (SYSPLL_SETUP) /* System PLL Setup */ + #define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1)) + #else + #define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * (1)) + #endif // SYSPLL_SETUP + + /* main clock calculation */ + #if ((MAINCLKSEL_Val & 0x03) == 0) + #define __MAIN_CLOCK (__IRC_OSC_CLK) + #elif ((MAINCLKSEL_Val & 0x03) == 1) + #define __MAIN_CLOCK (__SYS_PLLCLKIN) + #elif ((MAINCLKSEL_Val & 0x03) == 2) + #define __MAIN_CLOCK (__WDT_OSC_CLK) + #elif ((MAINCLKSEL_Val & 0x03) == 3) + #define __MAIN_CLOCK (__SYS_PLLCLKOUT) + #else + #define __MAIN_CLOCK (0) + #endif + + #define __SYSTEM_CLOCK (__MAIN_CLOCK / SYSAHBCLKDIV_Val) + + #else // SYSCLK_SETUP + #if (SYSAHBCLKDIV_Val == 0) + #define __SYSTEM_CLOCK (0) + #else + #define __SYSTEM_CLOCK (__XTAL / SYSAHBCLKDIV_Val) + #endif + #endif // SYSCLK_SETUP + +#else + #define __SYSTEM_CLOCK (__XTAL) +#endif // CLOCK_SETUP + + +/*---------------------------------------------------------------------------- + Clock Variable definitions + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/ + + +/*---------------------------------------------------------------------------- + Clock functions + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */ +{ + uint32_t wdt_osc = 0; + + /* Determine clock frequency according to clock register values */ + switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) { + case 0: wdt_osc = 400000; break; + case 1: wdt_osc = 500000; break; + case 2: wdt_osc = 800000; break; + case 3: wdt_osc = 1100000; break; + case 4: wdt_osc = 1400000; break; + case 5: wdt_osc = 1600000; break; + case 6: wdt_osc = 1800000; break; + case 7: wdt_osc = 2000000; break; + case 8: wdt_osc = 2200000; break; + case 9: wdt_osc = 2400000; break; + case 10: wdt_osc = 2600000; break; + case 11: wdt_osc = 2700000; break; + case 12: wdt_osc = 2900000; break; + case 13: wdt_osc = 3100000; break; + case 14: wdt_osc = 3200000; break; + case 15: wdt_osc = 3400000; break; + } + wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2; + + switch (LPC_SYSCON->MAINCLKSEL & 0x03) { + case 0: /* Internal RC oscillator */ + SystemCoreClock = __IRC_OSC_CLK; + break; + case 1: /* Input Clock to System PLL */ + switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) { + case 0: /* Internal RC oscillator */ + SystemCoreClock = __IRC_OSC_CLK; + break; + case 1: /* System oscillator */ + SystemCoreClock = __SYS_OSC_CLK; + break; + case 2: /* WDT Oscillator */ + SystemCoreClock = wdt_osc; + break; + case 3: /* Reserved */ + SystemCoreClock = 0; + break; + } + break; + case 2: /* WDT Oscillator */ + SystemCoreClock = wdt_osc; + break; + case 3: /* System PLL Clock Out */ + switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) { + case 0: /* Internal RC oscillator */ + if (LPC_SYSCON->SYSPLLCTRL & 0x180) { + SystemCoreClock = __IRC_OSC_CLK; + } else { + SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1); + } + break; + case 1: /* System oscillator */ + if (LPC_SYSCON->SYSPLLCTRL & 0x180) { + SystemCoreClock = __SYS_OSC_CLK; + } else { + SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1); + } + break; + case 2: /* WDT Oscillator */ + if (LPC_SYSCON->SYSPLLCTRL & 0x180) { + SystemCoreClock = wdt_osc; + } else { + SystemCoreClock = wdt_osc * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1); + } + break; + case 3: /* Reserved */ + SystemCoreClock = 0; + break; + } + break; + } + + SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV; + +} + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System. + */ +void SystemInit (void) +{ +#if (CLOCK_SETUP) /* Clock Setup */ +#if (SYSCLK_SETUP) /* System Clock Setup */ +#if (SYSOSC_SETUP) /* System Oscillator Setup */ + uint32_t i; + + LPC_SYSCON->PDRUNCFG &= ~(1 << 5); /* Power-up System Osc */ + LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val; + for (i = 0; i < 200; i++) __NOP(); + LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */ + LPC_SYSCON->SYSPLLCLKUEN = 0x01; /* Update Clock Source */ + LPC_SYSCON->SYSPLLCLKUEN = 0x00; /* Toggle Update Register */ + LPC_SYSCON->SYSPLLCLKUEN = 0x01; + while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */ +#if (SYSPLL_SETUP) /* System PLL Setup */ + LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val; + LPC_SYSCON->PDRUNCFG &= ~(1 << 7); /* Power-up SYSPLL */ + while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */ +#endif +#endif +#if (WDTOSC_SETUP) /* Watchdog Oscillator Setup*/ + LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val; + LPC_SYSCON->PDRUNCFG &= ~(1 << 6); /* Power-up WDT Clock */ +#endif + LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val; /* Select PLL Clock Output */ + LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */ + LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */ + LPC_SYSCON->MAINCLKUEN = 0x01; + while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */ +#endif + +#if (USBCLK_SETUP) /* USB Clock Setup */ + LPC_SYSCON->PDRUNCFG &= ~(1 << 10); /* Power-up USB PHY */ +#if (USBPLL_SETUP) /* USB PLL Setup */ + LPC_SYSCON->PDRUNCFG &= ~(1 << 8); /* Power-up USB PLL */ + LPC_SYSCON->USBPLLCLKSEL = USBPLLCLKSEL_Val; /* Select PLL Input */ + LPC_SYSCON->USBPLLCLKUEN = 0x01; /* Update Clock Source */ + LPC_SYSCON->USBPLLCLKUEN = 0x00; /* Toggle Update Register */ + LPC_SYSCON->USBPLLCLKUEN = 0x01; + while (!(LPC_SYSCON->USBPLLCLKUEN & 0x01)); /* Wait Until Updated */ + LPC_SYSCON->USBPLLCTRL = USBPLLCTRL_Val; + while (!(LPC_SYSCON->USBPLLSTAT & 0x01)); /* Wait Until PLL Locked */ + LPC_SYSCON->USBCLKSEL = 0x00; /* Select USB PLL */ +#else + LPC_SYSCON->USBCLKSEL = 0x01; /* Select Main Clock */ +#endif +#else + LPC_SYSCON->PDRUNCFG |= (1 << 10); /* Power-down USB PHY */ + LPC_SYSCON->PDRUNCFG |= (1 << 8); /* Power-down USB PLL */ +#endif + + LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val; + LPC_SYSCON->SYSAHBCLKCTRL = AHBCLKCTRL_Val; +#endif + + +#if (MEMMAP_SETUP || MEMMAP_INIT) /* Memory Mapping Setup */ + LPC_SYSCON->SYSMEMREMAP = SYSMEMREMAP_Val; +#endif +} diff --git a/openbeacon/lpc13xx/core/freertos/inc/FreeRTOS.h b/openbeacon/lpc13xx/core/freertos/inc/FreeRTOS.h new file mode 100644 index 0000000..34aa13f --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/FreeRTOS.h @@ -0,0 +1,424 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + +/* include project specific config */ +#include +#ifdef ENABLE_FREERTOS + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +/* Definitions specific to the port being used. */ +#include "portable.h" + + +/* Defines the prototype to which the application task hook function must +conform. */ +typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); + + + + + +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configUSE_PREEMPTION + #error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK + #error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK + #error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_CO_ROUTINES + #error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskPrioritySet + #error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_uxTaskPriorityGet + #error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelete + #error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskCleanUpResources + #error Missing definition: INCLUDE_vTaskCleanUpResources should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskSuspend + #error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelayUntil + #error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelay + #error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_16_BIT_TICKS + #error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API + #define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB + #define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #undef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 1 +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#if ( configUSE_MUTEXES == 1 ) + /* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism + within the mutex implementation so must be available if mutexes are used. */ + #undef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 1 +#else + #ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 0 + #endif +#endif + + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#endif + + +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 0 +#endif + +#if configQUEUE_REGISTRY_SIZE < 1 + #define configQUEUE_REGISTRY_SIZE 0 + #define vQueueAddToRegistry( xQueue, pcName ) + #define vQueueUnregisterQueue( xQueue ) +#endif + + +/* Remove any unused trace macros. */ +#ifndef traceSTART + /* Used to perform any necessary initialisation - for example, open a file + into which trace is to be written. */ + #define traceSTART() +#endif + +#ifndef traceEND + /* Use to close a trace, for example close a file into which trace has been + written. */ + #define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN + /* Called after a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the selected task. */ + #define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceTASK_SWITCHED_OUT + /* Called before a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the task being switched out. */ + #define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND + /* Task is about to block because it cannot write to a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the write was attempted. pxCurrentTCB points to the TCB of the + task that attempted the write. */ + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED() +#endif + +#ifndef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE + #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE + #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE + #define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED( pxNewTCB ) +#endif + +#ifndef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL + #define traceTASK_DELAY_UNTIL() +#endif + +#ifndef traceTASK_DELAY + #define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK + #define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. + #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + + #ifndef portGET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then portGET_RUN_TIME_COUNTER_VALUE must also be defined. portGET_RUN_TIME_COUNTER_VALUE should evaluate to the counter value of the timer/counter peripheral used as the run time counter time base. + #endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT + #define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API + #define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef pvPortMallocAligned + #define pvPortMallocAligned( x, puxStackBuffer ) ( ( puxStackBuffer == NULL ) ? ( pvPortMalloc( x ) ) : ( puxStackBuffer ) ) +#endif + +#ifndef vPortFreeAligned + #define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree ) +#endif + +#endif /* ENABLE_FREERTOS */ +#endif /* INC_FREERTOS_H */ + diff --git a/openbeacon/lpc13xx/core/freertos/inc/StackMacros.h b/openbeacon/lpc13xx/core/freertos/inc/StackMacros.h new file mode 100644 index 0000000..cd0a061 --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/StackMacros.h @@ -0,0 +1,173 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( configCHECK_FOR_STACK_OVERFLOW == 0 ) + + /* FreeRTOSConfig.h is not set to check for stack overflows. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */ +/*-----------------------------------------------------------*/ + +#if( configCHECK_FOR_STACK_OVERFLOW == 1 ) + + /* FreeRTOSConfig.h is only set to use the first method of + overflow checking. */ + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() + +#endif +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ + { \ + extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ + { \ + extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ + { \ + extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \ + static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ + { \ + extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \ + char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \ + static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#endif /* STACK_MACROS_H */ + diff --git a/openbeacon/lpc13xx/core/freertos/inc/croutine.h b/openbeacon/lpc13xx/core/freertos/inc/croutine.h new file mode 100644 index 0000000..8c2f1a6 --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/croutine.h @@ -0,0 +1,749 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef INC_FREERTOS_H + #error "#include FreeRTOS.h" must appear in source files before "#include croutine.h" +#endif + + + + +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to hide the implementation of the co-routine control block. The +control block structure however has to be included in the header due to +the macro implementation of the co-routine functionality. */ +typedef void * xCoRoutineHandle; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ + xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */ + unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ + unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + unsigned short uxState; /*< Used internally by the co-routine implementation. */ +} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */ + +/** + * croutine. h + *
+ portBASE_TYPE xCoRoutineCreate(
+                                 crCOROUTINE_CODE pxCoRoutineCode,
+                                 unsigned portBASE_TYPE uxPriority,
+                                 unsigned portBASE_TYPE uxIndex
+                               );
+ * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: +
+ // Co-routine to be created.
+ void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const portTickType uxFlashRates[ 2 ] = { 200, 400 };
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // This co-routine just delays for a fixed period, then toggles
+         // an LED.  Two co-routines are created using this function, so
+         // the uxIndex parameter is used to tell the co-routine which
+         // LED to flash and how long to delay.  This assumes xQueue has
+         // already been created.
+         vParTestToggleLED( cLedToFlash[ uxIndex ] );
+         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+		
+     // Create two co-routines at priority 0.  The first is given index 0
+     // so (from the code above) toggles LED 5 every 200 ticks.  The second
+     // is given index 1 so toggles LED 6 every 400 ticks.
+     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+     {
+         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+     }
+ }
+   
+ * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ); + + +/** + * croutine. h + *
+ void vCoRoutineSchedule( void );
+ * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: +
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+	vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+    for( ;; )
+    {
+        vCoRoutineSchedule();
+    }
+ }
+ 
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + *
+ crSTART( xCoRoutineHandle xHandle );
+ * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static long ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0: + +/** + * croutine. h + *
+ crEND();
+ * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static long ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): +#define crSET_STATE1( xHandle ) ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): + +/** + * croutine. h + *
+ crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );
+ * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+        // Delay for 200ms.
+        crDELAY( xHandle, xDelayTime );
+
+        // Do something here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + if( xTicksToDelay > 0 ) \ + { \ + vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \ + } \ + crSET_STATE0( xHandle ); + +/** + *
+ crQUEUE_SEND(
+                  xCoRoutineHandle xHandle,
+                  xQueueHandle pxQueue,
+                  void *pvItemToQueue,
+                  portTickType xTicksToWait,
+                  portBASE_TYPE *pxResult
+             )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: +
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xNumberToPost = 0;
+ static portBASE_TYPE xResult;
+
+    // Co-routines must begin with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // This assumes the queue has already been created.
+        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+        if( xResult != pdPASS )
+        {
+            // The message was not posted!
+        }
+
+        // Increment the number to be posted onto the queue.
+        xNumberToPost++;
+
+        // Delay for 100 ticks.
+        crDELAY( xHandle, 100 );
+    }
+
+    // Co-routines must end with a call to crEND().
+    crEND();
+ }
+ * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ +{ \ + *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait ); \ + if( *pxResult == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( xHandle ); \ + *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( xHandle ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_RECEIVE(
+                     xCoRoutineHandle xHandle,
+                     xQueueHandle pxQueue,
+                     void *pvBuffer,
+                     portTickType xTicksToWait,
+                     portBASE_TYPE *pxResult
+                 )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: +
+ // A co-routine receives the number of an LED to flash from a queue.  It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xResult;
+ static unsigned portBASE_TYPE uxLEDToFlash;
+
+    // All co-routines must start with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // Wait for data to become available on the queue.
+        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+        if( xResult == pdPASS )
+        {
+            // We received the LED to flash - flash it!
+            vParTestToggleLED( uxLEDToFlash );
+        }
+    }
+
+    crEND();
+ }
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ +{ \ + *pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait ); \ + if( *pxResult == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( xHandle ); \ + *pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( xHandle ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            xQueueHandle pxQueue,
+                            void *pvItemToQueue,
+                            portBASE_TYPE xCoRoutinePreviouslyWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: +
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ char cRxedChar;
+ portBASE_TYPE xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Wait for data to become available on the queue.  This assumes the
+         // queue xCommsRxQueue has already been created!
+         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+         // Was a character received?
+         if( xResult == pdPASS )
+         {
+             // Process the character here.
+         }
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+     // We loop around reading characters until there are none left in the UART.
+     while( UART_RX_REG_NOT_EMPTY() )
+     {
+         // Obtain the character from the UART.
+         cRxedChar = UART_RX_REG;
+
+         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
+         // the first time around the loop.  If the post causes a co-routine
+         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+         // In this manner we can ensure that if more than one co-routine is
+         // blocked on the queue only one is woken by this ISR no matter how
+         // many characters are posted to the queue.
+         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+     }
+ }
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) + + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            xQueueHandle pxQueue,
+                            void *pvBuffer,
+                            portBASE_TYPE * pxCoRoutineWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: +
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period.  The character is incremented each time.
+ static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ portBASE_TYPE xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Send the next character to the queue.
+         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+         if( xResult == pdPASS )
+         {
+             // The character was successfully posted to the queue.
+         }
+		 else
+		 {
+			// Could not post the character to the queue.
+		 }
+
+         // Enable the UART Tx interrupt to cause an interrupt in this
+		 // hypothetical UART.  The interrupt will obtain the character
+		 // from the queue and send it.
+		 ENABLE_RX_INTERRUPT();
+
+		 // Increment to the next character then block for a fixed period.
+		 // cCharToTx will maintain its value across the delay as it is
+		 // declared static.
+		 cCharToTx++;
+		 if( cCharToTx > 'x' )
+		 {
+			cCharToTx = 'a';
+		 }
+		 crDELAY( 100 );
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+     while( UART_TX_REG_EMPTY() )
+     {
+         // Are there any characters in the queue waiting to be sent?
+		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+		 // is woken by the post - ensuring that only a single co-routine is
+		 // woken no matter how many times we go around this loop.
+         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+		 {
+			 SEND_CHARACTER( cCharToTx );
+		 }
+     }
+ }
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ); + +#ifdef __cplusplus +} +#endif + +#endif /* CO_ROUTINE_H */ diff --git a/openbeacon/lpc13xx/core/freertos/inc/list.h b/openbeacon/lpc13xx/core/freertos/inc/list.h new file mode 100644 index 0000000..1733ecc --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/list.h @@ -0,0 +1,305 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * xLists can only store pointers to xListItems. Each xListItem contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * descending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + +/* + Changes from V4.3.1 + + + Included local const within listGET_OWNER_OF_NEXT_ENTRY() to assist + compiler with optimisation. Thanks B.R. +*/ + +#ifndef LIST_H +#define LIST_H + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST_ITEM +{ + portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ + volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */ + volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */ + void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */ +}; +typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */ + +struct xMINI_LIST_ITEM +{ + portTickType xItemValue; + volatile struct xLIST_ITEM *pxNext; + volatile struct xLIST_ITEM *pxPrevious; +}; +typedef struct xMINI_LIST_ITEM xMiniListItem; + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + volatile unsigned portBASE_TYPE uxNumberOfItems; + volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */ + volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ +} xList; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) pxOwner + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in descending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = xValue + +/* + * Access macro the retrieve the value of the list item. The value can + * represent anything - for example a the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entries pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ +{ \ +xList * const pxConstList = pxList; \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + } \ + pxTCB = ( pxConstList )->pxIndex->pvOwner; \ +} + + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( pxList->uxNumberOfItems != ( unsigned portBASE_TYPE ) 0 ) ? ( (&( pxList->xListEnd ))->pxNext->pvOwner ) : ( NULL ) ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE is the list item is in the list, otherwise pdFALSE. + * pointer against + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) pxList ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise( xList *pxList ); + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem( xListItem *pxItem ); + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (descending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item to that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert( xList *pxList, xListItem *pxNewListItem ); + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pvIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pvIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pvIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd( xList *pxList, xListItem *pxNewListItem ); + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param vListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * \page vListRemove vListRemove + * \ingroup LinkedList + */ +void vListRemove( xListItem *pxItemToRemove ); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openbeacon/lpc13xx/core/freertos/inc/mpu_wrappers.h b/openbeacon/lpc13xx/core/freertos/inc/mpu_wrappers.h new file mode 100644 index 0000000..a3a497f --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/mpu_wrappers.h @@ -0,0 +1,135 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but +only for ports that are using the MPU. */ +#ifdef portUSING_MPU_WRAPPERS + + /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is + included from queue.c or task.c to prevent it from having an effect within + those files. */ + #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + + #define xTaskGenericCreate MPU_xTaskGenericCreate + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define vTaskDelete MPU_vTaskDelete + #define vTaskDelayUntil MPU_vTaskDelayUntil + #define vTaskDelay MPU_vTaskDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define vTaskSuspend MPU_vTaskSuspend + #define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended + #define vTaskResume MPU_vTaskResume + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskResumeAll MPU_xTaskResumeAll + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define vTaskList MPU_vTaskList + #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats + #define vTaskStartTrace MPU_vTaskStartTrace + #define ulTaskEndTrace MPU_ulTaskEndTrace + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + + #define xQueueCreate MPU_xQueueCreate + #define xQueueCreateMutex MPU_xQueueCreateMutex + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueAltGenericSend MPU_xQueueAltGenericSend + #define xQueueAltGenericReceive MPU_xQueueAltGenericReceive + #define xQueueGenericReceive MPU_xQueueGenericReceive + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define vQueueDelete MPU_vQueueDelete + + #define pvPortMalloc MPU_pvPortMalloc + #define vPortFree MPU_vPortFree + #define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize + #define vPortInitialiseBlocks MPU_vPortInitialiseBlocks + + #if configQUEUE_REGISTRY_SIZE > 0 + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #endif + + /* Remove the privileged function macro. */ + #define PRIVILEGED_FUNCTION + + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + + /* Ensure API functions go in the privileged execution section. */ + #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + //#define PRIVILEGED_DATA + + #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA + #define portUSING_MPU_WRAPPERS 0 + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ + diff --git a/openbeacon/lpc13xx/core/freertos/inc/portable.h b/openbeacon/lpc13xx/core/freertos/inc/portable.h new file mode 100644 index 0000000..d6e42a2 --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/portable.h @@ -0,0 +1,390 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/*----------------------------------------------------------- + * Portable layer API. Each function must be defined for each port. + *----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Include the macro file relevant to the port being used. */ + +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT + #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT + #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef GCC_MEGA_AVR + #include "../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR + #include "../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT + #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT + #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT + #include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT + #include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h" +#endif + +#ifdef _FEDPICC + #include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL + #include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 + #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE + #include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx + #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 + #include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 + #include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 + #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS + #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC + #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR + #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR + #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR + #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR + #include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR + #include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC + #include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR + #include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S + #include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 + #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 + #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR + #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC + #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE + #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 + #include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 + #include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC + #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR + #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 + #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 + #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE + #include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef __GNUC__ + #ifdef __AVR32_AVR32A__ + #include "portmacro.h" + #endif +#endif + +#ifdef __ICCAVR32__ + #ifdef __CORE__ + #if __CORE__ == __AVR32A__ + #include "portmacro.h" + #endif + #endif +#endif + +#ifdef __91467D + #include "portmacro.h" +#endif + +#ifdef __96340 + #include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +/* Catch all to ensure portmacro.h is included in the build. Newer demos +have the path as part of the project options, rather than as relative from +the project location. If portENTER_CRITICAL() has not been defined then +portmacro.h has not yet been included - as every portmacro.h provides a +portENTER_CRITICAL() definition. Check the demo application for your demo +to find the path to the correct portmacro.h file. */ +#ifndef portENTER_CRITICAL + #include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#endif + +#if portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#endif + +#if portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#endif + +#if portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#endif + +#ifndef portBYTE_ALIGNMENT_MASK + #error "Invalid portBYTE_ALIGNMENT definition" +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS + #define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mpu_wrappers.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION; +#else + portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ); +#endif + +/* + * Map to the memory management routines required for the port. + */ +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void vPortFree( void *pv ) PRIVILEGED_FUNCTION; +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABLE_H */ + diff --git a/openbeacon/lpc13xx/core/freertos/inc/portmacro.h b/openbeacon/lpc13xx/core/freertos/inc/portmacro.h new file mode 100644 index 0000000..861ebf4 --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/portmacro.h @@ -0,0 +1,156 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE unsigned portLONG +#define portBASE_TYPE long + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef unsigned portSHORT portTickType; + #define portMAX_DELAY ( portTickType ) 0xffff +#else + typedef unsigned portLONG portTickType; + #define portMAX_DELAY ( portTickType ) 0xffffffff +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + + +/* Scheduler utilities. */ +extern void vPortYieldFromISR( void ); + +#define portYIELD() vPortYieldFromISR() + +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR() +/*-----------------------------------------------------------*/ + + +/* Critical section management. */ + +/* + * Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other + * registers. r0 is clobbered. + */ +#define portSET_INTERRUPT_MASK() \ + __asm volatile \ + ( \ + " mov r0, %0 \n" \ + " msr basepri, r0 \n" \ + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY):"r0" \ + ) + +/* + * Set basepri back to 0 without effective other registers. + * r0 is clobbered. + */ +#define portCLEAR_INTERRUPT_MASK() \ + __asm volatile \ + ( \ + " mov r0, #0 \n" \ + " msr basepri, r0 \n" \ + :::"r0" \ + ) + +#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x + + +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); + +#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK() +#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +#define portNOP() + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/openbeacon/lpc13xx/core/freertos/inc/projdefs.h b/openbeacon/lpc13xx/core/freertos/inc/projdefs.h new file mode 100644 index 0000000..5441415 --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/projdefs.h @@ -0,0 +1,77 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* Defines the prototype to which task functions must conform. */ +typedef void (*pdTASK_CODE)( void * ); + +#define pdTRUE ( 1 ) +#define pdFALSE ( 0 ) + +#define pdPASS ( 1 ) +#define pdFAIL ( 0 ) +#define errQUEUE_EMPTY ( 0 ) +#define errQUEUE_FULL ( 0 ) + +/* Error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errNO_TASK_TO_RUN ( -2 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +#endif /* PROJDEFS_H */ + + + diff --git a/openbeacon/lpc13xx/core/freertos/inc/queue.h b/openbeacon/lpc13xx/core/freertos/inc/queue.h new file mode 100644 index 0000000..214ee9c --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/queue.h @@ -0,0 +1,1261 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef INC_FREERTOS_H + #error "#include FreeRTOS.h" must appear in source files before "#include queue.h" +#endif + + + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "mpu_wrappers.h" + + +typedef void * xQueueHandle; + + +/* For internal use only. */ +#define queueSEND_TO_BACK ( 0 ) +#define queueSEND_TO_FRONT ( 1 ) + + +/** + * queue. h + *
+ xQueueHandle xQueueCreate(
+							  unsigned portBASE_TYPE uxQueueLength,
+							  unsigned portBASE_TYPE uxItemSize
+						  );
+ * 
+ * + * Creates a new queue instance. This allocates the storage required by the + * new queue and returns a handle for the queue. + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+	if( xQueue1 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue2 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ); + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToToFront(
+								   xQueueHandle	xQueue,
+								   const	void	*	pvItemToQueue,
+								   portTickType	xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToBack(
+								   xQueueHandle	xQueue,
+								   const	void	*	pvItemToQueue,
+								   portTickType	xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueSend(
+							  xQueueHandle xQueue,
+							  const void * pvItemToQueue,
+							  portTickType xTicksToWait
+						 );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK ) + + +/** + * queue. h + *
+ portBASE_TYPE xQueueGenericSend(
+									xQueueHandle xQueue,
+									const void * pvItemToQueue,
+									portTickType xTicksToWait
+									portBASE_TYPE xCopyPosition
+								);
+ * 
+ * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ); + +/** + * queue. h + *
+ portBASE_TYPE xQueuePeek(
+							 xQueueHandle xQueue,
+							 void *pvBuffer,
+							 portTickType xTicksToWait
+						 );
+ * + * This is a macro that calls the xQueueGenericReceive() function. + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. + * + * @param pxQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Peek a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask, but the item still remains on the queue.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueReceive(
+								 xQueueHandle xQueue,
+								 void *pvBuffer,
+								 portTickType xTicksToWait
+							);
+ * + * This is a macro that calls the xQueueGenericReceive() function. + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param pxQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_RATE_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE ) + + +/** + * queue. h + *
+ portBASE_TYPE xQueueGenericReceive(
+									   xQueueHandle	xQueue,
+									   void	*pvBuffer,
+									   portTickType	xTicksToWait
+									   portBASE_TYPE	xJustPeek
+									);
+ * + * It is preferred that the macro xQueueReceive() be used rather than calling + * this function directly. + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param pxQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * xQueueGenericReceive() will return immediately if the queue is empty and + * xTicksToWait is 0. + * + * @param xJustPeek When set to true, the item received from the queue is not + * actually removed from the queue - meaning a subsequent call to + * xQueueReceive() will return the same item. When set to false, the item + * being received from the queue is also removed from the queue. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek ); + +/** + * queue. h + *
unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );
+ * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \page uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue ); + +/** + * queue. h + *
void vQueueDelete( xQueueHandle xQueue );
+ * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \page vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete( xQueueHandle xQueue ); + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToFrontFromISR(
+										 xQueueHandle pxQueue,
+										 const void *pvItemToQueue,
+										 portBASE_TYPE *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPrioritTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_FRONT ) + + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToBackFromISR(
+										 xQueueHandle pxQueue,
+										 const void *pvItemToQueue,
+										 portBASE_TYPE *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendFromISR(
+									 xQueueHandle pxQueue,
+									 const void *pvItemToQueue,
+									 portBASE_TYPE *pxHigherPriorityTaskWoken
+								);
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		// Actual macro used here is port specific.
+		taskYIELD_FROM_ISR ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueGenericSendFromISR(
+										   xQueueHandle	pxQueue,
+										   const	void	*pvItemToQueue,
+										   portBASE_TYPE	*pxHigherPriorityTaskWoken,
+										   portBASE_TYPE	xCopyPosition
+									   );
+ 
+ * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWokenByPost;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWokenByPost = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post each byte.
+		xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.  Note that the
+	// name of the yield function required is port specific.
+	if( xHigherPriorityTaskWokenByPost )
+	{
+		taskYIELD_YIELD_FROM_ISR();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ); + +/** + * queue. h + *
+ portBASE_TYPE xQueueReceiveFromISR(
+									   xQueueHandle	pxQueue,
+									   void	*pvBuffer,
+									   portBASE_TYPE	*pxTaskWoken
+								   );
+ * 
+ * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param pxQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxTaskWoken A task may be blocked waiting for space to become + * available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+
+ xQueueHandle xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const portTickType xBlockTime = ( portTickType )0xff;
+
+	// Create a queue capable of containing 10 characters.
+	xQueue = xQueueCreate( 10, sizeof( char ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Post some characters that will be used within an ISR.  If the queue
+	// is full then this task will block for xBlockTime ticks.
+	cValueToPost = 'a';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+	cValueToPost = 'b';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+
+	// ... keep posting characters ... this task may block when the queue
+	// becomes full.
+
+	cValueToPost = 'c';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ portBASE_TYPE xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+	while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+	{
+		// A character was received.  Output the character now.
+		vOutputCharacter( cRxedChar );
+
+		// If removing the character from the queue woke the task that was
+		// posting onto the queue cTaskWokenByReceive will have been set to
+		// pdTRUE.  No matter how many times this loop iterates only one
+		// task will be woken.
+	}
+
+	if( cTaskWokenByPost != ( char ) pdFALSE;
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ); + +/* + * Utilities to query queue that are safe to use from an ISR. These utilities + * should be used only from witin an ISR, or within a critical section. + */ +signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ); +signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ); +unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ); + + +/* + * xQueueAltGenericSend() is an alternative version of xQueueGenericSend(). + * Likewise xQueueAltGenericReceive() is an alternative version of + * xQueueGenericReceive(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ); +signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ); +#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT ) +#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK ) +#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE ) +#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE ) + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ); +signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ); +signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ); +signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ); + +/* + * For internal use only. Use xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting() instead of calling these functions directly. + */ +xQueueHandle xQueueCreateMutex( void ); +xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ); + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ); +portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ); + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not effect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. + */ +#if configQUEUE_REGISTRY_SIZE > 0 + void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ); +#endif + + + + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + diff --git a/openbeacon/lpc13xx/core/freertos/inc/semphr.h b/openbeacon/lpc13xx/core/freertos/inc/semphr.h new file mode 100644 index 0000000..fcc75c7 --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/semphr.h @@ -0,0 +1,711 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef INC_FREERTOS_H + #error "#include FreeRTOS.h" must appear in source files before "#include semphr.h" +#endif + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#include "queue.h" + +typedef xQueueHandle xSemaphoreHandle; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1 ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0 ) +#define semGIVE_BLOCK_TIME ( ( portTickType ) 0 ) + + +/** + * semphr. h + *
vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )
+ * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#define vSemaphoreCreateBinary( xSemaphore ) { \ + xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \ + if( xSemaphore != NULL ) \ + { \ + xSemaphoreGive( xSemaphore ); \ + } \ + } + +/** + * semphr. h + *
xSemaphoreTake( 
+ *                   xSemaphoreHandle xSemaphore, 
+ *                   portTickType xBlockTime 
+ *               )
+ * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_RATE_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    vSemaphoreCreateBinary( xSemaphore );
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xSemaphore != NULL )
+    {
+        // See if we can obtain the semaphore.  If the semaphore is not available
+        // wait 10 ticks to see if it becomes free.	
+        if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the semaphore and can now access the
+            // shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource.  Release the 
+            // semaphore.
+            xSemaphoreGive( xSemaphore );
+        }
+        else
+        {
+            // We could not obtain the semaphore and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE ) + +/** + * semphr. h + * xSemaphoreTakeRecursive( + * xSemaphoreHandle xMutex, + * portTickType xBlockTime + * ) + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_RATE_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: +
+ xSemaphoreHandle xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.	
+        if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to 
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be 
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, but instead buried in a more complex
+			// call structure.  This is just for illustrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( xMutex, xBlockTime ) + + +/* + * xSemaphoreAltTake() is an alternative version of xSemaphoreTake(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE ) + +/** + * semphr. h + *
xSemaphoreGive( xSemaphoreHandle xSemaphore )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+        {
+            // We would expect this call to fail because we cannot give
+            // a semaphore without first "taking" it!
+        }
+
+        // Obtain the semaphore - don't block if the semaphore is not
+        // immediately available.
+        if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
+        {
+            // We now have the semaphore and can access the shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource so can free the
+            // semaphore.
+            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+            {
+                // We would not expect this call to fail because we must have
+                // obtained the semaphore to get here.
+            }
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )
+ * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: +
+ xSemaphoreHandle xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.	
+        if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to 
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be 
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, it would be more likely that the calls
+			// to xSemaphoreGiveRecursive() would be called as a call stack
+			// unwound.  This is just for demonstrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( xMutex ) + +/* + * xSemaphoreAltGive() is an alternative version of xSemaphoreGive(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
+ xSemaphoreGiveFromISR( 
+                          xSemaphoreHandle xSemaphore, 
+                          signed portBASE_TYPE *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: +
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT	10
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+    for( ;; )
+    {
+        // We want this task to run every 10 ticks of a timer.  The semaphore 
+        // was created before this task was started.
+
+        // Block waiting for the semaphore to become available.
+        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+        {
+            // It is time to execute.
+
+            // ...
+
+            // We have finished our task.  Return to the top of the loop where
+            // we will block on the semaphore until it is time to execute 
+            // again.  Note when using the semaphore for synchronisation with an
+			// ISR in this manner there is no need to 'give' the semaphore back.
+        }
+    }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static unsigned char ucLocalTickCount = 0;
+ static signed portBASE_TYPE xHigherPriorityTaskWoken;
+
+    // A timer tick has occurred.
+
+    // ... Do other time functions.
+
+    // Is it time for vATask () to run?
+	xHigherPriorityTaskWoken = pdFALSE;
+    ucLocalTickCount++;
+    if( ucLocalTickCount >= TICKS_TO_WAIT )
+    {
+        // Unblock the task by releasing the semaphore.
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+        // Reset the count so we release the semaphore again in 10 ticks time.
+        ucLocalTickCount = 0;
+    }
+
+    if( xHigherPriorityTaskWoken != pdFALSE )
+    {
+        // We can force a context switch here.  Context switching from an
+        // ISR uses port specific syntax.  Check the demo task for your port
+        // to find the syntax required.
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreHandle xSemaphoreCreateMutex( void )
+ * + * Macro that implements a mutex semaphore by using the existing queue + * mechanism. + * + * Mutexes created using this macro can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros should not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See vSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * xSemaphoreHandle. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex + * \ingroup Semaphores + */ +#define xSemaphoreCreateMutex() xQueueCreateMutex() + + +/** + * semphr. h + *
xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )
+ * + * Macro that implements a recursive mutex by using the existing queue + * mechanism. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros should not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See vSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * xSemaphoreHandle. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex + * \ingroup Semaphores + */ +#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex() + +/** + * semphr. h + *
xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )
+ * + * Macro that creates a counting semaphore by using the existing + * queue mechanism. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ xSemaphoreHandle xSemaphore = NULL;
+
+    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+    // The max value to which the semaphore can count should be 10, and the
+    // initial value assigned to the count should be 0.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount ) + + +#endif /* SEMAPHORE_H */ + + diff --git a/openbeacon/lpc13xx/core/freertos/inc/task.h b/openbeacon/lpc13xx/core/freertos/inc/task.h new file mode 100644 index 0000000..23beeb6 --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/inc/task.h @@ -0,0 +1,1279 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +#ifndef INC_FREERTOS_H + #error "#include FreeRTOS.h" must appear in source files before "#include task.h" +#endif + + + +#ifndef TASK_H +#define TASK_H + +#include "portable.h" +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V6.1.0" + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an xTaskHandle variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \page xTaskHandle xTaskHandle + * \ingroup Tasks + */ +typedef void * xTaskHandle; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + portBASE_TYPE xOverflowCount; + portTickType xTimeOnEntering; +} xTimeOutType; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + unsigned long ulLengthInBytes; + unsigned long ulParameters; +} xMemoryRegion; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMTERS +{ + pdTASK_CODE pvTaskCode; + const signed char * const pcName; + unsigned short usStackDepth; + void *pvParameters; + unsigned portBASE_TYPE uxPriority; + portSTACK_TYPE *puxStackBuffer; + xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ]; +} xTaskParameters; + +/* + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0 ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \page taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \page taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \page taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() + +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \page taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \page taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). */ +#define taskSCHEDULER_NOT_STARTED 0 +#define taskSCHEDULER_RUNNING 1 +#define taskSCHEDULER_SUSPENDED 2 + +/*----------------------------------------------------------- + * TASK CREATION API + *----------------------------------------------------------*/ + +/** + * task. h + *
+ portBASE_TYPE xTaskCreate(
+							  pdTASK_CODE pvTaskCode,
+							  const char * const pcName,
+							  unsigned short usStackDepth,
+							  void *pvParameters,
+							  unsigned portBASE_TYPE uxPriority,
+							  xTaskHandle *pvCreatedTask
+						  );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by tskMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pvCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file errors. h + * + * Example usage: +
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+	 }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+
+	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+	 // the new task attempts to access it.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) ) + +/** + * task. h + *
+ portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle *pxCreatedTask );
+ * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file errors. h + * + * Example usage: +
+// Create an xTaskParameters structure that defines the task to be created.
+static const xTaskParameters xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{											
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+};
+
+int main( void )
+{
+xTaskHandle xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) ) + +/** + * task. h + *
+ void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );
+ * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an xMemoryRegion structure that contains the + * new memory region definitions. + * + * Example usage: +
+// Define an array of xMemoryRegion structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const xMemoryRegion xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{											
+	// Base address		Length		Parameters
+	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
+	{ 0,				0,			0 },
+	{ 0,				0,			0 }
+};
+
+void vATask( void *pvParameters )
+{
+	// This task was created such that it has access to certain regions of
+	// memory as defined by the MPU configuration.  At some point it is
+	// desired that these MPU regions are replaced with that defined in the
+	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+	// for this purpose.  NULL is used as the task handle to indicate that this
+	// function should modify the MPU regions of the calling task.
+	vTaskAllocateMPURegions( NULL, xAltRegions );
+	
+	// Now the task can continue its function, but from this point on can only
+	// access its stack and the ucOneKByte array (unless any other statically
+	// defined or shared regions have been declared elsewhere).
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelete( xTaskHandle pxTask );
+ * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernels management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param pxTask The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: +
+ void vOtherFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create the task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete( xTaskHandle pxTask ) PRIVILEGED_FUNCTION; + + +/*----------------------------------------------------------- + * TASK CONTROL API + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskDelay( portTickType xTicksToDelay );
+ * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_RATE_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a cyclical task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + + void vTaskFunction( void * pvParameters ) + { + void vTaskFunction( void * pvParameters ) + { + // Block for 500ms. + const portTickType xDelay = 500 / portTICK_RATE_MS; + + for( ;; ) + { + // Simply toggle the LED every 500ms, blocking between each toggle. + vToggleLED(); + vTaskDelay( xDelay ); + } + } + + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay( portTickType xTicksToDelay ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );
+ * + * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by cyclical + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The constant portTICK_RATE_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within vTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * Example usage: +
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ portTickType xLastWakeTime;
+ const portTickType xFrequency = 10;
+
+	 // Initialise the xLastWakeTime variable with the current time.
+	 xLastWakeTime = xTaskGetTickCount ();
+	 for( ;; )
+	 {
+		 // Wait for the next cycle.
+		 vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+		 // Perform action here.
+	 }
+ }
+   
+ * \defgroup vTaskDelayUntil vTaskDelayUntil + * \ingroup TaskCtrl + */ +void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );
+ * + * INCLUDE_xTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param pxTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of pxTask. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to obtain the priority of the created task.
+	 // It was created with tskIDLE_PRIORITY, but may have changed
+	 // it itself.
+	 if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+	 {
+		 // The task has changed it's priority.
+	 }
+
+	 // ...
+
+	 // Is our priority higher than the created task?
+	 if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+	 {
+		 // Our priority (obtained using NULL handle) is higher.
+	 }
+ }
+   
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );
+ * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param pxTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to raise the priority of the created task.
+	 vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+	 // ...
+
+	 // Use a NULL handle to raise our priority to the same value.
+	 vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+   
+ * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspend( xTaskHandle pxTaskToSuspend );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param pxTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Suspend ourselves.
+	 vTaskSuspend( NULL );
+
+	 // We cannot get here unless another task calls vTaskResume
+	 // with our handle as the parameter.
+ }
+   
+ * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend( xTaskHandle pxTaskToSuspend ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskResume( xTaskHandle pxTaskToResume );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one of more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param pxTaskToResume Handle to the task being readied. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Resume the suspended task ourselves.
+	 vTaskResume( xHandle );
+
+	 // The created task will once again get microcontroller processing
+	 // time in accordance with it priority within the system.
+ }
+   
+ * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void xTaskResumeFromISR( xTaskHandle pxTaskToResume );
+ * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one of more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * @param pxTaskToResume Handle to the task being readied. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER CONTROL + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskStartScheduler( void );
+ * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. This function + * does not return until an executing task calls vTaskEndScheduler (). + * + * At least one task should be created via a call to xTaskCreate () + * before calling vTaskStartScheduler (). The idle task is created + * automatically when the first application task is created. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: +
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+   
+ * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskEndScheduler( void );
+ * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: +
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // At some point we want to end the real time kernel processing
+		 // so call ...
+		 vTaskEndScheduler ();
+	 }
+ }
+
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will only get here when the vTaskCode () task has called
+	 // vTaskEndScheduler ().  When we get here we are back to single task
+	 // execution.
+ }
+   
+ * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspendAll( void );
+ * + * Suspends all real time kernel activity while keeping interrupts (including the + * kernel tick) enabled. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the kernel
+		 // tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.
+		 xTaskResumeAll ();
+	 }
+ }
+   
+ * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
char xTaskResumeAll( void );
+ * + * Resumes real time kernel activity following a call to vTaskSuspendAll (). + * After a call to vTaskSuspendAll () the kernel will take control of which + * task is executing at any time. + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the real
+		 // time kernel tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.  We want to force
+		 // a context switch - but there is no point if resuming the scheduler
+		 // caused a context switch already.
+		 if( !xTaskResumeAll () )
+		 {
+			  taskYIELD ();
+		 }
+	 }
+ }
+   
+ * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );
+ * + * Utility task that simply returns pdTRUE if the task referenced by xTask is + * currently in the Suspended state, or pdFALSE if the task referenced by xTask + * is in any other state. + * + */ +signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK UTILITIES + *----------------------------------------------------------*/ + +/** + * task. h + *
portTickType xTaskGetTickCount( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \page xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
portTickType xTaskGetTickCountFromISR( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that portTickType is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \page xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +portTickType xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
unsigned short uxTaskGetNumberOfTasks( void );
+ * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskList( char *pcWriteBuffer );
+ * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * NOTE: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ascii form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \page vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskGetRunTimeStats( char *pcWriteBuffer );
+ * + * configGENERATE_RUN_TIME_STATS must be defined as 1 for this function + * to be available. The application must also then provide definitions + * for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter + * and return the timers current count value respectively. The counter + * should be at least 10 times the frequency of the tick count. + * + * NOTE: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ascii form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \page vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskStartTrace( char * pcBuffer, unsigned portBASE_TYPE uxBufferSize );
+ * + * Starts a real time kernel activity trace. The trace logs the identity of + * which task is running when. + * + * The trace file is stored in binary format. A separate DOS utility called + * convtrce.exe is used to convert this into a tab delimited text file which + * can be viewed and plotted in a spread sheet. + * + * @param pcBuffer The buffer into which the trace will be written. + * + * @param ulBufferSize The size of pcBuffer in bytes. The trace will continue + * until either the buffer in full, or ulTaskEndTrace () is called. + * + * \page vTaskStartTrace vTaskStartTrace + * \ingroup TaskUtils + */ +void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
unsigned long ulTaskEndTrace( void );
+ * + * Stops a kernel activity trace. See vTaskStartTrace (). + * + * @return The number of bytes that have been written into the trace buffer. + * + * \page usTaskEndTrace usTaskEndTrace + * \ingroup TaskUtils + */ +unsigned long ulTaskEndTrace( void ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in bytes) since the task + * started. The smaller the returned number the closer the task has come + * to overflowing its stack. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in bytes) + * since the task referenced by xTask was created. + */ +unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ +void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
void xTaskGetApplicationTaskTag( xTaskHandle xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. + */ +pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. + */ +portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) PRIVILEGED_FUNCTION; + + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + *----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. + */ +void vTaskIncrementTick( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks,the constant + * portTICK_RATE_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList () will be called if either an event occurs to + * unblock a task, or the block timeout period expires. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * INCLUDE_vTaskCleanUpResources and INCLUDE_vTaskSuspend must be defined as 1 + * for this function to be available. + * See the configuration section for more information. + * + * Empties the ready and delayed queues of task control blocks, freeing the + * memory allocated for the task control block and task stacks as it goes. + */ +void vTaskCleanUpResources( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +/* + * Capture the current time status for future reference. + */ +void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) PRIVILEGED_FUNCTION; + +/* + * Compare the time status now with that previously captured to see if the + * timeout has expired. + */ +portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +portBASE_TYPE xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Generic version of the task creation function which is in turn called by the + * xTaskCreate() and xTaskCreateRestricted() macros. + */ +signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif +#endif /* TASK_H */ + + + diff --git a/openbeacon/lpc13xx/core/freertos/src/heap_2.c b/openbeacon/lpc13xx/core/freertos/src/heap_2.c new file mode 100644 index 0000000..24b2297 --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/src/heap_2.c @@ -0,0 +1,283 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that permits + * allocated blocks to be freed, but does not combine adjacent free blocks + * into a single larger block. + * + * See heap_1.c and heap_3.c for alternative implementations, and the memory + * management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include +#ifdef ENABLE_FREERTOS +/*-----------------------------------------------------------*/ + +#include + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Allocate the memory for the heap. The struct is used to force byte +alignment without using any non-portable code. */ +static union xRTOS_HEAP +{ + #if portBYTE_ALIGNMENT == 8 + volatile portDOUBLE dDummy; + #else + volatile unsigned long ulDummy; + #endif + unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; +} xHeap; + +/* Define the linked list structure. This is used to link free blocks in order +of their size. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} xBlockLink; + + +static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ); +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) + +/* Create a couple of list links to mark the start and end of the list. */ +static xBlockLink xStart, xEnd; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = configTOTAL_HEAP_SIZE; + +/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ + +/* + * Insert a block into the list of free blocks - which is ordered by size of + * the block. Small blocks at the start of the list and large blocks at the end + * of the list. + */ +#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \ +{ \ +xBlockLink *pxIterator; \ +size_t xBlockSize; \ + \ + xBlockSize = pxBlockToInsert->xBlockSize; \ + \ + /* Iterate through the list until a block is found that has a larger size */ \ + /* than the block we are inserting. */ \ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \ + { \ + /* There is nothing to do here - just iterate to the correct position. */ \ + } \ + \ + /* Update the list to include the block being inserted in the correct */ \ + /* position. */ \ + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \ + pxIterator->pxNextFreeBlock = pxBlockToInsert; \ +} +/*-----------------------------------------------------------*/ + +#define prvHeapInit() \ +{ \ +xBlockLink *pxFirstFreeBlock; \ + \ + /* xStart is used to hold a pointer to the first item in the list of free */ \ + /* blocks. The void cast is used to prevent compiler warnings. */ \ + xStart.pxNextFreeBlock = ( void * ) xHeap.ucHeap; \ + xStart.xBlockSize = ( size_t ) 0; \ + \ + /* xEnd is used to mark the end of the list of free blocks. */ \ + xEnd.xBlockSize = configTOTAL_HEAP_SIZE; \ + xEnd.pxNextFreeBlock = NULL; \ + \ + /* To start with there is a single free block that is sized to take up the \ + entire heap space. */ \ + pxFirstFreeBlock = ( void * ) xHeap.ucHeap; \ + pxFirstFreeBlock->xBlockSize = configTOTAL_HEAP_SIZE; \ + pxFirstFreeBlock->pxNextFreeBlock = &xEnd; \ +} +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +static portBASE_TYPE xHeapHasBeenInitialised = pdFALSE; +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( xHeapHasBeenInitialised == pdFALSE ) + { + prvHeapInit(); + xHeapHasBeenInitialised = pdTRUE; + } + + /* The wanted size is increased so it can contain a xBlockLink + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += heapSTRUCT_SIZE; + + /* Ensure that blocks are always aligned to the required number of bytes. */ + if( xWantedSize & portBYTE_ALIGNMENT_MASK ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + } + + if( ( xWantedSize > 0 ) && ( xWantedSize < configTOTAL_HEAP_SIZE ) ) + { + /* Blocks are stored in byte order - traverse the list from the start + (smallest) block until one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If we found the end marker then a block of adequate size was not found. */ + if( pxBlock != &xEnd ) + { + /* Return the memory space - jumping over the xBlockLink structure + at its start. */ + pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); + + /* This block is being returned for use so must be taken our of the + list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new block + following the number of bytes requested. The void cast is + used to prevent byte alignment warnings from the compiler. */ + pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the single + block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + } + } + } + xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +unsigned char *puc = ( unsigned char * ) pv; +xBlockLink *pxLink; + + if( pv ) + { + /* The memory being freed will have an xBlockLink structure immediately + before it. */ + puc -= heapSTRUCT_SIZE; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) ); + xFreeBytesRemaining += pxLink->xBlockSize; + } + xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} + +#endif /* ENABLE_FREERTOS */ \ No newline at end of file diff --git a/openbeacon/lpc13xx/core/freertos/src/list.c b/openbeacon/lpc13xx/core/freertos/src/list.c new file mode 100644 index 0000000..bf65620 --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/src/list.c @@ -0,0 +1,193 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +#include +#include +#ifdef ENABLE_FREERTOS +/*-----------------------------------------------------------*/ +#include + +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +void vListInitialise( xList *pxList ) +{ + /* The list structure contains a list item which is used to mark the + end of the list. To initialise the list the list end is inserted + as the only list entry. */ + pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd ); + + /* The list end value is the highest possible value in the list to + ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + + /* The list end next and previous pointers point to itself so we know + when the list is empty. */ + pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd ); + pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd ); + + pxList->uxNumberOfItems = 0; +} +/*-----------------------------------------------------------*/ + +void vListInitialiseItem( xListItem *pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pvContainer = NULL; +} +/*-----------------------------------------------------------*/ + +void vListInsertEnd( xList *pxList, xListItem *pxNewListItem ) +{ +volatile xListItem * pxIndex; + + /* Insert a new list item into pxList, but rather than sort the list, + makes the new list item the last item to be removed by a call to + pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by + the pxIndex member. */ + pxIndex = pxList->pxIndex; + + pxNewListItem->pxNext = pxIndex->pxNext; + pxNewListItem->pxPrevious = pxList->pxIndex; + pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem; + pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem; + pxList->pxIndex = ( volatile xListItem * ) pxNewListItem; + + /* Remember which list the item is in. */ + pxNewListItem->pvContainer = ( void * ) pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void vListInsert( xList *pxList, xListItem *pxNewListItem ) +{ +volatile xListItem *pxIterator; +portTickType xValueOfInsertion; + + /* Insert the new list item into the list, sorted in ulListItem order. */ + xValueOfInsertion = pxNewListItem->xItemValue; + + /* If the list already contains a list item with the same item value then + the new list item should be placed after it. This ensures that TCB's which + are stored in ready lists (all of which have the same ulListItem value) + get an equal share of the CPU. However, if the xItemValue is the same as + the back marker the iteration loop below will not end. This means we need + to guard against this by checking the value first and modifying the + algorithm slightly if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + { + pxIterator = pxList->xListEnd.pxPrevious; + } + else + { + /* *** NOTE *********************************************************** + If you find your application is crashing here then likely causes are: + 1) Stack overflow - + see http://www.freertos.org/Stacks-and-stack-overflow-checking.html + 2) Incorrect interrupt priority assignment, especially on Cortex M3 + parts where numerically high priority values denote low actual + interrupt priories, which can seem counter intuitive. See + configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html + 3) Calling an API function from within a critical section or when + the scheduler is suspended. + 4) Using a queue or semaphore before it has been initialised or + before the scheduler has been started (are interrupts firing + before vTaskStartScheduler() has been called?). + See http://www.freertos.org/FAQHelp.html for more tips. + **********************************************************************/ + + for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) + { + /* There is nothing to do here, we are just iterating to the + wanted insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem; + pxNewListItem->pxPrevious = pxIterator; + pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem; + + /* Remember which list the item is in. This allows fast removal of the + item later. */ + pxNewListItem->pvContainer = ( void * ) pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void vListRemove( xListItem *pxItemToRemove ) +{ +xList * pxList; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + + /* The list item knows which list it is in. Obtain the list from the list + item. */ + pxList = ( xList * ) pxItemToRemove->pvContainer; + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + } + + pxItemToRemove->pvContainer = NULL; + ( pxList->uxNumberOfItems )--; +} +/*-----------------------------------------------------------*/ +#endif /* ENABLE_FREERTOS */ diff --git a/openbeacon/lpc13xx/core/freertos/src/port.c b/openbeacon/lpc13xx/core/freertos/src/port.c new file mode 100644 index 0000000..82e8f5e --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/src/port.c @@ -0,0 +1,292 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM3 port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include +#ifdef ENABLE_FREERTOS +/*-----------------------------------------------------------*/ +#include + +/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is +defined. The value should also ensure backward compatibility. +FreeRTOS.org versions prior to V4.4.0 did not include this definition. */ +#ifndef configKERNEL_INTERRUPT_PRIORITY + #define configKERNEL_INTERRUPT_PRIORITY 255 +#endif + +/* Constants required to manipulate the NVIC. */ +#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned long *) 0xe000e010 ) +#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned long *) 0xe000e014 ) +#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 ) +#define portNVIC_SYSPRI2 ( ( volatile unsigned long *) 0xe000ed20 ) +#define portNVIC_SYSTICK_CLK 0x00000004 +#define portNVIC_SYSTICK_INT 0x00000002 +#define portNVIC_SYSTICK_ENABLE 0x00000001 +#define portNVIC_PENDSVSET 0x10000000 +#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16 ) +#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24 ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) + +/* The priority used by the kernel is assigned to a variable to make access +from inline assembler easier. */ +const unsigned long ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY; + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. + */ +static void prvSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ) __attribute__ (( naked )); + +/* + * Tap into existing exceptino table + */ +void SVCall_Handler (void) __attribute__ ((alias ("vPortSVCHandler"))); +void PendSV_Handler (void) __attribute__ ((alias ("xPortPendSVHandler"))); +void SysTick_Handler (void) __attribute__ ((alias ("xPortSysTickHandler"))); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +void vPortStartFirstTask( void ) __attribute__ (( naked )); + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = 0; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */ + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + __asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" + " orr r14, #0xd \n" + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +void vPortStartFirstTask( void ) +{ + __asm volatile( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " svc 0 \n" /* System call to start first task. */ + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +portBASE_TYPE xPortStartScheduler( void ) +{ + /* Make PendSV, CallSV and SysTick the same priroity as the kernel. */ + *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI; + *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + prvSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Start the first task. */ + vPortStartFirstTask(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* It is unlikely that the CM3 port will require this function as there + is nothing to return to. */ +} +/*-----------------------------------------------------------*/ + +void vPortYieldFromISR( void ) +{ + /* Set a PendSV to request a context switch. */ + *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET; +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" + " \n" /* Restore the context, including the critical nesting count. */ + " ldr r1, [r3] \n" + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11} \n" /* Pop the registers. */ + " msr psp, r0 \n" + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ +unsigned long ulDummy; + + /* If using preemption, also force a context switch. */ + #if configUSE_PREEMPTION == 1 + *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET; + #endif + + ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); + { + vTaskIncrementTick(); + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); +} +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +void prvSetupTimerInterrupt( void ) +{ + /* Configure SysTick to interrupt at the requested rate. */ + *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE; +} + +/*-----------------------------------------------------------*/ +#endif /* ENABLE_FREERTOS */ +/*-----------------------------------------------------------*/ diff --git a/openbeacon/lpc13xx/core/freertos/src/queue.c b/openbeacon/lpc13xx/core/freertos/src/queue.c new file mode 100644 index 0000000..0b875f9 --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/src/queue.c @@ -0,0 +1,1632 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include +#ifdef ENABLE_FREERTOS +/*-----------------------------------------------------------*/ +#include +#include + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +/* Constants used with the cRxLock and cTxLock structure members. */ +#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 ) +#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 ) + +#define queueERRONEOUS_UNBLOCK ( -1 ) + +/* For internal use only. */ +#define queueSEND_TO_BACK ( 0 ) +#define queueSEND_TO_FRONT ( 1 ) + +/* Effectively make a union out of the xQUEUE structure. */ +#define pxMutexHolder pcTail +#define uxQueueType pcHead +#define uxRecursiveCallCount pcReadFrom +#define queueQUEUE_IS_MUTEX NULL + +/* Semaphores do not actually store or copy data, so have an items size of +zero. */ +#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 ) +#define queueDONT_BLOCK ( ( portTickType ) 0 ) +#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0 ) + +/* + * Definition of the queue used by the scheduler. + * Items are queued by copy, not reference. + */ +typedef struct QueueDefinition +{ + signed char *pcHead; /*< Points to the beginning of the queue storage area. */ + signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + + signed char *pcWriteTo; /*< Points to the free next place in the storage area. */ + signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */ + + xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + + volatile unsigned portBASE_TYPE uxMessagesWaiting; /*< The number of items currently in the queue. */ + unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */ + + signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + +} xQUEUE; +/*-----------------------------------------------------------*/ + +/* + * Inside this file xQueueHandle is a pointer to a xQUEUE structure. + * To keep the definition private the API header file defines it as a + * pointer to void. + */ +typedef xQUEUE *xQueueHandle; + +/* + * Prototypes for public functions are included here so we don't have to + * include the API header file (as it defines xQueueHandle differently). These + * functions are documented in the API header file. + */ +xQueueHandle +xQueueCreate (unsigned portBASE_TYPE uxQueueLength, + unsigned portBASE_TYPE uxItemSize) + PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueGenericSend (xQueueHandle xQueue, + const void *const pvItemToQueue, + portTickType xTicksToWait, + portBASE_TYPE xCopyPosition) + PRIVILEGED_FUNCTION; + unsigned portBASE_TYPE uxQueueMessagesWaiting (const xQueueHandle + pxQueue) + PRIVILEGED_FUNCTION; + void vQueueDelete (xQueueHandle xQueue) PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueGenericSendFromISR (xQueueHandle pxQueue, + const void *const + pvItemToQueue, + signed portBASE_TYPE * + pxHigherPriorityTaskWoken, + portBASE_TYPE + xCopyPosition) + PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueGenericReceive (xQueueHandle pxQueue, + void *const pvBuffer, + portTickType xTicksToWait, + portBASE_TYPE xJustPeeking) + PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueReceiveFromISR (xQueueHandle pxQueue, + void *const pvBuffer, + signed portBASE_TYPE * + pxTaskWoken) + PRIVILEGED_FUNCTION; + xQueueHandle xQueueCreateMutex (void) PRIVILEGED_FUNCTION; + xQueueHandle xQueueCreateCountingSemaphore (unsigned portBASE_TYPE + uxCountValue, + unsigned portBASE_TYPE + uxInitialCount) + PRIVILEGED_FUNCTION; + portBASE_TYPE xQueueTakeMutexRecursive (xQueueHandle xMutex, + portTickType xBlockTime) + PRIVILEGED_FUNCTION; + portBASE_TYPE xQueueGiveMutexRecursive (xQueueHandle xMutex) + PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueAltGenericSend (xQueueHandle pxQueue, + const void *const + pvItemToQueue, + portTickType xTicksToWait, + portBASE_TYPE xCopyPosition) + PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueAltGenericReceive (xQueueHandle pxQueue, + void *const pvBuffer, + portTickType xTicksToWait, + portBASE_TYPE xJustPeeking) + PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueIsQueueEmptyFromISR (const xQueueHandle + pxQueue) + PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueIsQueueFullFromISR (const xQueueHandle + pxQueue) + PRIVILEGED_FUNCTION; + unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR (const xQueueHandle + pxQueue) + PRIVILEGED_FUNCTION; + +/* + * Co-routine queue functions differ from task queue functions. Co-routines are + * an optional component. + */ +#if configUSE_CO_ROUTINES == 1 + signed portBASE_TYPE xQueueCRSendFromISR (xQueueHandle pxQueue, + const void *pvItemToQueue, + signed portBASE_TYPE + xCoRoutinePreviouslyWoken) + PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueCRReceiveFromISR (xQueueHandle pxQueue, + void *pvBuffer, + signed portBASE_TYPE * + pxTaskWoken) + PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueCRSend (xQueueHandle pxQueue, + const void *pvItemToQueue, + portTickType xTicksToWait) + PRIVILEGED_FUNCTION; + signed portBASE_TYPE xQueueCRReceive (xQueueHandle pxQueue, + void *pvBuffer, + portTickType xTicksToWait) + PRIVILEGED_FUNCTION; +#endif + +/* + * The queue registry is just a means for kernel aware debuggers to locate + * queue structures. It has no other purpose so is an optional component. + */ +#if configQUEUE_REGISTRY_SIZE > 0 + + /* The type stored within the queue registry array. This allows a name + to be assigned to each queue making kernel aware debugging a little + more user friendly. */ + typedef struct QUEUE_REGISTRY_ITEM + { + signed char *pcQueueName; + xQueueHandle xHandle; + } xQueueRegistryItem; + + /* The queue registry is simply an array of xQueueRegistryItem structures. + The pcQueueName member of a structure being NULL is indicative of the + array position being vacant. */ + xQueueRegistryItem xQueueRegistry[configQUEUE_REGISTRY_SIZE]; + + /* Removes a queue from the registry by simply setting the pcQueueName + member to NULL. */ + static void vQueueUnregisterQueue (xQueueHandle xQueue) + PRIVILEGED_FUNCTION; + void vQueueAddToRegistry (xQueueHandle xQueue, + signed char *pcQueueName) PRIVILEGED_FUNCTION; +#endif + +/* + * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not + * prevent an ISR from adding or removing items to the queue, but does prevent + * an ISR from removing tasks from the queue event lists. If an ISR finds a + * queue is locked it will instead increment the appropriate queue lock count + * to indicate that a task may require unblocking. When the queue in unlocked + * these lock counts are inspected, and the appropriate action taken. + */ + static void prvUnlockQueue (xQueueHandle pxQueue) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any data in a queue. + * + * @return pdTRUE if the queue contains no items, otherwise pdFALSE. + */ + static signed portBASE_TYPE prvIsQueueEmpty (const xQueueHandle pxQueue) + PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any space in a queue. + * + * @return pdTRUE if there is no space, otherwise pdFALSE; + */ + static signed portBASE_TYPE prvIsQueueFull (const xQueueHandle pxQueue) + PRIVILEGED_FUNCTION; + +/* + * Copies an item into the queue, either at the front of the queue or the + * back of the queue. + */ + static void prvCopyDataToQueue (xQUEUE * pxQueue, + const void *pvItemToQueue, + portBASE_TYPE xPosition) + PRIVILEGED_FUNCTION; + +/* + * Copies an item out of a queue. + */ + static void prvCopyDataFromQueue (xQUEUE * const pxQueue, + const void *pvBuffer) + PRIVILEGED_FUNCTION; +/*-----------------------------------------------------------*/ + +/* + * Macro to mark a queue as locked. Locking a queue prevents an ISR from + * accessing the queue event lists. + */ +#define prvLockQueue( pxQueue ) \ +{ \ + taskENTER_CRITICAL(); \ + { \ + if( pxQueue->xRxLock == queueUNLOCKED ) \ + { \ + pxQueue->xRxLock = queueLOCKED_UNMODIFIED; \ + } \ + if( pxQueue->xTxLock == queueUNLOCKED ) \ + { \ + pxQueue->xTxLock = queueLOCKED_UNMODIFIED; \ + } \ + } \ + taskEXIT_CRITICAL(); \ +} +/*-----------------------------------------------------------*/ + + +/*----------------------------------------------------------- + * PUBLIC QUEUE MANAGEMENT API documented in queue.h + *----------------------------------------------------------*/ + + xQueueHandle xQueueCreate (unsigned portBASE_TYPE uxQueueLength, + unsigned portBASE_TYPE uxItemSize) +{ + xQUEUE *pxNewQueue; + size_t xQueueSizeInBytes; + + /* Allocate the new queue structure. */ + if (uxQueueLength > (unsigned portBASE_TYPE) 0) + { + pxNewQueue = (xQUEUE *) pvPortMalloc (sizeof (xQUEUE)); + if (pxNewQueue != NULL) + { + /* Create the list of pointers to queue items. The queue is one byte + longer than asked for to make wrap checking easier/faster. */ + xQueueSizeInBytes = + (size_t) (uxQueueLength * uxItemSize) + (size_t) 1; + + pxNewQueue->pcHead = + (signed char *) pvPortMalloc (xQueueSizeInBytes); + if (pxNewQueue->pcHead != NULL) + { + /* Initialise the queue members as described above where the + queue type is defined. */ + pxNewQueue->pcTail = + pxNewQueue->pcHead + (uxQueueLength * uxItemSize); + pxNewQueue->uxMessagesWaiting = 0; + pxNewQueue->pcWriteTo = pxNewQueue->pcHead; + pxNewQueue->pcReadFrom = + pxNewQueue->pcHead + ((uxQueueLength - 1) * uxItemSize); + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + pxNewQueue->xRxLock = queueUNLOCKED; + pxNewQueue->xTxLock = queueUNLOCKED; + + /* Likewise ensure the event queues start with the correct state. */ + vListInitialise (&(pxNewQueue->xTasksWaitingToSend)); + vListInitialise (&(pxNewQueue->xTasksWaitingToReceive)); + + traceQUEUE_CREATE (pxNewQueue); + return pxNewQueue; + } + else + { + traceQUEUE_CREATE_FAILED (); + vPortFree (pxNewQueue); + } + } + } + + /* Will only reach here if we could not allocate enough memory or no memory + was required. */ + return NULL; +} + +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + +xQueueHandle +xQueueCreateMutex (void) +{ + xQUEUE *pxNewQueue; + + /* Allocate the new queue structure. */ + pxNewQueue = (xQUEUE *) pvPortMalloc (sizeof (xQUEUE)); + if (pxNewQueue != NULL) + { + /* Information required for priority inheritance. */ + pxNewQueue->pxMutexHolder = NULL; + pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; + + /* Queues used as a mutex no data is actually copied into or out + of the queue. */ + pxNewQueue->pcWriteTo = NULL; + pxNewQueue->pcReadFrom = NULL; + + /* Each mutex has a length of 1 (like a binary semaphore) and + an item size of 0 as nothing is actually copied into or out + of the mutex. */ + pxNewQueue->uxMessagesWaiting = 0; + pxNewQueue->uxLength = 1; + pxNewQueue->uxItemSize = 0; + pxNewQueue->xRxLock = queueUNLOCKED; + pxNewQueue->xTxLock = queueUNLOCKED; + + /* Ensure the event queues start with the correct state. */ + vListInitialise (&(pxNewQueue->xTasksWaitingToSend)); + vListInitialise (&(pxNewQueue->xTasksWaitingToReceive)); + + /* Start with the semaphore in the expected state. */ + xQueueGenericSend (pxNewQueue, NULL, 0, queueSEND_TO_BACK); + + traceCREATE_MUTEX (pxNewQueue); + } + else + { + traceCREATE_MUTEX_FAILED (); + } + + return pxNewQueue; +} + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if configUSE_RECURSIVE_MUTEXES == 1 + +portBASE_TYPE +xQueueGiveMutexRecursive (xQueueHandle pxMutex) +{ + portBASE_TYPE xReturn; + + /* If this is the task that holds the mutex then pxMutexHolder will not + change outside of this task. If this task does not hold the mutex then + pxMutexHolder can never coincidentally equal the tasks handle, and as + this is the only condition we are interested in it does not matter if + pxMutexHolder is accessed simultaneously by another task. Therefore no + mutual exclusion is required to test the pxMutexHolder variable. */ + if (pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle ()) + { + traceGIVE_MUTEX_RECURSIVE (pxMutex); + + /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to + the task handle, therefore no underflow check is required. Also, + uxRecursiveCallCount is only modified by the mutex holder, and as + there can only be one, no mutual exclusion is required to modify the + uxRecursiveCallCount member. */ + (pxMutex->uxRecursiveCallCount)--; + + /* Have we unwound the call count? */ + if (pxMutex->uxRecursiveCallCount == 0) + { + /* Return the mutex. This will automatically unblock any other + task that might be waiting to access the mutex. */ + xQueueGenericSend (pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, + queueSEND_TO_BACK); + } + + xReturn = pdPASS; + } + else + { + /* We cannot give the mutex because we are not the holder. */ + xReturn = pdFAIL; + + traceGIVE_MUTEX_RECURSIVE_FAILED (pxMutex); + } + + return xReturn; +} + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if configUSE_RECURSIVE_MUTEXES == 1 + +portBASE_TYPE +xQueueTakeMutexRecursive (xQueueHandle pxMutex, portTickType xBlockTime) +{ + portBASE_TYPE xReturn; + + /* Comments regarding mutual exclusion as per those within + xQueueGiveMutexRecursive(). */ + + traceTAKE_MUTEX_RECURSIVE (pxMutex); + + if (pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle ()) + { + (pxMutex->uxRecursiveCallCount)++; + xReturn = pdPASS; + } + else + { + xReturn = xQueueGenericReceive (pxMutex, NULL, xBlockTime, pdFALSE); + + /* pdPASS will only be returned if we successfully obtained the mutex, + we may have blocked to reach here. */ + if (xReturn == pdPASS) + { + (pxMutex->uxRecursiveCallCount)++; + } + } + + return xReturn; +} + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if configUSE_COUNTING_SEMAPHORES == 1 + +xQueueHandle +xQueueCreateCountingSemaphore (unsigned portBASE_TYPE uxCountValue, + unsigned portBASE_TYPE uxInitialCount) +{ + xQueueHandle pxHandle; + + pxHandle = + xQueueCreate ((unsigned portBASE_TYPE) uxCountValue, + queueSEMAPHORE_QUEUE_ITEM_LENGTH); + + if (pxHandle != NULL) + { + pxHandle->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE (); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED (); + } + + return pxHandle; +} + +#endif /* configUSE_COUNTING_SEMAPHORES */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE +xQueueGenericSend (xQueueHandle pxQueue, const void *const pvItemToQueue, + portTickType xTicksToWait, portBASE_TYPE xCopyPosition) +{ + signed portBASE_TYPE xEntryTimeSet = pdFALSE; + xTimeOutType xTimeOut; + + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + for (;;) + { + taskENTER_CRITICAL (); + { + /* Is there room on the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if (pxQueue->uxMessagesWaiting < pxQueue->uxLength) + { + traceQUEUE_SEND (pxQueue); + prvCopyDataToQueue (pxQueue, pvItemToQueue, xCopyPosition); + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if (listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive)) == + pdFALSE) + { + if (xTaskRemoveFromEventList + (&(pxQueue->xTasksWaitingToReceive)) == pdTRUE) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to do + this from within the critical section - the kernel + takes care of that. */ + portYIELD_WITHIN_API (); + } + } + + taskEXIT_CRITICAL (); + + /* Return to the original privilege level before exiting the + function. */ + return pdPASS; + } + else + { + if (xTicksToWait == (portTickType) 0) + { + /* The queue was full and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL (); + + /* Return to the original privilege level before exiting + the function. */ + traceQUEUE_SEND_FAILED (pxQueue); + return errQUEUE_FULL; + } + else if (xEntryTimeSet == pdFALSE) + { + /* The queue was full and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState (&xTimeOut); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL (); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll (); + prvLockQueue (pxQueue); + + /* Update the timeout state to see if it has expired yet. */ + if (xTaskCheckForTimeOut (&xTimeOut, &xTicksToWait) == pdFALSE) + { + if (prvIsQueueFull (pxQueue)) + { + traceBLOCKING_ON_QUEUE_SEND (pxQueue); + vTaskPlaceOnEventList (&(pxQueue->xTasksWaitingToSend), + xTicksToWait); + + /* Unlocking the queue means queue events can effect the + event list. It is possible that interrupts occurring now + remove this task from the event list again - but as the + scheduler is suspended the task will go onto the pending + ready last instead of the actual ready list. */ + prvUnlockQueue (pxQueue); + + /* Resuming the scheduler will move tasks from the pending + ready list into the ready list - so it is feasible that this + task is already in a ready list before it yields - in which + case the yield will not cause a context switch unless there + is also a higher priority task in the pending ready list. */ + if (!xTaskResumeAll ()) + { + portYIELD_WITHIN_API (); + } + } + else + { + /* Try again. */ + prvUnlockQueue (pxQueue); + (void) xTaskResumeAll (); + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue (pxQueue); + (void) xTaskResumeAll (); + + /* Return to the original privilege level before exiting the + function. */ + traceQUEUE_SEND_FAILED (pxQueue); + return errQUEUE_FULL; + } + } +} + +/*-----------------------------------------------------------*/ + +#if configUSE_ALTERNATIVE_API == 1 + +signed portBASE_TYPE +xQueueAltGenericSend (xQueueHandle pxQueue, const void *const pvItemToQueue, + portTickType xTicksToWait, portBASE_TYPE xCopyPosition) +{ + signed portBASE_TYPE xEntryTimeSet = pdFALSE; + xTimeOutType xTimeOut; + + for (;;) + { + taskENTER_CRITICAL (); + { + /* Is there room on the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if (pxQueue->uxMessagesWaiting < pxQueue->uxLength) + { + traceQUEUE_SEND (pxQueue); + prvCopyDataToQueue (pxQueue, pvItemToQueue, xCopyPosition); + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if (listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive)) == + pdFALSE) + { + if (xTaskRemoveFromEventList + (&(pxQueue->xTasksWaitingToReceive)) == pdTRUE) + { + /* The unblocked task has a priority higher than + our own so yield immediately. */ + portYIELD_WITHIN_API (); + } + } + + taskEXIT_CRITICAL (); + return pdPASS; + } + else + { + if (xTicksToWait == (portTickType) 0) + { + taskEXIT_CRITICAL (); + return errQUEUE_FULL; + } + else if (xEntryTimeSet == pdFALSE) + { + vTaskSetTimeOutState (&xTimeOut); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL (); + + taskENTER_CRITICAL (); + { + if (xTaskCheckForTimeOut (&xTimeOut, &xTicksToWait) == pdFALSE) + { + if (prvIsQueueFull (pxQueue)) + { + traceBLOCKING_ON_QUEUE_SEND (pxQueue); + vTaskPlaceOnEventList (&(pxQueue->xTasksWaitingToSend), + xTicksToWait); + portYIELD_WITHIN_API (); + } + } + else + { + taskEXIT_CRITICAL (); + traceQUEUE_SEND_FAILED (pxQueue); + return errQUEUE_FULL; + } + } + taskEXIT_CRITICAL (); + } +} + +#endif /* configUSE_ALTERNATIVE_API */ +/*-----------------------------------------------------------*/ + +#if configUSE_ALTERNATIVE_API == 1 + +signed portBASE_TYPE +xQueueAltGenericReceive (xQueueHandle pxQueue, void *const pvBuffer, + portTickType xTicksToWait, + portBASE_TYPE xJustPeeking) +{ + signed portBASE_TYPE xEntryTimeSet = pdFALSE; + xTimeOutType xTimeOut; + signed char *pcOriginalReadPosition; + + for (;;) + { + taskENTER_CRITICAL (); + { + if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0) + { + /* Remember our read position in case we are just peeking. */ + pcOriginalReadPosition = pxQueue->pcReadFrom; + + prvCopyDataFromQueue (pxQueue, pvBuffer); + + if (xJustPeeking == pdFALSE) + { + traceQUEUE_RECEIVE (pxQueue); + + /* We are actually removing data. */ + --(pxQueue->uxMessagesWaiting); + +#if ( configUSE_MUTEXES == 1 ) + { + if (pxQueue->uxQueueType == queueQUEUE_IS_MUTEX) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle (); + } + } +#endif + + if (listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToSend)) == + pdFALSE) + { + if (xTaskRemoveFromEventList + (&(pxQueue->xTasksWaitingToSend)) == pdTRUE) + { + portYIELD_WITHIN_API (); + } + } + } + else + { + traceQUEUE_PEEK (pxQueue); + + /* We are not removing the data, so reset our read + pointer. */ + pxQueue->pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive))) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if (xTaskRemoveFromEventList + (&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) + { + /* The task waiting has a higher priority than this task. */ + portYIELD_WITHIN_API (); + } + } + + } + + taskEXIT_CRITICAL (); + return pdPASS; + } + else + { + if (xTicksToWait == (portTickType) 0) + { + taskEXIT_CRITICAL (); + traceQUEUE_RECEIVE_FAILED (pxQueue); + return errQUEUE_EMPTY; + } + else if (xEntryTimeSet == pdFALSE) + { + vTaskSetTimeOutState (&xTimeOut); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL (); + + taskENTER_CRITICAL (); + { + if (xTaskCheckForTimeOut (&xTimeOut, &xTicksToWait) == pdFALSE) + { + if (prvIsQueueEmpty (pxQueue)) + { + traceBLOCKING_ON_QUEUE_RECEIVE (pxQueue); + +#if ( configUSE_MUTEXES == 1 ) + { + if (pxQueue->uxQueueType == queueQUEUE_IS_MUTEX) + { + portENTER_CRITICAL (); + vTaskPriorityInherit ((void *) pxQueue->pxMutexHolder); + portEXIT_CRITICAL (); + } + } +#endif + + vTaskPlaceOnEventList (&(pxQueue->xTasksWaitingToReceive), + xTicksToWait); + portYIELD_WITHIN_API (); + } + } + else + { + taskEXIT_CRITICAL (); + traceQUEUE_RECEIVE_FAILED (pxQueue); + return errQUEUE_EMPTY; + } + } + taskEXIT_CRITICAL (); + } +} + + +#endif /* configUSE_ALTERNATIVE_API */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE +xQueueGenericSendFromISR (xQueueHandle pxQueue, + const void *const pvItemToQueue, + signed portBASE_TYPE * pxHigherPriorityTaskWoken, + portBASE_TYPE xCopyPosition) +{ + signed portBASE_TYPE xReturn; + unsigned portBASE_TYPE uxSavedInterruptStatus; + + /* Similar to xQueueGenericSend, except we don't block if there is no room + in the queue. Also we don't directly wake a task that was blocked on a + queue read, instead we return a flag to say whether a context switch is + required or not (i.e. has a task with a higher priority than us been woken + by this post). */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR (); + { + if (pxQueue->uxMessagesWaiting < pxQueue->uxLength) + { + traceQUEUE_SEND_FROM_ISR (pxQueue); + + prvCopyDataToQueue (pxQueue, pvItemToQueue, xCopyPosition); + + /* If the queue is locked we do not alter the event list. This will + be done when the queue is unlocked later. */ + if (pxQueue->xTxLock == queueUNLOCKED) + { + if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive))) + { + if (xTaskRemoveFromEventList + (&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + *pxHigherPriorityTaskWoken = pdTRUE; + } + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + ++(pxQueue->xTxLock); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED (pxQueue); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR (uxSavedInterruptStatus); + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE +xQueueGenericReceive (xQueueHandle pxQueue, void *const pvBuffer, + portTickType xTicksToWait, portBASE_TYPE xJustPeeking) +{ + signed portBASE_TYPE xEntryTimeSet = pdFALSE; + xTimeOutType xTimeOut; + signed char *pcOriginalReadPosition; + + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + + for (;;) + { + taskENTER_CRITICAL (); + { + /* Is there data in the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0) + { + /* Remember our read position in case we are just peeking. */ + pcOriginalReadPosition = pxQueue->pcReadFrom; + + prvCopyDataFromQueue (pxQueue, pvBuffer); + + if (xJustPeeking == pdFALSE) + { + traceQUEUE_RECEIVE (pxQueue); + + /* We are actually removing data. */ + --(pxQueue->uxMessagesWaiting); + +#if ( configUSE_MUTEXES == 1 ) + { + if (pxQueue->uxQueueType == queueQUEUE_IS_MUTEX) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle (); + } + } +#endif + + if (listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToSend)) == + pdFALSE) + { + if (xTaskRemoveFromEventList + (&(pxQueue->xTasksWaitingToSend)) == pdTRUE) + { + portYIELD_WITHIN_API (); + } + } + } + else + { + traceQUEUE_PEEK (pxQueue); + + /* We are not removing the data, so reset our read + pointer. */ + pxQueue->pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive))) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if (xTaskRemoveFromEventList + (&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) + { + /* The task waiting has a higher priority than this task. */ + portYIELD_WITHIN_API (); + } + } + + } + + taskEXIT_CRITICAL (); + return pdPASS; + } + else + { + if (xTicksToWait == (portTickType) 0) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL (); + traceQUEUE_RECEIVE_FAILED (pxQueue); + return errQUEUE_EMPTY; + } + else if (xEntryTimeSet == pdFALSE) + { + /* The queue was empty and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState (&xTimeOut); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL (); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll (); + prvLockQueue (pxQueue); + + /* Update the timeout state to see if it has expired yet. */ + if (xTaskCheckForTimeOut (&xTimeOut, &xTicksToWait) == pdFALSE) + { + if (prvIsQueueEmpty (pxQueue)) + { + traceBLOCKING_ON_QUEUE_RECEIVE (pxQueue); + +#if ( configUSE_MUTEXES == 1 ) + { + if (pxQueue->uxQueueType == queueQUEUE_IS_MUTEX) + { + portENTER_CRITICAL (); + { + vTaskPriorityInherit ((void *) pxQueue->pxMutexHolder); + } + portEXIT_CRITICAL (); + } + } +#endif + + vTaskPlaceOnEventList (&(pxQueue->xTasksWaitingToReceive), + xTicksToWait); + prvUnlockQueue (pxQueue); + if (!xTaskResumeAll ()) + { + portYIELD_WITHIN_API (); + } + } + else + { + /* Try again. */ + prvUnlockQueue (pxQueue); + (void) xTaskResumeAll (); + } + } + else + { + prvUnlockQueue (pxQueue); + (void) xTaskResumeAll (); + traceQUEUE_RECEIVE_FAILED (pxQueue); + return errQUEUE_EMPTY; + } + } +} + +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE +xQueueReceiveFromISR (xQueueHandle pxQueue, void *const pvBuffer, + signed portBASE_TYPE * pxTaskWoken) +{ + signed portBASE_TYPE xReturn; + unsigned portBASE_TYPE uxSavedInterruptStatus; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR (); + { + /* We cannot block from an ISR, so check there is data available. */ + if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0) + { + traceQUEUE_RECEIVE_FROM_ISR (pxQueue); + + prvCopyDataFromQueue (pxQueue, pvBuffer); + --(pxQueue->uxMessagesWaiting); + + /* If the queue is locked we will not modify the event list. Instead + we update the lock count so the task that unlocks the queue will know + that an ISR has removed data while the queue was locked. */ + if (pxQueue->xRxLock == queueUNLOCKED) + { + if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToSend))) + { + if (xTaskRemoveFromEventList (&(pxQueue->xTasksWaitingToSend)) + != pdFALSE) + { + /* The task waiting has a higher priority than us so + force a context switch. */ + *pxTaskWoken = pdTRUE; + } + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was removed while it was locked. */ + ++(pxQueue->xRxLock); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_RECEIVE_FROM_ISR_FAILED (pxQueue); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR (uxSavedInterruptStatus); + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE +uxQueueMessagesWaiting (const xQueueHandle pxQueue) +{ + unsigned portBASE_TYPE uxReturn; + + taskENTER_CRITICAL (); + uxReturn = pxQueue->uxMessagesWaiting; + taskEXIT_CRITICAL (); + + return uxReturn; +} + +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE +uxQueueMessagesWaitingFromISR (const xQueueHandle pxQueue) +{ + unsigned portBASE_TYPE uxReturn; + + uxReturn = pxQueue->uxMessagesWaiting; + + return uxReturn; +} + +/*-----------------------------------------------------------*/ + +void +vQueueDelete (xQueueHandle pxQueue) +{ + traceQUEUE_DELETE (pxQueue); + vQueueUnregisterQueue (pxQueue); + vPortFree (pxQueue->pcHead); + vPortFree (pxQueue); +} + +/*-----------------------------------------------------------*/ + +static void +prvCopyDataToQueue (xQUEUE * pxQueue, const void *pvItemToQueue, + portBASE_TYPE xPosition) +{ + if (pxQueue->uxItemSize == (unsigned portBASE_TYPE) 0) + { +#if ( configUSE_MUTEXES == 1 ) + { + if (pxQueue->uxQueueType == queueQUEUE_IS_MUTEX) + { + /* The mutex is no longer being held. */ + vTaskPriorityDisinherit ((void *) pxQueue->pxMutexHolder); + pxQueue->pxMutexHolder = NULL; + } + } +#endif + } + else if (xPosition == queueSEND_TO_BACK) + { + memcpy ((void *) pxQueue->pcWriteTo, pvItemToQueue, + (unsigned) pxQueue->uxItemSize); + pxQueue->pcWriteTo += pxQueue->uxItemSize; + if (pxQueue->pcWriteTo >= pxQueue->pcTail) + { + pxQueue->pcWriteTo = pxQueue->pcHead; + } + } + else + { + memcpy ((void *) pxQueue->pcReadFrom, pvItemToQueue, + (unsigned) pxQueue->uxItemSize); + pxQueue->pcReadFrom -= pxQueue->uxItemSize; + if (pxQueue->pcReadFrom < pxQueue->pcHead) + { + pxQueue->pcReadFrom = (pxQueue->pcTail - pxQueue->uxItemSize); + } + } + + ++(pxQueue->uxMessagesWaiting); +} + +/*-----------------------------------------------------------*/ + +static void +prvCopyDataFromQueue (xQUEUE * const pxQueue, const void *pvBuffer) +{ + if (pxQueue->uxQueueType != queueQUEUE_IS_MUTEX) + { + pxQueue->pcReadFrom += pxQueue->uxItemSize; + if (pxQueue->pcReadFrom >= pxQueue->pcTail) + { + pxQueue->pcReadFrom = pxQueue->pcHead; + } + memcpy ((void *) pvBuffer, (void *) pxQueue->pcReadFrom, + (unsigned) pxQueue->uxItemSize); + } +} + +/*-----------------------------------------------------------*/ + +static void +prvUnlockQueue (xQueueHandle pxQueue) +{ + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ + + /* The lock counts contains the number of extra data items placed or + removed from the queue while the queue was locked. When a queue is + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL (); + { + /* See if data was added to the queue while it was locked. */ + while (pxQueue->xTxLock > queueLOCKED_UNMODIFIED) + { + /* Data was posted while the queue was locked. Are any tasks + blocked waiting for data to become available? */ + if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive))) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if (xTaskRemoveFromEventList (&(pxQueue->xTasksWaitingToReceive)) + != pdFALSE) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield (); + } + + --(pxQueue->xTxLock); + } + else + { + break; + } + } + + pxQueue->xTxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL (); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL (); + { + while (pxQueue->xRxLock > queueLOCKED_UNMODIFIED) + { + if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToSend))) + { + if (xTaskRemoveFromEventList (&(pxQueue->xTasksWaitingToSend)) != + pdFALSE) + { + vTaskMissedYield (); + } + + --(pxQueue->xRxLock); + } + else + { + break; + } + } + + pxQueue->xRxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL (); +} + +/*-----------------------------------------------------------*/ + +static signed portBASE_TYPE +prvIsQueueEmpty (const xQueueHandle pxQueue) +{ + signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL (); + xReturn = (pxQueue->uxMessagesWaiting == (unsigned portBASE_TYPE) 0); + taskEXIT_CRITICAL (); + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE +xQueueIsQueueEmptyFromISR (const xQueueHandle pxQueue) +{ + signed portBASE_TYPE xReturn; + + xReturn = (pxQueue->uxMessagesWaiting == (unsigned portBASE_TYPE) 0); + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +static signed portBASE_TYPE +prvIsQueueFull (const xQueueHandle pxQueue) +{ + signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL (); + xReturn = (pxQueue->uxMessagesWaiting == pxQueue->uxLength); + taskEXIT_CRITICAL (); + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE +xQueueIsQueueFullFromISR (const xQueueHandle pxQueue) +{ + signed portBASE_TYPE xReturn; + + xReturn = (pxQueue->uxMessagesWaiting == pxQueue->uxLength); + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE +xQueueCRSend (xQueueHandle pxQueue, const void *pvItemToQueue, + portTickType xTicksToWait) +{ + signed portBASE_TYPE xReturn; + + /* If the queue is already full we may have to block. A critical section + is required to prevent an interrupt removing something from the queue + between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS (); + { + if (prvIsQueueFull (pxQueue)) + { + /* The queue is full - do we want to block or just leave without + posting? */ + if (xTicksToWait > (portTickType) 0) + { + /* As this is called from a coroutine we cannot block directly, but + return indicating that we need to block. */ + vCoRoutineAddToDelayedList (xTicksToWait, + &(pxQueue->xTasksWaitingToSend)); + portENABLE_INTERRUPTS (); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS (); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS (); + + portNOP (); + + portDISABLE_INTERRUPTS (); + { + if (pxQueue->uxMessagesWaiting < pxQueue->uxLength) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue (pxQueue, pvItemToQueue, queueSEND_TO_BACK); + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive))) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if (xCoRoutineRemoveFromEventList + (&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) + { + /* The co-routine waiting has a higher priority so record + that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + } + } + } + else + { + xReturn = errQUEUE_FULL; + } + } + portENABLE_INTERRUPTS (); + + return xReturn; +} +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE +xQueueCRReceive (xQueueHandle pxQueue, void *pvBuffer, + portTickType xTicksToWait) +{ + signed portBASE_TYPE xReturn; + + /* If the queue is already empty we may have to block. A critical section + is required to prevent an interrupt adding something to the queue + between the check to see if the queue is empty and blocking on the queue. */ + portDISABLE_INTERRUPTS (); + { + if (pxQueue->uxMessagesWaiting == (unsigned portBASE_TYPE) 0) + { + /* There are no messages in the queue, do we want to block or just + leave with nothing? */ + if (xTicksToWait > (portTickType) 0) + { + /* As this is a co-routine we cannot block directly, but return + indicating that we need to block. */ + vCoRoutineAddToDelayedList (xTicksToWait, + &(pxQueue->xTasksWaitingToReceive)); + portENABLE_INTERRUPTS (); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS (); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS (); + + portNOP (); + + portDISABLE_INTERRUPTS (); + { + if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0) + { + /* Data is available from the queue. */ + pxQueue->pcReadFrom += pxQueue->uxItemSize; + if (pxQueue->pcReadFrom >= pxQueue->pcTail) + { + pxQueue->pcReadFrom = pxQueue->pcHead; + } + --(pxQueue->uxMessagesWaiting); + memcpy ((void *) pvBuffer, (void *) pxQueue->pcReadFrom, + (unsigned) pxQueue->uxItemSize); + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToSend))) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if (xCoRoutineRemoveFromEventList + (&(pxQueue->xTasksWaitingToSend)) != pdFALSE) + { + xReturn = errQUEUE_YIELD; + } + } + } + else + { + xReturn = pdFAIL; + } + } + portENABLE_INTERRUPTS (); + + return xReturn; +} +#endif +/*-----------------------------------------------------------*/ + + + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE +xQueueCRSendFromISR (xQueueHandle pxQueue, const void *pvItemToQueue, + signed portBASE_TYPE xCoRoutinePreviouslyWoken) +{ + /* Cannot block within an ISR so if there is no space on the queue then + exit without doing anything. */ + if (pxQueue->uxMessagesWaiting < pxQueue->uxLength) + { + prvCopyDataToQueue (pxQueue, pvItemToQueue, queueSEND_TO_BACK); + + /* We only want to wake one co-routine per ISR, so check that a + co-routine has not already been woken. */ + if (!xCoRoutinePreviouslyWoken) + { + if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive))) + { + if (xCoRoutineRemoveFromEventList + (&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) + { + return pdTRUE; + } + } + } + } + + return xCoRoutinePreviouslyWoken; +} +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_CO_ROUTINES == 1 +signed portBASE_TYPE +xQueueCRReceiveFromISR (xQueueHandle pxQueue, void *pvBuffer, + signed portBASE_TYPE * pxCoRoutineWoken) +{ + signed portBASE_TYPE xReturn; + + /* We cannot block from an ISR, so check there is data available. If + not then just leave without doing anything. */ + if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0) + { + /* Copy the data from the queue. */ + pxQueue->pcReadFrom += pxQueue->uxItemSize; + if (pxQueue->pcReadFrom >= pxQueue->pcTail) + { + pxQueue->pcReadFrom = pxQueue->pcHead; + } + --(pxQueue->uxMessagesWaiting); + memcpy ((void *) pvBuffer, (void *) pxQueue->pcReadFrom, + (unsigned) pxQueue->uxItemSize); + + if (!(*pxCoRoutineWoken)) + { + if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToSend))) + { + if (xCoRoutineRemoveFromEventList + (&(pxQueue->xTasksWaitingToSend)) != pdFALSE) + { + *pxCoRoutineWoken = pdTRUE; + } + } + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; +} +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + +void +vQueueAddToRegistry (xQueueHandle xQueue, signed char *pcQueueName) +{ + unsigned portBASE_TYPE ux; + + /* See if there is an empty space in the registry. A NULL name denotes + a free slot. */ + for (ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++) + { + if (xQueueRegistry[ux].pcQueueName == NULL) + { + /* Store the information on this queue. */ + xQueueRegistry[ux].pcQueueName = pcQueueName; + xQueueRegistry[ux].xHandle = xQueue; + break; + } + } +} + +#endif + /*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + +static void +vQueueUnregisterQueue (xQueueHandle xQueue) +{ + unsigned portBASE_TYPE ux; + + /* See if the handle of the queue being unregistered in actually in the + registry. */ + for (ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++) + { + if (xQueueRegistry[ux].xHandle == xQueue) + { + /* Set the name to NULL to show that this slot if free again. */ + xQueueRegistry[ux].pcQueueName = NULL; + break; + } + } + +} + +#endif + +/*-----------------------------------------------------------*/ +#endif /* ENABLE_FREERTOS */ +/*-----------------------------------------------------------*/ diff --git a/openbeacon/lpc13xx/core/freertos/src/tasks.c b/openbeacon/lpc13xx/core/freertos/src/tasks.c new file mode 100644 index 0000000..ad5572f --- /dev/null +++ b/openbeacon/lpc13xx/core/freertos/src/tasks.c @@ -0,0 +1,2347 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +#include +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include +#ifdef ENABLE_FREERTOS +/*-----------------------------------------------------------*/ +#include +#include + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* + * Macro to define the amount of stack available to the idle task. + */ +#define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE + +/* + * Task control block. A task control block (TCB) is allocated to each task, + * and stores the context of the task. + */ +typedef struct tskTaskControlBlock +{ + volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */ + #endif + + xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */ + xListItem xEventListItem; /*< List item used to place the TCB in event lists. */ + unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */ + portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */ + signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ + + #if ( portSTACK_GROWTH > 0 ) + portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + unsigned portBASE_TYPE uxCriticalNesting; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + pdTASK_HOOK_CODE pxTaskTag; + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */ + #endif + +} tskTCB; + + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + +/*lint -e956 */ +PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL; + +/* Lists for ready and blocked tasks. --------------------*/ + +PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */ +PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */ +PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ +PRIVILEGED_DATA static xList * volatile pxDelayedTaskList ; /*< Points to the delayed task list currently being used. */ +PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ +PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready queue when the scheduler is resumed. */ + +#if ( INCLUDE_vTaskDelete == 1 ) + + PRIVILEGED_DATA static volatile xList xTasksWaitingTermination; /*< Tasks that have been deleted - but the their memory not yet freed. */ + PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0; + +#endif + +#if ( INCLUDE_vTaskSuspend == 1 ) + + PRIVILEGED_DATA static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */ + +#endif + +/* File private variables. --------------------------------*/ +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0; +PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0; +PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY; +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY; +PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE; +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE; +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0; +PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE; +PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0; +PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0; + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + PRIVILEGED_DATA static char pcStatsString[ 50 ] ; + PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ + static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime ) PRIVILEGED_FUNCTION; + +#endif + +/* Debugging and trace facilities private variables and macros. ------------*/ + +/* + * The value used to fill the stack of a task when the task is created. This + * is used purely for checking the high water mark for tasks. + */ +#define tskSTACK_FILL_BYTE ( 0xa5 ) + +/* + * Macros used by vListTask to indicate which state a task is in. + */ +#define tskBLOCKED_CHAR ( ( signed char ) 'B' ) +#define tskREADY_CHAR ( ( signed char ) 'R' ) +#define tskDELETED_CHAR ( ( signed char ) 'D' ) +#define tskSUSPENDED_CHAR ( ( signed char ) 'S' ) + +/* + * Macros and private variables used by the trace facility. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + #define tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned long ) ( sizeof( unsigned long ) + sizeof( unsigned long ) ) ) + PRIVILEGED_DATA static volatile signed char * volatile pcTraceBuffer; + PRIVILEGED_DATA static signed char *pcTraceBufferStart; + PRIVILEGED_DATA static signed char *pcTraceBufferEnd; + PRIVILEGED_DATA static signed portBASE_TYPE xTracing = pdFALSE; + static unsigned portBASE_TYPE uxPreviousTask = 255; + PRIVILEGED_DATA static char pcStatusString[ 50 ]; + +#endif + +/*-----------------------------------------------------------*/ + +/* + * Macro that writes a trace of scheduler activity to a buffer. This trace + * shows which task is running when and is very useful as a debugging tool. + * As this macro is called each context switch it is a good idea to undefine + * it if not using the facility. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + #define vWriteTraceToBuffer() \ + { \ + if( xTracing ) \ + { \ + if( uxPreviousTask != pxCurrentTCB->uxTCBNumber ) \ + { \ + if( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd ) \ + { \ + uxPreviousTask = pxCurrentTCB->uxTCBNumber; \ + *( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount; \ + pcTraceBuffer += sizeof( unsigned long ); \ + *( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask; \ + pcTraceBuffer += sizeof( unsigned long ); \ + } \ + else \ + { \ + xTracing = pdFALSE; \ + } \ + } \ + } \ + } + +#else + + #define vWriteTraceToBuffer() + +#endif +/*-----------------------------------------------------------*/ + +/* + * Place the task represented by pxTCB into the appropriate ready queue for + * the task. It is inserted at the end of the list. One quirk of this is + * that if the task being inserted is at the same priority as the currently + * executing task, then it will only be rescheduled after the currently + * executing task has been rescheduled. + */ +#define prvAddTaskToReadyQueue( pxTCB ) \ +{ \ + if( pxTCB->uxPriority > uxTopReadyPriority ) \ + { \ + uxTopReadyPriority = pxTCB->uxPriority; \ + } \ + vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ); \ +} +/*-----------------------------------------------------------*/ + +/* + * Macro that looks at the list of tasks that are currently delayed to see if + * any require waking. + * + * Tasks are stored in the queue in the order of their wake time - meaning + * once one tasks has been found whose timer has not expired we need not look + * any further down the list. + */ +#define prvCheckDelayedTasks() \ +{ \ +register tskTCB *pxTCB; \ + \ + while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ) ) != NULL ) \ + { \ + if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) ) \ + { \ + break; \ + } \ + vListRemove( &( pxTCB->xGenericListItem ) ); \ + /* Is the task waiting on an event also? */ \ + if( pxTCB->xEventListItem.pvContainer ) \ + { \ + vListRemove( &( pxTCB->xEventListItem ) ); \ + } \ + prvAddTaskToReadyQueue( pxTCB ); \ + } \ +} +/*-----------------------------------------------------------*/ + +/* + * Several functions take an xTaskHandle parameter that can optionally be NULL, + * where NULL is used to indicate that the handle of the currently executing + * task should be used in place of the parameter. This macro simply checks to + * see if the parameter is NULL and returns a pointer to the appropriate TCB. + */ +#define prvGetTCBFromHandle( pxHandle ) ( ( pxHandle == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) pxHandle ) + + +/* File private functions. --------------------------------*/ + +/* + * Utility to ready a TCB for a given task. Mainly just copies the parameters + * into the TCB structure. + */ +static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) PRIVILEGED_FUNCTION; + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first task. + */ +static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; + +/* + * The idle task, which as all tasks is implemented as a never ending loop. + * The idle task is automatically created and added to the ready lists upon + * creation of the first user task. + * + * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ); + +/* + * Utility to free all memory allocated by the scheduler to hold a TCB, + * including the stack pointed to by the TCB. + * + * This does not free memory allocated by the task itself (i.e. memory + * allocated by calls to pvPortMalloc from within the tasks application code). + */ +#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) ) + + static void prvDeleteTCB( tskTCB *pxTCB ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Used only by the idle task. This checks to see if anything has been placed + * in the list of tasks waiting to be deleted. If so the task is cleaned up + * and its TCB deleted. + */ +static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; + +/* + * Allocates memory from the heap for a TCB and associated stack. Checks the + * allocation was successful. + */ +static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) PRIVILEGED_FUNCTION; + +/* + * Called from vTaskList. vListTasks details all the tasks currently under + * control of the scheduler. The tasks may be in one of a number of lists. + * prvListTaskWithinSingleList accepts a list and details the tasks from + * within just that list. + * + * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM + * NORMAL APPLICATION CODE. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) PRIVILEGED_FUNCTION; + +#endif + +/* + * When a task is created, the stack of the task is filled with a known value. + * This function determines the 'high water mark' of the task stack by + * determining how much of the stack remains at the original preset value. + */ +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + + static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) PRIVILEGED_FUNCTION; + +#endif + + +/*lint +e956 */ + + + +/*----------------------------------------------------------- + * TASK CREATION API documented in task.h + *----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) +{ +signed portBASE_TYPE xReturn; +tskTCB * pxNewTCB; + + /* Allocate the memory required by the TCB and stack for the new task, + checking that the allocation was successful. */ + pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer ); + + if( pxNewTCB != NULL ) + { + portSTACK_TYPE *pxTopOfStack; + + #if( portUSING_MPU_WRAPPERS == 1 ) + /* Should the task be created in privileged mode? */ + portBASE_TYPE xRunPrivileged; + if( ( uxPriority & portPRIVILEGE_BIT ) != 0x00 ) + { + xRunPrivileged = pdTRUE; + } + else + { + xRunPrivileged = pdFALSE; + } + uxPriority &= ~portPRIVILEGE_BIT; + #endif /* portUSING_MPU_WRAPPERS == 1 */ + + /* Calculate the top of stack address. This depends on whether the + stack grows from high memory to low (as per the 80x86) or visa versa. + portSTACK_GROWTH is used to make the result positive or negative as + required by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ); + pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( unsigned long ) pxTopOfStack ) & ( ( unsigned long ) ~portBYTE_ALIGNMENT_MASK ) ); + } + #else + { + pxTopOfStack = pxNewTCB->pxStack; + + /* If we want to use stack checking on architectures that use + a positive stack growth direction then we also need to store the + other extreme of the stack space. */ + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ); + } + #endif + + /* Setup the newly allocated TCB with the initial state of the task. */ + prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth ); + + /* Initialize the TCB stack to look as if the task was already running, + but had been interrupted by the scheduler. The return address is set + to the start of the task function. Once the stack has been initialised + the top of stack variable is updated. */ + #if( portUSING_MPU_WRAPPERS == 1 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + } + #endif + + if( ( void * ) pxCreatedTask != NULL ) + { + /* Pass the TCB out - in an anonymous way. The calling function/ + task can use this as a handle to delete the task later if + required.*/ + *pxCreatedTask = ( xTaskHandle ) pxNewTCB; + } + + /* We are going to manipulate the task queues to add this task to a + ready list, so must make sure no interrupts occur. */ + portENTER_CRITICAL(); + { + uxCurrentNumberOfTasks++; + if( pxCurrentTCB == NULL ) + { + /* There are no other tasks, or all the other tasks are in + the suspended state - make this the current task. */ + pxCurrentTCB = pxNewTCB; + + if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 ) + { + /* This is the first task to be created so do the preliminary + initialisation required. We will not recover if this call + fails, but we will report the failure. */ + prvInitialiseTaskLists(); + } + } + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ + if( xSchedulerRunning == pdFALSE ) + { + if( pxCurrentTCB->uxPriority <= uxPriority ) + { + pxCurrentTCB = pxNewTCB; + } + } + } + + /* Remember the top priority to make context switching faster. Use + the priority in pxNewTCB as this has been capped to a valid value. */ + if( pxNewTCB->uxPriority > uxTopUsedPriority ) + { + uxTopUsedPriority = pxNewTCB->uxPriority; + } + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif + uxTaskNumber++; + + prvAddTaskToReadyQueue( pxNewTCB ); + + xReturn = pdPASS; + traceTASK_CREATE( pxNewTCB ); + } + portEXIT_CRITICAL(); + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + traceTASK_CREATE_FAILED( pxNewTCB ); + } + + if( xReturn == pdPASS ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* If the created task is of a higher priority than the current task + then it should run now. */ + if( pxCurrentTCB->uxPriority < uxPriority ) + { + portYIELD_WITHIN_API(); + } + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + void vTaskDelete( xTaskHandle pxTaskToDelete ) + { + tskTCB *pxTCB; + + portENTER_CRITICAL(); + { + /* Ensure a yield is performed if the current task is being + deleted. */ + if( pxTaskToDelete == pxCurrentTCB ) + { + pxTaskToDelete = NULL; + } + + /* If null is passed in here then we are deleting ourselves. */ + pxTCB = prvGetTCBFromHandle( pxTaskToDelete ); + + /* Remove task from the ready list and place in the termination list. + This will stop the task from be scheduled. The idle task will check + the termination list and free up any memory allocated by the + scheduler for the TCB and stack. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + + /* Is the task waiting on an event also? */ + if( pxTCB->xEventListItem.pvContainer ) + { + vListRemove( &( pxTCB->xEventListItem ) ); + } + + vListInsertEnd( ( xList * ) &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) ); + + /* Increment the ucTasksDeleted variable so the idle task knows + there is a task that has been deleted and that it should therefore + check the xTasksWaitingTermination list. */ + ++uxTasksDeleted; + + /* Increment the uxTaskNumberVariable also so kernel aware debuggers + can detect that the task lists need re-generating. */ + uxTaskNumber++; + + traceTASK_DELETE( pxTCB ); + } + portEXIT_CRITICAL(); + + /* Force a reschedule if we have just deleted the current task. */ + if( xSchedulerRunning != pdFALSE ) + { + if( ( void * ) pxTaskToDelete == NULL ) + { + portYIELD_WITHIN_API(); + } + } + } + +#endif + + + + + + +/*----------------------------------------------------------- + * TASK CONTROL API documented in task.h + *----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + + void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) + { + portTickType xTimeToWake; + portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE; + + vTaskSuspendAll(); + { + /* Generate the tick time at which the task wants to wake. */ + xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; + + if( xTickCount < *pxPreviousWakeTime ) + { + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xTickCount ) ) + { + xShouldDelay = pdTRUE; + } + } + else + { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) ) + { + xShouldDelay = pdTRUE; + } + } + + /* Update the wake time ready for the next call. */ + *pxPreviousWakeTime = xTimeToWake; + + if( xShouldDelay ) + { + traceTASK_DELAY_UNTIL(); + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( !xAlreadyYielded ) + { + portYIELD_WITHIN_API(); + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + + void vTaskDelay( portTickType xTicksToDelay ) + { + portTickType xTimeToWake; + signed portBASE_TYPE xAlreadyYielded = pdFALSE; + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( portTickType ) 0 ) + { + vTaskSuspendAll(); + { + traceTASK_DELAY(); + + /* A task that is removed from the event list while the + scheduler is suspended will not get placed in the ready + list or removed from the blocked list until the scheduler + is resumed. + + This task cannot be in an event list as it is the currently + executing task. */ + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + xAlreadyYielded = xTaskResumeAll(); + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( !xAlreadyYielded ) + { + portYIELD_WITHIN_API(); + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) + { + tskTCB *pxTCB; + unsigned portBASE_TYPE uxReturn; + + portENTER_CRITICAL(); + { + /* If null is passed in here then we are changing the + priority of the calling function. */ + pxTCB = prvGetTCBFromHandle( pxTask ); + uxReturn = pxTCB->uxPriority; + } + portEXIT_CRITICAL(); + + return uxReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) + { + tskTCB *pxTCB; + unsigned portBASE_TYPE uxCurrentPriority, xYieldRequired = pdFALSE; + + /* Ensure the new priority is valid. */ + if( uxNewPriority >= configMAX_PRIORITIES ) + { + uxNewPriority = configMAX_PRIORITIES - 1; + } + + portENTER_CRITICAL(); + { + if( pxTask == pxCurrentTCB ) + { + pxTask = NULL; + } + + /* If null is passed in here then we are changing the + priority of the calling function. */ + pxTCB = prvGetTCBFromHandle( pxTask ); + + traceTASK_PRIORITY_SET( pxTask, uxNewPriority ); + + #if ( configUSE_MUTEXES == 1 ) + { + uxCurrentPriority = pxTCB->uxBasePriority; + } + #else + { + uxCurrentPriority = pxTCB->uxPriority; + } + #endif + + if( uxCurrentPriority != uxNewPriority ) + { + /* The priority change may have readied a task of higher + priority than the calling task. */ + if( uxNewPriority > uxCurrentPriority ) + { + if( pxTask != NULL ) + { + /* The priority of another task is being raised. If we + were raising the priority of the currently running task + there would be no need to switch as it must have already + been the highest priority task. */ + xYieldRequired = pdTRUE; + } + } + else if( pxTask == NULL ) + { + /* Setting our own priority down means there may now be another + task of higher priority that is ready to execute. */ + xYieldRequired = pdTRUE; + } + + + + #if ( configUSE_MUTEXES == 1 ) + { + /* Only change the priority being used if the task is not + currently using an inherited priority. */ + if( pxTCB->uxBasePriority == pxTCB->uxPriority ) + { + pxTCB->uxPriority = uxNewPriority; + } + + /* The base priority gets set whatever. */ + pxTCB->uxBasePriority = uxNewPriority; + } + #else + { + pxTCB->uxPriority = uxNewPriority; + } + #endif + + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) ); + + /* If the task is in the blocked or suspended list we need do + nothing more than change it's priority variable. However, if + the task is in a ready list it needs to be removed and placed + in the queue appropriate to its new priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxCurrentPriority ] ), &( pxTCB->xGenericListItem ) ) ) + { + /* The task is currently in its ready list - remove before adding + it to it's new ready list. As we are in a critical section we + can do this even if the scheduler is suspended. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + } + + if( xYieldRequired == pdTRUE ) + { + portYIELD_WITHIN_API(); + } + } + } + portEXIT_CRITICAL(); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( xTaskHandle pxTaskToSuspend ) + { + tskTCB *pxTCB; + + portENTER_CRITICAL(); + { + /* Ensure a yield is performed if the current task is being + suspended. */ + if( pxTaskToSuspend == pxCurrentTCB ) + { + pxTaskToSuspend = NULL; + } + + /* If null is passed in here then we are suspending ourselves. */ + pxTCB = prvGetTCBFromHandle( pxTaskToSuspend ); + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the suspended list. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + + /* Is the task waiting on an event also? */ + if( pxTCB->xEventListItem.pvContainer ) + { + vListRemove( &( pxTCB->xEventListItem ) ); + } + + vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ); + } + portEXIT_CRITICAL(); + + if( ( void * ) pxTaskToSuspend == NULL ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* We have just suspended the current task. */ + portYIELD_WITHIN_API(); + } + else + { + /* The scheduler is not running, but the task that was pointed + to by pxCurrentTCB has just been suspended and pxCurrentTCB + must be adjusted to point to a different task. */ + if( uxCurrentNumberOfTasks == 1 ) + { + /* No other tasks are defined, so set pxCurrentTCB back to + NULL so when the next task is created pxCurrentTCB will + be set to point to it no matter what its relative priority + is. */ + pxCurrentTCB = NULL; + } + else + { + vTaskSwitchContext(); + } + } + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) + { + portBASE_TYPE xReturn = pdFALSE; + const tskTCB * const pxTCB = ( tskTCB * ) xTask; + + /* Is the task we are attempting to resume actually in the + suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE ) + { + /* Is it in the suspended list because it is in the + Suspended state? It is possible to be in the suspended + list because it is blocked on a task with no timeout + specified. */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE ) + { + xReturn = pdTRUE; + } + } + } + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskResume( xTaskHandle pxTaskToResume ) + { + tskTCB *pxTCB; + + /* Remove the task from whichever list it is currently in, and place + it in the ready list. */ + pxTCB = ( tskTCB * ) pxTaskToResume; + + /* The parameter cannot be NULL as it is impossible to resume the + currently executing task. */ + if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) + { + portENTER_CRITICAL(); + { + if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + { + traceTASK_RESUME( pxTCB ); + + /* As we are in a critical section we can access the ready + lists even if the scheduler is suspended. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + + /* We may have just resumed a higher priority task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* This yield may not cause the task just resumed to run, but + will leave the lists in the correct state for the next yield. */ + portYIELD_WITHIN_API(); + } + } + } + portEXIT_CRITICAL(); + } + } + +#endif + +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) + { + portBASE_TYPE xYieldRequired = pdFALSE; + tskTCB *pxTCB; + + pxTCB = ( tskTCB * ) pxTaskToResume; + + if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ); + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + } + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed, at which point a + yield will be performed if necessary. */ + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + + return xYieldRequired; + } + +#endif + + + + +/*----------------------------------------------------------- + * PUBLIC SCHEDULER CONTROL documented in task.h + *----------------------------------------------------------*/ + + +void vTaskStartScheduler( void ) +{ +portBASE_TYPE xReturn; + + /* Add the idle task at the lowest priority. */ + xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( xTaskHandle * ) NULL ); + + if( xReturn == pdPASS ) + { + /* Interrupts are turned off here, to ensure a tick does not occur + before or during the call to xPortStartScheduler(). The stacks of + the created tasks contain a status word with interrupts switched on + so interrupts will automatically get re-enabled when the first task + starts to run. + + STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE + DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */ + portDISABLE_INTERRUPTS(); + + xSchedulerRunning = pdTRUE; + xTickCount = ( portTickType ) 0; + + /* If configGENERATE_RUN_TIME_STATS is defined then the following + macro must be defined to configure the timer/counter used to generate + the run time counter time base. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + /* Setting up the timer tick is hardware specific and thus in the + portable interface. */ + if( xPortStartScheduler() ) + { + /* Should not reach here as if the scheduler is running the + function will not return. */ + } + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } +} +/*-----------------------------------------------------------*/ + +void vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + routine so the original ISRs can be restored if necessary. The port + layer must ensure interrupts enable bit is left in the correct state. */ + portDISABLE_INTERRUPTS(); + xSchedulerRunning = pdFALSE; + vPortEndScheduler(); +} +/*----------------------------------------------------------*/ + +void vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + portBASE_TYPE. */ + ++uxSchedulerSuspended; +} +/*----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskResumeAll( void ) +{ +register tskTCB *pxTCB; +signed portBASE_TYPE xAlreadyYielded = pdFALSE; + + /* It is possible that an ISR caused a task to be removed from an event + list while the scheduler was suspended. If this was the case then the + removed task will have been added to the xPendingReadyList. Once the + scheduler has been resumed it is safe to move all the pending ready + tasks from this list into their appropriate ready list. */ + portENTER_CRITICAL(); + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0 ) + { + portBASE_TYPE xYieldRequired = pdFALSE; + + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL ) + { + vListRemove( &( pxTCB->xEventListItem ) ); + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + + /* If we have moved a task that has a priority higher than + the current task then we should yield. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + } + + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does not + slip, and that any delayed tasks are resumed at the correct time. */ + if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 ) + { + while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 ) + { + vTaskIncrementTick(); + --uxMissedTicks; + } + + /* As we have processed some ticks it is appropriate to yield + to ensure the highest priority task that is ready to run is + the task actually running. */ + #if configUSE_PREEMPTION == 1 + { + xYieldRequired = pdTRUE; + } + #endif + } + + if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) ) + { + xAlreadyYielded = pdTRUE; + xMissedYield = pdFALSE; + portYIELD_WITHIN_API(); + } + } + } + } + portEXIT_CRITICAL(); + + return xAlreadyYielded; +} + + + + + + +/*----------------------------------------------------------- + * PUBLIC TASK UTILITIES documented in task.h + *----------------------------------------------------------*/ + + + +portTickType xTaskGetTickCount( void ) +{ +portTickType xTicks; + + /* Critical section required if running on a 16 bit processor. */ + portENTER_CRITICAL(); + { + xTicks = xTickCount; + } + portEXIT_CRITICAL(); + + return xTicks; +} +/*-----------------------------------------------------------*/ + +portTickType xTaskGetTickCountFromISR( void ) +{ + return xTickCount; +} +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + portBASE_TYPE. */ + return uxCurrentNumberOfTasks; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskList( signed char *pcWriteBuffer ) + { + unsigned portBASE_TYPE uxQueue; + + /* This is a VERY costly function that should be used for debug only. + It leaves interrupts disabled for a LONG time. */ + + vTaskSuspendAll(); + { + /* Run through all the lists that could potentially contain a TCB and + report the task name, state and stack high water mark. */ + + pcWriteBuffer[ 0 ] = ( signed char ) 0x00; + strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" ); + + uxQueue = uxTopUsedPriority + 1; + + do + { + uxQueue--; + + if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR ); + } + }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY ); + + if( !listLIST_IS_EMPTY( pxDelayedTaskList ) ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR ); + } + + if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR ); + } + + #if( INCLUDE_vTaskDelete == 1 ) + { + if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, tskDELETED_CHAR ); + } + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, tskSUSPENDED_CHAR ); + } + } + #endif + } + xTaskResumeAll(); + } + +#endif +/*----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) + { + unsigned portBASE_TYPE uxQueue; + unsigned long ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + + /* This is a VERY costly function that should be used for debug only. + It leaves interrupts disabled for a LONG time. */ + + vTaskSuspendAll(); + { + /* Run through all the lists that could potentially contain a TCB, + generating a table of run timer percentages in the provided + buffer. */ + + pcWriteBuffer[ 0 ] = ( signed char ) 0x00; + strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" ); + + uxQueue = uxTopUsedPriority + 1; + + do + { + uxQueue--; + + if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), ulTotalRunTime ); + } + }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY ); + + if( !listLIST_IS_EMPTY( pxDelayedTaskList ) ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, ulTotalRunTime ); + } + + if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, ulTotalRunTime ); + } + + #if ( INCLUDE_vTaskDelete == 1 ) + { + if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, ulTotalRunTime ); + } + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, ulTotalRunTime ); + } + } + #endif + } + xTaskResumeAll(); + } + +#endif +/*----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) + { + portENTER_CRITICAL(); + { + pcTraceBuffer = ( signed char * )pcBuffer; + pcTraceBufferStart = pcBuffer; + pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE ); + xTracing = pdTRUE; + } + portEXIT_CRITICAL(); + } + +#endif +/*----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + unsigned long ulTaskEndTrace( void ) + { + unsigned long ulBufferLength; + + portENTER_CRITICAL(); + xTracing = pdFALSE; + portEXIT_CRITICAL(); + + ulBufferLength = ( unsigned long ) ( pcTraceBuffer - pcTraceBufferStart ); + + return ulBufferLength; + } + +#endif + + + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + * documented in task.h + *----------------------------------------------------------*/ + + +void vTaskIncrementTick( void ) +{ + /* Called by the portable layer each time a tick interrupt occurs. + Increments the tick then checks to see if the new tick value will cause any + tasks to be unblocked. */ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + ++xTickCount; + if( xTickCount == ( portTickType ) 0 ) + { + xList *pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. + If there are any items in pxDelayedTaskList here then there is + an error! */ + pxTemp = pxDelayedTaskList; + pxDelayedTaskList = pxOverflowDelayedTaskList; + pxOverflowDelayedTaskList = pxTemp; + xNumOfOverflows++; + } + + /* See if this tick has made a timeout expire. */ + prvCheckDelayedTasks(); + } + else + { + ++uxMissedTicks; + + /* The tick hook gets called at regular intervals, even if the + scheduler is locked. */ + #if ( configUSE_TICK_HOOK == 1 ) + { + extern void vApplicationTickHook( void ); + + vApplicationTickHook(); + } + #endif + } + + #if ( configUSE_TICK_HOOK == 1 ) + { + extern void vApplicationTickHook( void ); + + /* Guard against the tick hook being called when the missed tick + count is being unwound (when the scheduler is being unlocked. */ + if( uxMissedTicks == 0 ) + { + vApplicationTickHook(); + } + } + #endif + + traceTASK_INCREMENT_TICK( xTickCount ); +} +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_vTaskCleanUpResources == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + void vTaskCleanUpResources( void ) + { + unsigned short usQueue; + volatile tskTCB *pxTCB; + + usQueue = ( unsigned short ) uxTopUsedPriority + ( unsigned short ) 1; + + /* Remove any TCB's from the ready queues. */ + do + { + usQueue--; + + while( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ usQueue ] ) ) ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &( pxReadyTasksLists[ usQueue ] ) ); + vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ); + + prvDeleteTCB( ( tskTCB * ) pxTCB ); + } + }while( usQueue > ( unsigned short ) tskIDLE_PRIORITY ); + + /* Remove any TCB's from the delayed queue. */ + while( !listLIST_IS_EMPTY( &xDelayedTaskList1 ) ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList1 ); + vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ); + + prvDeleteTCB( ( tskTCB * ) pxTCB ); + } + + /* Remove any TCB's from the overflow delayed queue. */ + while( !listLIST_IS_EMPTY( &xDelayedTaskList2 ) ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList2 ); + vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ); + + prvDeleteTCB( ( tskTCB * ) pxTCB ); + } + + while( !listLIST_IS_EMPTY( &xSuspendedTaskList ) ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xSuspendedTaskList ); + vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ); + + prvDeleteTCB( ( tskTCB * ) pxTCB ); + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue ) + { + tskTCB *xTCB; + + /* If xTask is NULL then we are setting our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( tskTCB * ) pxCurrentTCB; + } + else + { + xTCB = ( tskTCB * ) xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + portENTER_CRITICAL(); + xTCB->pxTaskTag = pxTagValue; + portEXIT_CRITICAL(); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) + { + tskTCB *xTCB; + pdTASK_HOOK_CODE xReturn; + + /* If xTask is NULL then we are setting our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( tskTCB * ) pxCurrentTCB; + } + else + { + xTCB = ( tskTCB * ) xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + portENTER_CRITICAL(); + xReturn = xTCB->pxTaskTag; + portEXIT_CRITICAL(); + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) + { + tskTCB *xTCB; + portBASE_TYPE xReturn; + + /* If xTask is NULL then we are calling our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( tskTCB * ) pxCurrentTCB; + } + else + { + xTCB = ( tskTCB * ) xTask; + } + + if( xTCB->pxTaskTag != NULL ) + { + xReturn = xTCB->pxTaskTag( pvParameter ); + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +void vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE ) + { + /* The scheduler is currently suspended - do not allow a context + switch. */ + xMissedYield = pdTRUE; + return; + } + + traceTASK_SWITCHED_OUT(); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + unsigned long ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE(); + + /* Add the amount of time the task has been running to the accumulated + time so far. The time the task started running was stored in + ulTaskSwitchedInTime. Note that there is no overflow protection here + so count values are only valid until the timer overflows. Generally + this will be about 1 hour assuming a 1uS timer increment. */ + pxCurrentTCB->ulRunTimeCounter += ( ulTempCounter - ulTaskSwitchedInTime ); + ulTaskSwitchedInTime = ulTempCounter; + } + #endif + + taskFIRST_CHECK_FOR_STACK_OVERFLOW(); + taskSECOND_CHECK_FOR_STACK_OVERFLOW(); + + /* Find the highest priority queue that contains ready tasks. */ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) + { + --uxTopReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the + same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); + + traceTASK_SWITCHED_IN(); + vWriteTraceToBuffer(); +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) +{ +portTickType xTimeToWake; + + /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED. */ + + /* Place the event list item of the TCB in the appropriate event list. + This is placed in the list in priority order so the highest priority task + is the first to be woken by the event. */ + vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) ); + + /* We must remove ourselves from the ready list before adding ourselves + to the blocked list as the same list item is used for both lists. We have + exclusive access to the ready lists as the scheduler is locked. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( xTicksToWait == portMAX_DELAY ) + { + /* Add ourselves to the suspended task list instead of a delayed task + list to ensure we are not woken by a timing event. We will block + indefinitely. */ + vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter. */ + xTimeToWake = xTickCount + xTicksToWait; + + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + } + #else + { + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter. */ + xTimeToWake = xTickCount + xTicksToWait; + + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + } + } + #endif +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) +{ +tskTCB *pxUnblockedTCB; +portBASE_TYPE xReturn; + + /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED. It can also be called from within an ISR. */ + + /* The event list is sorted in priority order, so we can remove the + first in the list, remove the TCB from the delayed list, and add + it to the ready list. + + If an event is for a queue that is locked then this function will never + get called - the lock count on the queue will get modified instead. This + means we can always expect exclusive access to the event list here. */ + pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + vListRemove( &( pxUnblockedTCB->xEventListItem ) ); + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + vListRemove( &( pxUnblockedTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxUnblockedTCB ); + } + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed. */ + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + } + + if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has + a higher priority than the calling task. This allows + the calling task to know if it should force a context + switch now. */ + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) +{ + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) +{ +portBASE_TYPE xReturn; + + portENTER_CRITICAL(); + { + #if ( INCLUDE_vTaskSuspend == 1 ) + /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is + the maximum block time then the task should block indefinitely, and + therefore never time out. */ + if( *pxTicksToWait == portMAX_DELAY ) + { + xReturn = pdFALSE; + } + else /* We are not blocking indefinitely, perform the checks below. */ + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) ) + { + /* The tick count is greater than the time at which vTaskSetTimeout() + was called, but has also overflowed since vTaskSetTimeOut() was called. + It must have wrapped all the way around and gone past us again. This + passed since vTaskSetTimeout() was called. */ + xReturn = pdTRUE; + } + else if( ( ( portTickType ) ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait ) + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ); + vTaskSetTimeOutState( pxTimeOut ); + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + } + portEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskMissedYield( void ) +{ + xMissedYield = pdTRUE; +} + +/* + * ----------------------------------------------------------- + * The Idle task. + * ---------------------------------------------------------- + * + * The portTASK_FUNCTION() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION( prvIdleTask, pvParameters ) +{ + /* Stop warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* See if any tasks have been deleted. */ + prvCheckTasksWaitingTermination(); + + #if ( configUSE_PREEMPTION == 0 ) + { + /* If we are not using preemption we keep forcing a task switch to + see if any other task has become available. If we are using + preemption we don't need to do this as any task becoming available + will automatically get the processor anyway. */ + taskYIELD(); + } + #endif + + #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) + { + /* When using preemption tasks of equal priority will be + timesliced. If a task that is sharing the idle priority is ready + to run then the idle task should yield before the end of the + timeslice. + + A critical region is not required here as we are just reading from + the list, and an occasional incorrect value will not matter. If + the ready list at the idle priority contains more than one task + then a task other than the idle task is ready to execute. */ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( unsigned portBASE_TYPE ) 1 ) + { + taskYIELD(); + } + } + #endif + + #if ( configUSE_IDLE_HOOK == 1 ) + { + extern void vApplicationIdleHook( void ); + + /* Call the user defined function from within the idle task. This + allows the application designer to add background functionality + without the overhead of a separate task. + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, + CALL A FUNCTION THAT MIGHT BLOCK. */ + vApplicationIdleHook(); + } + #endif + } +} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */ + + + + + + + +/*----------------------------------------------------------- + * File private functions documented at the top of the file. + *----------------------------------------------------------*/ + + + +static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) +{ + /* Store the function name in the TCB. */ + #if configMAX_TASK_NAME_LEN > 1 + { + /* Don't bring strncpy into the build unnecessarily. */ + strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN ); + } + #endif + pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = '\0'; + + /* This is used as an array index so must ensure it's not too large. First + remove the privilege bit if one is present. */ + if( uxPriority >= configMAX_PRIORITIES ) + { + uxPriority = configMAX_PRIORITIES - 1; + } + + pxTCB->uxPriority = uxPriority; + #if ( configUSE_MUTEXES == 1 ) + { + pxTCB->uxBasePriority = uxPriority; + } + #endif + + vListInitialiseItem( &( pxTCB->xGenericListItem ) ); + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + + /* Set the pxTCB as a link back from the xListItem. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + { + pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0; + } + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + { + pxTCB->pxTaskTag = NULL; + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTCB->ulRunTimeCounter = 0UL; + } + #endif + + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth ); + } + #else + { + ( void ) xRegions; + ( void ) usStackDepth; + } + #endif +} +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + void vTaskAllocateMPURegions( xTaskHandle xTaskToModify, const xMemoryRegion * const xRegions ) + { + tskTCB *pxTCB; + + if( xTaskToModify == pxCurrentTCB ) + { + xTaskToModify = NULL; + } + + /* If null is passed in here then we are deleting ourselves. */ + pxTCB = prvGetTCBFromHandle( xTaskToModify ); + + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); + } + /*-----------------------------------------------------------*/ +#endif + +static void prvInitialiseTaskLists( void ) +{ +unsigned portBASE_TYPE uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( xList * ) &( pxReadyTasksLists[ uxPriority ] ) ); + } + + vListInitialise( ( xList * ) &xDelayedTaskList1 ); + vListInitialise( ( xList * ) &xDelayedTaskList2 ); + vListInitialise( ( xList * ) &xPendingReadyList ); + + #if ( INCLUDE_vTaskDelete == 1 ) + { + vListInitialise( ( xList * ) &xTasksWaitingTermination ); + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( ( xList * ) &xSuspendedTaskList ); + } + #endif + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + pxOverflowDelayedTaskList = &xDelayedTaskList2; +} +/*-----------------------------------------------------------*/ + +static void prvCheckTasksWaitingTermination( void ) +{ + #if ( INCLUDE_vTaskDelete == 1 ) + { + portBASE_TYPE xListIsEmpty; + + /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called + too often in the idle task. */ + if( uxTasksDeleted > ( unsigned portBASE_TYPE ) 0 ) + { + vTaskSuspendAll(); + xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination ); + xTaskResumeAll(); + + if( !xListIsEmpty ) + { + tskTCB *pxTCB; + + portENTER_CRITICAL(); + { + pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) ); + vListRemove( &( pxTCB->xGenericListItem ) ); + --uxCurrentNumberOfTasks; + --uxTasksDeleted; + } + portEXIT_CRITICAL(); + + prvDeleteTCB( pxTCB ); + } + } + } + #endif +} +/*-----------------------------------------------------------*/ + +static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) +{ +tskTCB *pxNewTCB; + + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function. */ + pxNewTCB = ( tskTCB * ) pvPortMalloc( sizeof( tskTCB ) ); + + if( pxNewTCB != NULL ) + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer ); + + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + pxNewTCB = NULL; + } + else + { + /* Just to help debugging. */ + memset( pxNewTCB->pxStack, tskSTACK_FILL_BYTE, usStackDepth * sizeof( portSTACK_TYPE ) ); + } + } + + return pxNewTCB; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) + { + volatile tskTCB *pxNextTCB, *pxFirstTCB; + unsigned short usStackRemaining; + + /* Write the details of all the TCB's in pxList into the buffer. */ + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + #if ( portSTACK_GROWTH > 0 ) + { + usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack ); + } + #else + { + usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack ); + } + #endif + + sprintf( pcStatusString, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, ( unsigned int ) pxNextTCB->uxPriority, usStackRemaining, ( unsigned int ) pxNextTCB->uxTCBNumber ); + strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatusString ); + + } while( pxNextTCB != pxFirstTCB ); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime ) + { + volatile tskTCB *pxNextTCB, *pxFirstTCB; + unsigned long ulStatsAsPercentage; + + /* Write the run time stats of all the TCB's in pxList into the buffer. */ + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + /* Get next TCB in from the list. */ + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + + /* Divide by zero check. */ + if( ulTotalRunTime > 0UL ) + { + /* Has the task run at all? */ + if( pxNextTCB->ulRunTimeCounter == 0 ) + { + /* The task has used no CPU time at all. */ + sprintf( pcStatsString, ( char * ) "%s\t\t0\t\t0%%\r\n", pxNextTCB->pcTaskName ); + } + else + { + /* What percentage of the total run time as the task used? + This will always be rounded down to the nearest integer. */ + ulStatsAsPercentage = ( 100UL * pxNextTCB->ulRunTimeCounter ) / ulTotalRunTime; + + if( ulStatsAsPercentage > 0UL ) + { + sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); + } + else + { + /* If the percentage is zero here then the task has + consumed less than 1% of the total run time. */ + sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter ); + } + } + + strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatsString ); + } + + } while( pxNextTCB != pxFirstTCB ); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + + static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) + { + register unsigned short usCount = 0; + + while( *pucStackByte == tskSTACK_FILL_BYTE ) + { + pucStackByte -= portSTACK_GROWTH; + usCount++; + } + + usCount /= sizeof( portSTACK_TYPE ); + + return usCount; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) + { + tskTCB *pxTCB; + unsigned char *pcEndOfStack; + unsigned portBASE_TYPE uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pcEndOfStack = ( unsigned char * ) pxTCB->pxStack; + } + #else + { + pcEndOfStack = ( unsigned char * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = ( unsigned portBASE_TYPE ) usTaskCheckFreeStackSpace( pcEndOfStack ); + + return uxReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) ) + + static void prvDeleteTCB( tskTCB *pxTCB ) + { + /* Free up the memory allocated by the scheduler for the task. It is up to + the task to free any memory allocated at the application level. */ + vPortFreeAligned( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + +#endif + + +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) + + xTaskHandle xTaskGetCurrentTaskHandle( void ) + { + xTaskHandle xReturn; + + /* A critical section is not required as this is not called from + an interrupt and the current TCB will always be the same for any + individual execution thread. */ + xReturn = pxCurrentTCB; + + return xReturn; + } + +#endif + +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + + portBASE_TYPE xTaskGetSchedulerState( void ) + { + portBASE_TYPE xReturn; + + if( xSchedulerRunning == pdFALSE ) + { + xReturn = taskSCHEDULER_NOT_STARTED; + } + else + { + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + xReturn = taskSCHEDULER_RUNNING; + } + else + { + xReturn = taskSCHEDULER_SUSPENDED; + } + } + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) + { + tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder; + + if( pxTCB->uxPriority < pxCurrentTCB->uxPriority ) + { + /* Adjust the mutex holder state to account for its new priority. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority ); + + /* If the task being modified is in the ready state it will need to + be moved in to a new list. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) ) + { + vListRemove( &( pxTCB->xGenericListItem ) ); + + /* Inherit the priority before being moved into the new list. */ + pxTCB->uxPriority = pxCurrentTCB->uxPriority; + prvAddTaskToReadyQueue( pxTCB ); + } + else + { + /* Just inherit the priority. */ + pxTCB->uxPriority = pxCurrentTCB->uxPriority; + } + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) + { + tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder; + + if( pxMutexHolder != NULL ) + { + if( pxTCB->uxPriority != pxTCB->uxBasePriority ) + { + /* We must be the running task to be able to give the mutex back. + Remove ourselves from the ready list we currently appear in. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + + /* Disinherit the priority before adding ourselves into the new + ready list. */ + pxTCB->uxPriority = pxTCB->uxBasePriority; + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority ); + prvAddTaskToReadyQueue( pxTCB ); + } + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskEnterCritical( void ) + { + portDISABLE_INTERRUPTS(); + + if( xSchedulerRunning != pdFALSE ) + { + ( pxCurrentTCB->uxCriticalNesting )++; + } + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + +void vTaskExitCritical( void ) +{ + if( xSchedulerRunning != pdFALSE ) + { + if( pxCurrentTCB->uxCriticalNesting > 0 ) + { + ( pxCurrentTCB->uxCriticalNesting )--; + + if( pxCurrentTCB->uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } + } + } +} + +#endif +/*-----------------------------------------------------------*/ +#endif /* ENABLE_FREERTOS */ +/*-----------------------------------------------------------*/ + diff --git a/openbeacon/lpc13xx/core/linker/LPC1342.ld b/openbeacon/lpc13xx/core/linker/LPC1342.ld new file mode 100644 index 0000000..7c92f4b --- /dev/null +++ b/openbeacon/lpc13xx/core/linker/LPC1342.ld @@ -0,0 +1,9 @@ +MEMORY +{ + flash : ORIGIN = 0x00000000, LENGTH = 16K + ram : ORIGIN = 0x10000180, LENGTH = 4K - 0x180 +} + +__stack_end__ = 0x10000000 + 4K - 32; + +INCLUDE "../core/linker/LPC13xx.ld" \ No newline at end of file diff --git a/openbeacon/lpc13xx/core/linker/LPC1343.ld b/openbeacon/lpc13xx/core/linker/LPC1343.ld new file mode 100644 index 0000000..5b9ff6c --- /dev/null +++ b/openbeacon/lpc13xx/core/linker/LPC1343.ld @@ -0,0 +1,9 @@ +MEMORY +{ + flash : ORIGIN = 0x00000000, LENGTH = 32K + ram : ORIGIN = 0x10000180, LENGTH = 8K - 0x180 +} + +__stack_end__ = 0x10000000 + 8K - 32; + +INCLUDE "../core/linker/LPC13xx.ld" \ No newline at end of file diff --git a/openbeacon/lpc13xx/core/linker/LPC13xx.ld b/openbeacon/lpc13xx/core/linker/LPC13xx.ld new file mode 100644 index 0000000..bcdca70 --- /dev/null +++ b/openbeacon/lpc13xx/core/linker/LPC13xx.ld @@ -0,0 +1,55 @@ +ENTRY(ResetISR) + +SECTIONS +{ + . = 0; + startup : { *(.startup)} >flash + + prog : + { + KEEP(*(.isr_vector)) + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.glue_7) + *(.glue_7t) + } >flash + + __end_of_text__ = .; + + .data : + { + __data_beg__ = .; + __data_beg_src__ = __end_of_text__; + *(.data) + *(.data.*) + *(.fastrun) + *(.ramfunc) + __data_end__ = .; + } >ram AT>flash + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } >ram AT>flash + __exidx_end = .; + + .bss : + { + __bss_beg__ = .; + *(.bss) + *(.bss.*) + __bss_end__ = .; + } >ram + + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); + _end = .; + _bss_end__ = . ; __bss_end__ = . ; __end__ = . ; + PROVIDE (end = .); +} + . = ALIGN(32 / 8); diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/crc16.h b/openbeacon/lpc13xx/core/openbeacon/inc/crc16.h new file mode 100644 index 0000000..7b0d1d8 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/inc/crc16.h @@ -0,0 +1,29 @@ +/*************************************************************** + * + * OpenBeacon.org - CRC16 routine + * + * Copyright 2007 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __CRC16_H__ +#define __CRC16_H__ + +extern uint16_t crc16 (const uint8_t *buffer, uint32_t size); + +#endif/*__CRC16_H__*/ diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/debug_printf.h b/openbeacon/lpc13xx/core/openbeacon/inc/debug_printf.h new file mode 100644 index 0000000..3d52345 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/inc/debug_printf.h @@ -0,0 +1,20 @@ +/* + * linux/lib/vsprintf.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + */ + +#ifndef __DEBUG_PRINTF_H__ +#define __DEBUG_PRINTF_H__ +#ifdef UART_DISABLE +#define debug_printf(...) +#else /*UART_DISABLE*/ +extern void debug_printf (const char *fmt, ...); +extern void hex_dump (const unsigned char *buf, unsigned int addr, unsigned int len); +#endif/*UART_DISABLE*/ +#endif/*__DEBUG_PRINTF_H__*/ diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/hid.h b/openbeacon/lpc13xx/core/openbeacon/inc/hid.h new file mode 100644 index 0000000..ef2c48b --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/inc/hid.h @@ -0,0 +1,30 @@ +/*************************************************************** + * + * OpenBeacon.org - HID ROM function code for LPC13xx + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#ifndef __HID_H__ +#define __HID_H__ + +extern void hid_init (void); +extern void GetInReport (uint8_t *src, uint32_t length); +extern void SetOutReport (uint8_t *dst, uint32_t length); + +#endif/*__HID_H__*/ diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/iap.h b/openbeacon/lpc13xx/core/openbeacon/inc/iap.h new file mode 100644 index 0000000..6143265 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/inc/iap.h @@ -0,0 +1,32 @@ +/*************************************************************** + * + * OpenBeacon.org - IAP - in application programming + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __IAP_H__ +#define __IAP_H__ + +typedef uint32_t TDeviceUID[4]; + +extern void iap_read_uid (TDeviceUID * uid); +extern void iap_invoke_isp (void); + +#endif/*__IAP_H__*/ diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/msd.h b/openbeacon/lpc13xx/core/openbeacon/inc/msd.h new file mode 100644 index 0000000..631d95f --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/inc/msd.h @@ -0,0 +1,52 @@ +/*************************************************************** + * + * OpenBeacon.org - MSD ROM function code for LPC13xx + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#ifndef __MSD_H__ +#define __MSD_H__ + +/*************************************************************** + * bytes per sector + ***************************************************************/ +#define DISK_BLOCK_SIZE 512UL + +/*************************************************************** + * disk geometry - make it small enough + * to allow FAT16 with 512 byte cluster size + ***************************************************************/ +#define DISK_CYLINDERS 31UL +#define DISK_HEADS 255UL +#define DISK_SECTORS_PER_TRACK 63UL + +/*************************************************************** + * derieved values + ***************************************************************/ +#define DISK_SECTORS (DISK_CYLINDERS*DISK_HEADS*DISK_SECTORS_PER_TRACK) +#define DISK_SIZE (DISK_SECTORS*DISK_BLOCK_SIZE) + +/*************************************************************** + * exported functions + ***************************************************************/ +extern void msd_init (void); +extern void msd_read (uint32_t offset, uint8_t *dst, uint32_t length); +extern void msd_write (uint32_t offset, uint8_t *src, uint32_t length); + +#endif/*__MSD_H__*/ diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/openbeacon.h b/openbeacon/lpc13xx/core/openbeacon/inc/openbeacon.h new file mode 100644 index 0000000..230352c --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/inc/openbeacon.h @@ -0,0 +1,113 @@ +#ifndef __OPENBEACON_H__ +#define __OPENBEACON_H__ + +#include +#include +#include + +#define PACKED __attribute__((packed)) +#define WEAK __attribute__ ((weak)) +#define ALIAS(f) __attribute__ ((weak, alias (#f))) + +typedef uint8_t BOOL; +#define TRUE 1 +#define FALSE 0 + +/* this definition is linked weakly against UARTSendChar */ +extern BOOL default_putchar (uint8_t data); + +#ifdef ENABLE_FREERTOS +#include +#include +#include +#endif/*ENABLE_FREERTOS*/ + +#ifdef __LPC13xx__ + +#include +#include +#ifdef ENALBLE_USB_FULLFEATURED +#include +#include +#include +#include +#include +#include +#else /*ENALBLE_USB_FULLFEATURED*/ +#include +#include +#include +#endif/*ENALBLE_USB_FULLFEATURED*/ +#include + +/* PDSLEEPCFG, PDAWAKECFG, PDRUNCFG */ +#define IRCOUT_PD (1<< 0) +#define IRC_PD (1<< 1) +#define FLASH_PD (1<< 2) +#define BOD_PD (1<< 3) +#define ADC_PD (1<< 4) +#define SYSOSC_PD (1<< 5) +#define WDTOSC_PD (1<< 6) +#define SYSPLL_PD (1<< 7) +#define USBPLL_PD (1<< 8) +#define RESERVED1_PD (1<< 9) +#define USBPAD_PD (1<<10) +#define RESERVED2_PD (1<<11) + +/* LPC_SYSCON->SYSAHBCLKCTRL bits */ +#define EN_SYS (1<< 0) +#define EN_ROM (1<< 1) +#define EN_RAM (1<< 2) +#define EN_FLASHREG (1<< 3) +#define EN_FLASHARRAY (1<< 4) +#define EN_I2C (1<< 5) +#define EN_GPIO (1<< 6) +#define EN_CT16B0 (1<< 7) +#define EN_CT16B1 (1<< 8) +#define EN_CT32B0 (1<< 9) +#define EN_CT32B1 (1<<10) +#define EN_SSP (1<<11) +#define EN_UART (1<<12) +#define EN_ADC (1<<13) +#define EN_USB_REG (1<<14) +#define EN_WDT (1<<15) +#define EN_IOCON (1<<16) + +#ifdef __LPC1343__ +#define LPC_RAM_SIZE (8*1024) +#define LPC_FLASH_SIZE (32*1024) +#endif/*__LPC1343__*/ +#ifdef __LPC1342__ +#define LPC_RAM_SIZE (4*1024) +#define LPC_FLASH_SIZE (16*1024) +#endif/*__LPC1342__*/ + +#else /*__LPC13xx__*/ +#error Please specify architecture +#endif/*__LPC13xx__*/ + +#define DEVICEID_LPC1311 0x2C42502BUL +#define DEVICEID_LPC1313 0x2C40102BUL +#define DEVICEID_LPC1342 0x3D01402BUL +#define DEVICEID_LPC1343 0x3D00002BUL + +#include +#include +#include + +static inline uint16_t htons(uint16_t x) +{ + __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x)); + return x; +} + +static inline uint32_t htonl(uint32_t x) +{ + __asm__ ("rev %0, %1" : "=r" (x) : "r" (x)); + return x; +} + +#define ntohl(l) htonl(l) +#define ntohs(s) htons(s) + +#endif/*__OPENBEACON_H__*/ diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/spi.h b/openbeacon/lpc13xx/core/openbeacon/inc/spi.h new file mode 100644 index 0000000..f74a577 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/inc/spi.h @@ -0,0 +1,43 @@ +/*************************************************************** + * + * OpenBeacon.org - SPI routines for LPC13xx + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#ifndef __SPI_H__ +#define __SPI_H__ + +typedef uint32_t spi_cs; + +#define SPI_CS_MODE_NORMAL 0 +#define SPI_CS_MODE_INVERT_CS 1 +#define SPI_CS_MODE_BIT_REVERSED 2 +#define SPI_CS_MODE_SKIP_TX 4 +#define SPI_CS_MODE_SKIP_CS_ASSERT 8 +#define SPI_CS_MODE_SKIP_CS_DEASSERT 0x10 +#define SPI_CS_MODE_SKIP_CS (SPI_CS_MODE_SKIP_CS_ASSERT|SPI_CS_MODE_SKIP_CS_DEASSERT) +#define SPI_CS(port,pin,CPSDVSR,mode) ((spi_cs)( ((((uint32_t)port)&0xFF)<<24) | ((((uint32_t)pin)&0xFF)<<16) | ((((uint32_t)CPSDVSR)&0xFF)<<8) | (((uint32_t)mode)&0xFF) )) + +extern void spi_init (void); +extern void spi_status (void); +extern void spi_init_pin (spi_cs chipselect); +extern int spi_txrx (spi_cs chipselect, const void *tx, uint16_t txlen, + void *rx, uint16_t rxlen); + +#endif/*__SPI_H__*/ diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/vfs.h b/openbeacon/lpc13xx/core/openbeacon/inc/vfs.h new file mode 100644 index 0000000..a83103d --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/inc/vfs.h @@ -0,0 +1,70 @@ +/*************************************************************** + * + * OpenBeacon.org - virtual FAT16 file system support + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __VFS_H__ +#define __VFS_H__ + +typedef void (*TDiskHandler) (uint32_t offset, uint32_t length, + const void *src, uint8_t * dst); + +typedef struct _TDiskFile +{ + uint32_t length; + TDiskHandler handler; + const void *data; + const char *name; + const struct _TDiskFile *next; +} TDiskFile; + +typedef struct +{ + uint8_t BS_jmpBoot[3]; + char BS_OEMName[8]; + uint16_t BPB_BytsPerSec; + uint8_t BPB_SecPerClus; + uint16_t BPB_RsvdSecCnt; + uint8_t BPB_NumFATs; + uint16_t BPB_RootEntCnt; + uint16_t BPB_TotSec16; + uint8_t BPB_Media; + uint16_t BPB_FATSz16; + uint16_t BPB_SecPerTrk; + uint16_t BPB_NumHeads; + uint32_t BPB_HiddSec; + uint32_t BPB_TotSec32; + /* FAT12/FAT16 definition */ + uint8_t BS_DrvNum; + uint8_t BS_Reserved1; + uint8_t BS_BootSig; + uint32_t BS_VolID; + char BS_VolLab[11]; + char BS_FilSysType[8]; +} PACKED TDiskBPB; + +extern const TDiskBPB DiskBPB; +extern const uint32_t DiskSignature; + +extern void vfs_init (const TDiskFile *file); +extern void vfs_status (void); + +#endif/*__VFS_H__*/ diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/xxtea.h b/openbeacon/lpc13xx/core/openbeacon/inc/xxtea.h new file mode 100644 index 0000000..96a54ca --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/inc/xxtea.h @@ -0,0 +1,37 @@ +/*************************************************************** + * + * OpenBeacon.org - XXTEA based block encryption + * + * based on "correction to XTEA" by David J. Wheeler and + * Roger M. Needham. + * Computer Laboratory - Cambridge University in 1998 + * + * Copyright 2006 Milosch Meriac + * + * ripped into pieces - optimized for the special case + * where 16 bytes are regarded for encryption and decryption + * to increase speed and to decrease memory consumption + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __XXTEA_H__ +#define __XXTEA_H__ + +extern void xxtea_decode (uint32_t * v, uint32_t length, const uint32_t * tea_key); +extern void xxtea_encode (uint32_t * v, uint32_t length, const uint32_t * tea_key); + +#endif/*__XXTEA_H__*/ \ No newline at end of file diff --git a/openbeacon/lpc13xx/core/openbeacon/src/crc16.c b/openbeacon/lpc13xx/core/openbeacon/src/crc16.c new file mode 100644 index 0000000..44f2ba0 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/src/crc16.c @@ -0,0 +1,43 @@ +/*************************************************************** + * + * OpenBeacon.org - CRC16 routine + * + * Copyright 2007 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#include +#include "crc16.h" + +uint16_t +crc16 (const uint8_t *buffer, uint32_t size) +{ + uint16_t crc = 0xFFFF; + + if (buffer && size) + while (size--) + { + crc = (crc >> 8) | (crc << 8); + crc ^= *buffer++; + crc ^= ((unsigned char) crc) >> 4; + crc ^= crc << 12; + crc ^= (crc & 0xFF) << 5; + } + + return crc; +} diff --git a/openbeacon/lpc13xx/core/openbeacon/src/debug_printf.c b/openbeacon/lpc13xx/core/openbeacon/src/debug_printf.c new file mode 100644 index 0000000..51f1c4e --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/src/debug_printf.c @@ -0,0 +1,367 @@ +/* + * linux/lib/vsprintf.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + */ + +#include +#ifndef UART_DISABLE +#include +#include +#include +#include +#include + +unsigned long +simple_strtoul (const char *cp, char **endp, unsigned int base) +{ + unsigned long result = 0, value; + + if (*cp == '0') + { + cp++; + if ((*cp == 'x') && isxdigit ((int)cp[1])) + { + base = 16; + cp++; + } + if (!base) + { + base = 8; + } + } + if (!base) + { + base = 10; + } + while (isxdigit ((int)*cp) && (value = isdigit ((int)*cp) ? *cp - '0' : (islower ((int)*cp) + ? + toupper ((int)*cp) + : *cp) - + 'A' + 10) < base) + { + result = result * base + value; + cp++; + } + if (endp) + *endp = (char *) cp; + return result; +} + +long +simple_strtol (const char *cp, char **endp, unsigned int base) +{ + if (*cp == '-') + return -simple_strtoul (cp + 1, endp, base); + return simple_strtoul (cp, endp, base); +} + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int +skip_atoi (const char **s) +{ + int i = 0; + + while (is_digit (**s)) + i = i * 10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + +#define do_div(n,base) ({ \ + int __res; \ + __res = ((unsigned long) n) % base; \ + n = ((unsigned long) n) / base; \ + __res; \ +}) + +static void +number (long num, unsigned int base, int size, int precision, + int type) +{ + char c, sign; + static char tmp[66]; + + const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + int i; + + if (type & LARGE) + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) + { + if (num < 0) + { + sign = '-'; + num = -num; + size--; + } + else if (type & PLUS) + { + sign = '+'; + size--; + } + else if (type & SPACE) + { + sign = ' '; + size--; + } + } + i = 0; + if (num == 0) + tmp[i++] = '0'; + else + while (num != 0) + tmp[i++] = digits[do_div (num, base)]; + if (i > precision) + precision = i; + size -= precision; + if (!(type & (ZEROPAD + LEFT))) + while (size-- > 0) + default_putchar(' '); + if (sign) + default_putchar(sign); + if (!(type & LEFT)) + while (size-- > 0) + default_putchar(c); + while (i < precision--) + default_putchar('0'); + while (i-- > 0) + default_putchar(tmp[i]); + while (size-- > 0) + default_putchar(' '); +} + +static void +tiny_vsprintf (const char *fmt, va_list args) +{ + int len; + unsigned long num; + int i, base; + const char *s; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'q' for integer fields */ + + for (; *fmt; ++fmt) + { + if (*fmt != '%') + { + if(*fmt=='\n') + default_putchar('\r'); + default_putchar(*fmt); + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) + { + case '-': + flags |= LEFT; + goto repeat; + case '+': + flags |= PLUS; + goto repeat; + case ' ': + flags |= SPACE; + goto repeat; + case '0': + flags |= ZEROPAD; + goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit (*fmt)) + field_width = skip_atoi (&fmt); + else if (*fmt == '*') + { + ++fmt; + /* it's the next argument */ + field_width = va_arg (args, int); + if (field_width < 0) + { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') + { + ++fmt; + if (is_digit (*fmt)) + precision = skip_atoi (&fmt); + else if (*fmt == '*') + { + ++fmt; + /* it's the next argument */ + precision = va_arg (args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || + *fmt == 'Z' || *fmt == 'z' || *fmt == 't' || *fmt == 'q') + { + qualifier = *fmt; + if (qualifier == 'l' && *(fmt + 1) == 'l') + { + qualifier = 'q'; + ++fmt; + } + ++fmt; + } + + /* default base */ + base = 10; + + switch (*fmt) + { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + default_putchar(' '); + default_putchar((unsigned char) va_arg (args, int)); + while (--field_width > 0) + default_putchar(' '); + continue; + + case 's': + s = va_arg (args, char *); + if (!s) + s = ""; + + len = strnlen (s, precision); + + if (!(flags & LEFT)) + while (len < field_width--) + default_putchar(' '); + for (i = 0; i < len; ++i) + default_putchar(*s++); + while (len < field_width--) + default_putchar(' '); + continue; + + case '%': + default_putchar('%'); + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'X': + flags |= LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + default_putchar('%'); + if (*fmt) + default_putchar(*fmt); + else + --fmt; + continue; + } + + if (qualifier == 'l') + { + num = va_arg (args, unsigned long); + } + else if (qualifier == 'Z' || qualifier == 'z') + { + num = va_arg (args, size_t); + } + else if (qualifier == 'h') + { + num = (unsigned short) va_arg (args, int); + if (flags & SIGN) + num = (short) num; + } + else if (flags & SIGN) + num = va_arg (args, int); + else + num = va_arg (args, unsigned int); + number (num, base, field_width, precision, flags); + } +} + +void +debug_printf (const char *fmt, ...) +{ + va_list args; + + va_start (args, fmt); + tiny_vsprintf (fmt, args); + va_end (args); +} + +void hex_dump (const unsigned char *buf, unsigned int addr, unsigned int len) +{ + unsigned int start, i, j; + char c; + + start = addr & ~0xf; + + for (j=0; j= addr && start+i+j < addr+len) + debug_printf(" %02x", buf[start+i+j]); + else + debug_printf(" "); + } + debug_printf(" |"); + for (i=0; i<16; i++) { + if (start+i+j >= addr && start+i+j < addr+len) { + c = buf[start+i+j]; + if (c >= ' ' && c < 127) + debug_printf("%c", c); + else + debug_printf("."); + } else + debug_printf(" "); + } + debug_printf("|\n\r"); + } +} +#endif /* UART_DISABLE */ diff --git a/openbeacon/lpc13xx/core/openbeacon/src/hid.c b/openbeacon/lpc13xx/core/openbeacon/src/hid.c new file mode 100644 index 0000000..6e8dc18 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/src/hid.c @@ -0,0 +1,112 @@ +/*************************************************************** + * + * OpenBeacon.org - HID ROM function code for LPC13xx + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#include +#include "hid.h" + +#if (USB_HID_IN_REPORT_SIZE>0)||(USB_HID_OUT_REPORT_SIZE>0) + +#define EN_TIMER32_1 (1<<10) +#define EN_IOCON (1<<16) +#define EN_USBREG (1<<14) + +static ROM **rom = (ROM **) 0x1fff1ff8; + +void +USB_IRQHandler (void) +{ + (*rom)->pUSBD->isr (); +} + +/* USB String Descriptor (optional) */ +const uint8_t USB_StringDescriptor[] = { + /* Index 0x00: LANGID Codes */ + 0x04, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL (0x0409), /* US English - wLANGID */ + /* Index 0x04: Manufacturer */ + 0x1C, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'B', 0, 'i', 0, 't', 0, 'm', 0, 'a', 0, 'n', 0, 'u', 0, 'f', 0, + 'a', 0, 'k', 0, 't', 0, 'u', 0, 'r', 0, + /* Index 0x20: Product */ + 0x28, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'O', 0, 'p', 0, 'e', 0, 'n', 0, 'B', 0, 'e', 0, 'a', 0, 'c', 0, + 'o', 0, 'n', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'I', 0, + 'I', 0, ' ', 0, ' ', 0, + /* Index 0x48: Serial Number */ + 0x1A, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, + '0', 0, '0', 0, '0', 0, '0', 0, + /* Index 0x62: Interface 0, Alternate Setting 0 */ + 0x0E, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'H', 0, 'I', 0, 'D', 0, ' ', 0, ' ', 0, ' ', 0, +}; + +void +hid_init (void) +{ + volatile int i; + + /* Setup ROM initialization structure */ + static const HID_DEVICE_INFO HidDevInfo = { + .idVendor = USB_VENDOR_ID, + .idProduct = USB_PROD_ID, + .bcdDevice = USB_DEVICE, + .StrDescPtr = (uint32_t) & USB_StringDescriptor[0], + .InReportCount = USB_HID_IN_REPORT_SIZE, + .OutReportCount = USB_HID_OUT_REPORT_SIZE, + .SampleInterval = 0x20, + .InReport = GetInReport, + .OutReport = SetOutReport + }; + + /* Point DeviceInfo to HidDevInfo */ + static const USB_DEV_INFO DeviceInfo = { + .DevType = USB_DEVICE_CLASS_HUMAN_INTERFACE, + .DevDetailPtr = (uint32_t) & HidDevInfo + }; + + /* Enable Timer32_1, IOCON, and USB blocks (for USB ROM driver) */ + LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG); + + /* Use pll and pin init function in rom */ + (*rom)->pUSBD->init_clk_pins (); + /* fixing NXP stupidity - they break system clock */ + SystemCoreClockUpdate (); + + /* insert delay between init_clk_pins() and usb init */ + for (i = 0; i < 75; i++); + + /* USB Initialization ... */ + (*rom)->pUSBD->init (&DeviceInfo); + + /* ... and USB Connect */ + (*rom)->pUSBD->connect (1); + +} + +#endif /* (USB_HID_IN_REPORT_SIZE>0)||(USB_HID_OUT_REPORT_SIZE>0) */ diff --git a/openbeacon/lpc13xx/core/openbeacon/src/iap.c b/openbeacon/lpc13xx/core/openbeacon/src/iap.c new file mode 100644 index 0000000..b28e3a8 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/src/iap.c @@ -0,0 +1,45 @@ +/*************************************************************** + * + * OpenBeacon.org - IAP - in application programming + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#include +#include "iap.h" + +typedef void (*IAP_FUNC) (const uint32_t * cmd, uint32_t * result); + +static const IAP_FUNC iap = (IAP_FUNC) 0x1fff1ff1; + +void +iap_invoke_isp (void) +{ + static const uint32_t cmd = 57; + + (*iap) (&cmd, NULL); +} + +void +iap_read_uid (TDeviceUID * uid) +{ + static const uint32_t cmd = 58; + + (*iap) (&cmd, (uint32_t *) uid); +} diff --git a/openbeacon/lpc13xx/core/openbeacon/src/msd.c b/openbeacon/lpc13xx/core/openbeacon/src/msd.c new file mode 100644 index 0000000..b0cba17 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/src/msd.c @@ -0,0 +1,117 @@ +/*************************************************************** + * + * OpenBeacon.org - HID ROM function code for LPC13xx + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#include +#include "msd.h" + +#ifdef USB_DISK_SUPPORT + +#define EN_TIMER32_1 (1<<10) +#define EN_IOCON (1<<16) +#define EN_USBREG (1<<14) + +static ROM **rom = (ROM **) 0x1fff1ff8; + +void +USB_IRQHandler (void) +{ + (*rom)->pUSBD->isr (); +} + +/* USB String Descriptor (optional) */ +const uint8_t USB_StringDescriptor[] = { + /* Index 0x00: LANGID Codes */ + 0x04, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL (0x0409), /* US English - wLANGID */ + /* Index 0x04: Manufacturer */ + 0x1C, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'B', 0, 'i', 0, 't', 0, 'm', 0, 'a', 0, 'n', 0, 'u', 0, 'f', 0, + 'a', 0, 'k', 0, 't', 0, 'u', 0, 'r', 0, + /* Index 0x20: Product */ + 0x28, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'O', 0, 'p', 0, 'e', 0, 'n', 0, 'B', 0, 'e', 0, 'a', 0, 'c', 0, + 'o', 0, 'n', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'I', 0, + 'I', 0, ' ', 0, ' ', 0, + /* Index 0x48: Serial Number */ + 0x1A, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, + '0', 0, '0', 0, '0', 0, '0', 0, + /* Index 0x62: Interface 0, Alternate Setting 0 */ + 0x0E, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'M', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, +}; + +void +msd_init (void) +{ + volatile int i; + + /* 28 byte long SCSI inquiry string */ + static const uint8_t SCSI_Inquiry_String[28] = + "Logfile OpenBeacon Tag 2.0a"; + + /* Setup ROM initialization structure */ + static const MSC_DEVICE_INFO MscDevInfo = { + .idVendor = USB_VENDOR_ID, + .idProduct = USB_PROD_ID, + .bcdDevice = USB_DEVICE, + .StrDescPtr = (uint32_t) & USB_StringDescriptor[0], + .MSCInquiryStr = (uint32_t) & SCSI_Inquiry_String, + .BlockSize = DISK_BLOCK_SIZE, + .BlockCount = DISK_SECTORS, + .MemorySize = DISK_SIZE, + .MSC_Read = msd_read, + .MSC_Write = msd_write + }; + + /* Point DeviceInfo to MscDevInfo */ + static const USB_DEV_INFO DeviceInfo = { + .DevType = USB_DEVICE_CLASS_STORAGE, + .DevDetailPtr = (uint32_t) & MscDevInfo + }; + + /* Enable Timer32_1, IOCON, and USB blocks (for USB ROM driver) */ + LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG); + + /* Use pll and pin init function in rom */ + (*rom)->pUSBD->init_clk_pins (); + /* fixing NXP stupidity - they break system clock */ + SystemCoreClockUpdate (); + + /* insert delay between init_clk_pins() and usb init */ + for (i = 0; i < 75; i++); + + /* USB Initialization ... */ + (*rom)->pUSBD->init (&DeviceInfo); + /* Initialize Storage */ + init_msdstate (); + /* ... and USB Connect */ + (*rom)->pUSBD->connect (1); +} + +#endif /* USB_DISK_SUPPORT */ diff --git a/openbeacon/lpc13xx/core/openbeacon/src/spi.c b/openbeacon/lpc13xx/core/openbeacon/src/spi.c new file mode 100644 index 0000000..9656378 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/src/spi.c @@ -0,0 +1,128 @@ +/*************************************************************** + * + * OpenBeacon.org - SPI routines for LPC13xx + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#include +#include "spi.h" + +#define BIT_REVERSE(x) ((unsigned char)(__RBIT(x)>>24)) + +void spi_init_pin(spi_cs chipselect) +{ + GPIOSetDir((uint8_t) (chipselect >> 24), (uint8_t) (chipselect >> 16), 1); +} + +int spi_txrx(spi_cs chipselect, const void *tx, uint16_t txlen, void *rx, + uint16_t rxlen) +{ + uint8_t data, status; + uint16_t total, xfered; + + /* SSP0 Clock Prescale Register to SYSCLK/CPSDVSR */ + LPC_SSP->CPSR = (chipselect >> 8) & 0xFF; + + /* activate chip select */ + if ((chipselect & SPI_CS_MODE_SKIP_CS_ASSERT) == 0) + GPIOSetValue((uint8_t) (chipselect >> 24), + (uint8_t) (chipselect >> 16), chipselect + & SPI_CS_MODE_INVERT_CS); + + /* calculate SPI transaction size */ + xfered = total = (chipselect & SPI_CS_MODE_SKIP_TX) ? rxlen + txlen + : (txlen >= rxlen) ? txlen : rxlen; + + while (xfered) + { + status = (uint8_t) LPC_SSP->SR; + + if (total && (status & 0x02)) + { + total--; + + if (txlen) + { + txlen--; + data = *((uint8_t *) tx); + tx = ((uint8_t *) tx) + 1; + if (chipselect & SPI_CS_MODE_BIT_REVERSED) + data = BIT_REVERSE (data); + } + else + data = 0; + + LPC_SSP->DR = data; + } + + if (status & 0x04) + { + data = LPC_SSP->DR; + xfered--; + + /* skip txlen in output if SPI_CS_MODE_SKIP_TX */ + if (rxlen && (xfered < rxlen)) + { + rxlen--; + if (chipselect & SPI_CS_MODE_BIT_REVERSED) + data = BIT_REVERSE (data); + *((uint8_t *) rx) = data; + rx = ((uint8_t *) rx) + 1; + } + } + } + + /* de-activate chip select */ + if ((chipselect & SPI_CS_MODE_SKIP_CS_DEASSERT) == 0) + GPIOSetValue((uint8_t) (chipselect >> 24), + (uint8_t) (chipselect >> 16), (chipselect + & SPI_CS_MODE_INVERT_CS) ^ SPI_CS_MODE_INVERT_CS); + + return 0; +} + +void spi_status(void) +{ + debug_printf(" * SPI: CLK:%uMHz\n", (SystemCoreClock / LPC_SSP->CPSR) + / 1000000); +} + +void spi_init(void) +{ + /* reset SSP peripheral */ + LPC_SYSCON->PRESETCTRL = 0x01; + + /* Enable SSP clock */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 11); + + /* Enable SSP peripheral MISO, Pulldown */ + LPC_IOCON->PIO0_8 = 0x01 | (0x01 << 3); + /* MOSI */ + LPC_IOCON->PIO0_9 = 0x01; + /* route to PIO2_11 */ + LPC_IOCON->SCKLOC = 0x01; + /* SCK */ + LPC_IOCON->PIO2_11 = 0x01; + + /* Set SSP PCLK to 48MHz DIV=1 */ + LPC_SYSCON->SSPCLKDIV = 0x01; + /* 8 bit, SPI, SCR=0 */ + LPC_SSP->CR0 = 0x0007; + LPC_SSP->CR1 = 0x0002; +} diff --git a/openbeacon/lpc13xx/core/openbeacon/src/vfs.c b/openbeacon/lpc13xx/core/openbeacon/src/vfs.c new file mode 100644 index 0000000..0087133 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/src/vfs.c @@ -0,0 +1,533 @@ +/*************************************************************** + * + * OpenBeacon.org - virtual FAT16 file system support + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#include +#include "msd.h" +#include "vfs.h" + +#ifdef USB_DISK_SUPPORT + +#define VOLUME_START 1UL +#define VOLUME_SECTORS (DISK_SECTORS-VOLUME_START) +#define DISK_SECTORS_PER_CLUSTER 8UL +#define DISK_CLUSTER_SIZE (DISK_SECTORS_PER_CLUSTER*DISK_BLOCK_SIZE) +#define FAT16_SIZE_SECTORS ((uint32_t)((((VOLUME_SECTORS/DISK_SECTORS_PER_CLUSTER+2)*2)+DISK_BLOCK_SIZE-1)/DISK_BLOCK_SIZE)) +#define RESERVED_SECTORS_COUNT 1UL +#define BPB_NUMFATS 2UL +#define ROOT_DIR_SECTORS 1UL +#define MAX_FILES_IN_ROOT ((ROOT_DIR_SECTORS*DISK_BLOCK_SIZE)/sizeof(TDiskDirectoryEntry)) +#define FIRST_FAT_SECTOR (RESERVED_SECTORS_COUNT) +#define FIRST_ROOT_DIR_SECTOR (FIRST_FAT_SECTOR+(BPB_NUMFATS*FAT16_SIZE_SECTORS)) +#define FIRST_DATA_SECTOR (FIRST_ROOT_DIR_SECTOR+ROOT_DIR_SECTORS) +#define DATA_SECTORS (DISK_SECTORS-FIRST_DATA_SECTOR) +#define FIRST_SECTOR_OF_CLUSTER(N) (((N-2UL)*DISK_SECTORS_PER_CLUSTER)+FIRST_DATA_SECTOR) +#define BPB_MEDIA_TYPE 0xF8 +#define DISK_FAT_EOC (0xFF00|BPB_MEDIA_TYPE) + +static const TDiskFile *root_directory = NULL; + +typedef uint16_t TFatCluster; + +typedef struct TDiskRecord +{ + uint32_t offset, length; + TDiskHandler handler; + const void *data; +} TDiskRecord; + +typedef struct +{ + uint8_t head, sector, cylinder; +} PACKED TDiskPartitionTableEntryCHS; + +typedef struct +{ + uint8_t bootable; + TDiskPartitionTableEntryCHS start; + uint8_t partition_type; + TDiskPartitionTableEntryCHS end; + uint32_t start_lba; + uint32_t length; +} PACKED TDiskPartitionTableEntry; + +#define ATTR_READ_ONLY 0x01 +#define ATTR_HIDDEN 0x02 +#define ATTR_SYSTEM 0x04 +#define ATTR_VOLUME_ID 0x08 +#define ATTR_DIRECTORY 0x10 +#define ATTR_ARCHIVE 0x20 +#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID) + +typedef struct +{ + char DIR_Name[11]; + uint8_t DIR_Attr; + uint8_t DIR_NTRes; + uint8_t DIR_CrtTimeTenth; + uint16_t DIR_CrtTime; + uint16_t DIR_CrtDate; + uint16_t DIR_LstAccDate; + uint16_t DIR_FstClusHI; + uint16_t DIR_WrtTime; + uint16_t DIR_WrtDate; + uint16_t DIR_FstClusLO; + uint32_t DIR_FileSize; +} PACKED TDiskDirectoryEntry; + +/* disk signature */ +const uint32_t DiskSignature = 0x1B07CF6E; + +/* BPB - BIOS Parameter Block: actual volume boot block */ +const TDiskBPB DiskBPB = { + .BS_jmpBoot = {0xEB, 0x00, 0x90}, + .BS_OEMName = "MSWIN4.1", + .BPB_BytsPerSec = DISK_BLOCK_SIZE, + .BPB_SecPerClus = DISK_SECTORS_PER_CLUSTER, + .BPB_RsvdSecCnt = RESERVED_SECTORS_COUNT, + .BPB_NumFATs = BPB_NUMFATS, + .BPB_RootEntCnt = MAX_FILES_IN_ROOT, + .BPB_Media = BPB_MEDIA_TYPE, + .BPB_FATSz16 = FAT16_SIZE_SECTORS, + .BPB_SecPerTrk = DISK_SECTORS_PER_TRACK, + .BPB_NumHeads = DISK_HEADS, + .BPB_HiddSec = VOLUME_START, + .BPB_TotSec32 = VOLUME_SECTORS, + /* FAT12/FAT16 definition */ + .BS_DrvNum = 0x80, + .BS_BootSig = 0x29, + .BS_VolID = 0xe9d9489f, + .BS_VolLab = "OPENBEACON ", + .BS_FilSysType = "FAT16 ", +}; + +static void +msd_read_data_area (uint32_t offset, uint32_t length, const void *src, + uint8_t * dst) +{ + uint32_t t; + uint32_t cluster, cluster_start, cluster_end, cluster_count; + uint32_t cluster_file_count; + + /* remember variable content over calls to enable caching */ + static const TDiskFile *file = NULL; + static uint32_t cluster_file_start, cluster_file_end; + + /* touch unused parameter 'src' */ + (void) src; + + /* ignore zero size read requests */ + if (!length) + return; + + /* get extent of read/write request */ + cluster_start = offset / DISK_CLUSTER_SIZE; + cluster_count = (length + DISK_CLUSTER_SIZE - 1) / DISK_CLUSTER_SIZE; + cluster_end = cluster_start + cluster_count - 1; + + /* check for cached file request */ + if (file && (cluster_end >= cluster_file_start) + && (cluster_start <= cluster_file_end)) + { + if (file->handler) + file->handler (offset - + (cluster_file_start * DISK_CLUSTER_SIZE), + length, file->data, dst); + else + memset (dst, ' ', length); + } + + /* if no file cached, try to find file */ + cluster = 0; + file = root_directory; + while (file) + { + if (file->length) + { + cluster_file_start = cluster; + cluster_file_count = + (file->length + DISK_CLUSTER_SIZE - 1) / DISK_CLUSTER_SIZE; + cluster_file_end = cluster_file_start + cluster_file_count - 1; + + if ((cluster_end >= cluster_file_start) + && (cluster_start <= cluster_file_end)) + { + /* normalize offset to file start */ + offset -= (cluster_file_start * DISK_CLUSTER_SIZE); + + /* if handler exists - run */ + if (file->handler) + file->handler (offset, length, file->data, dst); + /* if no handler exists copy data */ + else if ((file->data) && (offset < file->length)) + { + /* calculate remaining length */ + if ((t = file->length - offset) > length) + t = length; + + /* copy data to output buffer */ + memcpy (dst, ((uint8_t *) file->data) + offset, t); + + /* if data is smaller, sent remainder to zero */ + if (t < length) + memset (&dst[t], 0, length - t); + } + /* if no data exists, set to zero */ + else + memset (dst, 0, length); + + /* request could be satisfied - bail out with cached file + handle after handling request */ + return; + } + + cluster += cluster_file_count; + } + file = file->next; + } + + /* didn't find a matching request - reset cached file to NULL */ + file = NULL; +} + +static void +msd_read_fat_area (uint32_t offset, uint32_t length, const void *src, + uint8_t * dst) +{ + const TDiskFile *file; + uint32_t count, t, index, remaining; + uint32_t cluster, cluster_start, cluster_end, cluster_count; + uint32_t cluster_file_start, cluster_file_end, cluster_file_count; + TFatCluster *fat; + + /* touch unused parameter 'src' */ + (void) src; + + /* ignore read requests for sizes < cluster table granularity */ + if (length < sizeof (TFatCluster)) + return; + + /* get extent of read/write request */ + cluster_start = offset / sizeof (TFatCluster); + cluster_count = length / sizeof (TFatCluster); + cluster_end = cluster_start + cluster_count - 1; + + /* pre-set FAT */ + fat = (TFatCluster *) dst; + t = cluster_count; + + /* special treatment for reserved clusters */ + if (!offset) + { + /* indicate media type */ + *fat++ = DISK_FAT_EOC; + /* indicate clean volume */ + *fat++ = (0x8000 | 0x4000); + t -= 2; + } + + /* mark all custers as bad by default to make + sure there is no free space left on the disk + for new files */ + while (t--) + *fat++ = 0xFFF7; + + /* first cluster number on disk is 2 */ + cluster = 2; + file = root_directory; + while (file) + { + if (file->length) + { + cluster_file_start = cluster; + cluster_file_count = + (file->length + DISK_CLUSTER_SIZE - 1) / DISK_CLUSTER_SIZE; + cluster_file_end = cluster_file_start + cluster_file_count - 1; + + if ((cluster_end >= cluster_file_start) + && (cluster_start < cluster_file_end)) + { + if (cluster_file_start < cluster_start) + { + index = cluster_start - cluster_file_start; + remaining = cluster_file_count - index; + index += cluster; + count = + (cluster_count > remaining) ? remaining : cluster_count; + fat = (TFatCluster *) dst; + } + else + { + index = cluster; + remaining = cluster_file_count; + t = (cluster_file_start - cluster_start); + count = cluster_count - t; + fat = ((TFatCluster *) dst) + t; + } + + /* populate FAT entries with linked FAT list */ + if (remaining) + for (t = 1; t <= count; t++) + if (remaining-- > 1) + *fat++ = index + t; + else + { + /* set last entry to EOC (End Of Chain) */ + *fat = DISK_FAT_EOC; + break; + } + } + cluster += cluster_file_count; + } + file = file->next; + } +} + +static void +msd_read_root_dir (uint32_t offset, uint32_t length, const void *src, + uint8_t * dst) +{ + uint32_t cluster, t; + const TDiskFile *file; + TDiskDirectoryEntry *entry; + + /* touch unused parameter 'src' */ + (void) src; + + /* initialize response with zero */ + memset (dst, 0, length); + + /* first cluster number on disk is 2 */ + cluster = 2; + /* skip first entries */ + file = root_directory; + t = offset / sizeof (TDiskDirectoryEntry); + while (t--) + { + if (!file) + return; + cluster += (file->length + DISK_CLUSTER_SIZE - 1) / DISK_CLUSTER_SIZE; + file = file->next; + } + + entry = (TDiskDirectoryEntry *) dst; + t = length / sizeof (TDiskDirectoryEntry); + while (t--) + { + if (!file) + return; + + /* turn last entry to volume ID */ + entry->DIR_Attr = file->next ? ATTR_READ_ONLY : ATTR_VOLUME_ID; + + /* populate directory entry */ + entry->DIR_FileSize = file->length; + entry->DIR_FstClusLO = (file->length) ? cluster : 0; + strncpy (entry->DIR_Name, file->name, sizeof (entry->DIR_Name)); + + /* increment cluster pos */ + cluster += (file->length + DISK_CLUSTER_SIZE - 1) / DISK_CLUSTER_SIZE; + + /* go to next entry */ + entry++; + file = file->next; + } +} + +static void +msd_read_memory (uint32_t offset, uint32_t length, const void *src, + uint8_t * dst) +{ + memcpy (dst, ((const uint8_t *) src) + offset, length); +} + +void +msd_read (uint32_t offset, uint8_t * dst, uint32_t length) +{ + const TDiskRecord *rec; + uint32_t t, read_end, rec_start, rec_end, pos, count, written; + uint8_t *p; + + + /* first partition table entry */ + static const TDiskPartitionTableEntry DiskPartitionTableEntry = { + .bootable = 0x00, + .start = { + .head = 0, + .sector = VOLUME_START + 1, + .cylinder = 0}, + .partition_type = 0x06, + .end = { + .head = DISK_HEADS - 1, + .sector = DISK_SECTORS_PER_TRACK, + .cylinder = DISK_CYLINDERS - 1}, + .start_lba = 1, + .length = VOLUME_SECTORS + }; + + /* MBR termination signature */ + static const uint16_t BootSignature = 0xAA55; + + + /* data mapping of virtual drive */ + static const TDiskRecord DiskRecord[] = { + /* data area */ + { + .offset = (VOLUME_START + FIRST_DATA_SECTOR) * DISK_BLOCK_SIZE, + .length = DATA_SECTORS * DISK_BLOCK_SIZE, + .handler = msd_read_data_area, + .data = NULL} + , + /* FAT area - primary copy */ + { + .offset = (VOLUME_START + FIRST_FAT_SECTOR) * DISK_BLOCK_SIZE, + .length = FAT16_SIZE_SECTORS * DISK_BLOCK_SIZE, + .handler = msd_read_fat_area, + .data = NULL} + , + /* FAT area - secondary copy */ + { + .offset = + (VOLUME_START + FIRST_FAT_SECTOR + FAT16_SIZE_SECTORS) * DISK_BLOCK_SIZE, + .length = FAT16_SIZE_SECTORS * DISK_BLOCK_SIZE, + .handler = msd_read_fat_area, + .data = NULL} + , + /* root dir */ + { + .offset = (VOLUME_START + FIRST_ROOT_DIR_SECTOR) * DISK_BLOCK_SIZE, + .length = ROOT_DIR_SECTORS * DISK_BLOCK_SIZE, + .handler = msd_read_root_dir, + .data = NULL} + , + /* disk signature */ + { + .offset = 0x1B8, + .length = sizeof (DiskSignature), + .handler = msd_read_memory, + .data = &DiskSignature} + , + /* first partition table entry */ + { + .offset = 0x1BE, + .length = sizeof (DiskPartitionTableEntry), + .handler = msd_read_memory, + .data = &DiskPartitionTableEntry} + , + /* MBR termination signature */ + { + .offset = 0x1FE, + .length = sizeof (BootSignature), + .handler = msd_read_memory, + .data = &BootSignature} + , + /* BPB - BIOS Parameter Block: actual volume boot block */ + { + .offset = (VOLUME_START * DISK_BLOCK_SIZE), + .length = sizeof (DiskBPB), + .handler = msd_read_memory, + .data = &DiskBPB} + , + /* BPB termination signature */ + { + .offset = (VOLUME_START * DISK_BLOCK_SIZE) + 0x1FE, + .length = sizeof (BootSignature), + .handler = msd_read_memory, + .data = &BootSignature} + , + }; + + /* ignore zero reads and reads outside of disk area */ + if (!length || (offset >= DISK_SIZE)) + return; + + /* iterate DiskRecords and fill request with content */ + rec = DiskRecord; + t = sizeof (DiskRecord) / sizeof (DiskRecord[0]); + read_end = offset + length; + written = 0; + + while (t--) + { + rec_start = rec->offset; + rec_end = rec_start + rec->length; + + if ((read_end >= rec_start) && (offset < rec_end)) + { + if (rec_start >= offset) + { + pos = 0; + p = &dst[rec_start - offset]; + count = (rec_end <= read_end) ? + rec->length : read_end - rec_start; + } + else + { + pos = offset - rec_start; + p = dst; + count = (read_end > rec_end) ? rec_end - offset : length; + } + + /* set memory of partial read to zero before filling up */ + if (!written && (count != length)) + memset (dst, 0, length); + + /* handle request */ + rec->handler (pos, count, rec->data, p); + written += count; + + /* all bytes handled -> quit */ + if (written == length) + break; + } + rec++; + } + + /* set memory to zero if not written yet */ + if (!written) + memset (dst, 0, length); +} + +void +msd_write (uint32_t offset, uint8_t * src, uint32_t length) +{ + (void) offset; + (void) src; + (void) length; +} + +void +vfs_status (void) +{ +} + +void +vfs_init (const TDiskFile * file) +{ + if (file) + { + root_directory = file; + /* init USB mass storage */ + msd_init (); + } +} + +#endif /* USB_DISK_SUPPORT */ diff --git a/openbeacon/lpc13xx/core/openbeacon/src/xxtea.c b/openbeacon/lpc13xx/core/openbeacon/src/xxtea.c new file mode 100644 index 0000000..888fe90 --- /dev/null +++ b/openbeacon/lpc13xx/core/openbeacon/src/xxtea.c @@ -0,0 +1,102 @@ +/*************************************************************** + * + * OpenBeacon.org - XXTEA based block encryption + * + * based on "correction to XTEA" by David J. Wheeler and + * Roger M. Needham. + * Computer Laboratory - Cambridge University in 1998 + * + * Copyright 2006 Milosch Meriac + * + * ripped into pieces - optimized for the special case + * where 16 bytes are regarded for encryption and decryption + * to increase speed and to decrease memory consumption + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include +#include "xxtea.h" + +static const uint32_t DELTA = 0x9e3779b9UL; + +#define MX ( (((z>>5)^(y<<2))+((y>>3)^(z<<4)))^((sum^y)+(tea_key[(p&3)^e]^z)) ); + +static void +xxtea_shuffle (uint32_t * v, uint32_t length) +{ + while (length--) + { + *v = htonl (*v); + v++; + } +} + +void +xxtea_encode (uint32_t * v, uint32_t length, const uint32_t * tea_key) +{ + uint32_t z, y, sum, e, p, q; + + if (!v || !tea_key) + return; + + xxtea_shuffle (v, length); + + q = 6 + 52 / length; + sum = 0; + z = v[length - 1]; + do + { + sum += DELTA; + e = (sum >> 2) & 3; + + for (p = 0; p < (length - 1); p++) + y = v[p + 1], z = v[p] += MX; + + y = v[0]; + z = v[length - 1] += MX; + } + while (--q); + + xxtea_shuffle (v, length); +} + +void +xxtea_decode (uint32_t * v, uint32_t length, const uint32_t * tea_key) +{ + uint32_t z, y, sum, e, p, q; + + if (!v || !tea_key) + return; + + xxtea_shuffle (v, length); + + q = 6 + 52 / length; + sum = q * DELTA; + y = v[0]; + while (sum) + { + e = (sum >> 2) & 3; + for (p = length - 1; p > 0; p--) + z = v[p - 1], y = v[p] -= MX; + + z = v[length - 1]; + y = v[0] -= MX; + sum -= DELTA; + } + + xxtea_shuffle (v, length); +} diff --git a/openbeacon/lpc13xx/core/peripherals/inc/gpio.h b/openbeacon/lpc13xx/core/peripherals/inc/gpio.h new file mode 100644 index 0000000..f7aa3d0 --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/gpio.h @@ -0,0 +1,70 @@ +/***************************************************************************** + * gpio.h: Header file for NXP LPC13xx Family Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2008.09.01 ver 1.00 Preliminary version, first Release + * 2009.12.09 ver 1.05 Mod to use mask registers for GPIO writes + inlining (.h) + * +******************************************************************************/ +#ifndef __GPIO_H +#define __GPIO_H + +extern void GPIOInit (void); +extern LPC_GPIO_TypeDef (*const LPC_GPIO[4]); + +/***************************************************************************** +** Function name: GPIOSetValue +** +** Descriptions: Set/clear a bitvalue in a specific bit position +** in GPIO portX(X is the port number.) +** +** parameters: port num, bit position, bit value +** Returned value: None +** +*****************************************************************************/ +static __INLINE void +GPIOSetValue (uint32_t portNum, uint32_t bitPosi, uint32_t bitVal) +{ + LPC_GPIO[portNum]->MASKED_ACCESS[(1 << bitPosi)] = (bitVal << bitPosi); +} + +/***************************************************************************** +** Function name: GPIOGetValue +** +** Descriptions: Get a bitvalue in a specific bit position +** in GPIO portX(X is the port number.) +** +** parameters: port num, bit position +** Returned value: bit value +** +*****************************************************************************/ +static __INLINE uint32_t GPIOGetValue( uint32_t portNum, uint32_t bitPosi) +{ + return LPC_GPIO[portNum]->MASKED_ACCESS[(1<DIR |= 1 << bitPosi; + else + LPC_GPIO[portNum]->DIR &= ~(1 << bitPosi); +} + +#endif /* end __GPIO_H */ +/***************************************************************************** +** End Of File +******************************************************************************/ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/rom_drivers.h b/openbeacon/lpc13xx/core/peripherals/inc/rom_drivers.h new file mode 100644 index 0000000..a0b6746 --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/rom_drivers.h @@ -0,0 +1,62 @@ +/***************************************************************************** + * rom_drivers.h: Header file for NXP LPC13xx Family Microprocessors + * + * Copyright(C) 2009, NXP Semiconductor + * All rights reserved. + * + * History + * 2009.09.17 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ +#ifndef ROM_DRIVERS_H_ +#define ROM_DRIVERS_H_ + +typedef struct _USB_DEVICE_INFO +{ + uint16_t DevType; + uint32_t DevDetailPtr; +} USB_DEV_INFO; + +typedef struct _USBD +{ + void (*init_clk_pins) (void); + void (*isr) (void); + void (*init) (const USB_DEV_INFO * DevInfoPtr); + void (*connect) (uint32_t con); +} USBD; + +#define init_msdstate() *((uint32_t *)(0x10000054)) = 0x0 + +typedef struct _ROM +{ + const USBD *pUSBD; +} ROM; + +typedef struct _MSC_DEVICE_INFO +{ + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint32_t StrDescPtr; + uint32_t MSCInquiryStr; + uint32_t BlockCount; + uint32_t BlockSize; + uint32_t MemorySize; + void (*MSC_Write) (uint32_t offset, uint8_t *src, uint32_t length); + void (*MSC_Read) (uint32_t offset, uint8_t *dst, uint32_t length); +} MSC_DEVICE_INFO; + +typedef struct _HID_DEVICE_INFO +{ + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint32_t StrDescPtr; + uint8_t InReportCount; + uint8_t OutReportCount; + uint8_t SampleInterval; + void (*InReport) (uint8_t *src, uint32_t length); + void (*OutReport) (uint8_t *dst, uint32_t length); +} HID_DEVICE_INFO; + +#endif /*ROM_DRIVERS_H_ */ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/uart.h b/openbeacon/lpc13xx/core/peripherals/inc/uart.h new file mode 100644 index 0000000..d4a655c --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/uart.h @@ -0,0 +1,60 @@ +/***************************************************************************** + * uart.h: Header file for NXP LPC13xx Family Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2008.08.21 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ +#ifndef __UART_H__ +#define __UART_H__ +#ifndef UART_DISABLE + +#define RS485_ENABLED 0 +#define TX_INTERRUPT 0 /* 0 if TX uses polling, 1 interrupt driven. */ +#define MODEM_TEST 0 + +#define IER_RBR 0x01 +#define IER_THRE 0x02 +#define IER_RLS 0x04 + +#define IIR_PEND 0x01 +#define IIR_RLS 0x03 +#define IIR_RDA 0x02 +#define IIR_CTI 0x06 +#define IIR_THRE 0x01 + +#define LSR_RDR 0x01 +#define LSR_OE 0x02 +#define LSR_PE 0x04 +#define LSR_FE 0x08 +#define LSR_BI 0x10 +#define LSR_THRE 0x20 +#define LSR_TEMT 0x40 +#define LSR_RXFE 0x80 + +#define BUFSIZE 0x40 + +/* RS485 mode definition. */ +#define RS485_NMMEN (0x1<<0) +#define RS485_RXDIS (0x1<<1) +#define RS485_AADEN (0x1<<2) +#define RS485_SEL (0x1<<3) +#define RS485_DCTRL (0x1<<4) +#define RS485_OINV (0x1<<5) + +extern void UARTInit (uint32_t Baudrate,uint8_t rtscts); +extern void UART_IRQHandler (void); +extern BOOL UARTSendChar (uint8_t data); +extern void UARTSend (const uint8_t * BufferPtr, uint32_t Length); + +extern volatile uint32_t UARTCount; +extern volatile uint8_t UARTBuffer[BUFSIZE]; + +#endif /* UART_DISABLE */ +#endif /* end __UART_H__ */ +/***************************************************************************** +** End Of File +******************************************************************************/ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb.h b/openbeacon/lpc13xx/core/peripherals/inc/usb.h new file mode 100644 index 0000000..705578b --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/usb.h @@ -0,0 +1,237 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usb.h + * Purpose: USB Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USB_H__ +#define __USB_H__ + +typedef union +{ + uint16_t W; + struct + { + uint8_t L; + uint8_t H; + } __attribute__((packed)) WB; +} __attribute__((packed)) WORD_BYTE; + +/* bmRequestType.Dir */ +#define REQUEST_HOST_TO_DEVICE 0 +#define REQUEST_DEVICE_TO_HOST 1 + +/* bmRequestType.Type */ +#define REQUEST_STANDARD 0 +#define REQUEST_CLASS 1 +#define REQUEST_VENDOR 2 +#define REQUEST_RESERVED 3 + +/* bmRequestType.Recipient */ +#define REQUEST_TO_DEVICE 0 +#define REQUEST_TO_INTERFACE 1 +#define REQUEST_TO_ENDPOINT 2 +#define REQUEST_TO_OTHER 3 + +/* bmRequestType Definition */ +typedef union _REQUEST_TYPE +{ + struct _BM + { + uint8_t Recipient:5; + uint8_t Type:2; + uint8_t Dir:1; + } __attribute__((packed)) BM; + uint8_t B; +} __attribute__((packed)) REQUEST_TYPE; + +/* USB Standard Request Codes */ +#define USB_REQUEST_GET_STATUS 0 +#define USB_REQUEST_CLEAR_FEATURE 1 +#define USB_REQUEST_SET_FEATURE 3 +#define USB_REQUEST_SET_ADDRESS 5 +#define USB_REQUEST_GET_DESCRIPTOR 6 +#define USB_REQUEST_SET_DESCRIPTOR 7 +#define USB_REQUEST_GET_CONFIGURATION 8 +#define USB_REQUEST_SET_CONFIGURATION 9 +#define USB_REQUEST_GET_INTERFACE 10 +#define USB_REQUEST_SET_INTERFACE 11 +#define USB_REQUEST_SYNC_FRAME 12 + +/* USB GET_STATUS Bit Values */ +#define USB_GETSTATUS_SELF_POWERED 0x01 +#define USB_GETSTATUS_REMOTE_WAKEUP 0x02 +#define USB_GETSTATUS_ENDPOINT_STALL 0x01 + +/* USB Standard Feature selectors */ +#define USB_FEATURE_ENDPOINT_STALL 0 +#define USB_FEATURE_REMOTE_WAKEUP 1 + +/* USB Default Control Pipe Setup Packet */ +typedef struct _USB_SETUP_PACKET +{ + REQUEST_TYPE bmRequestType; + uint8_t bRequest; + WORD_BYTE wValue; + WORD_BYTE wIndex; + uint16_t wLength; +} __attribute__((packed)) USB_SETUP_PACKET; + + +/* USB Descriptor Types */ +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_STRING_DESCRIPTOR_TYPE 3 +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 +#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6 +#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7 +#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8 +#define USB_OTG_DESCRIPTOR_TYPE 9 +#define USB_DEBUG_DESCRIPTOR_TYPE 10 +#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11 + +/* USB Device Classes */ +#define USB_DEVICE_CLASS_RESERVED 0x00 +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +#define USB_DEVICE_CLASS_MONITOR 0x04 +#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 +#define USB_DEVICE_CLASS_POWER 0x06 +#define USB_DEVICE_CLASS_PRINTER 0x07 +#define USB_DEVICE_CLASS_STORAGE 0x08 +#define USB_DEVICE_CLASS_HUB 0x09 +#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF + +/* bmAttributes in Configuration Descriptor */ +#define USB_CONFIG_POWERED_MASK 0x40 +#define USB_CONFIG_BUS_POWERED 0x80 +#define USB_CONFIG_SELF_POWERED 0xC0 +#define USB_CONFIG_REMOTE_WAKEUP 0x20 + +/* bMaxPower in Configuration Descriptor */ +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +/* bEndpointAddress in Endpoint Descriptor */ +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) + +/* bmAttributes in Endpoint Descriptor */ +#define USB_ENDPOINT_TYPE_MASK 0x03 +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_TYPE_BULK 0x02 +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 +#define USB_ENDPOINT_SYNC_MASK 0x0C +#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 +#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 +#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 +#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C +#define USB_ENDPOINT_USAGE_MASK 0x30 +#define USB_ENDPOINT_USAGE_DATA 0x00 +#define USB_ENDPOINT_USAGE_FEEDBACK 0x10 +#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 +#define USB_ENDPOINT_USAGE_RESERVED 0x30 + +/* USB Standard Device Descriptor */ +typedef struct _USB_DEVICE_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__((packed)) USB_DEVICE_DESCRIPTOR; + +/* USB 2.0 Device Qualifier Descriptor */ +typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} __attribute__((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR; + +/* USB Standard Configuration Descriptor */ +typedef struct _USB_CONFIGURATION_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR; + +/* USB Standard Interface Descriptor */ +typedef struct _USB_INTERFACE_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR; + +/* USB Standard Endpoint Descriptor */ +typedef struct _USB_ENDPOINT_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR; + +/* USB String Descriptor */ +typedef struct _USB_STRING_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bString /*[] */ ; +} __attribute__((packed)) USB_STRING_DESCRIPTOR; + +/* USB Common Descriptor */ +typedef struct _USB_COMMON_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; +} __attribute__((packed)) USB_COMMON_DESCRIPTOR; + +#endif /* __USB_H__ */ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/cdc.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdc.h new file mode 100644 index 0000000..d61b85b --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdc.h @@ -0,0 +1,241 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: CDC.h + * Purpose: USB Communication Device Class Definitions + * Version: V1.00 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __CDC_H +#define __CDC_H + +/*---------------------------------------------------------------------------- + * Definitions based on usbcdc11.pdf (www.usb.org) + *---------------------------------------------------------------------------*/ +// Communication device class specification version 1.10 +#define CDC_V1_10 0x0110 + +// Communication interface class code +// (usbcdc11.pdf, 4.2, Table 15) +#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 + +// Communication interface class subclass codes +// (usbcdc11.pdf, 4.3, Table 16) +#define CDC_DIRECT_LINE_CONTROL_MODEL 0x01 +#define CDC_ABSTRACT_CONTROL_MODEL 0x02 +#define CDC_TELEPHONE_CONTROL_MODEL 0x03 +#define CDC_MULTI_CHANNEL_CONTROL_MODEL 0x04 +#define CDC_CAPI_CONTROL_MODEL 0x05 +#define CDC_ETHERNET_NETWORKING_CONTROL_MODEL 0x06 +#define CDC_ATM_NETWORKING_CONTROL_MODEL 0x07 + +// Communication interface class control protocol codes +// (usbcdc11.pdf, 4.4, Table 17) +#define CDC_PROTOCOL_COMMON_AT_COMMANDS 0x01 + +// Data interface class code +// (usbcdc11.pdf, 4.5, Table 18) +#define CDC_DATA_INTERFACE_CLASS 0x0A + +// Data interface class protocol codes +// (usbcdc11.pdf, 4.7, Table 19) +#define CDC_PROTOCOL_ISDN_BRI 0x30 +#define CDC_PROTOCOL_HDLC 0x31 +#define CDC_PROTOCOL_TRANSPARENT 0x32 +#define CDC_PROTOCOL_Q921_MANAGEMENT 0x50 +#define CDC_PROTOCOL_Q921_DATA_LINK 0x51 +#define CDC_PROTOCOL_Q921_MULTIPLEXOR 0x52 +#define CDC_PROTOCOL_V42 0x90 +#define CDC_PROTOCOL_EURO_ISDN 0x91 +#define CDC_PROTOCOL_V24_RATE_ADAPTATION 0x92 +#define CDC_PROTOCOL_CAPI 0x93 +#define CDC_PROTOCOL_HOST_BASED_DRIVER 0xFD +#define CDC_PROTOCOL_DESCRIBED_IN_PUFD 0xFE + +// Type values for bDescriptorType field of functional descriptors +// (usbcdc11.pdf, 5.2.3, Table 24) +#define CDC_CS_INTERFACE 0x24 +#define CDC_CS_ENDPOINT 0x25 + +// Type values for bDescriptorSubtype field of functional descriptors +// (usbcdc11.pdf, 5.2.3, Table 25) +#define CDC_HEADER 0x00 +#define CDC_CALL_MANAGEMENT 0x01 +#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 +#define CDC_DIRECT_LINE_MANAGEMENT 0x03 +#define CDC_TELEPHONE_RINGER 0x04 +#define CDC_REPORTING_CAPABILITIES 0x05 +#define CDC_UNION 0x06 +#define CDC_COUNTRY_SELECTION 0x07 +#define CDC_TELEPHONE_OPERATIONAL_MODES 0x08 +#define CDC_USB_TERMINAL 0x09 +#define CDC_NETWORK_CHANNEL 0x0A +#define CDC_PROTOCOL_UNIT 0x0B +#define CDC_EXTENSION_UNIT 0x0C +#define CDC_MULTI_CHANNEL_MANAGEMENT 0x0D +#define CDC_CAPI_CONTROL_MANAGEMENT 0x0E +#define CDC_ETHERNET_NETWORKING 0x0F +#define CDC_ATM_NETWORKING 0x10 + +// CDC class-specific request codes +// (usbcdc11.pdf, 6.2, Table 46) +// see Table 45 for info about the specific requests. +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define CDC_SET_COMM_FEATURE 0x02 +#define CDC_GET_COMM_FEATURE 0x03 +#define CDC_CLEAR_COMM_FEATURE 0x04 +#define CDC_SET_AUX_LINE_STATE 0x10 +#define CDC_SET_HOOK_STATE 0x11 +#define CDC_PULSE_SETUP 0x12 +#define CDC_SEND_PULSE 0x13 +#define CDC_SET_PULSE_TIME 0x14 +#define CDC_RING_AUX_JACK 0x15 +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 +#define CDC_SEND_BREAK 0x23 +#define CDC_SET_RINGER_PARMS 0x30 +#define CDC_GET_RINGER_PARMS 0x31 +#define CDC_SET_OPERATION_PARMS 0x32 +#define CDC_GET_OPERATION_PARMS 0x33 +#define CDC_SET_LINE_PARMS 0x34 +#define CDC_GET_LINE_PARMS 0x35 +#define CDC_DIAL_DIGITS 0x36 +#define CDC_SET_UNIT_PARAMETER 0x37 +#define CDC_GET_UNIT_PARAMETER 0x38 +#define CDC_CLEAR_UNIT_PARAMETER 0x39 +#define CDC_GET_PROFILE 0x3A +#define CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define CDC_SET_ETHERNET_PMP_FILTER 0x41 +#define CDC_GET_ETHERNET_PMP_FILTER 0x42 +#define CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define CDC_GET_ETHERNET_STATISTIC 0x44 +#define CDC_SET_ATM_DATA_FORMAT 0x50 +#define CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define CDC_SET_ATM_DEFAULT_VC 0x52 +#define CDC_GET_ATM_VC_STATISTICS 0x53 + +// Communication feature selector codes +// (usbcdc11.pdf, 6.2.2..6.2.4, Table 47) +#define CDC_ABSTRACT_STATE 0x01 +#define CDC_COUNTRY_SETTING 0x02 + +// Feature Status returned for ABSTRACT_STATE Selector +// (usbcdc11.pdf, 6.2.3, Table 48) +#define CDC_IDLE_SETTING (1 << 0) +#define CDC_DATA_MULTPLEXED_STATE (1 << 1) + + +// Control signal bitmap values for the SetControlLineState request +// (usbcdc11.pdf, 6.2.14, Table 51) +#define CDC_DTE_PRESENT (1 << 0) +#define CDC_ACTIVATE_CARRIER (1 << 1) + +// CDC class-specific notification codes +// (usbcdc11.pdf, 6.3, Table 68) +// see Table 67 for Info about class-specific notifications +#define CDC_NOTIFICATION_NETWORK_CONNECTION 0x00 +#define CDC_RESPONSE_AVAILABLE 0x01 +#define CDC_AUX_JACK_HOOK_STATE 0x08 +#define CDC_RING_DETECT 0x09 +#define CDC_NOTIFICATION_SERIAL_STATE 0x20 +#define CDC_CALL_STATE_CHANGE 0x28 +#define CDC_LINE_STATE_CHANGE 0x29 +#define CDC_CONNECTION_SPEED_CHANGE 0x2A + +// UART state bitmap values (Serial state notification). +// (usbcdc11.pdf, 6.3.5, Table 69) +#define CDC_SERIAL_STATE_OVERRUN (1 << 6) // receive data overrun error has occurred +#define CDC_SERIAL_STATE_PARITY (1 << 5) // parity error has occurred +#define CDC_SERIAL_STATE_FRAMING (1 << 4) // framing error has occurred +#define CDC_SERIAL_STATE_RING (1 << 3) // state of ring signal detection +#define CDC_SERIAL_STATE_BREAK (1 << 2) // state of break detection +#define CDC_SERIAL_STATE_TX_CARRIER (1 << 1) // state of transmission carrier +#define CDC_SERIAL_STATE_RX_CARRIER (1 << 0) // state of receiver carrier + + +/*---------------------------------------------------------------------------- + * Structures based on usbcdc11.pdf (www.usb.org) + *---------------------------------------------------------------------------*/ + +// Header functional descriptor +// (usbcdc11.pdf, 5.2.3.1) +// This header must precede any list of class-specific descriptors. +typedef struct _CDC_HEADER_DESCRIPTOR +{ + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // Header functional descriptor subtype + uint16_t bcdCDC; // USB CDC specification release version +} __attribute__ ((packed)) CDC_HEADER_DESCRIPTOR; + +//Call management functional descriptor +// (usbcdc11.pdf, 5.2.3.2) +// Describes the processing of calls for the communication class interface. +typedef struct _CDC_CALL_MANAGEMENT_DESCRIPTOR +{ + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // call management functional descriptor subtype + uint8_t bmCapabilities; // capabilities that this configuration supports + uint8_t bDataInterface; // interface number of the data class interface used for call management (optional) +} __attribute__ ((packed)) CDC_CALL_MANAGEMENT_DESCRIPTOR; + +// Abstract control management functional descriptor +// (usbcdc11.pdf, 5.2.3.3) +// Describes the command supported by the communication interface class with the Abstract Control Model subclass code. +typedef struct _CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR +{ + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // abstract control management functional descriptor subtype + uint8_t bmCapabilities; // capabilities supported by this configuration +} __attribute__ ((packed)) CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR; + +// Union functional descriptors +// (usbcdc11.pdf, 5.2.3.8) +// Describes the relationship between a group of interfaces that can be considered to form a functional unit. +typedef struct _CDC_UNION_DESCRIPTOR +{ + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // union functional descriptor subtype + uint8_t bMasterInterface; // interface number designated as master +} __attribute__ ((packed)) CDC_UNION_DESCRIPTOR; + +// Union functional descriptors with one slave interface +// (usbcdc11.pdf, 5.2.3.8) +typedef struct _CDC_UNION_1SLAVE_DESCRIPTOR +{ + CDC_UNION_DESCRIPTOR sUnion; // Union functional descriptor + uint8_t bSlaveInterfaces[1]; // Slave interface 0 +} __attribute__ ((packed)) CDC_UNION_1SLAVE_DESCRIPTOR; + +// Line coding structure +// Format of the data returned when a GetLineCoding request is received +// (usbcdc11.pdf, 6.2.13) +typedef struct _CDC_LINE_CODING +{ + uint32_t dwDTERate; // Data terminal rate in bits per second + uint8_t bCharFormat; // Number of stop bits + uint8_t bParityType; // Parity bit type + uint8_t bDataBits; // Number of data bits +} __attribute__ ((packed)) CDC_LINE_CODING; + +// Notification header +// Data sent on the notification endpoint must follow this header. +// see USB_SETUP_PACKET in file usb.h +typedef USB_SETUP_PACKET CDC_NOTIFICATION_HEADER; + +#endif /* __CDC_H */ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusb.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusb.h new file mode 100644 index 0000000..cef6473 --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusb.h @@ -0,0 +1,240 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usb.h + * Purpose: USB Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __CDCUSB_H__ +#define __CDCUSB_H__ + + +typedef union +{ + uint16_t W; + struct + { + uint8_t L; + uint8_t H; + } __attribute__ ((packed)) WB; +} __attribute__ ((packed)) WORD_BYTE; + + +/* bmRequestType.Dir */ +#define REQUEST_HOST_TO_DEVICE 0 +#define REQUEST_DEVICE_TO_HOST 1 + +/* bmRequestType.Type */ +#define REQUEST_STANDARD 0 +#define REQUEST_CLASS 1 +#define REQUEST_VENDOR 2 +#define REQUEST_RESERVED 3 + +/* bmRequestType.Recipient */ +#define REQUEST_TO_DEVICE 0 +#define REQUEST_TO_INTERFACE 1 +#define REQUEST_TO_ENDPOINT 2 +#define REQUEST_TO_OTHER 3 + +/* bmRequestType Definition */ +typedef union _REQUEST_TYPE +{ + struct _BM + { + uint8_t Recipient:5; + uint8_t Type:2; + uint8_t Dir:1; + } __attribute__ ((packed)) BM; + uint8_t B; +} __attribute__ ((packed)) REQUEST_TYPE; + +/* USB Standard Request Codes */ +#define USB_REQUEST_GET_STATUS 0 +#define USB_REQUEST_CLEAR_FEATURE 1 +#define USB_REQUEST_SET_FEATURE 3 +#define USB_REQUEST_SET_ADDRESS 5 +#define USB_REQUEST_GET_DESCRIPTOR 6 +#define USB_REQUEST_SET_DESCRIPTOR 7 +#define USB_REQUEST_GET_CONFIGURATION 8 +#define USB_REQUEST_SET_CONFIGURATION 9 +#define USB_REQUEST_GET_INTERFACE 10 +#define USB_REQUEST_SET_INTERFACE 11 +#define USB_REQUEST_SYNC_FRAME 12 + +/* USB GET_STATUS Bit Values */ +#define USB_GETSTATUS_SELF_POWERED 0x01 +#define USB_GETSTATUS_REMOTE_WAKEUP 0x02 +#define USB_GETSTATUS_ENDPOINT_STALL 0x01 + +/* USB Standard Feature selectors */ +#define USB_FEATURE_ENDPOINT_STALL 0 +#define USB_FEATURE_REMOTE_WAKEUP 1 + +/* USB Default Control Pipe Setup Packet */ +typedef struct _USB_SETUP_PACKET +{ + REQUEST_TYPE bmRequestType; + uint8_t bRequest; + WORD_BYTE wValue; + WORD_BYTE wIndex; + uint16_t wLength; +} __attribute__ ((packed)) USB_SETUP_PACKET; + + +/* USB Descriptor Types */ +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_STRING_DESCRIPTOR_TYPE 3 +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 +#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6 +#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7 +#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8 +#define USB_OTG_DESCRIPTOR_TYPE 9 +#define USB_DEBUG_DESCRIPTOR_TYPE 10 +#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11 + +/* USB Device Classes */ +#define USB_DEVICE_CLASS_RESERVED 0x00 +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +#define USB_DEVICE_CLASS_MONITOR 0x04 +#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 +#define USB_DEVICE_CLASS_POWER 0x06 +#define USB_DEVICE_CLASS_PRINTER 0x07 +#define USB_DEVICE_CLASS_STORAGE 0x08 +#define USB_DEVICE_CLASS_HUB 0x09 +#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF + +/* bmAttributes in Configuration Descriptor */ +#define USB_CONFIG_POWERED_MASK 0x40 +#define USB_CONFIG_BUS_POWERED 0x80 +#define USB_CONFIG_SELF_POWERED 0xC0 +#define USB_CONFIG_REMOTE_WAKEUP 0x20 + +/* bMaxPower in Configuration Descriptor */ +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +/* bEndpointAddress in Endpoint Descriptor */ +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) + +/* bmAttributes in Endpoint Descriptor */ +#define USB_ENDPOINT_TYPE_MASK 0x03 +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_TYPE_BULK 0x02 +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 +#define USB_ENDPOINT_SYNC_MASK 0x0C +#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 +#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 +#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 +#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C +#define USB_ENDPOINT_USAGE_MASK 0x30 +#define USB_ENDPOINT_USAGE_DATA 0x00 +#define USB_ENDPOINT_USAGE_FEEDBACK 0x10 +#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 +#define USB_ENDPOINT_USAGE_RESERVED 0x30 + +/* USB Standard Device Descriptor */ +typedef struct _USB_DEVICE_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__ ((packed)) USB_DEVICE_DESCRIPTOR; + +/* USB 2.0 Device Qualifier Descriptor */ +typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} __attribute__ ((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR; + +/* USB Standard Configuration Descriptor */ +typedef struct _USB_CONFIGURATION_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} __attribute__ ((packed)) USB_CONFIGURATION_DESCRIPTOR; + +/* USB Standard Interface Descriptor */ +typedef struct _USB_INTERFACE_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} __attribute__ ((packed)) USB_INTERFACE_DESCRIPTOR; + +/* USB Standard Endpoint Descriptor */ +typedef struct _USB_ENDPOINT_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __attribute__ ((packed)) USB_ENDPOINT_DESCRIPTOR; + +/* USB String Descriptor */ +typedef struct _USB_STRING_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bString /*[] */ ; +} __attribute__ ((packed)) USB_STRING_DESCRIPTOR; + +/* USB Common Descriptor */ +typedef struct _USB_COMMON_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; +} __attribute__ ((packed)) USB_COMMON_DESCRIPTOR; + + +#endif /* __CDCUSB_H__ */ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusbdesc.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusbdesc.h new file mode 100644 index 0000000..3bb227d --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusbdesc.h @@ -0,0 +1,35 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbdesc.h + * Purpose: USB Descriptors Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __CDCUSBDESC_H__ +#define __CDCUSBDESC_H__ + + +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR)) +#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR)) +#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR)) +#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR)) + +extern const uint8_t USB_DeviceDescriptor[]; +extern const uint8_t USB_ConfigDescriptor[]; +extern const uint8_t USB_StringDescriptor[]; + + +#endif /* __CDCUSBDESC_H__ */ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcuser.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcuser.h new file mode 100644 index 0000000..6887b8b --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcuser.h @@ -0,0 +1,60 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: cdcuser.h + * Purpose: USB Communication Device Class User module Definitions + * Version: V1.10 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __CDCUSER_H__ +#define __CDCUSER_H__ + +/* CDC Data In/Out Endpoint Address */ +#define CDC_DEP_IN 0x83 +#define CDC_DEP_OUT 0x03 + +/* CDC Communication In Endpoint Address */ +#define CDC_CEP_IN 0x81 + +/* CDC Requests Callback Functions */ +extern uint32_t CDC_SendEncapsulatedCommand (void); +extern uint32_t CDC_GetEncapsulatedResponse (void); +extern uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_GetLineCoding (void); +extern uint32_t CDC_SetLineCoding (void); +extern uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap); +extern uint32_t CDC_SendBreak (unsigned short wDurationOfBreak); + +/* CDC Bulk Callback Functions */ +extern void CDC_BulkIn (void); +extern void CDC_BulkOut (void); + +/* FreeRTOS pipe management for CDC ACM */ +#ifdef ENABLE_FREERTOS +extern BOOL CDC_PutChar (uint8_t data); +extern portLONG CDC_Recv (portCHAR *cByte, portLONG size, portTickType xTicksToWait); +extern void CDC_Flush (void); +#endif/*ENABLE_FREERTOS*/ + +/* CDC Notification Callback Function */ +extern void CDC_NotificationIn (void); + +/* CDC Initializtion Function */ +extern void CDC_Init (void); + +/* CDC prepare the SERAIAL_STATE */ +extern unsigned short CDC_GetSerialState (void); + +#endif /* __CDCUSER_H__ */ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/usbcore.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbcore.h new file mode 100644 index 0000000..9549b30 --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbcore.h @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcore.h + * Purpose: USB Core Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBCORE_H__ +#define __USBCORE_H__ + + +/* USB Endpoint Data Structure */ +typedef struct _USB_EP_DATA +{ + uint8_t *pData; + uint16_t Count; +} USB_EP_DATA; + +/* USB Core Global Variables */ +extern uint16_t USB_DeviceStatus; +extern uint8_t USB_DeviceAddress; +extern uint8_t USB_Configuration; +extern uint32_t USB_EndPointMask; +extern uint32_t USB_EndPointHalt; +extern uint32_t USB_EndPointStall; +extern uint8_t USB_AltSetting[USB_IF_NUM]; + +/* USB Endpoint 0 Buffer */ +extern uint8_t EP0Buf[USB_MAX_PACKET0]; + +/* USB Endpoint 0 Data Info */ +extern USB_EP_DATA EP0Data; + +/* USB Setup Packet */ +extern USB_SETUP_PACKET SetupPacket; + +/* USB Core Functions */ +extern void USB_ResetCore (void); + +/* Newer C compilers make it really difficult to add + * an integer to a pointer */ +__inline void UsbAddPtr (void **vpptr, uint32_t n); + + + +#endif /* __USBCORE_H__ */ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/usbhw.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbhw.h new file mode 100644 index 0000000..e379aa7 --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbhw.h @@ -0,0 +1,95 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbhw.h + * Purpose: USB Hardware Layer Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added USB_ClearEPBuf + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ + +#ifndef __USBHW_H__ +#define __USBHW_H__ + + +/* USB Error Codes */ +#define USB_ERR_PID 0x0001 /* PID Error */ +#define USB_ERR_UEPKT 0x0002 /* Unexpected Packet */ +#define USB_ERR_DCRC 0x0004 /* Data CRC Error */ +#define USB_ERR_TIMOUT 0x0008 /* Bus Time-out Error */ +#define USB_ERR_EOP 0x0010 /* End of Packet Error */ +#define USB_ERR_B_OVRN 0x0020 /* Buffer Overrun */ +#define USB_ERR_BTSTF 0x0040 /* Bit Stuff Error */ +#define USB_ERR_TGL 0x0080 /* Toggle Bit Error */ + +/* USB Hardware Functions */ +extern void USBIOClkConfig (void); +extern void USB_Init (void); +extern void USB_Connect (uint32_t con); +extern void USB_Reset (void); +extern void USB_Suspend (void); +extern void USB_Resume (void); +extern void USB_WakeUp (void); +extern void USB_WakeUpCfg (uint32_t cfg); +extern void USB_SetAddress (uint32_t adr); +extern void USB_Configure (uint32_t cfg); +extern void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD); +extern void USB_DirCtrlEP (uint32_t dir); +extern void USB_EnableEP (uint32_t EPNum); +extern void USB_DisableEP (uint32_t EPNum); +extern void USB_ResetEP (uint32_t EPNum); +extern void USB_SetStallEP (uint32_t EPNum); +extern void USB_ClrStallEP (uint32_t EPNum); +extern void USB_ClearEPBuf (uint32_t EPNum); +extern uint32_t USB_ReadEP (uint32_t EPNum, uint8_t * pData); +extern void USB_ReadEP_Terminate (uint32_t EPNum); +extern uint32_t USB_ReadEP_Count (uint32_t EPNum); +extern uint32_t USB_WriteEP (uint32_t EPNum, uint8_t * pData, uint32_t cnt); +extern void USB_WriteEP_Terminate (uint32_t EPNum); +extern void USB_WriteEP_Count (uint32_t EPNum, uint32_t cnt); +extern uint32_t USB_GetFrame (void); +extern void USB_IRQHandler (void); + +/* + * Read USB Endpoint Data + * Parameters: none + * Return Value: current block data + * + * Use USB_ReadEPCount to switch Endpoint and get block count + * + */ + +static inline uint32_t +USB_ReadEP_Block (void) +{ + return LPC_USB->RxData; +} + +/* + * Write USB Endpoint Data + * Parameters: data: transmit block data + * Return Value: none + * + * Use USB_ReadEPCount to switch Endpoint and get block count + * + */ + +static inline void +USB_WriteEP_Block (uint32_t data) +{ + LPC_USB->TxData = data; +} + +#endif /* __USBHW_H__ */ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/usbreg.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbreg.h new file mode 100644 index 0000000..f2d1000 --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbreg.h @@ -0,0 +1,134 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: USBREG.H + * Purpose: USB Hardware Layer Definitions for NXP LPC13xx + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBREG_H +#define __USBREG_H + +/* Device Interrupt Bit Definitions */ +#define FRAME_INT (0x1<<0) +#define EP0_INT (0x1<<1) +#define EP1_INT (0x1<<2) +#define EP2_INT (0x1<<3) +#define EP3_INT (0x1<<4) +#define EP4_INT (0x1<<5) +#define EP5_INT (0x1<<6) +#define EP6_INT (0x1<<7) +#define EP7_INT (0x1<<8) +#define DEV_STAT_INT (0x1<<9) +#define CCEMTY_INT (0x1<<10) +#define CDFULL_INT (0x1<<11) +#define RxENDPKT_INT (0x1<<12) +#define TxENDPKT_INT (0x1<<13) + +/* Rx & Tx Packet Length Definitions */ +#define PKT_LNGTH_MASK 0x000003FF +#define PKT_DV 0x00000400 +#define PKT_RDY 0x00000800 + +/* USB Control Definitions */ +#define CTRL_RD_EN 0x00000001 +#define CTRL_WR_EN 0x00000002 + +/* Command Codes */ +#define CMD_SET_ADDR 0x00D00500 +#define CMD_CFG_DEV 0x00D80500 +#define CMD_SET_MODE 0x00F30500 +#define CMD_RD_INT 0x00F40500 +#define DAT_RD_INT 0x00F40200 +#define CMD_RD_FRAME 0x00F50500 +#define DAT_RD_FRAME 0x00F50200 +#define CMD_RD_CHIP_ID 0x00FD0500 +#define DAT_RD_CHIP_ID 0x00FD0200 + +#define CMD_SET_DEV_STAT 0x00FE0500 +#define CMD_GET_DEV_STAT 0x00FE0500 +#define DAT_GET_DEV_STAT 0x00FE0200 +#define CMD_GET_ERR_CODE 0x00FF0500 +#define DAT_GET_ERR_CODE 0x00FF0200 + +#define DAT_WR_BYTE(x) (0x00000100 | ((x) << 16)) +#define CMD_SEL_EP(x) (0x00000500 | ((x) << 16)) +#define DAT_SEL_EP(x) (0x00000200 | ((x) << 16)) +#define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16)) +#define DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16)) +#define CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16)) +#define CMD_CLR_BUF 0x00F20500 +#define CMD_VALID_BUF 0x00FA0500 + +/* Device Address Register Definitions */ +#define DEV_ADDR_MASK 0x7F +#define DEV_EN 0x80 + +/* Device Configure Register Definitions */ +#define CONF_DVICE 0x01 + +/* Device Mode Register Definitions */ +#define AP_CLK 0x01 +#define INAK_CI 0x02 +#define INAK_CO 0x04 +#define INAK_AI 0x08 +#define INAK_AO 0x10 + +/* Device Status Register Definitions */ +#define DEV_CON 0x01 +#define DEV_CON_CH 0x02 +#define DEV_SUS 0x04 +#define DEV_SUS_CH 0x08 +#define DEV_RST 0x10 + +/* Error Code Register Definitions */ +#define ERR_EC_MASK 0x0F +#define ERR_EA 0x10 + +/* Error Status Register Definitions */ +#define ERR_NOERROR 0x00 +#define ERR_PID_ENCODE 0x01 +#define ERR_UNKNOWN_PID 0x02 +#define ERR_UNEXPECT_PKT 0x03 +#define ERR_TCRC 0x04 +#define ERR_DCRC 0x05 +#define ERR_TIMEOUT 0x06 +#define ERR_BABBIE 0x07 +#define ERR_EOF_PKT 0x08 +#define ERR_TX_RX_NAK 0x09 +#define ERR_SENT_STALL 0x0A +#define ERR_BUF_OVERRUN 0x0B +#define ERR_SENT_EPT_PKT 0x0C +#define ERR_BIT_STUFF 0x0D +#define ERR_SYNC 0x0E +#define ERR_TOGGLE_BIT 0x0F + +/* Endpoint Select Register Definitions */ +#define EP_SEL_F 0x01 +#define EP_SEL_ST 0x02 +#define EP_SEL_STP 0x04 +#define EP_SEL_PO 0x08 +#define EP_SEL_EPN 0x10 +#define EP_SEL_B_1_FULL 0x20 +#define EP_SEL_B_2_FULL 0x40 + +/* Endpoint Status Register Definitions */ +#define EP_STAT_ST 0x01 +#define EP_STAT_DA 0x20 +#define EP_STAT_RF_MO 0x40 +#define EP_STAT_CND_ST 0x80 + +/* Clear Buffer Register Definitions */ +#define CLR_BUF_PO 0x01 + +#endif /* __USBREG_H */ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/usbuser.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbuser.h new file mode 100644 index 0000000..03a429e --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbuser.h @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: USBUSER.H + * Purpose: USB Custom User Definitions + * Version: V1.10 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2005-2009 Keil Software. + *---------------------------------------------------------------------------*/ + +#ifndef __USBUSER_H__ +#define __USBUSER_H__ + + +/* USB Device Events Callback Functions */ +extern void USB_Power_Event (uint32_t power); +extern void USB_Reset_Event (void); +extern void USB_Suspend_Event (void); +extern void USB_Resume_Event (void); +extern void USB_WakeUp_Event (void); +extern void USB_SOF_Event (void); +extern void USB_Error_Event (uint32_t error); + +/* USB Endpoint Callback Events */ +#define USB_EVT_SETUP 1 /* Setup Packet */ +#define USB_EVT_OUT 2 /* OUT Packet */ +#define USB_EVT_IN 3 /* IN Packet */ +#define USB_EVT_OUT_NAK 4 /* OUT Packet - Not Acknowledged */ +#define USB_EVT_IN_NAK 5 /* IN Packet - Not Acknowledged */ +#define USB_EVT_OUT_STALL 6 /* OUT Packet - Stalled */ +#define USB_EVT_IN_STALL 7 /* IN Packet - Stalled */ + +/* USB Endpoint Events Callback Pointers */ +extern void (*const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event); + +/* USB Endpoint Events Callback Functions */ +extern void USB_EndPoint0 (uint32_t event); +extern void USB_EndPoint1 (uint32_t event); +extern void USB_EndPoint2 (uint32_t event); +extern void USB_EndPoint3 (uint32_t event); +extern void USB_EndPoint4 (uint32_t event); + +/* USB Core Events Callback Functions */ +extern void USB_Configure_Event (void); +extern void USB_Interface_Event (void); +extern void USB_Feature_Event (void); + + +#endif /* __USBUSER_H__ */ diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usbdesc.h b/openbeacon/lpc13xx/core/peripherals/inc/usbdesc.h new file mode 100644 index 0000000..64a19ba --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/inc/usbdesc.h @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbdesc.h + * Purpose: USB Descriptors Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBDESC_H__ +#define __USBDESC_H__ + + +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR)) +#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR)) +#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR)) +#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR)) + +#define HID_DESC_OFFSET 0x0012 +#define HID_DESC_SIZE (sizeof(HID_DESCRIPTOR)) +#define HID_REPORT_DESC_SIZE (sizeof(HID_ReportDescriptor)) + +extern const uint8_t USB_DeviceDescriptor[]; +extern const uint8_t USB_ConfigDescriptor[]; +extern const uint8_t USB_StringDescriptor[]; + +extern const uint8_t HID_ReportDescriptor[]; +extern const uint16_t HID_ReportDescSize; + + +#endif /* __USBDESC_H__ */ diff --git a/openbeacon/lpc13xx/core/peripherals/src/gpio.c b/openbeacon/lpc13xx/core/peripherals/src/gpio.c new file mode 100644 index 0000000..e442207 --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/src/gpio.c @@ -0,0 +1,42 @@ +/***************************************************************************** + * gpio.c: GPIO C file for NXP LPC13xx Family Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2008.07.20 ver 1.00 Preliminary version, first Release + * 2009.12.09 ver 1.05 Mod to use mask registers for GPIO writes + inlining (.h) + * +*****************************************************************************/ +#include "LPC13xx.h" /* LPC13xx Peripheral Registers */ +#include "gpio.h" + +LPC_GPIO_TypeDef (*const LPC_GPIO[4]) = { + LPC_GPIO0, + LPC_GPIO1, + LPC_GPIO2, + LPC_GPIO3 +}; + +/***************************************************************************** +** Function name: GPIOInit +** +** Descriptions: Initialize GPIO, install the +** GPIO interrupt handler +** +** parameters: None +** Returned value: true or false, return false if the VIC table +** is full and GPIO interrupt handler can be +** installed. +** +*****************************************************************************/ +void GPIOInit(void) +{ + /* Enable AHB clock to the GPIO domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6); +} + +/****************************************************************************** +** End Of File +******************************************************************************/ diff --git a/openbeacon/lpc13xx/core/peripherals/src/uart.c b/openbeacon/lpc13xx/core/peripherals/src/uart.c new file mode 100644 index 0000000..6b7e34b --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/src/uart.c @@ -0,0 +1,190 @@ +/***************************************************************************** + * uart.c: UART API file for NXP LPC13xx Family Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2008.08.21 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ +#include +#ifndef UART_DISABLE +#include "uart.h" + +/* CodeRed - change for CMSIS 1.3 */ +#define SystemFrequency SystemCoreClock + +volatile uint32_t UARTStatus; +volatile uint8_t UARTTxEmpty = 1; +volatile uint8_t UARTBuffer[BUFSIZE]; +volatile uint32_t UARTCount = 0; + +/* allow to override default putchar output from serial to something else */ +BOOL default_putchar (uint8_t data) ALIAS(UARTSendChar); + +/***************************************************************************** +** Function name: UART_IRQHandler +** +** Descriptions: UART interrupt handler +** +** parameters: None +** Returned value: None +** +*****************************************************************************/ +void UART_IRQHandler(void) +{ + uint8_t IIRValue, LSRValue; + uint8_t Dummy = Dummy; + + IIRValue = LPC_UART->IIR; + + IIRValue >>= 1; /* skip pending bit in IIR */ + IIRValue &= 0x07; /* check bit 1~3, interrupt identification */ + if (IIRValue == IIR_RLS) { /* Receive Line Status */ + LSRValue = LPC_UART->LSR; + /* Receive Line Status */ + if (LSRValue & (LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI)) { + /* There are errors or break interrupt */ + /* Read LSR will clear the interrupt */ + UARTStatus = LSRValue; + Dummy = LPC_UART->RBR; /* Dummy read on RX to clear + interrupt, then bail out */ + return; + } + if (LSRValue & LSR_RDR) { /* Receive Data Ready */ + /* If no error on RLS, normal ready, save into the data buffer. */ + /* Note: read RBR will clear the interrupt */ + UARTBuffer[UARTCount++] = LPC_UART->RBR; + if (UARTCount == BUFSIZE) { + UARTCount = 0; /* buffer overflow */ + } + } + } else if (IIRValue == IIR_RDA) { /* Receive Data Available */ + /* Receive Data Available */ + UARTBuffer[UARTCount++] = LPC_UART->RBR; + if (UARTCount == BUFSIZE) { + UARTCount = 0; /* buffer overflow */ + } + } else if (IIRValue == IIR_CTI) { /* Character timeout indicator */ + /* Character Time-out indicator */ + UARTStatus |= 0x100; /* Bit 9 as the CTI error */ + } else if (IIRValue == IIR_THRE) { /* THRE, transmit holding register empty */ + /* THRE interrupt */ + LSRValue = LPC_UART->LSR; /* Check status in the LSR to see if + valid data in U0THR or not */ + if (LSRValue & LSR_THRE) { + UARTTxEmpty = 1; + } else { + UARTTxEmpty = 0; + } + } + return; +} + +/***************************************************************************** +** Function name: UARTInit +** +** Descriptions: Initialize UART0 port, setup pin select, +** clock, parity, stop bits, FIFO, etc. +** +** parameters: UART baudrate +** Returned value: None +** +*****************************************************************************/ +void UARTInit(uint32_t baudrate, uint8_t rtscts) +{ + uint32_t Fdiv; + uint32_t regVal; + + UARTTxEmpty = 1; + UARTCount = 0; + + NVIC_DisableIRQ(UART_IRQn); + + /* IO configuration */ + if(rtscts) + { + LPC_IOCON->PIO0_7=0x01; /* UART CTS */ + LPC_IOCON->PIO1_5=0x01; /* UART RTS */ + } + LPC_IOCON->PIO1_6=0x01; /* UART RXD */ + LPC_IOCON->PIO1_7=0x01; /* UART TXD */ + + /* Enable UART clock */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12); + LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */ + + LPC_UART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ + regVal = LPC_SYSCON->UARTCLKDIV; + Fdiv = (((SystemFrequency / LPC_SYSCON->SYSAHBCLKDIV) / regVal) / 16) / baudrate; /*baud rate */ + + LPC_UART->DLM = Fdiv / 256; + LPC_UART->DLL = Fdiv % 256; + LPC_UART->LCR = 0x03; /* DLAB = 0 */ + LPC_UART->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ + + /* Read to clear the line status. */ + regVal = LPC_UART->LSR; + + /* Ensure a clean start, no data in either TX or RX FIFO. */ + // CodeRed - added parentheses around comparison in operand of & + while ((LPC_UART->LSR & (LSR_THRE | LSR_TEMT)) != + (LSR_THRE | LSR_TEMT)); + while (LPC_UART->LSR & LSR_RDR) { + regVal = LPC_UART->RBR; /* Dump data from RX FIFO */ + } + + /* Enable the UART Interrupt */ + NVIC_EnableIRQ(UART_IRQn); + +#if TX_INTERRUPT + LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART interrupt */ +#else + LPC_UART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */ +#endif + return; +} + +BOOL UARTSendChar(uint8_t data) +{ + while (!(LPC_UART->LSR & LSR_THRE)); + LPC_UART->THR = data; + + return TRUE; +} + +/***************************************************************************** +** Function name: UARTSend +** +** Descriptions: Send a block of data to the UART 0 port based +** on the data length +** +** parameters: buffer pointer, and data length +** Returned value: None +** +*****************************************************************************/ +void UARTSend(const uint8_t * BufferPtr, uint32_t Length) +{ + + while (Length != 0) { + /* THRE status, contain valid data */ +#if !TX_INTERRUPT + while (!(LPC_UART->LSR & LSR_THRE)); + LPC_UART->THR = *BufferPtr; +#else + /* Below flag is set inside the interrupt handler when THRE occurs. */ + while (!(UARTTxEmpty & 0x01)); + LPC_UART->THR = *BufferPtr; + UARTTxEmpty = 0; /* not empty in the THR until it shifts out */ +#endif + BufferPtr++; + Length--; + } + return; +} + +/****************************************************************************** +** End Of File +******************************************************************************/ +#endif /* UART_DISABLE */ diff --git a/openbeacon/lpc13xx/core/peripherals/src/usb/cdcusbdesc.c b/openbeacon/lpc13xx/core/peripherals/src/usb/cdcusbdesc.c new file mode 100644 index 0000000..022a6ae --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/src/usb/cdcusbdesc.c @@ -0,0 +1,204 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbdesc.c + * Purpose: USB Descriptors + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Changed string descriptor handling + * V1.00 Initial Version + *---------------------------------------------------------------------------*/ +#include +#ifdef ENALBLE_USB_FULLFEATURED + +#include "cdcusb.h" +#include "cdc.h" +#include "usbcfg.h" +#include "cdcusbdesc.h" + + +/* USB Standard Device Descriptor */ +const uint8_t USB_DeviceDescriptor[] = { + USB_DEVICE_DESC_SIZE, /* bLength */ + USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL (0x0200), /* 2.0 *//* bcdUSB */ + USB_DEVICE_CLASS_COMMUNICATIONS, /* bDeviceClass CDC */ + 0x00, /* bDeviceSubClass */ + 0x00, /* bDeviceProtocol */ + USB_MAX_PACKET0, /* bMaxPacketSize0 */ + WBVAL (USB_VENDOR_ID), /* idVendor */ + WBVAL (USB_PROD_ID), /* idProduct */ + WBVAL (USB_DEVICE), /* 1.00 *//* bcdDevice */ + 0x01, /* iManufacturer */ + 0x02, /* iProduct */ + 0x03, /* iSerialNumber */ + 0x01 /* bNumConfigurations: one possible configuration */ +}; + +/* USB Configuration Descriptor */ +/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ +const uint8_t USB_ConfigDescriptor[] = { +/* Configuration 1 */ + USB_CONFIGUARTION_DESC_SIZE, /* bLength */ + USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL ( /* wTotalLength */ + 1 * USB_CONFIGUARTION_DESC_SIZE + 1 * USB_INTERFACE_DESC_SIZE + /* communication interface */ + 0x0013 + /* CDC functions */ + 1 * USB_ENDPOINT_DESC_SIZE + /* interrupt endpoint */ + 1 * USB_INTERFACE_DESC_SIZE + /* data interface */ + 2 * USB_ENDPOINT_DESC_SIZE /* bulk endpoints */ + ), + 0x02, /* bNumInterfaces */ + 0x01, /* bConfigurationValue: 0x01 is used to select this configuration */ + 0x00, /* iConfiguration: no string to describe this configuration */ + USB_CONFIG_BUS_POWERED /*| *//* bmAttributes */ +/*USB_CONFIG_REMOTE_WAKEUP*/ , + USB_CONFIG_POWER_MA (100), /* bMaxPower, device power consumption is 100 mA */ +/* Interface 0, Alternate Setting 0, Communication class interface descriptor */ + USB_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_CDC_CIF_NUM, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoint used */ + CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass: Communication Interface Class */ + CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass: Abstract Control Model */ + 0x00, /* bInterfaceProtocol: no protocol used */ + 0x5E, /* iInterface: */ +/*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_HEADER, /* bDescriptorSubtype: Header Func Desc */ + WBVAL (CDC_V1_10), /* 1.10 *//* bcdCDC */ +/*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_CALL_MANAGEMENT, /* bDescriptorSubtype: Call Management Func Desc */ + 0x01, /* bmCapabilities: device handles call management */ + 0x01, /* bDataInterface: CDC data IF ID */ +/*Abstract Control Management Functional Descriptor*/ + 0x04, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */ +/*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_UNION, /* bDescriptorSubtype: Union func desc */ + USB_CDC_CIF_NUM, /* bMasterInterface: Communication class interface is master */ + USB_CDC_DIF_NUM, /* bSlaveInterface0: Data class interface is slave 0 */ + /*Endpoint 1 Descriptor*//* event notification (optional) */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_IN (1), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ + WBVAL (0x0010), /* wMaxPacketSize */ + 0x02, /* 2ms *//* bInterval */ +/* Interface 1, Alternate Setting 0, Data class interface descriptor*/ + USB_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_CDC_DIF_NUM, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: no alternate setting */ + 0x02, /* bNumEndpoints: two endpoints used */ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass: Data Interface Class */ + 0x00, /* bInterfaceSubClass: no subclass available */ + 0x00, /* bInterfaceProtocol: no protocol used */ + 0x5E, /* iInterface: */ +/* Endpoint, EP3 Bulk Out */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_OUT (3), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ + WBVAL (USB_CDC_BUFSIZE), /* wMaxPacketSize */ + 0x00, /* bInterval: ignore for Bulk transfer */ +/* Endpoint, EP3 Bulk In */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_IN (3), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ + WBVAL (USB_CDC_BUFSIZE), /* wMaxPacketSize */ + 0x00, /* bInterval: ignore for Bulk transfer */ +/* Terminator */ + 0 /* bLength */ +}; + + + + +/* USB String Descriptor (optional) */ +const uint8_t USB_StringDescriptor[] = { +/* Index 0x00: LANGID Codes */ + 0x04, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL (0x0409), /* US English *//* wLANGID */ +/* Index 0x01: Manufacturer */ + (13 * 2 + 2), /* bLength (13 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'B', 0, + 'i', 0, + 't', 0, + 'm', 0, + 'a', 0, + 'n', 0, + 'u', 0, + 'f', 0, + 'a', 0, + 'k', 0, + 't', 0, + 'u', 0, + 'r', 0, +/* Index 0x02: Product */ + (17 * 2 + 2), /* bLength ( 17 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'O', 0, + 'p', 0, + 'e', 0, + 'n', 0, + 'B', 0, + 'e', 0, + 'a', 0, + 'c', 0, + 'o', 0, + 'n', 0, + ' ', 0, + 'C', 0, + 'D', 0, + 'C', 0, + 'A', 0, + 'C', 0, + 'M', 0, +/* Index 0x03: Serial Number */ + (12 * 2 + 2), /* bLength (12 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + '0', 0, + '0', 0, + '0', 0, + '0', 0, + '0', 0, + '0', 0, + '0', 0, + '0', 0, + '0', 0, + '0', 0, + '0', 0, + '0', 0, +/* Index 0x04: Interface 0, Alternate Setting 0 */ + (4 * 2 + 2), /* bLength (4 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'V', 0, + 'C', 0, + 'O', 0, + 'M', 0, +}; + +#endif/*ENALBLE_USB_FULLFEATURED*/ diff --git a/openbeacon/lpc13xx/core/peripherals/src/usb/cdcuser.c b/openbeacon/lpc13xx/core/peripherals/src/usb/cdcuser.c new file mode 100644 index 0000000..29deb4f --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/src/usb/cdcuser.c @@ -0,0 +1,372 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: cdcuser.c + * Purpose: USB Communication Device Class User module + * Version: V1.10 + *---------------------------------------------------------------------------- +* This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#include +#ifdef ENALBLE_USB_FULLFEATURED + +#include "cdcusb.h" +#include "usbhw.h" +#include "usbcfg.h" +#include "usbcore.h" +#include "cdc.h" +#include "cdcuser.h" + +static CDC_LINE_CODING CDC_LineCoding = { 115200, 0, 0, 8 }; + +static unsigned short CDC_SerialState = 0x0000; +static BOOL CDC_DepInEmpty; // Data IN EP is empty + +#ifdef ENABLE_FREERTOS +static xQueueHandle g_QueueRxUSB = NULL; +static xQueueHandle g_QueueTxUSB = NULL; +#endif/*ENABLE_FREERTOS*/ + +/*---------------------------------------------------------------------------- + CDC Initialisation + Initializes the data structures and serial port + Parameters: None + Return Value: None + *---------------------------------------------------------------------------*/ +void +CDC_Init (void) +{ + USBIOClkConfig(); + + CDC_DepInEmpty = TRUE; + CDC_SerialState = CDC_GetSerialState (); + +#ifdef ENABLE_FREERTOS + /* Create the queues used to hold Rx and Tx characters. */ + g_QueueRxUSB = xQueueCreate (USB_CDC_BUFSIZE*2, sizeof (uint8_t)); + g_QueueTxUSB = xQueueCreate (USB_CDC_BUFSIZE*2, sizeof (uint8_t)); +#endif/*ENABLE_FREERTOS*/ +} + + +/*---------------------------------------------------------------------------- + CDC SendEncapsulatedCommand Request Callback + Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_SendEncapsulatedCommand (void) +{ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetEncapsulatedResponse Request Callback + Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_GetEncapsulatedResponse (void) +{ + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetCommFeature Request Callback + Called automatically on CDC Set_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_SetCommFeature (unsigned short wFeatureSelector) +{ + (void) wFeatureSelector; + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetCommFeature Request Callback + Called automatically on CDC Get_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_GetCommFeature (unsigned short wFeatureSelector) +{ + (void) wFeatureSelector; + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC ClearCommFeature Request Callback + Called automatically on CDC CLEAR_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_ClearCommFeature (unsigned short wFeatureSelector) +{ + (void) wFeatureSelector; + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetLineCoding Request Callback + Called automatically on CDC SET_LINE_CODING Request + Parameters: none (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_SetLineCoding (void) +{ + CDC_LineCoding.dwDTERate = (EP0Buf[0] << 0) + | (EP0Buf[1] << 8) | (EP0Buf[2] << 16) | (EP0Buf[3] << 24); + CDC_LineCoding.bCharFormat = EP0Buf[4]; + CDC_LineCoding.bParityType = EP0Buf[5]; + CDC_LineCoding.bDataBits = EP0Buf[6]; + + /* configure serial port hardware settings if needed */ + + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetLineCoding Request Callback + Called automatically on CDC GET_LINE_CODING Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_GetLineCoding (void) +{ + EP0Buf[0] = (CDC_LineCoding.dwDTERate >> 0) & 0xFF; + EP0Buf[1] = (CDC_LineCoding.dwDTERate >> 8) & 0xFF; + EP0Buf[2] = (CDC_LineCoding.dwDTERate >> 16) & 0xFF; + EP0Buf[3] = (CDC_LineCoding.dwDTERate >> 24) & 0xFF; + EP0Buf[4] = CDC_LineCoding.bCharFormat; + EP0Buf[5] = CDC_LineCoding.bParityType; + EP0Buf[6] = CDC_LineCoding.bDataBits; + + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetControlLineState Request Callback + Called automatically on CDC SET_CONTROL_LINE_STATE Request + Parameters: ControlSignalBitmap + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_SetControlLineState (unsigned short wControlSignalBitmap) +{ + (void) wControlSignalBitmap; + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SendBreak Request Callback + Called automatically on CDC Set_COMM_FATURE Request + Parameters: 0xFFFF start of Break + 0x0000 stop of Break + 0x#### Duration of Break + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_SendBreak (unsigned short wDurationOfBreak) +{ + (void) wDurationOfBreak; + /* ... add code to handle request */ + return (TRUE); +} + + +#ifdef ENABLE_FREERTOS +/*---------------------------------------------------------------------------- + CDC_BulkIn_Handler call on DataIn Request + Parameters: from_isr - set true if called from ISR + Return Value: none + *---------------------------------------------------------------------------*/ +static void +CDC_BulkIn_Handler(BOOL from_isr) +{ + uint8_t* p; + uint32_t data, bs; + int count; + portBASE_TYPE xTaskWoken = pdFALSE; + + if(!from_isr) + vPortEnterCritical (); + + count = uxQueueMessagesWaitingFromISR(g_QueueTxUSB); + if(count>USB_CDC_BUFSIZE) + count = USB_CDC_BUFSIZE; + + if(!count) + CDC_DepInEmpty = 1; + else + { + USB_WriteEP_Count (CDC_DEP_IN, count); + while(count>0) + { + if(count>(int)sizeof(data)) + { + bs = sizeof(data); + count -= sizeof(data); + } + else + { + bs = count; + data = count = 0; + } + p = (uint8_t*) &data; + while(bs--) + xQueueReceiveFromISR (g_QueueTxUSB,p++, &xTaskWoken); + + USB_WriteEP_Block (data); + + } + USB_WriteEP_Terminate (CDC_DEP_IN); + + if(from_isr && xTaskWoken) + taskYIELD (); + } + + if(!from_isr) + vPortExitCritical (); +} + +/*---------------------------------------------------------------------------- + CDC_BulkIn call on DataIn Request + Parameters: none + Return Value: none + *---------------------------------------------------------------------------*/ +void +CDC_BulkIn(void) +{ + CDC_BulkIn_Handler(TRUE); +} + +void +CDC_Flush (void) +{ + if(CDC_DepInEmpty) + CDC_BulkIn_Handler (FALSE); +} + +BOOL +CDC_PutChar(uint8_t cByte) +{ + BOOL res; + + res = xQueueSend (g_QueueTxUSB, &cByte, 0) ? TRUE : FALSE; + + if(cByte == '\n') + CDC_Flush (); + + return res; +} + +/*---------------------------------------------------------------------------- + CDC_BulkOut call on DataOut Request + Parameters: none + Return Value: none + *---------------------------------------------------------------------------*/ +void CDC_BulkOut(void) +{ + int count, bs; + uint32_t data; + uint8_t* p; + portBASE_TYPE xTaskWoken = pdFALSE; + + count = USB_ReadEP_Count(CDC_DEP_OUT); + + while (count > 0) + { + data = USB_ReadEP_Block(); + bs = count > (int)sizeof(data) ? (int)sizeof(data) : count; + count -= bs; + p = (uint8_t*) &data; + while (bs--) + xQueueSendFromISR (g_QueueRxUSB,p++, &xTaskWoken); + } + USB_ReadEP_Terminate(CDC_DEP_OUT); + + if(xTaskWoken) + taskYIELD (); +} + +portLONG CDC_Recv (portCHAR *cByte, portLONG size, portTickType xTicksToWait) +{ + portLONG res; + + if (size <= 0 || !cByte || !g_QueueRxUSB) + return 0; + + res = 0; + while (size-- && xQueueReceive(g_QueueRxUSB, cByte++, xTicksToWait)) + res++; + + return res; +} +#endif/*ENABLE_FREERTOS*/ + + +/*---------------------------------------------------------------------------- + Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69. + Parameters: none + Return Value: SerialState as defined in usbcdc11.pdf + *---------------------------------------------------------------------------*/ +unsigned short +CDC_GetSerialState (void) +{ + return CDC_SerialState; +} + + +/*---------------------------------------------------------------------------- + Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5. + *---------------------------------------------------------------------------*/ +void +CDC_NotificationIn (void) +{ + uint8_t NotificationBuf[10]; + + NotificationBuf[0] = 0xA1; // bmRequestType + NotificationBuf[1] = CDC_NOTIFICATION_SERIAL_STATE; // bNotification (SERIAL_STATE) + NotificationBuf[2] = 0x00; // wValue + NotificationBuf[3] = 0x00; + NotificationBuf[4] = 0x00; // wIndex (Interface #, LSB first) + NotificationBuf[5] = 0x00; + NotificationBuf[6] = 0x02; // wLength (Data length = 2 bytes, LSB first) + NotificationBuf[7] = 0x00; + NotificationBuf[8] = (CDC_SerialState >> 0) & 0xFF; // UART State Bitmap (16bits, LSB first) + NotificationBuf[9] = (CDC_SerialState >> 8) & 0xFF; + + USB_WriteEP (CDC_CEP_IN, &NotificationBuf[0], 10); // send notification +} + +#endif /*ENALBLE_USB_FULLFEATURED*/ diff --git a/openbeacon/lpc13xx/core/peripherals/src/usb/usbcore.c b/openbeacon/lpc13xx/core/peripherals/src/usb/usbcore.c new file mode 100644 index 0000000..73b8d49 --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/src/usb/usbcore.c @@ -0,0 +1,1291 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcore.c + * Purpose: USB Core Module + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added vendor specific requests + * Changed string descriptor handling + * Reworked Endpoint0 + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ +#include +#ifdef ENALBLE_USB_FULLFEATURED + +#include "cdcusb.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "cdcusbdesc.h" +#include "usbuser.h" + +#if (USB_CLASS) + +#if (USB_AUDIO) +#include "audio.h" +#include "adcuser.h" +#endif + +#if (USB_HID) +#include "hid.h" +#include "hiduser.h" +#endif + +#if (USB_MSC) +#include "msc.h" +#include "mscuser.h" +extern MSC_CSW CSW; +#endif + +#if (USB_CDC) +#include "cdc.h" +#include "cdcuser.h" +#endif + +#endif + +#if (USB_VENDOR) +#include "vendor.h" +#endif + +uint16_t USB_DeviceStatus; +uint8_t USB_DeviceAddress; +uint8_t USB_Configuration; +uint32_t USB_EndPointMask; +uint32_t USB_EndPointHalt; +uint32_t USB_EndPointStall; /* EP must stay stalled */ +uint8_t USB_NumInterfaces; +uint8_t USB_AltSetting[USB_IF_NUM]; + +uint8_t EP0Buf[USB_MAX_PACKET0]; + + +USB_EP_DATA EP0Data; + +USB_SETUP_PACKET SetupPacket; + + +/* + * Reset USB Core + * Parameters: None + * Return Value: None + */ + +void +USB_ResetCore (void) +{ + + USB_DeviceStatus = USB_POWER; + USB_DeviceAddress = 0; + USB_Configuration = 0; + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; +} + + +/* + * USB Request - Setup Stage + * Parameters: None (global SetupPacket) + * Return Value: None + */ + +void +USB_SetupStage (void) +{ + USB_ReadEP (0x00, (uint8_t *) & SetupPacket); +} + + +/* + * USB Request - Data In Stage + * Parameters: None (global EP0Data) + * Return Value: None + */ + +void +USB_DataInStage (void) +{ + uint32_t cnt; + + if (EP0Data.Count > USB_MAX_PACKET0) + { + cnt = USB_MAX_PACKET0; + } + else + { + cnt = EP0Data.Count; + } + cnt = USB_WriteEP (0x80, EP0Data.pData, cnt); + EP0Data.pData += cnt; + EP0Data.Count -= cnt; +} + + +/* + * USB Request - Data Out Stage + * Parameters: None (global EP0Data) + * Return Value: None + */ + +void +USB_DataOutStage (void) +{ + uint32_t cnt; + + cnt = USB_ReadEP (0x00, EP0Data.pData); + EP0Data.pData += cnt; + EP0Data.Count -= cnt; +} + + +/* + * USB Request - Status In Stage + * Parameters: None + * Return Value: None + */ + +void +USB_StatusInStage (void) +{ + USB_WriteEP (0x80, NULL, 0); +} + + +/* + * USB Request - Status Out Stage + * Parameters: None + * Return Value: None + */ + +void +USB_StatusOutStage (void) +{ + USB_ReadEP (0x00, EP0Buf); +} + + +/* + * Get Status USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqGetStatus (void) +{ + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + EP0Data.pData = (uint8_t *) & USB_DeviceStatus; + break; + case REQUEST_TO_INTERFACE: + if ((USB_Configuration != 0) + && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) + { + *((uint16_t __attribute__ ((packed)) *) EP0Buf) = 0; + EP0Data.pData = EP0Buf; + } + else + { + return (FALSE); + } + break; + case REQUEST_TO_ENDPOINT: + n = SetupPacket.wIndex.WB.L & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if (((USB_Configuration != 0) || ((n & 0x0F) == 0)) + && (USB_EndPointMask & m)) + { + *((uint16_t __attribute__ ((packed)) *) EP0Buf) = + (USB_EndPointHalt & m) ? 1 : 0; + EP0Data.pData = EP0Buf; + } + else + { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set/Clear Feature USB Request + * Parameters: sc: 0 - Clear, 1 - Set + * (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqSetClrFeature (uint32_t sc) +{ + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + if (SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP) + { + if (sc) + { + USB_WakeUpCfg (TRUE); + USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP; + } + else + { + USB_WakeUpCfg (FALSE); + USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP; + } + } + else + { + return (FALSE); + } + break; + case REQUEST_TO_INTERFACE: + return (FALSE); + case REQUEST_TO_ENDPOINT: + n = SetupPacket.wIndex.WB.L & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if ((USB_Configuration != 0) && ((n & 0x0F) != 0) + && (USB_EndPointMask & m)) + { + if (SetupPacket.wValue.W == USB_FEATURE_ENDPOINT_STALL) + { + if (sc) + { + USB_SetStallEP (n); + USB_EndPointHalt |= m; + } + else + { + if ((USB_EndPointStall & m) != 0) + { + return (TRUE); + } + USB_ClrStallEP (n); +#if (USB_MSC) + if ((n == MSC_EP_IN) && ((USB_EndPointHalt & m) != 0)) + { + /* Compliance Test: rewrite CSW after unstall */ + if (CSW.dSignature == MSC_CSW_Signature) + { + USB_WriteEP (MSC_EP_IN, (uint8_t *) & CSW, + sizeof (CSW)); + } + } +#endif + USB_EndPointHalt &= ~m; + } + } + else + { + return (FALSE); + } + } + else + { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Address USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqSetAddress (void) +{ + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + USB_DeviceAddress = 0x80 | SetupPacket.wValue.WB.L; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Get Descriptor USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqGetDescriptor (void) +{ + uint8_t *pD; + uint32_t len, n; + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + switch (SetupPacket.wValue.WB.H) + { + case USB_DEVICE_DESCRIPTOR_TYPE: + EP0Data.pData = (uint8_t *) USB_DeviceDescriptor; + len = USB_DEVICE_DESC_SIZE; + break; + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + pD = (uint8_t *) USB_ConfigDescriptor; + for (n = 0; n != SetupPacket.wValue.WB.L; n++) + { + if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bLength != 0) + { + pD += ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength; + } + } + if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bLength == 0) + { + return (FALSE); + } + EP0Data.pData = pD; + len = ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength; + break; + case USB_STRING_DESCRIPTOR_TYPE: + pD = (uint8_t *) USB_StringDescriptor; + for (n = 0; n != SetupPacket.wValue.WB.L; n++) + { + if (((USB_STRING_DESCRIPTOR *) pD)->bLength != 0) + { + pD += ((USB_STRING_DESCRIPTOR *) pD)->bLength; + } + } + if (((USB_STRING_DESCRIPTOR *) pD)->bLength == 0) + { + return (FALSE); + } + EP0Data.pData = pD; + len = ((USB_STRING_DESCRIPTOR *) EP0Data.pData)->bLength; + break; + default: + return (FALSE); + } + break; + case REQUEST_TO_INTERFACE: + switch (SetupPacket.wValue.WB.H) + { +#if USB_HID + case HID_HID_DESCRIPTOR_TYPE: + if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) + { + return (FALSE); /* Only Single HID Interface is supported */ + } + EP0Data.pData = (uint8_t *) USB_ConfigDescriptor + HID_DESC_OFFSET; + len = HID_DESC_SIZE; + break; + case HID_REPORT_DESCRIPTOR_TYPE: + if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) + { + return (FALSE); /* Only Single HID Interface is supported */ + } + EP0Data.pData = (uint8_t *) HID_ReportDescriptor; + len = HID_ReportDescSize; + break; + case HID_PHYSICAL_DESCRIPTOR_TYPE: + return (FALSE); /* HID Physical Descriptor is not supported */ +#endif + default: + return (FALSE); + } + break; + default: + return (FALSE); + } + + if (EP0Data.Count > len) + { + EP0Data.Count = len; + } + + return (TRUE); +} + + +/* + * Get Configuration USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqGetConfiguration (void) +{ + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + EP0Data.pData = &USB_Configuration; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Add a number of bytes to a pointer's address + * Harder than you might think. Some compilers say: + * Expected an lvalue -- Assignment expects its first operand to be + * an lvalue. Please note that a cast removes the lvaluedness of an + * expression. + * + * vpptr = void pointer to pointer + * n = number of bytes to add to pointer + * Call looks like: AddPtr((void **)&myPointer, 8); + */ + +__inline void +UsbAddPtr (void **vpptr, uint32_t n) +{ + /* Declare a pointer to a pointer to a byte. Only a byte pointer + * can be incremented by a number of bytes. Other pointers will + * increment by a multiple of what they point to. + */ + uint8_t **bpptr; + + /* Convert our void pointer to a pointer to a byte pointer to a pointer */ + bpptr = (uint8_t **) vpptr; + + /* Add 'n' bytes to our pointer value */ + (*bpptr) += n; +} + +/* + * Set Configuration USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqSetConfiguration (void) +{ + USB_COMMON_DESCRIPTOR *pD; + uint32_t alt = 0; + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + + if (SetupPacket.wValue.WB.L) + { + pD = (USB_COMMON_DESCRIPTOR *) USB_ConfigDescriptor; + while (pD->bLength) + { + switch (pD->bDescriptorType) + { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (((USB_CONFIGURATION_DESCRIPTOR *) + pD)->bConfigurationValue == SetupPacket.wValue.WB.L) + { + USB_Configuration = SetupPacket.wValue.WB.L; + USB_NumInterfaces = + ((USB_CONFIGURATION_DESCRIPTOR *) pD)->bNumInterfaces; + for (n = 0; n < USB_IF_NUM; n++) + { + USB_AltSetting[n] = 0; + } + for (n = 1; n < 16; n++) + { + if (USB_EndPointMask & (1 << n)) + { + USB_DisableEP (n); + } + if (USB_EndPointMask & ((1 << 16) << n)) + { + USB_DisableEP (n | 0x80); + } + } + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; + USB_Configure (TRUE); + if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bmAttributes + & USB_CONFIG_POWERED_MASK) + { + USB_DeviceStatus |= USB_GETSTATUS_SELF_POWERED; + } + else + { + USB_DeviceStatus &= ~USB_GETSTATUS_SELF_POWERED; + } + } + else + { + UsbAddPtr ((void **) &pD, + ((USB_CONFIGURATION_DESCRIPTOR *) + pD)->wTotalLength); + continue; + } + break; + case USB_INTERFACE_DESCRIPTOR_TYPE: + alt = ((USB_INTERFACE_DESCRIPTOR *) pD)->bAlternateSetting; + break; + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if (alt == 0) + { + n = + ((USB_ENDPOINT_DESCRIPTOR *) pD)->bEndpointAddress & + 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + USB_EndPointMask |= m; + USB_ConfigEP ((USB_ENDPOINT_DESCRIPTOR *) pD); + USB_EnableEP (n); + USB_ResetEP (n); + } + break; + } + UsbAddPtr ((void **) &pD, pD->bLength); + } + } + else + { + USB_Configuration = 0; + for (n = 1; n < 16; n++) + { + if (USB_EndPointMask & (1 << n)) + { + USB_DisableEP (n); + } + if (USB_EndPointMask & ((1 << 16) << n)) + { + USB_DisableEP (n | 0x80); + } + } + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; + USB_Configure (FALSE); + } + + if (USB_Configuration != SetupPacket.wValue.WB.L) + { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Get Interface USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqGetInterface (void) +{ + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_INTERFACE: + if ((USB_Configuration != 0) + && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) + { + EP0Data.pData = USB_AltSetting + SetupPacket.wIndex.WB.L; + } + else + { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Interface USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqSetInterface (void) +{ + USB_COMMON_DESCRIPTOR *pD; + uint32_t ifn = 0, alt = 0, old = 0, msk = 0; + uint32_t n, m; + uint32_t set; + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_INTERFACE: + if (USB_Configuration == 0) + return (FALSE); + set = FALSE; + pD = (USB_COMMON_DESCRIPTOR *) USB_ConfigDescriptor; + while (pD->bLength) + { + switch (pD->bDescriptorType) + { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bConfigurationValue + != USB_Configuration) + { + UsbAddPtr ((void **) &pD, + ((USB_CONFIGURATION_DESCRIPTOR *) + pD)->wTotalLength); + continue; + } + break; + case USB_INTERFACE_DESCRIPTOR_TYPE: + ifn = ((USB_INTERFACE_DESCRIPTOR *) pD)->bInterfaceNumber; + alt = ((USB_INTERFACE_DESCRIPTOR *) pD)->bAlternateSetting; + msk = 0; + if ((ifn == SetupPacket.wIndex.WB.L) + && (alt == SetupPacket.wValue.WB.L)) + { + set = TRUE; + old = USB_AltSetting[ifn]; + USB_AltSetting[ifn] = (uint8_t) alt; + } + break; + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if (ifn == SetupPacket.wIndex.WB.L) + { + n = + ((USB_ENDPOINT_DESCRIPTOR *) pD)->bEndpointAddress & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if (alt == SetupPacket.wValue.WB.L) + { + USB_EndPointMask |= m; + USB_EndPointHalt &= ~m; + USB_ConfigEP ((USB_ENDPOINT_DESCRIPTOR *) pD); + USB_EnableEP (n); + USB_ResetEP (n); + msk |= m; + } + else if ((alt == old) && ((msk & m) == 0)) + { + USB_EndPointMask &= ~m; + USB_EndPointHalt &= ~m; + USB_DisableEP (n); + } + } + break; + } + UsbAddPtr ((void **) &pD, pD->bLength); + } + break; + default: + return (FALSE); + } + + return (set); +} + + +/* + * USB Endpoint 0 Event Callback + * Parameters: event + * Return Value: none + */ + +void +USB_EndPoint0 (uint32_t event) +{ + + switch (event) + { + case USB_EVT_SETUP: + USB_SetupStage (); + USB_DirCtrlEP (SetupPacket.bmRequestType.BM.Dir); + EP0Data.Count = SetupPacket.wLength; /* Number of bytes to transfer */ + switch (SetupPacket.bmRequestType.BM.Type) + { + + case REQUEST_STANDARD: + switch (SetupPacket.bRequest) + { + case USB_REQUEST_GET_STATUS: + if (!USB_ReqGetStatus ()) + { + goto stall_i; + } + USB_DataInStage (); + break; + + case USB_REQUEST_CLEAR_FEATURE: + if (!USB_ReqSetClrFeature (0)) + { + goto stall_i; + } + USB_StatusInStage (); +#if USB_FEATURE_EVENT + USB_Feature_Event (); +#endif + break; + + case USB_REQUEST_SET_FEATURE: + if (!USB_ReqSetClrFeature (1)) + { + goto stall_i; + } + USB_StatusInStage (); +#if USB_FEATURE_EVENT + USB_Feature_Event (); +#endif + break; + + case USB_REQUEST_SET_ADDRESS: + if (!USB_ReqSetAddress ()) + { + goto stall_i; + } + USB_StatusInStage (); + break; + + case USB_REQUEST_GET_DESCRIPTOR: + if (!USB_ReqGetDescriptor ()) + { + goto stall_i; + } + USB_DataInStage (); + break; + + case USB_REQUEST_SET_DESCRIPTOR: + /*stall_o: */ USB_SetStallEP (0x00); + /* not supported */ + EP0Data.Count = 0; + break; + + case USB_REQUEST_GET_CONFIGURATION: + if (!USB_ReqGetConfiguration ()) + { + goto stall_i; + } + USB_DataInStage (); + break; + + case USB_REQUEST_SET_CONFIGURATION: + if (!USB_ReqSetConfiguration ()) + { + goto stall_i; + } + USB_StatusInStage (); +#if USB_CONFIGURE_EVENT + USB_Configure_Event (); +#endif + break; + + case USB_REQUEST_GET_INTERFACE: + if (!USB_ReqGetInterface ()) + { + goto stall_i; + } + USB_DataInStage (); + break; + + case USB_REQUEST_SET_INTERFACE: + if (!USB_ReqSetInterface ()) + { + goto stall_i; + } + USB_StatusInStage (); +#if USB_INTERFACE_EVENT + USB_Interface_Event (); +#endif + break; + + default: + goto stall_i; + } + break; /* end case REQUEST_STANDARD */ + +#if USB_CLASS + case REQUEST_CLASS: + switch (SetupPacket.bmRequestType.BM.Recipient) + { + + case REQUEST_TO_DEVICE: + goto stall_i; /* not supported */ + + case REQUEST_TO_INTERFACE: +#if USB_HID + if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) + { /* IF number correct? */ + switch (SetupPacket.bRequest) + { + case HID_REQUEST_GET_REPORT: + if (HID_GetReport ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_REPORT: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + case HID_REQUEST_GET_IDLE: + if (HID_GetIdle ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_IDLE: + if (HID_SetIdle ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case HID_REQUEST_GET_PROTOCOL: + if (HID_GetProtocol ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_PROTOCOL: + if (HID_SetProtocol ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto setup_class_ok; + } + break; + } + } +#endif /* USB_HID */ +#if USB_MSC + if (SetupPacket.wIndex.WB.L == USB_MSC_IF_NUM) + { /* IF number correct? */ + switch (SetupPacket.bRequest) + { + case MSC_REQUEST_RESET: + if ((SetupPacket.wValue.W == 0) && /* RESET with invalid parameters -> STALL */ + (SetupPacket.wLength == 0)) + { + if (MSC_Reset ()) + { + USB_StatusInStage (); + goto setup_class_ok; + } + } + break; + case MSC_REQUEST_GET_MAX_LUN: + if ((SetupPacket.wValue.W == 0) && /* GET_MAX_LUN with invalid parameters -> STALL */ + (SetupPacket.wLength == 1)) + { + if (MSC_GetMaxLUN ()) + { + EP0Data.pData = EP0Buf; + USB_DataInStage (); + goto setup_class_ok; + } + } + break; + } + } +#endif /* USB_MSC */ +#if USB_AUDIO + if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || + (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) + { + switch (SetupPacket.bRequest) + { + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + if (ADC_IF_GetRequest ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + } + } +#endif /* USB_AUDIO */ +#if USB_CDC + if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM)) + { + switch (SetupPacket.bRequest) + { + case CDC_SEND_ENCAPSULATED_COMMAND: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_ENCAPSULATED_RESPONSE: + if (CDC_GetEncapsulatedResponse ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_SET_COMM_FEATURE: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_COMM_FEATURE: + if (CDC_GetCommFeature (SetupPacket.wValue.W)) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_CLEAR_COMM_FEATURE: + if (CDC_ClearCommFeature (SetupPacket.wValue.W)) + { + USB_StatusInStage (); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case CDC_SET_LINE_CODING: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_LINE_CODING: + if (CDC_GetLineCoding ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_SET_CONTROL_LINE_STATE: + if (CDC_SetControlLineState (SetupPacket.wValue.W)) + { + USB_StatusInStage (); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case CDC_SEND_BREAK: + if (CDC_SendBreak (SetupPacket.wValue.W)) + { + USB_StatusInStage (); /* send Acknowledge */ + goto setup_class_ok; + } + break; + } + } +#endif /* USB_CDC */ + goto stall_i; /* not supported */ + /* end case REQUEST_TO_INTERFACE */ + + case REQUEST_TO_ENDPOINT: +#if USB_AUDIO + switch (SetupPacket.bRequest) + { + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + if (ADC_EP_GetRequest ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + } +#endif /* USB_AUDIO */ + goto stall_i; + /* end case REQUEST_TO_ENDPOINT */ + + default: + goto stall_i; + } + setup_class_ok: /* request finished successfully */ + break; /* end case REQUEST_CLASS */ +#endif /* USB_CLASS */ + +#if USB_VENDOR + case REQUEST_VENDOR: + switch (SetupPacket.bmRequestType.BM.Recipient) + { + + case REQUEST_TO_DEVICE: + if (!USB_ReqVendorDev (TRUE)) + { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_INTERFACE: + if (!USB_ReqVendorIF (TRUE)) + { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_ENDPOINT: + if (!USB_ReqVendorEP (TRUE)) + { + goto stall_i; /* not supported */ + } + break; + + default: + goto stall_i; + } + + if (SetupPacket.wLength) + { + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST) + { + USB_DataInStage (); + } + } + else + { + USB_StatusInStage (); + } + + break; /* end case REQUEST_VENDOR */ +#endif /* USB_VENDOR */ + + default: + stall_i:USB_SetStallEP (0x80); + EP0Data.Count = 0; + break; + } + break; /* end case USB_EVT_SETUP */ + + case USB_EVT_OUT: + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_HOST_TO_DEVICE) + { + if (EP0Data.Count) + { /* still data to receive ? */ + USB_DataOutStage (); /* receive data */ + if (EP0Data.Count == 0) + { /* data complete ? */ + switch (SetupPacket.bmRequestType.BM.Type) + { + + case REQUEST_STANDARD: + goto stall_i; /* not supported */ + +#if (USB_CLASS) + case REQUEST_CLASS: + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + goto stall_i; /* not supported */ + + case REQUEST_TO_INTERFACE: +#if USB_HID + if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) + { /* IF number correct? */ + switch (SetupPacket.bRequest) + { + case HID_REQUEST_SET_REPORT: + if (HID_SetReport ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_HID */ +#if USB_AUDIO + if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || + (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) + { + switch (SetupPacket.bRequest) + { + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + if (ADC_IF_SetRequest ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_AUDIO */ +#if USB_CDC + if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM)) + { + switch (SetupPacket.bRequest) + { + case CDC_SEND_ENCAPSULATED_COMMAND: + if (CDC_SendEncapsulatedCommand ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + case CDC_SET_COMM_FEATURE: + if (CDC_SetCommFeature + (SetupPacket.wValue.W)) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + case CDC_SET_LINE_CODING: + if (CDC_SetLineCoding ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_CDC */ + goto stall_i; + /* end case REQUEST_TO_INTERFACE */ + + case REQUEST_TO_ENDPOINT: +#if USB_AUDIO + switch (SetupPacket.bRequest) + { + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + if (ADC_EP_SetRequest ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + } +#endif /* USB_AUDIO */ + goto stall_i; + /* end case REQUEST_TO_ENDPOINT */ + + default: + goto stall_i; + } + out_class_ok: /* request finished successfully */ + break; /* end case REQUEST_CLASS */ +#endif /* USB_CLASS */ + +#if USB_VENDOR + case REQUEST_VENDOR: + switch (SetupPacket.bmRequestType.BM.Recipient) + { + + case REQUEST_TO_DEVICE: + if (!USB_ReqVendorDev (FALSE)) + { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_INTERFACE: + if (!USB_ReqVendorIF (FALSE)) + { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_ENDPOINT: + if (!USB_ReqVendorEP (FALSE)) + { + goto stall_i; /* not supported */ + } + break; + + default: + goto stall_i; + } + + USB_StatusInStage (); + + break; /* end case REQUEST_VENDOR */ +#endif /* USB_VENDOR */ + + default: + goto stall_i; + } + } + } + } + else + { + USB_StatusOutStage (); /* receive Acknowledge */ + } + break; /* end case USB_EVT_OUT */ + + case USB_EVT_IN: + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST) + { + USB_DataInStage (); /* send data */ + } + else + { + if (USB_DeviceAddress & 0x80) + { + USB_DeviceAddress &= 0x7F; + USB_SetAddress (USB_DeviceAddress); + } + } + break; /* end case USB_EVT_IN */ + + case USB_EVT_OUT_STALL: + USB_ClrStallEP (0x00); + break; + + case USB_EVT_IN_STALL: + USB_ClrStallEP (0x80); + break; + + } +} + +#endif /*ENALBLE_USB_FULLFEATURED*/ diff --git a/openbeacon/lpc13xx/core/peripherals/src/usb/usbhw.c b/openbeacon/lpc13xx/core/peripherals/src/usb/usbhw.c new file mode 100644 index 0000000..f6cb202 --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/src/usb/usbhw.c @@ -0,0 +1,687 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbhw.c + * Purpose: USB Hardware Layer Module for Philips LPC17xx + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added USB_ClearEPBuf + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ +#include +#ifdef ENALBLE_USB_FULLFEATURED + +#include "cdcusb.h" +#include "usbcfg.h" +#include "usbreg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbuser.h" + + +/* + * USB and IO Clock configuration only. + * The same as call PeriClkIOInit(IOCON_USB); + * The purpose is to reduce the code space for + * overall USB project and reserve code space for + * USB debugging. + * Parameters: None + * Return Value: None + */ +void +USBIOClkConfig (void) +{ + /* Enable AHB clock to the GPIO domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6); + + /* Enable AHB clock to the USB block. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 14); + LPC_IOCON->PIO0_3 &= ~0x1F; + LPC_IOCON->PIO0_3 |= 0x01; /* Secondary function VBUS */ + LPC_IOCON->PIO0_6 &= ~0x07; + LPC_IOCON->PIO0_6 |= 0x01; /* Secondary function SoftConn */ + return; +} + +/* + * Delay number of clock cycles + * Parameters: Delay length + * Return Value: None + */ + +void +delay (uint32_t length) +{ + volatile uint32_t i; + + for (i = 0; i < length; i++); + return; +} + +/* + * Get Endpoint Physical Address + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: Endpoint Physical Address + */ + +uint32_t +EPAdr (uint32_t EPNum) +{ + uint32_t val; + + val = (EPNum & 0x0F) << 1; + if (EPNum & 0x80) + { + val += 1; + } + return (val); +} + + +/* + * Write Command + * Parameters: cmd: Command + * Return Value: None + */ + +void +WrCmd (uint32_t cmd) +{ + + LPC_USB->DevIntClr = CCEMTY_INT; + LPC_USB->CmdCode = cmd; + while ((LPC_USB->DevIntSt & (CCEMTY_INT | DEV_STAT_INT)) == 0); +} + + +/* + * Write Command Data + * Parameters: cmd: Command + * val: Data + * Return Value: None + */ + +void +WrCmdDat (uint32_t cmd, uint32_t val) +{ + + WrCmd (cmd); + WrCmd (val); +} + + +/* + * Write Command to Endpoint + * Parameters: cmd: Command + * val: Data + * Return Value: None + */ + +void +WrCmdEP (uint32_t EPNum, uint32_t cmd) +{ + + WrCmd (CMD_SEL_EP (EPAdr (EPNum))); + WrCmd (cmd); +} + + +/* + * Read Command Data + * Parameters: cmd: Command + * Return Value: Data Value + */ + +uint32_t +RdCmdDat (uint32_t cmd) +{ + + LPC_USB->DevIntClr = CCEMTY_INT | CDFULL_INT; + LPC_USB->CmdCode = cmd; + while ((LPC_USB->DevIntSt & (CDFULL_INT | DEV_STAT_INT)) == 0); + return (LPC_USB->CmdData); +} + + +/* + * USB Initialize Function + * Called by the User to initialize USB + * Return Value: None + */ + +void +USB_Init (void) +{ + +#if USB_FIQ_EVENT + /* It's important that only BULK and FRAME(ISO) can be routed + to FIQ. */ + LPC_USB->DevFIQSel = 0x01; /* SOF Use FIQ */ + + /* Enable the USB Interrupt */ + NVIC_EnableIRQ (USB_FIQn); +#endif + + /* Enable the USB Interrupt */ + NVIC_EnableIRQ (USB_IRQn); + + USB_Reset (); + USB_SetAddress (0); + return; +} + + +/* + * USB Connect Function + * Called by the User to Connect/Disconnect USB + * Parameters: con: Connect/Disconnect + * Return Value: None + */ + +void +USB_Connect (uint32_t con) +{ + WrCmdDat (CMD_SET_DEV_STAT, DAT_WR_BYTE (con ? DEV_CON : 0)); +} + + +/* + * USB Reset Function + * Called automatically on USB Reset + * Return Value: None + */ + +void +USB_Reset (void) +{ + + LPC_USB->DevIntClr = 0x000FFFFF; + /* Enable all eight(8) EPs, note: EP won't be ready until it's + configured/enabled when device sending SetEPStatus command + to the command engine. */ + LPC_USB->DevIntEn = DEV_STAT_INT | (0xFF << 1) | + (USB_SOF_EVENT ? FRAME_INT : 0); + return; +} + + +/* + * USB Suspend Function + * Called automatically on USB Suspend + * Return Value: None + */ + +void +USB_Suspend (void) +{ + /* Performed by Hardware */ +} + + +/* + * USB Resume Function + * Called automatically on USB Resume + * Return Value: None + */ + +void +USB_Resume (void) +{ + /* Performed by Hardware */ +} + + +/* + * USB Remote Wakeup Function + * Called automatically on USB Remote Wakeup + * Return Value: None + */ + +void +USB_WakeUp (void) +{ + + if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP) + { + WrCmdDat (CMD_SET_DEV_STAT, DAT_WR_BYTE (DEV_CON)); + } +} + + +/* + * USB Remote Wakeup Configuration Function + * Parameters: cfg: Enable/Disable + * Return Value: None + */ + +void +USB_WakeUpCfg (uint32_t cfg) +{ + cfg = cfg; /* Not needed */ +} + + +/* + * USB Set Address Function + * Parameters: adr: USB Address + * Return Value: None + */ + +void +USB_SetAddress (uint32_t adr) +{ + WrCmdDat (CMD_SET_ADDR, DAT_WR_BYTE (DEV_EN | adr)); /* Don't wait for next */ + WrCmdDat (CMD_SET_ADDR, DAT_WR_BYTE (DEV_EN | adr)); /* Setup Status Phase */ +} + + +/* + * USB Configure Function + * Parameters: cfg: Configure/Deconfigure + * Return Value: None + */ + +void +USB_Configure (uint32_t cfg) +{ + + WrCmdDat (CMD_CFG_DEV, DAT_WR_BYTE (cfg ? CONF_DVICE : 0)); + return; +} + + +/* + * Configure USB Endpoint according to Descriptor + * Parameters: pEPD: Pointer to Endpoint Descriptor + * Return Value: None + */ + +void +USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD) +{ + (void) pEPD; + return; +} + + +/* + * Set Direction for USB Control Endpoint + * Parameters: dir: Out (dir == 0), In (dir <> 0) + * Return Value: None + */ + +void +USB_DirCtrlEP (uint32_t dir) +{ + (void) dir; +} + + +/* + * Enable USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_EnableEP (uint32_t EPNum) +{ + WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0)); +} + + +/* + * Disable USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_DisableEP (uint32_t EPNum) +{ + WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (EP_STAT_DA)); +} + + +/* + * Reset USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_ResetEP (uint32_t EPNum) +{ + WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0)); +} + + +/* + * Set Stall for USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_SetStallEP (uint32_t EPNum) +{ + WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (EP_STAT_ST)); +} + + +/* + * Clear Stall for USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_ClrStallEP (uint32_t EPNum) +{ + WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0)); +} + + +/* + * Clear USB Endpoint Buffer + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_ClearEPBuf (uint32_t EPNum) +{ + WrCmdEP (EPNum, CMD_CLR_BUF); +} + + +/* + * Read USB Endpoint Size + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: Number of bytes read + */ + +uint32_t +USB_ReadEP_Count (uint32_t EPNum) +{ + uint32_t cnt; + + LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_RD_EN; + /* 3 clock cycles to fetch the packet length from RAM. */ + delay (5); + + while(((cnt = LPC_USB->RxPLen) & PKT_DV) == 0); + + return cnt & PKT_LNGTH_MASK; +} + + +/* + * Read USB Endpoint Data: Finalize Read + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: Number of bytes read + * + * + */ + +void +USB_ReadEP_Terminate (uint32_t EPNum) +{ + LPC_USB->Ctrl = 0; + + WrCmdEP (EPNum, CMD_CLR_BUF); +} + + +/* + * Read USB Endpoint Data + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * pData: Pointer to Data Buffer + * Return Value: Number of bytes read + */ + +uint32_t +USB_ReadEP (uint32_t EPNum, uint8_t * pData) +{ + uint32_t res, cnt, data; + uint8_t* p; + + res = cnt = USB_ReadEP_Count (EPNum); + + while(cnt>=sizeof(uint32_t)) + { + *((uint32_t __attribute__ ((packed)) *) pData) = USB_ReadEP_Block (); + pData += sizeof(uint32_t); + cnt-=sizeof(uint32_t); + } + + if(cnt>0) + { + data = USB_ReadEP_Block (); + p = (uint8_t*)&data; + while(cnt--) + *pData++ = *p++; + } + + USB_ReadEP_Terminate (EPNum); + + return res; +} + + +void +USB_WriteEP_Count (uint32_t EPNum, uint32_t cnt) +{ + LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN; + /* 3 clock cycles to fetch the packet length from RAM. */ + delay (5); + LPC_USB->TxPLen = cnt; +} + + +void +USB_WriteEP_Terminate (uint32_t EPNum) +{ + LPC_USB->Ctrl = 0; + + WrCmdEP (EPNum, CMD_VALID_BUF); +} + + +/* + * Write USB Endpoint Data + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * pData: Pointer to Data Buffer + * cnt: Number of bytes to write + * Return Value: Number of bytes written + */ + +uint32_t +USB_WriteEP (uint32_t EPNum, uint8_t * pData, uint32_t cnt) +{ + uint32_t n; + + USB_WriteEP_Count (EPNum, cnt); + + for (n = 0; n < (cnt + 3) / 4; n++) + { + USB_WriteEP_Block (*((uint32_t __attribute__ ((packed)) *) pData)); + pData += sizeof(uint32_t); + } + + USB_WriteEP_Terminate (EPNum); + + return cnt; +} + +/* + * Get USB Last Frame Number + * Parameters: None + * Return Value: Frame Number + */ + +uint32_t +USB_GetFrame (void) +{ + uint32_t val; + + WrCmd (CMD_RD_FRAME); + val = RdCmdDat (DAT_RD_FRAME); + val = val | (RdCmdDat (DAT_RD_FRAME) << 8); + + return (val); +} + + +/* + * USB Interrupt Service Routine + */ + +void +USB_IRQHandler (void) +{ + uint32_t disr, val, n, m; + + disr = LPC_USB->DevIntSt; /* Device Interrupt Status */ + LPC_USB->DevIntClr = disr; + + /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */ + if (disr & DEV_STAT_INT) + { + WrCmd (CMD_GET_DEV_STAT); + val = RdCmdDat (DAT_GET_DEV_STAT); /* Device Status */ + if (val & DEV_RST) + { /* Reset */ + USB_Reset (); +#if USB_RESET_EVENT + USB_Reset_Event (); +#endif + } + if (val & DEV_CON_CH) + { /* Connect change */ +#if USB_POWER_EVENT + USB_Power_Event (val & DEV_CON); +#endif + } + if (val & DEV_SUS_CH) + { /* Suspend/Resume */ + if (val & DEV_SUS) + { /* Suspend */ + USB_Suspend (); +#if USB_SUSPEND_EVENT + USB_Suspend_Event (); +#endif + } + else + { /* Resume */ + USB_Resume (); +#if USB_RESUME_EVENT + USB_Resume_Event (); +#endif + } + } + goto isr_end; + } + +#if USB_SOF_EVENT + /* Start of Frame Interrupt */ + if (disr & FRAME_INT) + { + LPC_USB->DevIntClr = FRAME_INT; + USB_SOF_Event (); + SOFIRQCount++; + } +#endif + +#if USB_ERROR_EVENT + /* NO error interrupt anymore, below code can be used + as example to get error status from command engine. */ + /* Error Interrupt */ + if (disr & ERR_INT) + { + WrCmd (CMD_RD_ERR_STAT); + val = RdCmdDat (DAT_RD_ERR_STAT); + USB_Error_Event (val); + } +#endif + + /* Endpoint's Interrupt */ + if (disr & (0xFF << 1)) + { + /* if any of the EP0 through EP7 is set, or bit 1 through 9 on disr */ + for (n = 0; n < USB_EP_NUM; n++) + { /* Check All Endpoints */ + /* skip frame interrupt at bit 0 in disr */ +// if (disr & ((1 << n)<<1)) { + if ((disr >> 1) & (1 << n)) + { + m = n >> 1; + /* clear EP interrupt by sending cmd to the command engine. */ + WrCmd (CMD_SEL_EP_CLRI (n)); + val = RdCmdDat (DAT_SEL_EP_CLRI (n)); + if ((n & 1) == 0) + { /* OUT Endpoint */ + if (n == 0) + { /* Control OUT Endpoint */ + if (val & EP_SEL_STP) + { /* Setup Packet */ + if (USB_P_EP[0]) + { + USB_P_EP[0] (USB_EVT_SETUP); + continue; + } + } + } + if (USB_P_EP[m]) + { + USB_P_EP[m] (USB_EVT_OUT); + } + } + else + { /* IN Endpoint */ + if (USB_P_EP[m]) + { + USB_P_EP[m] (USB_EVT_IN); + } + } + } + } + } +isr_end: + return; +} + +#endif /*ENALBLE_USB_FULLFEATURED*/ diff --git a/openbeacon/lpc13xx/core/peripherals/src/usb/usbuser.c b/openbeacon/lpc13xx/core/peripherals/src/usb/usbuser.c new file mode 100644 index 0000000..d97f466 --- /dev/null +++ b/openbeacon/lpc13xx/core/peripherals/src/usb/usbuser.c @@ -0,0 +1,234 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbuser.c + * Purpose: USB Custom User Module + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ +#include +#ifdef ENALBLE_USB_FULLFEATURED + +#include "cdcusb.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbuser.h" +#include "cdcuser.h" + + +/* + * USB Power Event Callback + * Called automatically on USB Power Event + * Parameter: power: On(TRUE)/Off(FALSE) + */ + +#if USB_POWER_EVENT +void +USB_Power_Event (uint32_t power) +{ +} +#endif + + +/* + * USB Reset Event Callback + * Called automatically on USB Reset Event + */ + +#if USB_RESET_EVENT +void +USB_Reset_Event (void) +{ + USB_ResetCore (); +} +#endif + + +/* + * USB Suspend Event Callback + * Called automatically on USB Suspend Event + */ + +#if USB_SUSPEND_EVENT +void +USB_Suspend_Event (void) +{ +} +#endif + + +/* + * USB Resume Event Callback + * Called automatically on USB Resume Event + */ + +#if USB_RESUME_EVENT +void +USB_Resume_Event (void) +{ +} +#endif + + +/* + * USB Remote Wakeup Event Callback + * Called automatically on USB Remote Wakeup Event + */ + +#if USB_WAKEUP_EVENT +void +USB_WakeUp_Event (void) +{ +} +#endif + + +/* + * USB Start of Frame Event Callback + * Called automatically on USB Start of Frame Event + */ + +#if USB_SOF_EVENT +void +USB_SOF_Event (void) +{ +} +#endif + + +/* + * USB Error Event Callback + * Called automatically on USB Error Event + * Parameter: error: Error Code + */ + +#if USB_ERROR_EVENT +void +USB_Error_Event (uint32_t error) +{ +} +#endif + + +/* + * USB Set Configuration Event Callback + * Called automatically on USB Set Configuration Request + */ + +#if USB_CONFIGURE_EVENT +void +USB_Configure_Event (void) +{ + + if (USB_Configuration) + { /* Check if USB is configured */ + /* add your code here */ + } +} +#endif + + +/* + * USB Set Interface Event Callback + * Called automatically on USB Set Interface Request + */ + +#if USB_INTERFACE_EVENT +void +USB_Interface_Event (void) +{ +} +#endif + + +/* + * USB Set/Clear Feature Event Callback + * Called automatically on USB Set/Clear Feature Request + */ + +#if USB_FEATURE_EVENT +void +USB_Feature_Event (void) +{ +} +#endif + + +#define P_EP(n) ((USB_EP_EVENT & (1 << (n))) ? USB_EndPoint##n : NULL) + +/* USB Endpoint Events Callback Pointers */ +void (*const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event) = +{ +P_EP (0), P_EP (1), P_EP (2), P_EP (3), P_EP (4),}; + + +/* + * USB Endpoint 1 Event Callback + * Called automatically on USB Endpoint 1 Event + * Parameter: event + */ + +void +USB_EndPoint1 (uint32_t event) +{ + uint16_t temp; + static uint16_t serialState; + + switch (event) + { + case USB_EVT_IN: + temp = CDC_GetSerialState (); + if (serialState != temp) + { + serialState = temp; + CDC_NotificationIn (); /* send SERIAL_STATE notification */ + } + break; + } +} + + +/* + * USB Endpoint 2 Event Callback + * Called automatically on USB Endpoint 2 Event + * Parameter: event + */ + +void +USB_EndPoint2 (uint32_t event) +{ + (void) event; +} + + +/* + * USB Endpoint 3 Event Callback + * Called automatically on USB Endpoint 3 Event + * Parameter: event + */ + +void +USB_EndPoint3 (uint32_t event) +{ + switch (event) + { + case USB_EVT_OUT: + CDC_BulkOut (); /* data received from Host */ + break; + case USB_EVT_IN: + CDC_BulkIn (); /* data expected from Host */ + break; + } +} + +#endif /*ENALBLE_USB_FULLFEATURED*/ diff --git a/openbeacon/lpc13xx/core/startup/LPC13xx.c b/openbeacon/lpc13xx/core/startup/LPC13xx.c new file mode 100644 index 0000000..1f1a225 --- /dev/null +++ b/openbeacon/lpc13xx/core/startup/LPC13xx.c @@ -0,0 +1,368 @@ +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Copyright (c) 2009 Code Red Technologies Ltd. +// +// Microcontroller Startup code for use with Red Suite +// +// Software License Agreement +// +// The software is owned by Code Red Technologies and/or its suppliers, and is +// protected under applicable copyright laws. All rights are reserved. Any +// use in violation of the foregoing restrictions may subject the user to criminal +// sanctions under applicable laws, as well as to civil liability for the breach +// of the terms and conditions of this license. +// +// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT +// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH +// CODE RED TECHNOLOGIES LTD. +// +//***************************************************************************** +#define WEAK __attribute__ ((weak)) +#define ALIAS(f) __attribute__ ((weak, alias (#f))) + +// Code Red - if CMSIS is being used, then SystemInit() routine +// will be called by startup code rather than in application's main() +#ifdef __USE_CMSIS +#include "system_LPC13xx.h" +#endif + +//***************************************************************************** +// +// Forward declaration of the default handlers. These are aliased. +// When the application defines a handler (with the same name), this will +// automatically take precedence over these weak definitions +// +//***************************************************************************** +void Reset_Handler(void); +void ResetISR(void) ALIAS(Reset_Handler); +WEAK void NMI_Handler(void); +WEAK void HardFault_Handler(void); +WEAK void MemManage_Handler(void); +WEAK void BusFault_Handler(void); +WEAK void UsageFault_Handler(void); +WEAK void SVCall_Handler(void); +WEAK void DebugMon_Handler(void); +WEAK void PendSV_Handler(void); +WEAK void SysTick_Handler(void); + +//***************************************************************************** +// +// Forward declaration of the specific IRQ handlers. These are aliased +// to the IntDefaultHandler, which is a 'forever' loop. When the application +// defines a handler (with the same name), this will automatically take +// precedence over these weak definitions +// +//***************************************************************************** + +void I2C_IRQHandler(void) ALIAS(IntDefaultHandler); +void TIMER16_0_IRQHandler(void) ALIAS(IntDefaultHandler); +void TIMER16_1_IRQHandler(void) ALIAS(IntDefaultHandler); +void TIMER32_0_IRQHandler(void) ALIAS(IntDefaultHandler); +void TIMER32_1_IRQHandler(void) ALIAS(IntDefaultHandler); +void SSP_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART_IRQHandler(void) ALIAS(IntDefaultHandler); +void USB_IRQHandler(void) ALIAS(IntDefaultHandler); +void USB_FIQHandler(void) ALIAS(IntDefaultHandler); +void ADC_IRQHandler(void) ALIAS(IntDefaultHandler); +void WDT_IRQHandler(void) ALIAS(IntDefaultHandler); +void BOD_IRQHandler(void) ALIAS(IntDefaultHandler); +void FMC_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIOINT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIOINT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIOINT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIOINT0_IRQHandler(void) ALIAS(IntDefaultHandler); + +void WAKEUP_IRQHandlerPIO0_0 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_1 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_2 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_3 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_4 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_5 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_6 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_7 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_8 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_9 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_10(void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO0_11(void) ALIAS(IntDefaultHandler); + +void WAKEUP_IRQHandlerPIO1_0 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_1 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_2 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_3 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_4 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_5 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_6 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_7 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_8 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_9 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_10(void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO1_11(void) ALIAS(IntDefaultHandler); + +void WAKEUP_IRQHandlerPIO2_0 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_1 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_2 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_3 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_4 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_5 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_6 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_7 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_8 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_9 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_10(void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO2_11(void) ALIAS(IntDefaultHandler); + +void WAKEUP_IRQHandlerPIO3_0 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO3_1 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO3_2 (void) ALIAS(IntDefaultHandler); +void WAKEUP_IRQHandlerPIO3_3 (void) ALIAS(IntDefaultHandler); + +//***************************************************************************** +// +// The entry point for the application. +// __main() is the entry point for redlib based applications +// main() is the entry point for newlib based applications +// +//***************************************************************************** +extern WEAK void __main(void); +extern WEAK void main(void); +//***************************************************************************** +// +// External declaration for the pointer to the stack top from the Linker Script +// +//***************************************************************************** +extern void __stack_end__(void); + +//***************************************************************************** +// +// The vector table. Note that the proper constructs must be placed on this to +// ensure that it ends up at physical address 0x0000.0000. +// +//***************************************************************************** +__attribute__ ((section(".isr_vector"))) +void (*const g_pfnVectors[]) (void) = +{ + // Core Level - CM3 + __stack_end__, // The initial stack pointer + Reset_Handler, // The reset handler + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + MemManage_Handler, // The MPU fault handler + BusFault_Handler, // The bus fault handler + UsageFault_Handler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVCall_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + // Wakeup sources (40 ea.) for the I/O pins: + // PIO0 (0:11) + // PIO1 (0:11) + // PIO2 (0:11) + // PIO3 (0:3) + WAKEUP_IRQHandlerPIO0_0, // PIO0_0 Wakeup + WAKEUP_IRQHandlerPIO0_1, // PIO0_1 Wakeup + WAKEUP_IRQHandlerPIO0_2, // PIO0_2 Wakeup + WAKEUP_IRQHandlerPIO0_3, // PIO0_3 Wakeup + WAKEUP_IRQHandlerPIO0_4, // PIO0_4 Wakeup + WAKEUP_IRQHandlerPIO0_5, // PIO0_5 Wakeup + WAKEUP_IRQHandlerPIO0_6, // PIO0_6 Wakeup + WAKEUP_IRQHandlerPIO0_7, // PIO0_7 Wakeup + WAKEUP_IRQHandlerPIO0_8, // PIO0_8 Wakeup + WAKEUP_IRQHandlerPIO0_9, // PIO0_9 Wakeup + WAKEUP_IRQHandlerPIO0_10, // PIO0_10 Wakeup + WAKEUP_IRQHandlerPIO0_11, // PIO0_11 Wakeup + WAKEUP_IRQHandlerPIO1_0, // PIO1_0 Wakeup + WAKEUP_IRQHandlerPIO1_1, // PIO1_1 Wakeup + WAKEUP_IRQHandlerPIO1_2, // PIO1_2 Wakeup + WAKEUP_IRQHandlerPIO1_3, // PIO1_3 Wakeup + WAKEUP_IRQHandlerPIO1_4, // PIO1_4 Wakeup + WAKEUP_IRQHandlerPIO1_5, // PIO1_5 Wakeup + WAKEUP_IRQHandlerPIO1_6, // PIO1_6 Wakeup + WAKEUP_IRQHandlerPIO1_7, // PIO1_7 Wakeup + WAKEUP_IRQHandlerPIO1_8, // PIO1_8 Wakeup + WAKEUP_IRQHandlerPIO1_9, // PIO1_9 Wakeup + WAKEUP_IRQHandlerPIO1_10, // PIO1_10 Wakeup + WAKEUP_IRQHandlerPIO1_11, // PIO1_11 Wakeup + WAKEUP_IRQHandlerPIO2_0, // PIO2_0 Wakeup + WAKEUP_IRQHandlerPIO2_1, // PIO2_1 Wakeup + WAKEUP_IRQHandlerPIO2_2, // PIO2_2 Wakeup + WAKEUP_IRQHandlerPIO2_3, // PIO2_3 Wakeup + WAKEUP_IRQHandlerPIO2_4, // PIO2_4 Wakeup + WAKEUP_IRQHandlerPIO2_5, // PIO2_5 Wakeup + WAKEUP_IRQHandlerPIO2_6, // PIO2_6 Wakeup + WAKEUP_IRQHandlerPIO2_7, // PIO2_7 Wakeup + WAKEUP_IRQHandlerPIO2_8, // PIO2_8 Wakeup + WAKEUP_IRQHandlerPIO2_9, // PIO2_9 Wakeup + WAKEUP_IRQHandlerPIO2_10, // PIO2_10 Wakeup + WAKEUP_IRQHandlerPIO2_11, // PIO2_11 Wakeup + WAKEUP_IRQHandlerPIO3_0, // PIO3_0 Wakeup + WAKEUP_IRQHandlerPIO3_1, // PIO3_1 Wakeup + WAKEUP_IRQHandlerPIO3_2, // PIO3_2 Wakeup + WAKEUP_IRQHandlerPIO3_3, // PIO3_3 Wakeup + I2C_IRQHandler, // I2C0 + TIMER16_0_IRQHandler, // CT16B0 (16-bit Timer 0) + TIMER16_1_IRQHandler, // CT16B1 (16-bit Timer 1) + TIMER32_0_IRQHandler, // CT32B0 (32-bit Timer 0) + TIMER32_1_IRQHandler, // CT32B1 (32-bit Timer 1) + SSP_IRQHandler, // SSP0 + UART_IRQHandler, // UART0 + USB_IRQHandler, // USB IRQ + USB_FIQHandler, // USB FIQ + ADC_IRQHandler, // ADC (A/D Converter) + WDT_IRQHandler, // WDT (Watchdog Timer) + BOD_IRQHandler, // BOD (Brownout Detect) + FMC_IRQHandler, // Flash (IP2111 Flash Memory Controller) + PIOINT3_IRQHandler, // PIO INT3 + PIOINT2_IRQHandler, // PIO INT2 + PIOINT1_IRQHandler, // PIO INT1 + PIOINT0_IRQHandler, // PIO INT0 +}; + +//***************************************************************************** +// +// The following are constructs created by the linker, indicating where the +// the "data" and "bss" segments reside in memory. The initializers for the +// for the "data" segment resides immediately following the "text" segment. +// +//***************************************************************************** +extern unsigned long __end_of_text__; +extern unsigned long __data_beg__; +extern unsigned long __data_end__; +extern unsigned long __bss_beg__; +extern unsigned long __bss_end__; + +//***************************************************************************** +// +// This is the code that gets called when the processor first starts execution +// following a reset event. Only the absolutely necessary set is performed, +// after which the application supplied entry() routine is called. Any fancy +// actions (such as making decisions based on the reset cause register, and +// resetting the bits in that register) are left solely in the hands of the +// application. +// +//***************************************************************************** +void +//ResetISR(void) +Reset_Handler(void) +{ + unsigned long *pulSrc, *pulDest; + + // + // Copy the data segment initializers from flash to SRAM. + // + pulSrc = &__end_of_text__; + for (pulDest = &__data_beg__; pulDest < &__data_end__;) { + *pulDest++ = *pulSrc++; + } + + // + // Zero fill the bss segment. This is done with inline assembly since this + // will clear the value of pulDest if it is not kept in a register. + // + __asm(" ldr r0, =__bss_beg__\n" " ldr r1, =__bss_end__\n" + " mov r2, #0\n" " .thumb_func\n" "zero_loop:\n" + " cmp r0, r1\n" " it lt\n" + " strlt r2, [r0], #4\n" " blt zero_loop"); + +#ifdef __USE_CMSIS + SystemInit(); +#endif + + main(); + + // + // main() shouldn't return, but if it does, we'll just enter an infinite loop + // + while (1) { + ; + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a NMI. This +// simply enters an infinite loop, preserving the system state for examination +// by a debugger. +// +//***************************************************************************** +void NMI_Handler(void) +{ + while (1) { + } +} + +void HardFault_Handler(void) +{ + while (1) { + } +} + +void MemManage_Handler(void) +{ + while (1) { + } +} + +void BusFault_Handler(void) +{ + while (1) { + } +} + +void UsageFault_Handler(void) +{ + while (1) { + } +} + +void SVCall_Handler(void) +{ + while (1) { + } +} + +void DebugMon_Handler(void) +{ + while (1) { + } +} + +void PendSV_Handler(void) +{ + while (1) { + } +} + +void SysTick_Handler(void) +{ + while (1) { + } +} + +//***************************************************************************** +// +// Processor ends up here if an unexpected interrupt occurs or a handler +// is not present in the application code. +// +//***************************************************************************** + +static void IntDefaultHandler(void) +{ + // + // Go into an infinite loop. + // + while (1) { + } +} diff --git a/openbeacon/lpc13xx/drivers/bitmanufaktur.inf b/openbeacon/lpc13xx/drivers/bitmanufaktur.inf new file mode 100644 index 0000000..1d9afe4 --- /dev/null +++ b/openbeacon/lpc13xx/drivers/bitmanufaktur.inf @@ -0,0 +1,60 @@ +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%BITMANUFAKTUR% +DriverVer=28/03/11 + +[Manufacturer] +%BITMANUFAKTUR%=BitmanufakturDevices + +[DestinationDirs] +DefaultDestDir=12 + +[SourceDisksFiles] + +[SourceDisksNames] + +[BitmanufakturDevices] +%OPENBEACON_USB2%=OpenBeacon_CDC_ACM, USB\VID_2366&PID_0002 +%OPENPCD2_BASIC%=OpenBeacon_CDC_ACM, USB\VID_2366&PID_0003 + +;------------------------------------------------------------------------------ +; Windows 2000/XP Sections +;------------------------------------------------------------------------------ + +[OpenBeacon_CDC_ACM.nt] +include=mdmcpq.inf +CopyFiles=DriverCopyFiles +AddReg=OpenBeacon_CDC_ACM.nt.AddReg + +[DriverCopyFiles] +usbser.sys,,,0x20 + +[OpenBeacon_CDC_ACM.nt.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,usbser.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[OpenBeacon_CDC_ACM.nt.Services] +include=mdmcpq.inf +AddService=usbser, 0x00000002, DriverService + +[OpenBeacon_CDC_ACM.nt.HW] +include=mdmcpq.inf + +[DriverService] +DisplayName=%DESCRIPTION% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\usbser.sys + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ + +[Strings] +BITMANUFAKTUR="Bitmanufaktur GmbH" +OPENPCD2_BASIC="OpenPCD 2 basic RFID Reader for 13.56MHz" +OPENBEACON_USB2="OpenBeacon USB 2 active 2.4GHz RFID" diff --git a/openbeacon/lpc13xx/hid-client/Makefile b/openbeacon/lpc13xx/hid-client/Makefile new file mode 100644 index 0000000..23e8535 --- /dev/null +++ b/openbeacon/lpc13xx/hid-client/Makefile @@ -0,0 +1,68 @@ +PROG = hid_listen + +OS = LINUX +#OS = DARWIN +#OS = WINDOWS + + +ifeq ($(OS), LINUX) +TARGET = $(PROG) +CC = gcc +STRIP = strip +CFLAGS = -O2 -Wall -D$(OS) +LIBS = +else ifeq ($(OS), DARWIN) +TARGET = $(PROG) +CC = gcc +STRIP = strip +SDK = /Developer/SDKs/MacOSX10.5.sdk +CFLAGS = -O2 -Wall -isysroot $(SDK) -D$(OS) -arch ppc -arch i386 +LIBS = -Xlinker -syslibroot -Xlinker $(SDK) -framework IOKit -framework CoreFoundation +else ifeq ($(OS), WINDOWS) +TARGET = $(PROG).exe +CC = i586-mingw32msvc-gcc +STRIP = i586-mingw32msvc-strip +WINDRES = i586-mingw32msvc-windres +CFLAGS = -O2 -Wall -D$(OS) +LIBS = -lhid -lsetupapi +KEY_SPC = ~/bin/cert/mykey.spc +KEY_PVK = ~/bin/cert/mykey.pvk +KEY_TS = http://timestamp.comodoca.com/authenticode +endif + + +MAKEFLAGS = --jobs=2 +OBJS = hid_listen.o rawhid.o + +all: $(TARGET) + +$(PROG): $(OBJS) + gcc -o $(PROG) $(OBJS) $(LIBS) + $(STRIP) $(PROG) + +$(PROG).app: $(PROG) Info.plist + mkdir -p $(PROG).app/Contents/MacOS + mkdir -p $(PROG).app/Contents/Resources/English.lproj + cp Info.plist $(PROG).app/Contents/ + echo -n 'APPL????' > $(PROG).app/Contents/PkgInfo + cp $(PROG) $(PROG).app/Contents/MacOS/$(PROG) + cp icons/$(PROG).icns $(PROG).app/Contents/Resources/$(PROG).icns + touch $(PROG).app + +$(PROG).dmg: $(PROG).app + hdiutil create -ov -srcfolder $(PROG).app $(PROG).dmg + +$(PROG).exe: $(OBJS) + $(CC) $(OBJS) -o $(PROG).exe $(LIBS) + $(STRIP) $(PROG).exe + -signcode -spc $(KEY_SPC) -v $(KEY_PVK) -t $(KEY_TS) $(PROG).exe + +resource.o: resource.rs icons/$(PROG).ico + $(WINDRES) -o resource.o resource.rs + + + +clean: + rm -f *.o $(PROG) $(PROG).exe $(PROG).exe.bak $(PROG).dmg + rm -rf $(PROG).app + diff --git a/openbeacon/lpc13xx/hid-client/hid_listen.c b/openbeacon/lpc13xx/hid-client/hid_listen.c new file mode 100644 index 0000000..a313ca7 --- /dev/null +++ b/openbeacon/lpc13xx/hid-client/hid_listen.c @@ -0,0 +1,65 @@ +/* HID Listen, http://www.pjrc.com/teensy/hid_listen.html + * Listens (and prints) all communication received from a USB HID device, + * which is useful for view debug messages from the Teensy USB Board. + * Copyright 2008, PJRC.COM, LLC + * + * You may redistribute this program and/or modify it under the terms + * of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ + */ + +#include +#include +#include +#include +#include "rawhid.h" + +static void delay_ms(unsigned int msec) +{ + usleep(msec * 1000); +} + +int main(void) +{ + unsigned char buf[64],prev; + rawhid_t *hid; + int num, count; + + printf("Waiting for device:"); + fflush(stdout); + prev=0; + while (1) { + hid = rawhid_open_only1(0x16c0, 0x08b4, 0,0); + if (hid == NULL) { + printf("."); + fflush(stdout); + delay_ms(1000); + continue; + } + printf("\nListening:\n"); + while (1) { + num = rawhid_read(hid, buf, sizeof(buf), 200); + if (num < 0) break; + if (num == 0) continue; + if(prev==buf[0]) continue; + prev=buf[0]; + printf("RX:"); + for (count=0; count +#include +#include +#include +#include "rawhid.h" + +#ifdef OPERATING_SYSTEM +#undef OPERATING_SYSTEM +#endif + + +/*************************************************************************/ +/** **/ +/** Linux **/ +/** **/ +/*************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +struct rawhid_struct { + int fd; + int name; + int isok; +}; + +rawhid_t * rawhid_open_only1(int vid, int pid, int usage_page, int usage) +{ + struct rawhid_struct *hid; + struct stat devstat; + struct hidraw_devinfo info; + struct hidraw_report_descriptor *desc; + char buf[512]; + int r, i, fd=-1, len, found=0; + + printf("Searching for device using hidraw....\n"); + for (i=0; i 0) close(fd); + snprintf(buf, sizeof(buf), "/dev/hidraw%d", i); + r = stat(buf, &devstat); + if (r < 0) continue; + printf("device: %s\n", buf); + fd = open(buf, O_RDWR); + if (fd < 0) continue; + printf(" opened\n"); + r = ioctl(fd, HIDIOCGRAWINFO, &info); + if (r < 0) continue; + printf(" vid=%04X, pid=%04X\n", info.vendor & 0xFFFF, info.product & 0xFFFF); + r = ioctl(fd, HIDIOCGRDESCSIZE, &len); + if (r < 0 || len < 1) continue; + printf(" len=%u\n", len); + desc = (struct hidraw_report_descriptor *)buf; + if (len > sizeof(buf)-sizeof(int)) len = sizeof(buf)-sizeof(int); + desc->size = len; + r = ioctl(fd, HIDIOCGRDESC, desc); + if (r < 0) continue; + printf(" Match\n"); + found = 1; + break; + } + if (!found) { + if (fd > 0) close(fd); + return NULL; + } + hid = (struct rawhid_struct *)malloc(sizeof(struct rawhid_struct)); + if (!hid) { + close(fd); + return NULL; + } + hid->fd = fd; + return hid; +} + +int rawhid_status(rawhid_t *hid) +{ + // TODO: how to check if device is still online? + return -1; +} + +int rawhid_read(rawhid_t *h, void *buf, int bufsize, int timeout_ms) +{ + struct rawhid_struct *hid; + int num; + + hid = (struct rawhid_struct *)h; + if (!hid || hid->fd < 0) return -1; + + while (1) { + num = read(hid->fd, buf, bufsize); + if (num < 0) { + if (errno == EINTR || errno == EAGAIN) continue; + if (errno == EIO) { + return -1; + printf("I/O Error\n"); + } + printf("read error, r=%d, errno=%d\n", num, errno); + return -1; + } + //printf("read %d bytes\n", num); + return num; + } +} + +void rawhid_close(rawhid_t *h) +{ + struct rawhid_struct *hid; + + hid = (struct rawhid_struct *)h; + if (!hid || hid->fd < 0) return; + close(hid->fd); + hid->fd = -1; +} diff --git a/openbeacon/lpc13xx/hid-client/rawhid.h b/openbeacon/lpc13xx/hid-client/rawhid.h new file mode 100644 index 0000000..47d24d1 --- /dev/null +++ b/openbeacon/lpc13xx/hid-client/rawhid.h @@ -0,0 +1,12 @@ +#ifndef rawhid_included_h__ +#define rawhid_included_h__ + +// Raw HID, Basic API +typedef void rawhid_t; +rawhid_t * rawhid_open_only1(int vid, int pid, int usage_page, int usage); +int rawhid_status(rawhid_t *hid); +int rawhid_read(rawhid_t *h, void *buf, int bufsize, int timeout_ms); +int rawhid_write(rawhid_t *hid, const void *buf, int len, int timeout_ms); +void rawhid_close(rawhid_t *h); + +#endif diff --git a/openbeacon/lpc13xx/lpc-flash/.gitignore b/openbeacon/lpc13xx/lpc-flash/.gitignore new file mode 100644 index 0000000..2ba63ef --- /dev/null +++ b/openbeacon/lpc13xx/lpc-flash/.gitignore @@ -0,0 +1,21 @@ +aclocal.m4 +autom4te.cache +ChangeLog +compile +config.h +config.h.in +config.log +config.status +configure +depcomp +INSTALL +install-sh +Makefile +Makefile.in +missing +src/.deps/ +src/lpc-flash +src/*.o +src/Makefile +src/Makefile.in +stamp-h1 diff --git a/openbeacon/lpc13xx/lpc-flash/AUTHORS b/openbeacon/lpc13xx/lpc-flash/AUTHORS new file mode 100644 index 0000000..311b448 --- /dev/null +++ b/openbeacon/lpc13xx/lpc-flash/AUTHORS @@ -0,0 +1 @@ +Milosch Meriac \ No newline at end of file diff --git a/openbeacon/lpc13xx/lpc-flash/COPYING b/openbeacon/lpc13xx/lpc-flash/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/openbeacon/lpc13xx/lpc-flash/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/openbeacon/lpc13xx/lpc-flash/Makefile.am b/openbeacon/lpc13xx/lpc-flash/Makefile.am new file mode 100644 index 0000000..1bfdcf4 --- /dev/null +++ b/openbeacon/lpc13xx/lpc-flash/Makefile.am @@ -0,0 +1 @@ +SUBDIRS=src diff --git a/openbeacon/lpc13xx/lpc-flash/NEWS b/openbeacon/lpc13xx/lpc-flash/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/openbeacon/lpc13xx/lpc-flash/README b/openbeacon/lpc13xx/lpc-flash/README new file mode 100644 index 0000000..e69de29 diff --git a/openbeacon/lpc13xx/lpc-flash/bootstrap b/openbeacon/lpc13xx/lpc-flash/bootstrap new file mode 100755 index 0000000..8f9a824 --- /dev/null +++ b/openbeacon/lpc13xx/lpc-flash/bootstrap @@ -0,0 +1,5 @@ +#!/bin/bash + +git pull openbeacon master +git log . > ChangeLog +autoreconf --install diff --git a/openbeacon/lpc13xx/lpc-flash/configure.ac b/openbeacon/lpc13xx/lpc-flash/configure.ac new file mode 100644 index 0000000..cdff695 --- /dev/null +++ b/openbeacon/lpc13xx/lpc-flash/configure.ac @@ -0,0 +1,16 @@ +AC_INIT([lpc-flash],[0.1],[meriac@bitmanufaktur.de]) +AM_INIT_AUTOMAKE([-Wall -Werror]) +AC_PROG_CC +AC_PROG_CXX +AM_PROG_CC_C_O +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_FILES([ + Makefile + src/Makefile +]) +AC_OUTPUT +AC_CHECK_HEADERS([stdio.h]) +AC_C_INLINE +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_UINT8_T diff --git a/openbeacon/lpc13xx/lpc-flash/src/Makefile.am b/openbeacon/lpc13xx/lpc-flash/src/Makefile.am new file mode 100644 index 0000000..ce0d8d4 --- /dev/null +++ b/openbeacon/lpc13xx/lpc-flash/src/Makefile.am @@ -0,0 +1,4 @@ +AM_CFLAGS = --pedantic -std=gnu99 +bin_PROGRAMS = lpc-flash +lpc_flash_SOURCES = lpc-flash.c +lpc_flash_CPPFLAGS = -Wall -Werror diff --git a/openbeacon/lpc13xx/lpc-flash/src/lpc-flash.c b/openbeacon/lpc13xx/lpc-flash/src/lpc-flash.c new file mode 100644 index 0000000..2e53a75 --- /dev/null +++ b/openbeacon/lpc13xx/lpc-flash/src/lpc-flash.c @@ -0,0 +1,165 @@ +/*************************************************************** + * + * OpenPCD.org - main entry for LPC flashing tool + * + * Copyright 2010 Milosch Meriac + * Copyright 2010 Henryk Plötz + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 3. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ + +/* Library includes. */ +#include +#include +#include +#include +#include +#include + +/* static buffer for the maximal flash size: 32 kibibytes + */ +static uint8_t data[32 * 1024]; + +static void print_usage(char *progname) +{ + fprintf(stderr, + "usage: %s inputfirmware.bin \"/media/CRP DISABLD/firmware.bin\"\n\n" + "Either or both input and output may be -, which indicates to work\n" + "on stdin or stdout\n\n", progname); +} + +static int parse_arguments(int argc, char **argv, int *input, int *output) +{ + if (argc != 3) { + print_usage(argv[0]); + return 0; + } + + /* open input file */ + if (strcmp(argv[1], "-") != 0) { + if ((*input = open(argv[1], O_RDONLY)) == -1) { + perror("Can't open input file for reading"); + return 0; + } + } else { + *input = 0; + } + + /* open output file */ + if (strcmp(argv[2], "-") != 0) { + if ((*output = open(argv[2], O_WRONLY | O_CREAT, 00664)) == -1) { + perror("Can't open output file for writing"); + close(*input); + return 0; + } + } else { + *output = 1; + } + + return 1; +} + +/** + * Converts Little-Endian data to host byte order + * \param ledata is a 32-bit integer stored in little endian order + * \return \e ledata converted to host byte order + */ +uint32_t letohl(uint32_t ledata) +{ + /* first convert input to big endian, then use ntohl */ + uint32_t bedata = + (((ledata >> 0) & 0xff) << 24) | (((ledata >> 8) & 0xff) << 16) | + (((ledata >> 16) & 0xff) << 8) | (((ledata >> 24) & 0xff) << 0); + return ntohl(bedata); +} + +/** + * Converts host byte order data to Little-Endian + * \param hdata is a 32-bit integer stored in host byte order + * \return \e hdata converted to little endian order + */ +uint32_t htolel(uint32_t hdata) +{ + /* use htonl, then convert from big endian */ + uint32_t bedata = htonl(hdata); + return (((bedata >> 0) & 0xff) << 24) | (((bedata >> 8) & 0xff) << 16) + | (((bedata >> 16) & 0xff) << 8) | (((bedata >> 24) & 0xff) << 0); +} + + +int main(int argc, char **argv) +{ + int input = -1, output = -1; + + if (!parse_arguments(argc, argv, &input, &output)) { + return 1; + } + + /* Read in the entire input file */ + ssize_t len_read, input_size = 0; + while ((len_read = + read(input, data + input_size, + sizeof(data) - input_size)) > 0) { + input_size += len_read; + } + + if (input_size < 8 * 4) { + fprintf(stderr, + "Error: Input file is too small, does not contain \n" + "at least 8 interrupt vectors\n"); + print_usage(argv[0]); + return 2; + } + + /* Now sum over the first 7 ISR values */ + uint32_t accumulator = 0, isr_value; + for (int i = 0; i < 7; i++) { + isr_value = ((uint32_t *) data)[i]; + /* The contents in the file are stored in little endian, need to + * convert to host byte order. + */ + isr_value = letohl(isr_value); + + accumulator += isr_value; + } + + /* The checksum is the twos complement of the sum */ + uint32_t checksum = ~accumulator + 1; + + /* Needs to be converted to little endian when storing */ + ((uint32_t *) data)[7] = htolel(checksum); + + /* Now write out the whole file */ + ssize_t len_written, output_size = 0; + while ((len_written = + write(output, data + output_size, + input_size - output_size)) > 0) { + output_size += len_written; + } + + if (output_size != input_size) { + perror("couldn't write complete output file, flash size might be" + "smaller than input size"); + } + + /* close & flush files */ + close(input); + fsync(output); + close(output); + + return 0; +} diff --git a/openbeacon/lpc13xx/openbeacon-sensor/Makefile b/openbeacon/lpc13xx/openbeacon-sensor/Makefile new file mode 100644 index 0000000..86afebc --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/Makefile @@ -0,0 +1,32 @@ +TARGET=openbeacon-sensor +ARCH=LPC13 +CPU=$(ARCH)42 +DEBUG=-g +OPTIM=-Os -mword-relocations + +APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS +APP_LDFLAGS=-lm + +APP_SRC= \ + src/main.c \ + src/pmu.c \ + src/sound.c \ + src/nRF_CMD.c \ + src/nRF_API.c \ + src/3d_acceleration.c + +APP_SRC+=$(IMAGES_C) + +all: $(TARGET).bin + +publish: clean $(TARGET).bin + rm -f $(TARGET).zip + ../lpc-flash/src/lpc-flash $(TARGET).bin firmware.bin + zip $(TARGET).zip firmware.bin + scp $(TARGET).zip firmware.bin meri@bitmanufaktur.net:/home/wwwrun/open.bitmanufaktur.com/web/www/people/milosch/usb2tag/ + +app_clean: + rm -f $(TARGET).zip $(TARGET)-firmware.bin + find src -name '*.o' -exec rm \{\} \; + +include ../core/Makefile.rules diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/3d_acceleration.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/3d_acceleration.h new file mode 100644 index 0000000..344acb6 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/3d_acceleration.h @@ -0,0 +1,32 @@ +/*************************************************************** + * + * OpenBeacon.org - 3D acceleration sensor support + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __3D_ACCELERATION_H__ +#define __3D_ACCELERATION_H__ + +extern void acc_init (uint8_t enabled); +extern void acc_power (uint8_t enabled); +extern void acc_status (void); +extern void acc_xyz_read (int *x, int *y, int *z); + +#endif/*__3D_ACCELERATION_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/config.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/config.h new file mode 100644 index 0000000..d3c3453 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/config.h @@ -0,0 +1,44 @@ +/*************************************************************** + * + * OpenBeacon.org - config file + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +/* Treshold for detecting 3D accelerometer movement */ +#define ACC_TRESHOLD 3 +#define ACC_MOVING_TRESHOLD 20 + +/* Clock Definition */ +#define SYSTEM_CRYSTAL_CLOCK 12000000 +#define SYSTEM_CORE_CLOCK (SYSTEM_CRYSTAL_CLOCK*6) + +/* Enable Sound Output */ +#define SOUND_ENABLE + +/* SPI_CS(io_port, io_pin, CPSDVSR frequency, mode) */ +#define SPI_CS_NRF SPI_CS( 1,10, 8, SPI_CS_MODE_NORMAL ) /* 9.0MHz */ +#define SPI_CS_ACC3D SPI_CS( 0, 4,18, SPI_CS_MODE_NORMAL ) /* 4.0MHz */ + +#define NRF_MAX_MAC_SIZE 5 + +#endif/*__CONFIG_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_API.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_API.h new file mode 100644 index 0000000..c246d57 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_API.h @@ -0,0 +1,60 @@ +/*************************************************************** + * + * OpenBeacon.org - function definitions + * + * Copyright 2007 Milosch Meriac + * + * provides high level initialization and startup sanity + * checks and test routines to verify that the chip is working + * properly and no soldering errors occored on the digital part. + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#ifndef NRF_API_H +#define NRF_API_H + +#include + +extern uint8_t nRFAPI_Init (uint8_t channel, const uint8_t * mac, uint8_t mac_size, uint8_t features); +extern void nRFAPI_SetTxPower (uint8_t power); +extern void nRFAPI_TxRetries (uint8_t count); +extern void nRFAPI_SetRxMode (uint8_t receive); +extern void nRFAPI_PipesEnable (uint8_t mask); +extern void nRFAPI_PipesAck (uint8_t mask); +extern uint8_t nRFAPI_GetSizeMac (void); +extern uint8_t nRFAPI_SetSizeMac (uint8_t addr_size); +extern void nRFAPI_GetTxMAC (uint8_t * addr, uint8_t addr_size); +extern void nRFAPI_SetTxMAC (const uint8_t * addr, uint8_t addr_size); +extern void nRFAPI_SetRxMAC (const uint8_t * addr, uint8_t addr_size, uint8_t pipe); +extern void nRFAPI_SetChannel (uint8_t channel); +extern uint8_t nRFAPI_GetChannel (void); +extern uint8_t nRFAPI_ClearIRQ (uint8_t status); +extern void nRFAPI_TX (uint8_t * buf, uint8_t count); +extern uint8_t nRFAPI_GetStatus (void); +extern uint8_t nRFAPI_GetPipeSizeRX (uint8_t pipe); +extern void nRFAPI_SetPipeSizeRX (uint8_t pipe, uint8_t size); +extern uint8_t nRFAPI_GetPipeCurrent (void); +extern uint8_t nRFAPI_RX (uint8_t * buf, uint8_t count); +extern void nRFAPI_FlushRX (void); +extern void nRFAPI_FlushTX (void); +extern void nRFAPI_ReuseTX (void); +extern uint8_t nRFAPI_GetFifoStatus (void); +extern uint8_t nRFAPI_CarrierDetect (void); +extern void nRFAPI_SetFeatures (uint8_t features); +extern void nRFAPI_PowerDown (void); + +#endif /*NRF_API_H */ diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_CMD.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_CMD.h new file mode 100644 index 0000000..15723f8 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_CMD.h @@ -0,0 +1,45 @@ +/*************************************************************** + * + * OpenBeacon.org - midlevel access function defines for + * issuing raw commands to the nRF24L01 2.4Ghz frontend + * + * Copyright 2007 Milosch Meriac + * + * provides generic register level access functions + * for accessing nRF24L01 registers at a generic level + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#ifndef NRF_CMD_H +#define NRF_CMD_H + +extern uint8_t nRFCMD_CmdExec (uint8_t reg); +extern uint8_t nRFCMD_RegRead (uint8_t reg); +extern uint8_t nRFCMD_RegWriteStatusRead (uint8_t reg, uint8_t value); +extern uint8_t nRFCMD_RegWriteBuf (uint8_t reg, const uint8_t * buf, uint8_t count); +extern uint8_t nRFCMD_RegReadBuf (uint8_t reg, uint8_t * buf, uint8_t count); +extern uint8_t nRFCMD_GetRegSize (uint8_t reg); +extern uint8_t nRFCMD_WaitRx (uint32_t ticks); +extern void nRFCMD_CE (uint8_t enable); +extern void nRFCMD_Power (uint8_t enable); +extern void nRFCMD_ReadWriteBuffer (const uint8_t * tx_data, uint8_t * rx_data, uint32_t len); +extern void nRFCMD_ExecMacro (const uint8_t * macro); +extern void nRFCMD_RegisterDump (void); +extern void nRFCMD_Init (void); +extern void nRFCMD_Status (void); + +#endif /*NRF_CMD_H */ diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_HW.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_HW.h new file mode 100644 index 0000000..c4d17dc --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_HW.h @@ -0,0 +1,109 @@ +/*************************************************************** + * + * OpenBeacon.org - opcode & register definitions for nRF24L01 + * + * Copyright 2007 Milosch Meriac + * + * provides a nice set of defines to work properly with the + * nRF24L01 CPU + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#ifndef NRF_HW_H +#define NRF_HW_H + +//********************************************************************************************************************// +// SPI(nRF24L01) commands +#define READ_REG 0x00 // Define read command to register +#define WRITE_REG 0x20 // Define write command to register +#define RD_RX_PLOAD 0x61 // Define RX payload register address +#define WR_TX_PLOAD 0xA0 // Define TX payload register address +#define FLUSH_TX 0xE1 // Define flush TX register command +#define FLUSH_RX 0xE2 // Define flush RX register command +#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command +#define OP_NOP 0xFF // Define No Operation, might be used to read status register +#define ACTIVATE 0x50 // ACTIVATE additional features +#define R_RX_PL_WID 0x60 // Define Read RX-payload width command +#define W_ACK_PAYLOAD 0xA8 // Write payload to be used in ACK packet on pipe PPP +#define W_TX_PAYLOAD_NOACK 0xB0 // Used in TX mode, Disable AUTOACK on this specific packet + + +//********************************************************************************************************************// +// SPI(nRF24L01) registers(addresses) +#define CONFIG 0x00 // 'Config' register address +#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address +#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address +#define SETUP_AW 0x03 // 'Setup address width' register address +#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address +#define RF_CH 0x05 // 'RF channel' register address +#define RF_SETUP 0x06 // 'RF setup' register address +#define STATUS 0x07 // 'Status' register address +#define OBSERVE_TX 0x08 // 'Observe TX' register address +#define CD 0x09 // 'Carrier Detect' register address +#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address +#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address +#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address +#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address +#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address +#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address +#define TX_ADDR 0x10 // 'TX address' register address +#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address +#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address +#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address +#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address +#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address +#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address +#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address +#define FEATURE 0x1D // Additional features register, needed to enable the additional commands + +//********************************************************************************************************************// +// SPI(nRF24L01) registers(bitmasks) +#define ERX_P0 0x01 // Enable Pipe 0 (register EN_RXADDR) +#define ERX_P1 0x02 // Enable Pipe 1 (register EN_RXADDR) +#define ERX_P2 0x04 // Enable Pipe 2 (register EN_RXADDR) +#define ERX_P3 0x08 // Enable Pipe 3 (register EN_RXADDR) +#define ERX_P4 0x10 // Enable Pipe 4 (register EN_RXADDR) +#define ERX_P5 0x20 // Enable Pipe 5 (register EN_RXADDR) + +//********************************************************************************************************************// +// 'Config' register mask bits +#define NRF_CONFIG_PRIM_RX 0x01 +#define NRF_CONFIG_PWR_UP 0x02 +#define NRF_CONFIG_CRCO 0x04 +#define NRF_CONFIG_EN_CRC 0x08 +#define NRF_CONFIG_MASK_MAX_RT 0x10 +#define NRF_CONFIG_MASK_TX_DS 0x20 +#define NRF_CONFIG_MASK_RX_DR 0x40 +#define NRF_CONFIG_MASK_IRQS (NRF_CONFIG_MASK_MAX_RT|NRF_CONFIG_MASK_TX_DS|NRF_CONFIG_MASK_RX_DR) + + +#define MASK_RX_DR_FLAG 0x40 +#define MASK_TX_DS_FLAG 0x20 +#define MASK_MAX_RT_FLAG 0x10 +#define MASK_IRQ_FLAGS (MASK_MAX_RT_FLAG|MASK_TX_DS_FLAG|MASK_RX_DR_FLAG) + +#define FIFO_RX_EMPTY 0x01 +#define FIFO_RX_FULL 0x02 +#define FIFO_TX_EMPTY 0x10 +#define FIFO_TX_FULL 0x20 +#define FIFO_TX_REUSE 0x40 + +#define NRF_MIN_MAC_SIZE 3 +#define NRF_MAX_MAC_SIZE 5 +#define NRF_MAX_BUFFER_SIZE 32 + +#endif /*NRF_HW_H */ diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/openbeacon-proto.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/openbeacon-proto.h new file mode 100644 index 0000000..6e7dded --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/openbeacon-proto.h @@ -0,0 +1,109 @@ +/**************************************************************************** + * + * OpenBeacon.org - OnAir protocol specification and definition + * + * Copyright 2007 Milosch Meriac + * + **************************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __OPENBEACON_PROTO_H__ +#define __OPENBEACON_PROTO_H__ + +#define CONFIG_TRACKER_CHANNEL 81 +#define CONFIG_PROX_CHANNEL 76 + +#define XXTEA_BLOCK_COUNT 4 + +#define RFBPROTO_READER_ANNOUNCE 22 +#define RFBPROTO_READER_COMMAND 23 +#define RFBPROTO_BEACONTRACKER 24 +#define RFBPROTO_PROXTRACKER 42 +#define RFBPROTO_PROXREPORT 69 + +#define PROX_MAX 4 + +#define RFBFLAGS_ACK 0x01 +#define RFBFLAGS_SENSOR 0x02 +#define RFBFLAGS_INFECTED 0x04 + +/* RFBPROTO_READER_COMMAND related opcodes */ +#define READER_CMD_NOP 0x00 +#define READER_CMD_RESET 0x01 +#define READER_CMD_RESET_CONFIG 0x02 +#define READER_CMD_RESET_FACTORY 0x03 +#define READER_CMD_RESET_WIFI 0x04 +#define READER_CMD_SET_OID 0x05 +/* RFBPROTO_READER_COMMAND related results */ +#define READ_RES__OK 0x00 +#define READ_RES__DENIED 0x01 +#define READ_RES__UNKNOWN_CMD 0xFF + +typedef struct +{ + uint8_t strength; + uint16_t oid_last_seen; + uint16_t powerup_count; + uint8_t reserved; + uint32_t seq; +} PACKED TBeaconTracker; + +typedef struct +{ + uint16_t oid_prox[PROX_MAX]; + uint16_t seq; +} PACKED TBeaconProx; + +typedef struct +{ + uint8_t opcode, res; + uint32_t data[2]; +} PACKED TBeaconReaderCommand; + +typedef struct +{ + uint8_t opcode, strength; + uint32_t uptime, ip; +} PACKED TBeaconReaderAnnounce; + +typedef union +{ + TBeaconProx prox; + TBeaconTracker tracker; + TBeaconReaderCommand reader_command; + TBeaconReaderAnnounce reader_announce; +} PACKED TBeaconPayload; + +typedef struct +{ + uint8_t proto; + uint16_t oid; + uint8_t flags; + + TBeaconPayload p; + + uint16_t crc; +} PACKED TBeaconWrapper; + +typedef union +{ + TBeaconWrapper pkt; + uint32_t block[XXTEA_BLOCK_COUNT]; + uint8_t byte[XXTEA_BLOCK_COUNT * 4]; +} PACKED TBeaconEnvelope; + +#endif/*__OPENBEACON_PROTO_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/pmu.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/pmu.h new file mode 100644 index 0000000..f19494a --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/pmu.h @@ -0,0 +1,31 @@ +/*************************************************************** + * + * OpenBeacon.org - LPC13xx Power Management Functions + * + * Copyright 2011 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ + +#ifndef __PMU_H__ +#define __PMU_H__ + +extern void pmu_wait_ms (uint16_t ms); +extern void pmu_sleep_ms (uint16_t ms); +extern void pmu_init (void); + +#endif/*__PMU_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/sound.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/sound.h new file mode 100644 index 0000000..5c7f1aa --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/sound.h @@ -0,0 +1,33 @@ +/*************************************************************** + * + * OpenBeacon.org - piezo speaker sound functions + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ + +#ifndef __SOUND_H__ +#define __SOUND_H__ + +#define TONES_MAX 32 + +extern void snd_beep (uint16_t frequency); +extern void snd_tone (uint8_t tone); +extern void snd_init (void); + +#endif/*__SOUND_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/3d_acceleration.c b/openbeacon/lpc13xx/openbeacon-sensor/src/3d_acceleration.c new file mode 100644 index 0000000..1cc3eba --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/src/3d_acceleration.c @@ -0,0 +1,100 @@ +/*************************************************************** + * + * OpenBeacon.org - 3D acceleration sensor support + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#include +#include "3d_acceleration.h" +#include "spi.h" + +static void +acc_reg_write (uint8_t addr, uint8_t data) +{ + uint8_t tx[2]; + + /* assemble SPI write request */ + tx[0] = 0x80 | addr << 1; + tx[1] = data; + + /* transmit packet */ + spi_txrx (SPI_CS_ACC3D, tx, sizeof (tx), NULL, 0); +} + +static uint8_t +acc_reg_read (uint8_t addr) +{ + uint8_t tx[2], rx[2]; + + /* assemble SPI read request */ + tx[0] = addr << 1; + tx[1] = 0; + /* transmit packet */ + spi_txrx (SPI_CS_ACC3D, tx, sizeof (tx), rx, sizeof (rx)); + + return rx[1]; +} + +void +acc_xyz_read (int *x, int *y, int *z) +{ + /* dummy read - FIXME */ + acc_reg_read (0); + + /* get acceleration values */ + *x = (int8_t) acc_reg_read (6); + *y = (int8_t) acc_reg_read (7); + *z = (int8_t) acc_reg_read (8); +} + +void +acc_status (void) +{ + int x, y, z; + + acc_xyz_read (&x, &y, &z); + + debug_printf (" * 3D_ACC: X=%04i Y=%04i Z=%04i\n", x, y, z); +} + +void +acc_power (uint8_t enabled) +{ + /* dummy read - FIXME */ + acc_reg_read (0); + /* set 3D acceleration sensor active, 2g - FIXME power saving */ + acc_reg_write (0x16, enabled ? (0x01 | 0x01 << 2) : 0x00); +} + +void +acc_init (uint8_t enabled) +{ + /* PIO, PIO0_4 in standard IO functionality */ + LPC_IOCON->PIO0_4 = 1 << 8; + + /* setup SPI chipselect pin */ + spi_init_pin (SPI_CS_ACC3D); + + /* PIO, Inactive Pull, Digital Mode */ + LPC_IOCON->PIO1_11 = 0x80; + GPIOSetDir (1, 11, 0); + + /* propagate power settings */ + acc_power (enabled); +} diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/main.c b/openbeacon/lpc13xx/openbeacon-sensor/src/main.c new file mode 100644 index 0000000..ad236a2 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/src/main.c @@ -0,0 +1,346 @@ +/*************************************************************** + * + * OpenBeacon.org - main file for OpenBeacon Sensor (CR123A) + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#include +#include "3d_acceleration.h" +#include "sound.h" +#include "xxtea.h" +#include "pmu.h" +#include "iap.h" +#include "spi.h" +#include "nRF_API.h" +#include "nRF_CMD.h" +#include "openbeacon-proto.h" + +uint32_t g_sysahbclkctrl; + +#define FIFO_DEPTH 10 +typedef struct { + int x,y,z; +} TFifoEntry; + +#define MAINCLKSEL_IRC 0 +#define MAINCLKSEL_SYSPLL_IN 1 +#define MAINCLKSEL_WDT 2 +#define MAINCLKSEL_SYSPLL_OUT 3 + +/* device UUID */ +static uint16_t tag_id; +static TDeviceUID device_uuid; + +/* OpenBeacon packet */ +static TBeaconEnvelope g_Beacon; + +/* Default TEA encryption key of the tag - MUST CHANGE ! */ +static const uint32_t xxtea_key[4] = { 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF }; + +/* set nRF24L01 broadcast mac */ +static const unsigned char broadcast_mac[NRF_MAX_MAC_SIZE] = { 1, 2, 3, 2, 1 }; + +static void +nRF_tx (uint8_t power) +{ + /* encrypt data */ + xxtea_encode(g_Beacon.block, XXTEA_BLOCK_COUNT, xxtea_key); + + /* set TX power */ + nRFAPI_SetTxPower (power & 0x3); + + /* upload data to nRF24L01 */ + nRFAPI_TX ((uint8_t*)&g_Beacon, sizeof(g_Beacon)); + + /* transmit data */ + nRFCMD_CE (1); + + /* wait for packet to be transmitted */ + pmu_sleep_ms (10); + + /* transmit data */ + nRFCMD_CE (0); +} + +void +nrf_off (void) +{ + /* disable RX mode */ + nRFCMD_CE (0); + + /* wait till RX is done */ + pmu_sleep_ms (5); + + /* switch to TX mode */ + nRFAPI_SetRxMode (0); + +} + +int +main (void) +{ + /* accelerometer readings fifo */ + TFifoEntry acc_lowpass; + TFifoEntry fifo_buf[FIFO_DEPTH]; + int fifo_pos; + TFifoEntry *fifo; + uint32_t seq; + + volatile int i; + int x, y, z, firstrun, tamper, moving; + + /* wait on boot - debounce */ + for (i = 0; i < 2000000; i++); + + /* Initialize GPIO (sets up clock) */ + GPIOInit (); + + /* initialize power management */ + pmu_init (); + + /* NVIC is installed inside UARTInit file. */ + UARTInit (115200, 0); + + LPC_IOCON->PIO2_0 = 0; + GPIOSetDir (2, 0, 1); //OUT + GPIOSetValue (2, 0, 0); + + LPC_IOCON->RESET_PIO0_0 = 0; + GPIOSetDir (0, 0, 0); //IN + + LPC_IOCON->PIO0_1 = 0; + GPIOSetDir (0, 1, 0); //IN + + LPC_IOCON->PIO1_8 = 0; + GPIOSetDir (1, 8, 1); //OUT + GPIOSetValue (1, 8, 0); + + LPC_IOCON->PIO0_2 = 0; + GPIOSetDir (0, 2, 1); //OUT + GPIOSetValue (0, 2, 0); + + LPC_IOCON->PIO0_3 = 0; + GPIOSetDir (0, 3, 0); //IN + + LPC_IOCON->PIO0_4 = 1 << 8; + GPIOSetDir (0, 4, 1); //OUT + GPIOSetValue (0, 4, 1); + + LPC_IOCON->PIO0_5 = 1 << 8; + GPIOSetDir (0, 5, 1); //OUT + GPIOSetValue (0, 5, 1); + + LPC_IOCON->PIO1_9 = 0; //FIXME + GPIOSetDir (1, 9, 1); //OUT + GPIOSetValue (1, 9, 0); + + LPC_IOCON->PIO0_6 = 0; + GPIOSetDir (0, 6, 1); //OUT + GPIOSetValue (0, 6, 1); + + LPC_IOCON->PIO0_7 = 0; + GPIOSetDir (0, 7, 1); //OUT + GPIOSetValue (0, 7, 0); + + /* select UART_TXD */ + LPC_IOCON->PIO1_7 = 1; + + LPC_IOCON->PIO1_6 = 0; + GPIOSetDir (1, 6, 1); //OUT + GPIOSetValue (1, 6, 0); + + LPC_IOCON->PIO1_5 = 0; + GPIOSetDir (1, 5, 1); //OUT + GPIOSetValue (1, 5, 0); + + LPC_IOCON->PIO3_2 = 0; // FIXME + GPIOSetDir (3, 2, 1); //OUT + GPIOSetValue (3, 2, 1); + + LPC_IOCON->PIO1_11 = 0x80; //FIXME + GPIOSetDir (1, 11, 1); // OUT + GPIOSetValue (1, 11, 0); + + LPC_IOCON->PIO1_4 = 0x80; + GPIOSetDir (1, 4, 0); // IN + + LPC_IOCON->ARM_SWDIO_PIO1_3 = 0x81; + GPIOSetDir (1, 3, 1); // OUT + GPIOSetValue (1, 3, 0); + + LPC_IOCON->JTAG_nTRST_PIO1_2 = 0x81; + GPIOSetDir (1, 2, 1); // OUT + GPIOSetValue (1, 2, 0); + + LPC_IOCON->JTAG_TDO_PIO1_1 = 0x81; + GPIOSetDir (1, 1, 1); // OUT + GPIOSetValue (1, 1, 0); + + LPC_IOCON->JTAG_TMS_PIO1_0 = 0x81; + GPIOSetDir (1, 0, 1); // OUT + GPIOSetValue (1, 0, 0); + + LPC_IOCON->JTAG_TDI_PIO0_11 = 0x81; + GPIOSetDir (0, 11, 1); // OUT + GPIOSetValue (0, 11, 0); + + LPC_IOCON->PIO1_10 = 0x80; + GPIOSetDir (1, 10, 1); // OUT + GPIOSetValue (1, 10, 1); + + LPC_IOCON->JTAG_TCK_PIO0_10 = 0x81; + GPIOSetDir (0, 10, 1); // OUT + GPIOSetValue (0, 10, 0); + + LPC_IOCON->PIO0_9 = 0; + GPIOSetDir (0, 9, 1); // OUT + GPIOSetValue (0, 9, 0); + + /* select MISO function for PIO0_8 */ + LPC_IOCON->PIO0_8 = 1; + + /* initialize SPI */ + spi_init (); + +#ifdef SOUND_ENABLE + /* Init Speaker Output */ + snd_init (); +#endif /*SOUND_ENABLE */ + + /* Init 3D acceleration sensor */ + acc_init (0); + + /* read device UUID */ + bzero (&device_uuid, sizeof (device_uuid)); + iap_read_uid (&device_uuid); + tag_id = crc16 ((uint8_t *) & device_uuid, sizeof (device_uuid)); + + /* Initialize OpenBeacon nRF24L01 interface */ + if (!nRFAPI_Init (81, broadcast_mac, sizeof (broadcast_mac), 0)) + for (;;) + { + GPIOSetValue (1, 3, 1); + pmu_sleep_ms (100); + GPIOSetValue (1, 3, 0); + pmu_sleep_ms (400); + } + /* set tx power power to high */ + nRFCMD_Power (1); + + /* blink LED for 1s to show readyness */ + GPIOSetValue (1, 3, 1); + pmu_sleep_ms (1000); + GPIOSetValue (1, 3, 0); + + /* reset fifo */ + fifo_pos=0; + bzero(&fifo_buf,sizeof(fifo_buf)); + bzero(&acc_lowpass,sizeof(acc_lowpass)); + + seq = firstrun = tamper = moving = 0; + while (1) + { + /* read acceleration sensor */ + nRFAPI_SetRxMode(0); + acc_power (1); + pmu_sleep_ms (20); + acc_xyz_read (&x, &y, &z); + acc_power (0); + + /* prepare packet */ + bzero (&g_Beacon, sizeof (g_Beacon)); + g_Beacon.pkt.proto = RFBPROTO_BEACONTRACKER; + g_Beacon.pkt.oid = htons (tag_id); + g_Beacon.pkt.p.tracker.strength = 5; + g_Beacon.pkt.p.tracker.seq = htonl (seq++); + g_Beacon.pkt.p.tracker.reserved = moving; + g_Beacon.pkt.crc = htons(crc16 (g_Beacon.byte, sizeof (g_Beacon) - sizeof (g_Beacon.pkt.crc))); + /* transmit packet */ + nRF_tx (g_Beacon.pkt.p.tracker.strength); + /* powering down */ + nRFAPI_PowerDown (); + + /* add new accelerometer values to lowpass */ + fifo = &fifo_buf[fifo_pos]; + if(fifo_pos>=(FIFO_DEPTH-1)) + fifo_pos=0; + else + fifo_pos++; + + acc_lowpass.x += x - fifo->x; + fifo->x = x; + acc_lowpass.y += y - fifo->y; + fifo->y = y; + acc_lowpass.z += z - fifo->z; + fifo->z = z; + + if (!firstrun) + { + if(fifo_pos) + { + pmu_sleep_ms (500); + continue; + } + else + { + /* confirm finalized initialization by double-blink */ + firstrun = 1; + GPIOSetValue (1, 3, 1); + pmu_sleep_ms (100); + GPIOSetValue (1, 3, 0); + pmu_sleep_ms (300); + GPIOSetValue (1, 3, 1); + pmu_sleep_ms (100); + GPIOSetValue (1, 3, 0); + } + } + else + if ((abs (acc_lowpass.x/FIFO_DEPTH - x) >= ACC_TRESHOLD) || + (abs (acc_lowpass.y/FIFO_DEPTH - y) >= ACC_TRESHOLD) || + (abs (acc_lowpass.z/FIFO_DEPTH - z) >= ACC_TRESHOLD)) + tamper = 5; + + if (tamper) + { + pmu_sleep_ms (750); + tamper--; + if (moving < ACC_MOVING_TRESHOLD) + moving++; + else + { + snd_tone (22); + GPIOSetValue (1, 3, 1); + pmu_wait_ms (20); + GPIOSetValue (1, 3, 0); + snd_tone (23); + pmu_wait_ms (50); + snd_tone (24); + pmu_wait_ms (30); + snd_tone (0); + } + } + else + { + pmu_sleep_ms (5000); + moving = 0; + } + } + + return 0; +} diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_API.c b/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_API.c new file mode 100644 index 0000000..eb37f10 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_API.c @@ -0,0 +1,330 @@ +/*************************************************************** + * + * OpenBeacon.org - high level nRF24L01 access functions + * + * Copyright 2007 Milosch Meriac + * + * provides high level initialization and startup sanity + * checks and test routines to verify that the chip is working + * properly and no soldering errors occored on the digital part. + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#include +#include "pmu.h" +#include "nRF_HW.h" +#include "nRF_CMD.h" +#include "nRF_API.h" + +#ifndef NRF_RFOPTIONS +#define NRF_RFOPTIONS 0x09 +#endif /*NRF_RFOPTIONS */ + +// set broadcast MAC to 'BCAST' +const uint8_t rfbroadcast_mac[NRF_MAX_MAC_SIZE] = { 'T', 'S', 'A', 'C', 'B' }; + +uint8_t +nRFAPI_DetectChip (void) +{ + uint8_t mac[NRF_MAX_MAC_SIZE], i; + + // blank read + nRFAPI_GetStatus (); + + // set dummy MAC size + nRFAPI_SetSizeMac (NRF_MIN_MAC_SIZE); + + // verify dummy MAC size + if (nRFAPI_GetSizeMac () != NRF_MIN_MAC_SIZE) + return 0; + + // set dummy MAC size + nRFAPI_SetSizeMac (NRF_MAX_MAC_SIZE); + + // verify dummy MAC size + if (nRFAPI_GetSizeMac () != NRF_MAX_MAC_SIZE) + return 0; + + // set dummy MAC + nRFAPI_SetTxMAC (rfbroadcast_mac, NRF_MAX_MAC_SIZE); + + // get dummy MAC + memset (&mac, 0, sizeof (mac)); + nRFAPI_GetTxMAC (mac, NRF_MAX_MAC_SIZE); + + // if can't verify written MAC - return with error + for (i = 0; i < NRF_MAX_MAC_SIZE; i++) + if (mac[i] != rfbroadcast_mac[i]) + return 0; + + // everything is fine + return 1; +} + +void +nRFAPI_SetRxMode (uint8_t receive) +{ + nRFCMD_RegWriteStatusRead (CONFIG | WRITE_REG, receive ? 0x3B : 0x3A); +} + +void +nRFAPI_PowerDown (void) +{ + nRFCMD_RegWriteStatusRead (CONFIG | WRITE_REG, 0x00); +} + +uint8_t +nRFAPI_Init (uint8_t channel, + const uint8_t * mac, uint8_t mac_size, uint8_t features) +{ + uint8_t i; + + // init IO layer of nRF24L01 + nRFCMD_Init (); + + /* wait for nRF to boot */ + pmu_sleep_ms(10); + + // check validity + if (mac_size < 3 || mac_size > 5 || !nRFAPI_DetectChip ()) + return 0; + + // update mac + nRFAPI_SetSizeMac (mac_size); + nRFAPI_SetTxMAC (mac, mac_size); + + // enables pipe + nRFAPI_SetRxMAC (mac, mac_size, 0); + nRFAPI_PipesEnable (ERX_P0); + nRFAPI_PipesAck (0); + + // set payload sizes + for (i = 0; i <= 5; i++) + nRFAPI_SetPipeSizeRX (i, 16); + + // set TX retry count + nRFAPI_TxRetries (0); + + // set selected channel + nRFAPI_SetChannel (channel); + + // set Tx power + nRFAPI_SetTxPower (3); + + // flush FIFOs + nRFAPI_FlushRX (); + nRFAPI_FlushTX (); + + if (features != 0) + nRFAPI_SetFeatures (features); + + return 1; +} + +void +nRFAPI_SetTxPower (uint8_t power) +{ + if (power > 3) + power = 3; + + nRFCMD_RegWriteStatusRead (RF_SETUP | WRITE_REG, + NRF_RFOPTIONS | (power << 1)); +} + +void +nRFAPI_TxRetries (uint8_t count) +{ + if (count > 15) + count = 15; + + // setup delay of 500us+86us + nRFCMD_RegWriteStatusRead (SETUP_RETR | WRITE_REG, 0x10 | count); +} + +void +nRFAPI_PipesEnable (uint8_t mask) +{ + nRFCMD_RegWriteStatusRead (EN_RXADDR | WRITE_REG, mask & 0x3F); +} + +void +nRFAPI_PipesAck (uint8_t mask) +{ + nRFCMD_RegWriteStatusRead (EN_AA | WRITE_REG, mask & 0x3F); +} + +uint8_t +nRFAPI_GetSizeMac (void) +{ + uint8_t addr_size; + + addr_size = nRFCMD_RegRead (SETUP_AW) & 0x03; + + return addr_size ? addr_size + 2 : 0; +} + +uint8_t +nRFAPI_SetSizeMac (uint8_t addr_size) +{ + if (addr_size >= 3 && addr_size <= 5) + addr_size -= 2; + else + addr_size = 0; + + nRFCMD_RegWriteStatusRead (SETUP_AW | WRITE_REG, addr_size); + + return addr_size; +} + +void +nRFAPI_GetTxMAC (uint8_t * addr, uint8_t addr_size) +{ + if (addr_size >= 3 && addr_size <= 5) + nRFCMD_RegReadBuf (TX_ADDR, addr, addr_size); +} + +void +nRFAPI_SetTxMAC (const uint8_t * addr, uint8_t addr_size) +{ + if (addr_size >= 3 && addr_size <= 5) + nRFCMD_RegWriteBuf (TX_ADDR | WRITE_REG, addr, addr_size); +} + +void +nRFAPI_SetRxMAC (const uint8_t * addr, uint8_t addr_size, uint8_t pipe) +{ + if ((pipe <= 1 && addr_size >= 3 && addr_size <= 5) + || (addr_size == 1 && pipe >= 2 && pipe <= 5)) + nRFCMD_RegWriteBuf ((RX_ADDR_P0 + pipe) | WRITE_REG, addr, addr_size); +} + +void +nRFAPI_SetChannel (uint8_t channel) +{ + nRFCMD_RegWriteStatusRead (RF_CH | WRITE_REG, channel & 0x7f); +} + +uint8_t +nRFAPI_GetChannel (void) +{ + return nRFCMD_RegRead (RF_CH) & 0x7F; +} + +uint8_t +nRFAPI_ClearIRQ (uint8_t status) +{ + return nRFCMD_RegWriteStatusRead (STATUS | WRITE_REG, + status & MASK_IRQ_FLAGS); +} + +void +nRFAPI_TX (uint8_t * buf, uint8_t count) +{ + nRFCMD_RegWriteBuf (WR_TX_PLOAD, buf, count); +} + +uint8_t +nRFAPI_GetStatus (void) +{ + return nRFCMD_CmdExec (OP_NOP); +} + +uint8_t +nRFAPI_GetPipeSizeRX (uint8_t pipe) +{ + if (pipe <= 5) + return nRFCMD_RegRead (RX_PW_P0 + pipe); + else + return 0; +} + +void +nRFAPI_SetPipeSizeRX (uint8_t pipe, uint8_t size) +{ + if (pipe <= 5) + nRFCMD_RegWriteStatusRead ((RX_PW_P0 + pipe) | WRITE_REG, size); +} + +uint8_t +nRFAPI_GetPipeCurrent (void) +{ + return (nRFAPI_GetStatus () >> 1) & 0x7; +} + +uint8_t +nRFAPI_RX (uint8_t * buf, uint8_t count) +{ + uint8_t size, pipe; + + pipe = nRFAPI_GetPipeCurrent (); + if (pipe >= 7) + size = 0; + else + { + size = nRFAPI_GetPipeSizeRX (pipe); + + if (size <= count) + nRFCMD_RegReadBuf (RD_RX_PLOAD, buf, size); + else + { + nRFAPI_FlushRX (); + size = 0; + } + } + + return size; +} + +void +nRFAPI_FlushRX (void) +{ + nRFCMD_CmdExec (FLUSH_RX); +} + +void +nRFAPI_FlushTX (void) +{ + nRFCMD_CmdExec (FLUSH_TX); +} + +void +nRFAPI_ReuseTX (void) +{ + nRFCMD_CmdExec (REUSE_TX_PL); +} + +uint8_t +nRFAPI_GetFifoStatus (void) +{ + return nRFCMD_RegRead (FIFO_STATUS); +} + +uint8_t +nRFAPI_CarrierDetect (void) +{ + return nRFCMD_RegRead (CD); +} + +void +nRFAPI_SetFeatures (uint8_t features) +{ + unsigned const char ACTIVATE_SEQUENCE[] = { ACTIVATE, 0x73 }; + uint8_t dummy_buffer[sizeof (ACTIVATE_SEQUENCE)] = { 0, 0 }; + nRFCMD_ReadWriteBuffer (ACTIVATE_SEQUENCE, dummy_buffer, + sizeof (ACTIVATE_SEQUENCE)); + nRFCMD_RegWriteStatusRead (FEATURE, features); +} diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_CMD.c b/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_CMD.c new file mode 100644 index 0000000..a87e477 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_CMD.c @@ -0,0 +1,238 @@ +/*************************************************************** + * + * OpenBeacon.org - midlevel access functions for + * issuing raw commands to the nRF24L01 2.4Ghz frontend + * + * Copyright 2007 Milosch Meriac + * + * provides generic register level access functions + * for accessing nRF24L01 registers at a generic level + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#include +#include "pmu.h" +#include "nRF_API.h" +#include "nRF_HW.h" +#include "nRF_CMD.h" +#include "spi.h" + +/* IO definitions */ +#define RF_IRQ_CPU_PORT 1 +#define RF_IRQ_CPU_PIN 9 +#define CPU_CE_RF_PORT 0 +#define CPU_CE_RF_PIN 11 +#define CPU_SWITCH_RF_PORT 0 +#define CPU_SWITCH_RF_PIN 2 + +#define SPI_MAX_XFER_LEN 33 +#define NRFCMD_MACRO_READ 0x80 + +#define SPI_MAX_XFER_LEN 33 +#define NRFCMD_MACRO_READ 0x80 +static uint8_t spi_outbuf[SPI_MAX_XFER_LEN]; +static uint8_t spi_inbuf[SPI_MAX_XFER_LEN]; + +void +nRFCMD_CE (uint8_t enable) +{ + GPIOSetValue (CPU_CE_RF_PORT, CPU_CE_RF_PIN, enable ? 1 : 0); +} + +void +nRFCMD_Power (uint8_t enable) +{ + GPIOSetValue (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, enable ? 0 : 1); +} + +void +nRFCMD_ReadWriteBuffer (const uint8_t * tx_data, uint8_t * rx_data, + uint32_t len) +{ + spi_txrx (SPI_CS_NRF, tx_data, len, rx_data, len); +} + +static uint8_t +nRFCMD_ReadWriteByte (uint8_t reg) +{ + uint8_t res; + + nRFCMD_ReadWriteBuffer (®, &res, 1); + + return res; +} + +uint8_t +nRFCMD_CmdExec (uint8_t cmd) +{ + uint8_t res; + + res = nRFCMD_ReadWriteByte (cmd); + + return res; +} + +uint8_t +nRFCMD_RegRead (uint8_t reg) +{ + spi_outbuf[0] = reg; + spi_outbuf[1] = 0; + + nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, 2); + + return spi_inbuf[1]; +} + +uint8_t +nRFCMD_RegWriteStatusRead (uint8_t reg, uint8_t value) +{ + spi_outbuf[0] = reg; + spi_outbuf[1] = value; + + nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, 2); + + return spi_inbuf[0]; +} + +uint8_t +nRFCMD_RegWriteBuf (uint8_t reg, const uint8_t * buf, uint8_t count) +{ + spi_outbuf[0] = reg; + memcpy (spi_outbuf + 1, buf, count); + nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, count + 1); + + return spi_inbuf[0]; +} + +uint8_t +nRFCMD_RegReadBuf (uint8_t reg, uint8_t * buf, uint8_t count) +{ + spi_outbuf[0] = reg; + nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, count + 2); + memcpy (buf, spi_inbuf + 1, count); + + return spi_inbuf[0]; +} + +uint8_t +nRFCMD_GetRegSize (uint8_t reg) +{ + uint8_t res; + + if (reg > 0x17) + res = 0; + else + switch (reg) + { + case RX_ADDR_P0: + case RX_ADDR_P1: + case TX_ADDR: + res = NRF_MAX_MAC_SIZE; + break; + default: + res = 1; + } + return res; +} + +void +nRFCMD_ExecMacro (const uint8_t * macro) +{ + unsigned char size; + + while ((size = *macro++) != 0) + { + nRFCMD_ReadWriteBuffer (macro, NULL, size - 1); + macro += size; + } +} + +void +nRFCMD_RegisterDump (void) +{ + uint8_t t, size, reg, buf[32]; + + reg = 0; + debug_printf ("\nnRFCMD_RegisterDump:\n"); + while (((size = nRFCMD_GetRegSize (reg)) > 0) && (reg < 0xFF)) + { + nRFCMD_RegReadBuf (reg, buf, size); + + debug_printf ("\treg[0x%02X]:", reg); + for (t = 0; t < size; t++) + debug_printf (" 0x%02X", buf[t]); + debug_printf ("\n"); + + reg++; + } + debug_printf ("\n"); +} + +void +WAKEUP_IRQHandlerPIO1_9 (void) +{ + /* Clear pending IRQ */ + LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO1_9; + + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __NOP (); +} + +void +nRFCMD_Shutdown (void) +{ + /* disable RX mode */ + nRFCMD_CE (0); + + /* wait 5ms */ + pmu_sleep_ms (5); + + /* switch to TX mode */ + nRFAPI_SetRxMode (0); + + /* powering down */ + nRFAPI_PowerDown (); + + /* set pins to lowest power */ + GPIOSetDir (RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 1); + GPIOSetValue (RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 0); + GPIOSetValue (CPU_CE_RF_PORT, CPU_CE_RF_PIN, 0); + GPIOSetValue (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 0); +} + +void +nRFCMD_Init (void) +{ + /* setup SPI chipselect pin */ + spi_init_pin (SPI_CS_NRF); + + /* setup IOs */ + LPC_IOCON->PIO1_9 = 0; + GPIOSetDir (RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 0); + NVIC_EnableIRQ (WAKEUP_PIO1_9_IRQn); + LPC_SYSCON->STARTAPRP0 = (LPC_SYSCON->STARTAPRP0 & ~STARTxPRP0_PIO1_9); + LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO1_9; + LPC_SYSCON->STARTERP0 |= STARTxPRP0_PIO1_9; + + LPC_IOCON->JTAG_TDI_PIO0_11 = 0x81; + GPIOSetDir (CPU_CE_RF_PORT, CPU_CE_RF_PIN, 1); + GPIOSetValue (CPU_CE_RF_PORT, CPU_CE_RF_PIN, 0); + + LPC_IOCON->PIO0_2 = 0; + GPIOSetDir (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 1); + GPIOSetValue (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 0); +} diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/pmu.c b/openbeacon/lpc13xx/openbeacon-sensor/src/pmu.c new file mode 100644 index 0000000..83167b6 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/src/pmu.c @@ -0,0 +1,160 @@ +/*************************************************************** + * + * OpenBeacon.org - LPC13xx Power Management Functions + * + * Copyright 2011 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#include +#include "pmu.h" +#include "spi.h" +#include "nRF_API.h" +#include "nRF_CMD.h" +#include "openbeacon-proto.h" + +static uint32_t g_sysahbclkctrl; + +#define MAINCLKSEL_IRC 0 +#define MAINCLKSEL_SYSPLL_IN 1 +#define MAINCLKSEL_WDT 2 +#define MAINCLKSEL_SYSPLL_OUT 3 + +#define SYSTEM_TMR16B0_PRESCALER 10000 + +void +WAKEUP_IRQHandlerPIO0_8 (void) +{ + if(LPC_SYSCON->MAINCLKSEL != MAINCLKSEL_SYSPLL_OUT) + { + /* switch to IRC oscillator */ + LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_SYSPLL_OUT; + /* push clock change */ + LPC_SYSCON->MAINCLKUEN = 0; + LPC_SYSCON->MAINCLKUEN = 1; + /* wait for clock change to be finished */ + while (!(LPC_SYSCON->MAINCLKUEN & 1)); + /* power down watchdog oscillator */ + LPC_SYSCON->PDRUNCFG |= WDTOSC_PD; + } + + /* re-trigger match output */ + LPC_TMR16B0->EMR &= ~1; + /* reset wakeup logic */ + LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO0_8; + /* disable deep sleep */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + /* enable previous clock settings */ + LPC_SYSCON->SYSAHBCLKCTRL = g_sysahbclkctrl; + /* select MISO function for PIO0_8 */ + LPC_IOCON->PIO0_8 = 1; + + /* vodoo -NOP */ + __NOP (); +} + +void +pmu_wait_ms (uint16_t ms) +{ + LPC_IOCON->PIO0_8 = 2; + + g_sysahbclkctrl = LPC_SYSCON->SYSAHBCLKCTRL; + LPC_SYSCON->SYSAHBCLKCTRL |= EN_CT16B0; + + /* prepare 16B0 timer */ + LPC_TMR16B0->TCR = 2; + LPC_TMR16B0->PR = SYSTEM_CORE_CLOCK/SYSTEM_TMR16B0_PRESCALER; + LPC_TMR16B0->EMR = 2 << 4; + LPC_TMR16B0->MR0 = ms*10; + /* enable IRQ, reset and timer stop in MR0 match */ + LPC_TMR16B0->MCR = 7; + + /* prepare sleep */ + LPC_PMU->PCON = (1 << 11) | (1 << 8); + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + /* start timer */ + LPC_TMR16B0->TCR = 1; + /* sleep */ + __WFI (); +} + +void +pmu_sleep_ms (uint16_t ms) +{ + if (ms < 10) + ms = 10; + + /* select CT16B0_MAT0 function for PIO0_8 */ + LPC_IOCON->PIO0_8 = 2; + + /* Turn off all other peripheral dividers FIXME save settings */ +/* LPC_SYSCON->SSPCLKDIV = 0; + LPC_SYSCON->USBCLKDIV = 0; + LPC_SYSCON->WDTCLKDIV = 0; + LPC_SYSCON->SYSTICKCLKDIV = 0;*/ + + g_sysahbclkctrl = LPC_SYSCON->SYSAHBCLKCTRL; + LPC_SYSCON->SYSAHBCLKCTRL = EN_RAM | EN_GPIO | EN_CT16B0 | EN_FLASHARRAY | EN_IOCON; + + /* prepare 16B0 timer */ + LPC_TMR16B0->TCR = 2; + LPC_TMR16B0->PR = 8; + LPC_TMR16B0->EMR = 2 << 4; + LPC_TMR16B0->MR0 = ms - 7; + /* enable IRQ, reset and timer stop in MR0 match */ + LPC_TMR16B0->MCR = 7; + + /* prepare sleep */ + LPC_PMU->PCON = (1 << 11) | (1 << 8); + SCB->SCR = SCB_SCR_SLEEPDEEP_Msk; + + /* power up watchdog */ + LPC_SYSCON->PDRUNCFG &= ~WDTOSC_PD; + /* save current power settings, power WDT on wake */ + LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; + /* power watchdog oscillator in deep sleep mode */ + LPC_SYSCON->PDSLEEPCFG = (~WDTOSC_PD) & 0xFFF; + /* switch MAINCLKSEL to Watchdog Oscillator */ + LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_WDT; + /* push clock change */ + LPC_SYSCON->MAINCLKUEN = 0; + LPC_SYSCON->MAINCLKUEN = 1; + /* wait for clock change to be executed */ + while (!(LPC_SYSCON->MAINCLKUEN & 1)); + + /* start timer */ + LPC_TMR16B0->TCR = 1; + /* sleep */ + __WFI (); +} + +void +pmu_init (void) +{ + /* reset 16B0 timer */ + LPC_TMR16B0->TCR = 2; + /* Turn on the watchdog oscillator */ + LPC_SYSCON->WDTOSCCTRL = 0x3F; + /* enable IRQ routine for PIO0_8 */ + NVIC_EnableIRQ (WAKEUP_PIO0_8_IRQn); + /* initialize start logic for PIO0_8 */ + LPC_SYSCON->STARTAPRP0 |= STARTxPRP0_PIO0_8; + LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO0_8; + LPC_SYSCON->STARTERP0 |= STARTxPRP0_PIO0_8; +} diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/sound.c b/openbeacon/lpc13xx/openbeacon-sensor/src/sound.c new file mode 100644 index 0000000..78f0b72 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-sensor/src/sound.c @@ -0,0 +1,93 @@ +/*************************************************************** + * + * OpenBeacon.org - piezo speaker sound functions + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#include +#include + +#ifdef SOUND_ENABLE + +#define ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0])) + +void +snd_beep (uint16_t frequency) +{ + uint32_t t; + + LPC_TMR32B1->TCR = 0; + if (frequency) + { + t = (SYSTEM_CORE_CLOCK / 2) / frequency; + + LPC_TMR32B1->MR0 = LPC_TMR32B1->MR1 = t; + + if (LPC_TMR32B1->TC >= t) + LPC_TMR32B1->TC = t; + + LPC_TMR32B1->TCR = 1; + } +} + +static inline uint16_t +snd_get_frequency_for_tone (uint8_t tone) +{ + static const uint16_t frequency[] = { 26263, 29366, 32963, 34923, 39200, 44000, 49388 }; + return (((uint32_t) frequency[tone % ARRAY_COUNT (frequency)]) * (1 << (tone/ARRAY_COUNT(frequency))))/100; +} + +void +snd_tone (uint8_t tone) +{ + static uint8_t lasttone = 0; + + if (tone != lasttone) + { + if (tone) + { + LPC_SYSCON->SYSAHBCLKCTRL |= EN_CT32B1; + LPC_TMR32B1->EMR = 1 | (0x3 << 4) | (0x3 << 6); + snd_beep (tone ? snd_get_frequency_for_tone (tone - 1) : 0); + } + else + { + LPC_TMR32B1->EMR = 0; + LPC_SYSCON->SYSAHBCLKCTRL &= ~EN_CT32B1; + } + + lasttone = tone; + } +} + +void +snd_init (void) +{ + /* Set sound port to PIO1_1 and PIO1_2 */ + LPC_GPIO1->DIR |= 0x6; + LPC_IOCON->JTAG_TDO_PIO1_1 = 3; + LPC_IOCON->JTAG_nTRST_PIO1_2 = 3; + + /* run 32 bit timer for sound generation */ + LPC_SYSCON->SYSAHBCLKCTRL |= EN_CT32B1; + LPC_TMR32B1->TCR = 2; + LPC_TMR32B1->MCR = 1 << 4; + LPC_TMR32B1->EMR = 0; +} +#endif /*SOUND_ENABLE */ diff --git a/openbeacon/lpc13xx/openbeacon-usb2/.gitignore b/openbeacon/lpc13xx/openbeacon-usb2/.gitignore new file mode 100644 index 0000000..86b18f5 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/.gitignore @@ -0,0 +1,2 @@ +.cproject +.project diff --git a/openbeacon/lpc13xx/openbeacon-usb2/Makefile b/openbeacon/lpc13xx/openbeacon-usb2/Makefile new file mode 100644 index 0000000..689585f --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/Makefile @@ -0,0 +1,32 @@ +TARGET=openbeacon-usb2 +ARCH=LPC13 +CPU=$(ARCH)43 +DEBUG=-g +OPTIM=-Os -mword-relocations + +APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS +APP_LDFLAGS=-lm + +APP_SRC= \ + src/main.c \ + src/nRF_CMD.c \ + src/nRF_API.c \ + src/pin.c \ + src/pmu.c \ + src/storage.c + +APP_SRC+=$(IMAGES_C) + +all: $(TARGET).bin + +publish: clean $(TARGET).bin + rm -f $(TARGET).zip + ../lpc-flash/src/lpc-flash $(TARGET).bin firmware.bin + zip $(TARGET).zip firmware.bin + scp $(TARGET).zip firmware.bin meri@bitmanufaktur.net:/home/wwwrun/open.bitmanufaktur.com/web/www/people/milosch/usb2tag/ + +app_clean: + rm -f $(TARGET).zip $(TARGET)-firmware.bin + find src -name '*.o' -exec rm \{\} \; + +include ../core/Makefile.rules diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/3d_acceleration.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/3d_acceleration.h new file mode 100644 index 0000000..941d839 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/3d_acceleration.h @@ -0,0 +1,31 @@ +/*************************************************************** + * + * OpenBeacon.org - 3D acceleration sensor support + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __3D_ACCELERATION_H__ +#define __3D_ACCELERATION_H__ + +extern void acc_init (uint8_t enabled); +extern void acc_status (void); +extern void acc_xyz_read (int *x, int *y, int *z); + +#endif/*__3D_ACCELERATION_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/FreeRTOSConfig.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/FreeRTOSConfig.h new file mode 100644 index 0000000..68126cc --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/FreeRTOSConfig.h @@ -0,0 +1,103 @@ +/* + FreeRTOS V6.0.0 - Copyright (C) 2009 Real Time Engineers Ltd. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. + */ + +/****************************************************************************** + See http://www.freertos.org/a00110.html for an explanation of the + definitions contained in this file. + ******************************************************************************/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "LPC13xx.h" + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) SystemCoreClock ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 128 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_CO_ROUTINES 0 +#define configUSE_MUTEXES 1 + +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configQUEUE_REGISTRY_SIZE 0 +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_MALLOC_FAILED_HOOK 0 + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 + +/* Use the system definition, if there is one */ +#ifdef __NVIC_PRIO_BITS +#define configPRIO_BITS __NVIC_PRIO_BITS +#else +#define configPRIO_BITS 5 /* 32 priority levels */ +#endif + +/* The lowest priority. */ +#define configKERNEL_INTERRUPT_PRIORITY ( 31 << (8 - configPRIO_BITS) ) +/* Priority 5, or 160 as only the top three bits are implemented. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - configPRIO_BITS) ) + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/bluetooth.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/bluetooth.h new file mode 100644 index 0000000..9c9d81a --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/bluetooth.h @@ -0,0 +1,29 @@ +/*************************************************************** + * + * OpenBeacon.org - Bluetooth related functions + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __BLUETOOTH_H__ +#define __BLUETOOTH_H__ + +extern void bt_init (uint8_t enabled); + +#endif/*__BLUETOOTH_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/config.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/config.h new file mode 100644 index 0000000..820edfc --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/config.h @@ -0,0 +1,47 @@ +/*************************************************************** + * + * OpenBeacon.org - config file + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +/* enable USB disk support */ +#define USB_DISK_SUPPORT +#define USB_VENDOR_ID 0x2366 +#define USB_PROD_ID 0x0003 +#define USB_DEVICE 1 + +/* SPI_CS(io_port, io_pin, CPSDVSR frequency, mode) */ +#define SPI_CS_FLASH SPI_CS( 2, 0, 24, SPI_CS_MODE_SKIP_TX ) /* 24.0MHz */ +#define SPI_CS_NRF SPI_CS( 1,10, 24, SPI_CS_MODE_NORMAL ) /* 9.6MHz */ +//#define SPI_CS_ACC3D SPI_CS( 0, 4, 6, SPI_CS_MODE_NORMAL ) /* 8.0MHz */ + +#define NRF_MAX_MAC_SIZE 5 + +/* FreeRTOS configuration */ +#define ENABLE_FREERTOS +#define TASK_NRF_STACK_SIZE 256 +#define TASK_NRF_PRIORITY (tskIDLE_PRIORITY + 2) + +#define UPDATE_INTERVAL_MS 50 + +#endif/*__CONFIG_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_API.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_API.h new file mode 100644 index 0000000..068e73f --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_API.h @@ -0,0 +1,63 @@ +/*************************************************************** + * + * OpenBeacon.org - function definitions + * + * Copyright 2007 Milosch Meriac + * + * provides high level initialization and startup sanity + * checks and test routines to verify that the chip is working + * properly and no soldering errors occored on the digital part. + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#ifndef NRF_API_H +#define NRF_API_H + +#include + +extern uint8_t nRFAPI_Init (uint8_t channel, + const uint8_t * mac, + uint8_t mac_size, uint8_t features); +extern void nRFAPI_SetTxPower (uint8_t power); +extern void nRFAPI_TxRetries (uint8_t count); +extern void nRFAPI_SetRxMode (uint8_t receive); +extern void nRFAPI_PipesEnable (uint8_t mask); +extern void nRFAPI_PipesAck (uint8_t mask); +extern uint8_t nRFAPI_GetSizeMac (void); +extern uint8_t nRFAPI_SetSizeMac (uint8_t addr_size); +extern void nRFAPI_GetTxMAC (uint8_t * addr, uint8_t addr_size); +extern void nRFAPI_SetTxMAC (const uint8_t * addr, uint8_t addr_size); +extern void nRFAPI_SetRxMAC (const uint8_t * addr, + uint8_t addr_size, uint8_t pipe); +extern void nRFAPI_SetChannel (uint8_t channel); +extern uint8_t nRFAPI_GetChannel (void); +extern uint8_t nRFAPI_ClearIRQ (uint8_t status); +extern void nRFAPI_TX (uint8_t * buf, uint8_t count); +extern uint8_t nRFAPI_GetStatus (void); +extern uint8_t nRFAPI_GetPipeSizeRX (uint8_t pipe); +extern void nRFAPI_SetPipeSizeRX (uint8_t pipe, uint8_t size); +extern uint8_t nRFAPI_GetPipeCurrent (void); +extern uint8_t nRFAPI_RX (uint8_t * buf, uint8_t count); +extern void nRFAPI_FlushRX (void); +extern void nRFAPI_FlushTX (void); +extern void nRFAPI_ReuseTX (void); +extern uint8_t nRFAPI_GetFifoStatus (void); +extern uint8_t nRFAPI_CarrierDetect (void); +extern void nRFAPI_SetFeatures (uint8_t features); +extern void nRFAPI_PowerDown (void); + +#endif /*NRF_API_H */ diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_CMD.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_CMD.h new file mode 100644 index 0000000..6f63908 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_CMD.h @@ -0,0 +1,46 @@ +/*************************************************************** + * + * OpenBeacon.org - midlevel access function defines for + * issuing raw commands to the nRF24L01 2.4Ghz frontend + * + * Copyright 2007 Milosch Meriac + * + * provides generic register level access functions + * for accessing nRF24L01 registers at a generic level + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#ifndef NRF_CMD_H +#define NRF_CMD_H + +extern uint8_t nRFCMD_CmdExec (uint8_t reg); +extern uint8_t nRFCMD_RegRead (uint8_t reg); +extern uint8_t nRFCMD_RegWriteStatusRead (uint8_t reg, uint8_t value); +extern uint8_t nRFCMD_RegWriteBuf (uint8_t reg, const uint8_t * buf, uint8_t count); +extern uint8_t nRFCMD_RegReadBuf (uint8_t reg, uint8_t * buf, uint8_t count); +extern uint8_t nRFCMD_GetRegSize (uint8_t reg); +extern uint8_t nRFCMD_WaitRx(uint32_t ticks); +extern void nRFCMD_CE (uint8_t enable); +extern void nRFCMD_Power (uint8_t enable); +extern void nRFCMD_ReadWriteBuffer (const uint8_t * tx_data, uint8_t * rx_data, uint32_t len); +extern void nRFCMD_ExecMacro (const uint8_t * macro); +extern void nRFCMD_RegisterDump (void); +extern void nRFCMD_Init (void); +extern void nRFCMD_Status (void); + +#endif /*NRF_CMD_H */ + diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_HW.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_HW.h new file mode 100644 index 0000000..c4d17dc --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_HW.h @@ -0,0 +1,109 @@ +/*************************************************************** + * + * OpenBeacon.org - opcode & register definitions for nRF24L01 + * + * Copyright 2007 Milosch Meriac + * + * provides a nice set of defines to work properly with the + * nRF24L01 CPU + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#ifndef NRF_HW_H +#define NRF_HW_H + +//********************************************************************************************************************// +// SPI(nRF24L01) commands +#define READ_REG 0x00 // Define read command to register +#define WRITE_REG 0x20 // Define write command to register +#define RD_RX_PLOAD 0x61 // Define RX payload register address +#define WR_TX_PLOAD 0xA0 // Define TX payload register address +#define FLUSH_TX 0xE1 // Define flush TX register command +#define FLUSH_RX 0xE2 // Define flush RX register command +#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command +#define OP_NOP 0xFF // Define No Operation, might be used to read status register +#define ACTIVATE 0x50 // ACTIVATE additional features +#define R_RX_PL_WID 0x60 // Define Read RX-payload width command +#define W_ACK_PAYLOAD 0xA8 // Write payload to be used in ACK packet on pipe PPP +#define W_TX_PAYLOAD_NOACK 0xB0 // Used in TX mode, Disable AUTOACK on this specific packet + + +//********************************************************************************************************************// +// SPI(nRF24L01) registers(addresses) +#define CONFIG 0x00 // 'Config' register address +#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address +#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address +#define SETUP_AW 0x03 // 'Setup address width' register address +#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address +#define RF_CH 0x05 // 'RF channel' register address +#define RF_SETUP 0x06 // 'RF setup' register address +#define STATUS 0x07 // 'Status' register address +#define OBSERVE_TX 0x08 // 'Observe TX' register address +#define CD 0x09 // 'Carrier Detect' register address +#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address +#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address +#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address +#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address +#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address +#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address +#define TX_ADDR 0x10 // 'TX address' register address +#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address +#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address +#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address +#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address +#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address +#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address +#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address +#define FEATURE 0x1D // Additional features register, needed to enable the additional commands + +//********************************************************************************************************************// +// SPI(nRF24L01) registers(bitmasks) +#define ERX_P0 0x01 // Enable Pipe 0 (register EN_RXADDR) +#define ERX_P1 0x02 // Enable Pipe 1 (register EN_RXADDR) +#define ERX_P2 0x04 // Enable Pipe 2 (register EN_RXADDR) +#define ERX_P3 0x08 // Enable Pipe 3 (register EN_RXADDR) +#define ERX_P4 0x10 // Enable Pipe 4 (register EN_RXADDR) +#define ERX_P5 0x20 // Enable Pipe 5 (register EN_RXADDR) + +//********************************************************************************************************************// +// 'Config' register mask bits +#define NRF_CONFIG_PRIM_RX 0x01 +#define NRF_CONFIG_PWR_UP 0x02 +#define NRF_CONFIG_CRCO 0x04 +#define NRF_CONFIG_EN_CRC 0x08 +#define NRF_CONFIG_MASK_MAX_RT 0x10 +#define NRF_CONFIG_MASK_TX_DS 0x20 +#define NRF_CONFIG_MASK_RX_DR 0x40 +#define NRF_CONFIG_MASK_IRQS (NRF_CONFIG_MASK_MAX_RT|NRF_CONFIG_MASK_TX_DS|NRF_CONFIG_MASK_RX_DR) + + +#define MASK_RX_DR_FLAG 0x40 +#define MASK_TX_DS_FLAG 0x20 +#define MASK_MAX_RT_FLAG 0x10 +#define MASK_IRQ_FLAGS (MASK_MAX_RT_FLAG|MASK_TX_DS_FLAG|MASK_RX_DR_FLAG) + +#define FIFO_RX_EMPTY 0x01 +#define FIFO_RX_FULL 0x02 +#define FIFO_TX_EMPTY 0x10 +#define FIFO_TX_FULL 0x20 +#define FIFO_TX_REUSE 0x40 + +#define NRF_MIN_MAC_SIZE 3 +#define NRF_MAX_MAC_SIZE 5 +#define NRF_MAX_BUFFER_SIZE 32 + +#endif /*NRF_HW_H */ diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/openbeacon-proto.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/openbeacon-proto.h new file mode 100644 index 0000000..6e7dded --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/openbeacon-proto.h @@ -0,0 +1,109 @@ +/**************************************************************************** + * + * OpenBeacon.org - OnAir protocol specification and definition + * + * Copyright 2007 Milosch Meriac + * + **************************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __OPENBEACON_PROTO_H__ +#define __OPENBEACON_PROTO_H__ + +#define CONFIG_TRACKER_CHANNEL 81 +#define CONFIG_PROX_CHANNEL 76 + +#define XXTEA_BLOCK_COUNT 4 + +#define RFBPROTO_READER_ANNOUNCE 22 +#define RFBPROTO_READER_COMMAND 23 +#define RFBPROTO_BEACONTRACKER 24 +#define RFBPROTO_PROXTRACKER 42 +#define RFBPROTO_PROXREPORT 69 + +#define PROX_MAX 4 + +#define RFBFLAGS_ACK 0x01 +#define RFBFLAGS_SENSOR 0x02 +#define RFBFLAGS_INFECTED 0x04 + +/* RFBPROTO_READER_COMMAND related opcodes */ +#define READER_CMD_NOP 0x00 +#define READER_CMD_RESET 0x01 +#define READER_CMD_RESET_CONFIG 0x02 +#define READER_CMD_RESET_FACTORY 0x03 +#define READER_CMD_RESET_WIFI 0x04 +#define READER_CMD_SET_OID 0x05 +/* RFBPROTO_READER_COMMAND related results */ +#define READ_RES__OK 0x00 +#define READ_RES__DENIED 0x01 +#define READ_RES__UNKNOWN_CMD 0xFF + +typedef struct +{ + uint8_t strength; + uint16_t oid_last_seen; + uint16_t powerup_count; + uint8_t reserved; + uint32_t seq; +} PACKED TBeaconTracker; + +typedef struct +{ + uint16_t oid_prox[PROX_MAX]; + uint16_t seq; +} PACKED TBeaconProx; + +typedef struct +{ + uint8_t opcode, res; + uint32_t data[2]; +} PACKED TBeaconReaderCommand; + +typedef struct +{ + uint8_t opcode, strength; + uint32_t uptime, ip; +} PACKED TBeaconReaderAnnounce; + +typedef union +{ + TBeaconProx prox; + TBeaconTracker tracker; + TBeaconReaderCommand reader_command; + TBeaconReaderAnnounce reader_announce; +} PACKED TBeaconPayload; + +typedef struct +{ + uint8_t proto; + uint16_t oid; + uint8_t flags; + + TBeaconPayload p; + + uint16_t crc; +} PACKED TBeaconWrapper; + +typedef union +{ + TBeaconWrapper pkt; + uint32_t block[XXTEA_BLOCK_COUNT]; + uint8_t byte[XXTEA_BLOCK_COUNT * 4]; +} PACKED TBeaconEnvelope; + +#endif/*__OPENBEACON_PROTO_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/pin.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/pin.h new file mode 100644 index 0000000..2702f74 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/pin.h @@ -0,0 +1,36 @@ +/*************************************************************** + * + * OpenBeacon.org - GPIO declaration + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __PIN_H__ +#define __PIN_H__ + +#define GPIO_LEDS_OFF 0 +#define GPIO_LED0 1 +#define GPIO_LED1 2 + +extern void pin_init (void); +extern void pin_led (uint8_t led); +extern void pin_mode_pmu (uint8_t mode); +extern uint8_t pin_button0 (void); + +#endif /*__PIN_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/pmu.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/pmu.h new file mode 100644 index 0000000..6616ff9 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/pmu.h @@ -0,0 +1,49 @@ +/*************************************************************** + * + * OpenBeacon.org - Power Management + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __PMU_H__ +#define __PMU_H__ + +#define PMU_IRCOUT_PD (1UL << 0) +#define PMU_IRC_PD (1UL << 1) +#define PMU_FLASH_PD (1UL << 2) +#define PMU_BOD_PD (1UL << 3) +#define PMU_ADC_PD (1UL << 4) +#define PMU_SYSOSC_PD (1UL << 5) +#define PMU_WDTOSC_PD (1UL << 6) +#define PMU_SYSPLL_PD (1UL << 7) +#define PMU_USBPLL_PD (1UL << 8) +#define PMU_RESERVED1_DEEP_PD (1UL << 9) +#define PMU_USBPAD_PD (1UL <<10) +#define PMU_RESERVED2_DEEP_PD (1UL <<11) + +#define NVIC_LP_SEVONPEND (0x10) +#define NVIC_LP_SLEEPDEEP (0x04) +#define NVIC_LP_SLEEPONEXIT (0x02) + +extern void pmu_init (void); +extern void pmu_status (void); +extern void pmu_off (uint32_t reason); +extern uint32_t pmu_reason (void); + +#endif /*__PMU_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/storage.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/storage.h new file mode 100644 index 0000000..948998d --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/storage.h @@ -0,0 +1,32 @@ +/*************************************************************** + * + * OpenBeacon.org - FLASH storage support + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#ifndef __STORAGE_H__ +#define __STORAGE_H__ + +#include "msd.h" + +extern void storage_init (void); +extern void storage_status (void); + +#endif/*__STORAGE_H__*/ diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/3d_acceleration.c b/openbeacon/lpc13xx/openbeacon-usb2/src/3d_acceleration.c new file mode 100644 index 0000000..263b5ac --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/src/3d_acceleration.c @@ -0,0 +1,100 @@ +/*************************************************************** + * + * OpenBeacon.org - 3D acceleration sensor support + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#include +#include "3d_acceleration.h" +#include "spi.h" + +/* IO definitions */ +#define ACC_INT_PORT 1 +#define ACC_INT_PIN 11 + +static void +acc_reg_write (uint8_t addr, uint8_t data) +{ + uint8_t tx[2]; + + /* assemble SPI write request */ + tx[0] = 0x80 | addr << 1; + tx[1] = data; + + /* transmit packet */ + spi_txrx (SPI_CS_ACC3D, tx, sizeof (tx), NULL, 0); +} + +static uint8_t +acc_reg_read (uint8_t addr) +{ + uint8_t tx[2], rx[2]; + + /* assemble SPI read request */ + tx[0] = addr << 1; + tx[1] = 0; + /* transmit packet */ + spi_txrx (SPI_CS_ACC3D, tx, sizeof (tx), rx, sizeof (rx)); + + return rx[1]; +} + +void +acc_xyz_read (int *x, int *y, int *z) +{ + /* dummy read - FIXME */ + acc_reg_read (0); + + /* get acceleration values */ + *x = (int8_t) acc_reg_read (6); + *y = (int8_t) acc_reg_read (7); + *z = (int8_t) acc_reg_read (8); +} + +void +acc_status (void) +{ + int x, y, z; + + acc_xyz_read (&x, &y, &z); + + debug_printf (" * 3D_ACC: X=%04i Y=%04i Z=%04i\n", x, y, z); +} + +void +acc_init (uint8_t enabled) +{ + /* PIO, PIO0_4 in standard IO functionality */ + LPC_IOCON->PIO0_4 = 1 << 8; + + /* PIO, Inactive Pull, Digital Mode */ + LPC_IOCON->PIO1_11 = (1<<7)|(2<<3); + + /* setup SPI chipselect pin */ + spi_init_pin (SPI_CS_ACC3D); + + /* Set ACC_INT port to input */ + GPIOSetDir (ACC_INT_PORT, ACC_INT_PIN, 0); + + /* dummy read - FIXME */ + acc_reg_read (0); + + /* set 3D acceleration sensor active, 2g - FIXME power saving */ + acc_reg_write (0x16, enabled ? (0x01 | 0x01 << 2) : 0x00); +} diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/bluetooth.c b/openbeacon/lpc13xx/openbeacon-usb2/src/bluetooth.c new file mode 100644 index 0000000..91c76ec --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/src/bluetooth.c @@ -0,0 +1,87 @@ +/*************************************************************** + * + * OpenBeacon.org - Bluetooth related functions + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#include +#include "bluetooth.h" + +#define CPU_WAKEUP_BLT_PORT 1 +#define CPU_WAKEUP_BLT_PIN 3 +#define CPU_BLT_WAKEUP_PORT 2 +#define CPU_BLT_WAKEUP_PIN 0 +#define CPU_ON_OFF_BLT_PORT 1 +#define CPU_ON_OFF_BLT_PIN 0 + +static const char *bt_init_strings[] = { + "SEC=3,2,2,04,0000", + "SLN=17,OpenBeacon USB II", + "RLS=1101,13,Debug Console,01,000000", + "DIS=3", + "AAC=1", + "SCR" +}; + +#define BT_INIT_STRINGS_COUNT ((int)(sizeof(bt_init_strings)/sizeof(bt_init_strings[0]))) + +void +bt_init (uint8_t enabled) +{ + int bt_init_pos = 0; + + /* Init UART for Bluetooth module without RTS/CTS */ + UARTInit (115200, 0); + + /* fake CTS for now */ + GPIOSetDir (1, 5, 1); + GPIOSetValue (1, 5, 0); + + /* Set CPU_WAKEUP_BLT port pin to output */ + LPC_IOCON->ARM_SWDIO_PIO1_3 = 1; + GPIOSetDir (CPU_WAKEUP_BLT_PORT, CPU_WAKEUP_BLT_PIN, 1); + GPIOSetValue (CPU_WAKEUP_BLT_PORT, CPU_WAKEUP_BLT_PIN, enabled ? 1 : 0); + + /* Set CPU_BLT_WAKEUP port pin to input */ + LPC_IOCON->PIO2_0 = 0; + GPIOSetDir (CPU_BLT_WAKEUP_PORT, CPU_BLT_WAKEUP_PIN, 0); + GPIOSetValue (CPU_BLT_WAKEUP_PORT, CPU_BLT_WAKEUP_PIN, 0); + + /* Set CPU_ON-OFF_BLT port pin to output */ + LPC_IOCON->JTAG_TMS_PIO1_0 = 1; + GPIOSetDir (CPU_ON_OFF_BLT_PORT, CPU_ON_OFF_BLT_PIN, 1); + GPIOSetValue (CPU_ON_OFF_BLT_PORT, CPU_ON_OFF_BLT_PIN, enabled ? 1 : 0); + + /* iterate through all bt_init_strings if activated */ + if (enabled) + while (bt_init_pos <= BT_INIT_STRINGS_COUNT) + { + /* wait for CR */ + while (UARTCount) + if (UARTBuffer[--UARTCount] == '\n') + { + /* emmpty buffers */ + UARTCount = 0; + /* output next init string */ + if (bt_init_pos < BT_INIT_STRINGS_COUNT) + debug_printf ("AT+J%s\n", bt_init_strings[bt_init_pos]); + bt_init_pos++; + } + } +} diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/main.c b/openbeacon/lpc13xx/openbeacon-usb2/src/main.c new file mode 100644 index 0000000..36e55ae --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/src/main.c @@ -0,0 +1,379 @@ +/*************************************************************** + * + * OpenBeacon.org - main file for OpenBeacon USB II Bluetooth + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#include +#include "pin.h" +#include "hid.h" +#include "spi.h" +#include "iap.h" +#include "pmu.h" +#include "crc16.h" +#include "xxtea.h" +#include "bluetooth.h" +#include "storage.h" +#include "nRF_API.h" +#include "nRF_CMD.h" +#include "openbeacon-proto.h" + +/* OpenBeacon packet */ +static TBeaconEnvelope g_Beacon; + +/* Default TEA encryption key of the tag - MUST CHANGE ! */ +static const uint32_t xxtea_key[4] = +{ 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF }; + +/* set nRF24L01 broadcast mac */ +static const unsigned char broadcast_mac[NRF_MAX_MAC_SIZE] = +{ 1, 2, 3, 2, 1 }; + +/* device UUID */ +static uint16_t tag_id; +static TDeviceUID device_uuid; + +#if (USB_HID_IN_REPORT_SIZE>0)||(USB_HID_OUT_REPORT_SIZE>0) +static uint8_t hid_buffer[USB_HID_IN_REPORT_SIZE]; + +void +GetInReport (uint8_t * src, uint32_t length) +{ + (void) src; + (void) length; + + if (length > USB_HID_IN_REPORT_SIZE) + length = USB_HID_IN_REPORT_SIZE; + + memcpy (src, hid_buffer, length); +} + +void +SetOutReport (uint8_t * dst, uint32_t length) +{ + (void) dst; + (void) length; +} +#endif + +static void show_version(void) +{ + debug_printf(" * Tag ID: %i\n", (uint16_t) device_uuid[3]); + debug_printf(" * Device UID: %08X:%08X:%08X:%08X\n", device_uuid[0], + device_uuid[1], device_uuid[2], device_uuid[3]); + debug_printf(" * free heap memory: %i bytes\n",xPortGetFreeHeapSize()); +} + +void main_menue(uint8_t cmd) +{ + /* ignore non-printable characters */ + if (cmd <= ' ') + return; + /* show key pressed */ + debug_printf("%c\n", cmd); + /* map lower case to upper case */ + if (cmd > 'a' && cmd < 'z') + cmd -= ('a' - 'A'); + + switch (cmd) + { + case '?': + case 'H': + debug_printf("\n" + " *****************************************************\n" + " * OpenBeacon USB II - Bluetooth Console *\n" + " * (C) 2010 Milosch Meriac *\n" + " *****************************************************\n" + " * H,? - this help screen\n" +#ifdef MENUE_ALLOW_ISP_REBOOT + " * P - invoke ISP programming mode\n" +#endif + " * S - show device status\n" + " * R - OpenBeacon nRF24L01 register dump\n" + " *****************************************************\n" + "\n"); + break; +#ifdef MENUE_ALLOW_ISP_REBOOT + case 'P': + debug_printf ("\nRebooting..."); + iap_invoke_isp (); + break; +#endif + case 'R': + nRFCMD_RegisterDump(); + break; + case 'S': + debug_printf("\n" + " *****************************************************\n" + " * OpenBeacon Status Information *\n" + " *****************************************************\n"); + show_version(); + spi_status(); + nRFCMD_Status(); + // pmu_status (); +#if (DISK_SIZE>0) + storage_status(); +#endif + nRFCMD_Status(); + debug_printf(" *****************************************************\n" + "\n"); + break; + default: + debug_printf("Unknown command '%c' - please press 'H' for help \n", cmd); + } + debug_printf("\n# "); +} + +static +void nRF_tx(uint8_t power) +{ + /* update crc */ + g_Beacon.pkt.crc = htons(crc16(g_Beacon.byte, sizeof(g_Beacon) + - sizeof(uint16_t))); + /* encrypt data */ + xxtea_encode(g_Beacon.block, XXTEA_BLOCK_COUNT, xxtea_key); + + pin_led(GPIO_LED0); + + /* update power pin */ + nRFCMD_Power(power & 0x4); + + /* disable RX mode */ + nRFCMD_CE(0); + vTaskDelay(5 / portTICK_RATE_MS); + + /* switch to TX mode */ + nRFAPI_SetRxMode(0); + + /* set TX power */ + nRFAPI_SetTxPower(power & 0x3); + + /* upload data to nRF24L01 */ + nRFAPI_TX(g_Beacon.byte, sizeof(g_Beacon)); + + /* transmit data */ + nRFCMD_CE(1); + + /* wait until packet is transmitted */ + vTaskDelay(2 / portTICK_RATE_MS); + + /* switch to RX mode again */ + nRFAPI_SetRxMode(1); + + pin_led(GPIO_LEDS_OFF); + + if (power & 0x4) + nRFCMD_Power(0); +} + +static +void nRF_Task(void *pvParameters) +{ + int t, active; + uint8_t strength, status; + uint16_t crc; + uint32_t seq, oid; + portTickType LastUpdateTicks, Ticks; + + (void) pvParameters; + + /* Initialize OpenBeacon nRF24L01 interface */ + if (!nRFAPI_Init(81, broadcast_mac, sizeof(broadcast_mac), 0)) + /* bail out if can't initialize */ + // for (;;) + { + pin_led(GPIO_LED0 | GPIO_LED1); + vTaskDelay(500 / portTICK_RATE_MS); + + pin_led(GPIO_LEDS_OFF); + vTaskDelay(500 / portTICK_RATE_MS); + } + + /* blink as a sign of boot to detect crashes */ + for (t = 0; t < 20; t++) + { + pin_led(GPIO_LED0); + vTaskDelay(50 / portTICK_RATE_MS); + + pin_led(GPIO_LEDS_OFF); + vTaskDelay(50 / portTICK_RATE_MS); + } + + nRFAPI_SetRxMode(1); + nRFCMD_CE(1); + + LastUpdateTicks = xTaskGetTickCount(); + + /* main loop */ + active = 0; + seq = t = 0; + UARTCount = 0; + while (1) + { + /* turn off after button press */ + if (!pin_button0()) + { + pin_mode_pmu(0); + pmu_off(0); + } + + if (nRFCMD_WaitRx(10 / portTICK_RATE_MS)) + do + { + // read packet from nRF chip + nRFCMD_RegReadBuf(RD_RX_PLOAD, g_Beacon.byte, sizeof(g_Beacon)); + + // adjust byte order and decode + xxtea_decode(g_Beacon.block, XXTEA_BLOCK_COUNT, xxtea_key); + + // verify the CRC checksum + crc = crc16(g_Beacon.byte, sizeof(g_Beacon) - sizeof(uint16_t)); + + if (ntohs (g_Beacon.pkt.crc) == crc) + { + pin_led(GPIO_LED1); + + oid = ntohs (g_Beacon.pkt.oid); + if (((g_Beacon.pkt.flags & RFBFLAGS_SENSOR) > 0) && active) + debug_printf("BUTTON: %i\n", oid); + + switch (g_Beacon.pkt.proto) + { + case RFBPROTO_READER_ANNOUNCE: + strength = g_Beacon.pkt.p.reader_announce.strength; + break; + + case RFBPROTO_BEACONTRACKER: + strength = g_Beacon.pkt.p.tracker.strength; + if (active) + debug_printf(" R: %04i={%i,0x%08X}\n", (int) oid, + (int) strength, + ntohl (g_Beacon.pkt.p.tracker.seq)); + break; + + case RFBPROTO_PROXREPORT: + strength = 3; + if (active) + debug_printf(" P: %04i={%i,0x%04X}\n", (int) oid, + (int) strength, + (int) ntohs (g_Beacon.pkt.p.prox.seq)); + for (t = 0; t < PROX_MAX; t++) + { + crc = (ntohs (g_Beacon.pkt.p.prox.oid_prox[t])); + if (crc && active) + debug_printf("PX: %04i={%04i,%i,%i}\n", + (int) oid, (int) ((crc >> 0) & 0x7FF), + (int) ((crc >> 14) & 0x3), (int) ((crc + >> 11) & 0x7)); + } + break; + + default: + strength = 0xFF; + if (active) + debug_printf("Unknown Protocol: %i\n", + (int) g_Beacon.pkt.proto); + } + + if (strength < 0xFF) + { + /* do something with the data */ + } + pin_led(GPIO_LEDS_OFF); + } + status = nRFAPI_GetFifoStatus(); + } while ((status & FIFO_RX_EMPTY) == 0); + + nRFAPI_ClearIRQ(MASK_IRQ_FLAGS); + + // update regularly + if (((Ticks = xTaskGetTickCount()) - LastUpdateTicks) + > UPDATE_INTERVAL_MS) + { + LastUpdateTicks = Ticks; + + /* setup tracking packet */ + bzero(&g_Beacon, sizeof(g_Beacon)); + g_Beacon.pkt.oid = ntohs ((uint16_t)device_uuid[3]); + g_Beacon.pkt.proto = RFBPROTO_BEACONTRACKER; + g_Beacon.pkt.p.tracker.strength = seq % 8; + g_Beacon.pkt.p.tracker.seq = htonl(seq++); + + /* send away packet */ + nRF_tx(g_Beacon.pkt.p.tracker.strength); + } + + if (UARTCount) + { + /* blink LED1 upon Bluetooth command */ + pin_led(GPIO_LED1); + + /* show help screen upon Bluetooth connect */ + if (!active) + { + active = 1; + debug_printf("press 'H' for help...\n# "); + } + else + /* execute menu command with last character received */ + main_menue(UARTBuffer[UARTCount - 1]); + + /* LED1 off again */ + pin_led(GPIO_LEDS_OFF); + + /* clear UART buffer */ + UARTCount = 0; + } + } +} + +int main(void) +{ + volatile int i; + /* wait on boot - debounce */ + for (i = 0; i < 2000000; i++) + ; + /* initialize pins */ + pin_init(); + /* Init SPI */ + spi_init(); + /* Init Storage */ +#ifdef USB_DISK_SUPPORT + storage_init(); +#endif + /* Init USB HID interface */ +#if (USB_HID_IN_REPORT_SIZE>0)||(USB_HID_OUT_REPORT_SIZE>0) + hid_init (); + #error hid +#endif + /* power management init */ + pmu_init(); + /* read device UUID */ + bzero(&device_uuid, sizeof(device_uuid)); + iap_read_uid(&device_uuid); + tag_id = crc16((uint8_t*) &device_uuid, sizeof(device_uuid)); + + xTaskCreate(nRF_Task, (const signed char*) "nRF", TASK_NRF_STACK_SIZE, + NULL, TASK_NRF_PRIORITY, NULL); + + /* Start the tasks running. */ + vTaskStartScheduler(); + + return 0; +} diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_API.c b/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_API.c new file mode 100644 index 0000000..7941852 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_API.c @@ -0,0 +1,329 @@ +/*************************************************************** + * + * OpenBeacon.org - high level nRF24L01 access functions + * + * Copyright 2007 Milosch Meriac + * + * provides high level initialization and startup sanity + * checks and test routines to verify that the chip is working + * properly and no soldering errors occored on the digital part. + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#include +#include "nRF_HW.h" +#include "nRF_CMD.h" +#include "nRF_API.h" + +#ifndef NRF_RFOPTIONS +#define NRF_RFOPTIONS 0x09 +#endif /*NRF_RFOPTIONS */ + +// set broadcast MAC to 'BCAST' +const uint8_t rfbroadcast_mac[NRF_MAX_MAC_SIZE] = { 'T', 'S', 'A', 'C', 'B' }; + +uint8_t +nRFAPI_DetectChip (void) +{ + uint8_t mac[NRF_MAX_MAC_SIZE], i; + + // blank read + nRFAPI_GetStatus (); + + // set dummy MAC size + nRFAPI_SetSizeMac (NRF_MIN_MAC_SIZE); + + // verify dummy MAC size + if (nRFAPI_GetSizeMac () != NRF_MIN_MAC_SIZE) + return 0; + + // set dummy MAC size + nRFAPI_SetSizeMac (NRF_MAX_MAC_SIZE); + + // verify dummy MAC size + if (nRFAPI_GetSizeMac () != NRF_MAX_MAC_SIZE) + return 0; + + // set dummy MAC + nRFAPI_SetTxMAC (rfbroadcast_mac, NRF_MAX_MAC_SIZE); + + // get dummy MAC + memset (&mac, 0, sizeof (mac)); + nRFAPI_GetTxMAC (mac, NRF_MAX_MAC_SIZE); + + // if can't verify written MAC - return with error + for (i = 0; i < NRF_MAX_MAC_SIZE; i++) + if (mac[i] != rfbroadcast_mac[i]) + return 0; + + // everything is fine + return 1; +} + +void +nRFAPI_SetRxMode (uint8_t receive) +{ + nRFCMD_RegWriteStatusRead (CONFIG | WRITE_REG, receive ? 0x3B : 0x3A); +} + +void +nRFAPI_PowerDown (void) +{ + nRFCMD_RegWriteStatusRead (CONFIG | WRITE_REG, 0x00); +} + +uint8_t +nRFAPI_Init (uint8_t channel, + const uint8_t * mac, uint8_t mac_size, uint8_t features) +{ + uint8_t i; + + // init IO layer of nRF24L01 + nRFCMD_Init (); + + /* wait for nRF to boot */ + vTaskDelay(10 / portTICK_RATE_MS); + + // check validity + if (mac_size < 3 || mac_size > 5 || !nRFAPI_DetectChip ()) + return 0; + + // update mac + nRFAPI_SetSizeMac (mac_size); + nRFAPI_SetTxMAC (mac, mac_size); + + // enables pipe + nRFAPI_SetRxMAC (mac, mac_size, 0); + nRFAPI_PipesEnable (ERX_P0); + nRFAPI_PipesAck (0); + + // set payload sizes + for (i = 0; i <= 5; i++) + nRFAPI_SetPipeSizeRX (i, 16); + + // set TX retry count + nRFAPI_TxRetries (0); + + // set selected channel + nRFAPI_SetChannel (channel); + + // set Tx power + nRFAPI_SetTxPower (3); + + // flush FIFOs + nRFAPI_FlushRX (); + nRFAPI_FlushTX (); + + if (features != 0) + nRFAPI_SetFeatures (features); + + return 1; +} + +void +nRFAPI_SetTxPower (uint8_t power) +{ + if (power > 3) + power = 3; + + nRFCMD_RegWriteStatusRead (RF_SETUP | WRITE_REG, + NRF_RFOPTIONS | (power << 1)); +} + +void +nRFAPI_TxRetries (uint8_t count) +{ + if (count > 15) + count = 15; + + // setup delay of 500us+86us + nRFCMD_RegWriteStatusRead (SETUP_RETR | WRITE_REG, 0x10 | count); +} + +void +nRFAPI_PipesEnable (uint8_t mask) +{ + nRFCMD_RegWriteStatusRead (EN_RXADDR | WRITE_REG, mask & 0x3F); +} + +void +nRFAPI_PipesAck (uint8_t mask) +{ + nRFCMD_RegWriteStatusRead (EN_AA | WRITE_REG, mask & 0x3F); +} + +uint8_t +nRFAPI_GetSizeMac (void) +{ + uint8_t addr_size; + + addr_size = nRFCMD_RegRead (SETUP_AW) & 0x03; + + return addr_size ? addr_size + 2 : 0; +} + +uint8_t +nRFAPI_SetSizeMac (uint8_t addr_size) +{ + if (addr_size >= 3 && addr_size <= 5) + addr_size -= 2; + else + addr_size = 0; + + nRFCMD_RegWriteStatusRead (SETUP_AW | WRITE_REG, addr_size); + + return addr_size; +} + +void +nRFAPI_GetTxMAC (uint8_t * addr, uint8_t addr_size) +{ + if (addr_size >= 3 && addr_size <= 5) + nRFCMD_RegReadBuf (TX_ADDR, addr, addr_size); +} + +void +nRFAPI_SetTxMAC (const uint8_t * addr, uint8_t addr_size) +{ + if (addr_size >= 3 && addr_size <= 5) + nRFCMD_RegWriteBuf (TX_ADDR | WRITE_REG, addr, addr_size); +} + +void +nRFAPI_SetRxMAC (const uint8_t * addr, uint8_t addr_size, uint8_t pipe) +{ + if ((pipe <= 1 && addr_size >= 3 && addr_size <= 5) + || (addr_size == 1 && pipe >= 2 && pipe <= 5)) + nRFCMD_RegWriteBuf ((RX_ADDR_P0 + pipe) | WRITE_REG, addr, addr_size); +} + +void +nRFAPI_SetChannel (uint8_t channel) +{ + nRFCMD_RegWriteStatusRead (RF_CH | WRITE_REG, channel & 0x7f); +} + +uint8_t +nRFAPI_GetChannel (void) +{ + return nRFCMD_RegRead (RF_CH) & 0x7F; +} + +uint8_t +nRFAPI_ClearIRQ (uint8_t status) +{ + return nRFCMD_RegWriteStatusRead (STATUS | WRITE_REG, + status & MASK_IRQ_FLAGS); +} + +void +nRFAPI_TX (uint8_t * buf, uint8_t count) +{ + nRFCMD_RegWriteBuf (WR_TX_PLOAD, buf, count); +} + +uint8_t +nRFAPI_GetStatus (void) +{ + return nRFCMD_CmdExec (OP_NOP); +} + +uint8_t +nRFAPI_GetPipeSizeRX (uint8_t pipe) +{ + if (pipe <= 5) + return nRFCMD_RegRead (RX_PW_P0 + pipe); + else + return 0; +} + +void +nRFAPI_SetPipeSizeRX (uint8_t pipe, uint8_t size) +{ + if (pipe <= 5) + nRFCMD_RegWriteStatusRead ((RX_PW_P0 + pipe) | WRITE_REG, size); +} + +uint8_t +nRFAPI_GetPipeCurrent (void) +{ + return (nRFAPI_GetStatus () >> 1) & 0x7; +} + +uint8_t +nRFAPI_RX (uint8_t * buf, uint8_t count) +{ + uint8_t size, pipe; + + pipe = nRFAPI_GetPipeCurrent (); + if (pipe >= 7) + size = 0; + else + { + size = nRFAPI_GetPipeSizeRX (pipe); + + if (size <= count) + nRFCMD_RegReadBuf (RD_RX_PLOAD, buf, size); + else + { + nRFAPI_FlushRX (); + size = 0; + } + } + + return size; +} + +void +nRFAPI_FlushRX (void) +{ + nRFCMD_CmdExec (FLUSH_RX); +} + +void +nRFAPI_FlushTX (void) +{ + nRFCMD_CmdExec (FLUSH_TX); +} + +void +nRFAPI_ReuseTX (void) +{ + nRFCMD_CmdExec (REUSE_TX_PL); +} + +uint8_t +nRFAPI_GetFifoStatus (void) +{ + return nRFCMD_RegRead (FIFO_STATUS); +} + +uint8_t +nRFAPI_CarrierDetect (void) +{ + return nRFCMD_RegRead (CD); +} + +void +nRFAPI_SetFeatures (uint8_t features) +{ + unsigned const char ACTIVATE_SEQUENCE[] = { ACTIVATE, 0x73 }; + uint8_t dummy_buffer[sizeof (ACTIVATE_SEQUENCE)] = { 0, 0 }; + nRFCMD_ReadWriteBuffer (ACTIVATE_SEQUENCE, dummy_buffer, + sizeof (ACTIVATE_SEQUENCE)); + nRFCMD_RegWriteStatusRead (FEATURE, features); +} diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_CMD.c b/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_CMD.c new file mode 100644 index 0000000..1cfbb94 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_CMD.c @@ -0,0 +1,226 @@ +/*************************************************************** + * + * OpenBeacon.org - midlevel access functions for + * issuing raw commands to the nRF24L01 2.4Ghz frontend + * + * Copyright 2007 Milosch Meriac + * + * provides generic register level access functions + * for accessing nRF24L01 registers at a generic level + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#include +#include "nRF_HW.h" +#include "nRF_CMD.h" +#include "spi.h" + +/* IO definitions */ +#define RF_IRQ_CPU_PORT 0 +#define RF_IRQ_CPU_PIN 7 +#define CPU_CE_RF_PORT 1 +#define CPU_CE_RF_PIN 5 +//#define CPU_SWITCH_RF_PORT 0 +//#define CPU_SWITCH_RF_PIN 2 + +#define SPI_MAX_XFER_LEN 33 +#define NRFCMD_MACRO_READ 0x80 + +#define SPI_MAX_XFER_LEN 33 +#define NRFCMD_MACRO_READ 0x80 +static uint8_t spi_outbuf[SPI_MAX_XFER_LEN]; +static uint8_t spi_inbuf[SPI_MAX_XFER_LEN]; +static volatile uint8_t g_packet_rxed = 0; + +static xSemaphoreHandle xnRF_SemaphoreACK; + +void nRFCMD_CE(uint8_t enable) +{ + GPIOSetValue(CPU_CE_RF_PORT, CPU_CE_RF_PIN, enable ? 1 : 0); +} + +void nRFCMD_Power(uint8_t enable) +{ + enable = 0; + //GPIOSetValue(CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, enable ? 0 : 1); +} + +void nRFCMD_ReadWriteBuffer(const uint8_t * tx_data, uint8_t * rx_data, + uint32_t len) +{ + spi_txrx(SPI_CS_NRF, tx_data, len, rx_data, len); +} + +static uint8_t nRFCMD_ReadWriteByte(uint8_t reg) +{ + uint8_t res; + + nRFCMD_ReadWriteBuffer(®, &res, 1); + + return res; +} + +uint8_t nRFCMD_CmdExec(uint8_t cmd) +{ + uint8_t res; + + res = nRFCMD_ReadWriteByte(cmd); + + return res; +} + +uint8_t nRFCMD_RegRead(uint8_t reg) +{ + spi_outbuf[0] = reg; + spi_outbuf[1] = 0; + + nRFCMD_ReadWriteBuffer(spi_outbuf, spi_inbuf, 2); + + return spi_inbuf[1]; +} + +uint8_t nRFCMD_RegWriteStatusRead(uint8_t reg, uint8_t value) +{ + spi_outbuf[0] = reg; + spi_outbuf[1] = value; + + nRFCMD_ReadWriteBuffer(spi_outbuf, spi_inbuf, 2); + + return spi_inbuf[0]; +} + +uint8_t nRFCMD_RegWriteBuf(uint8_t reg, const uint8_t * buf, uint8_t count) +{ + spi_outbuf[0] = reg; + memcpy(spi_outbuf + 1, buf, count); + nRFCMD_ReadWriteBuffer(spi_outbuf, spi_inbuf, count + 1); + + return spi_inbuf[0]; +} + +uint8_t nRFCMD_RegReadBuf(uint8_t reg, uint8_t * buf, uint8_t count) +{ + spi_outbuf[0] = reg; + nRFCMD_ReadWriteBuffer(spi_outbuf, spi_inbuf, count + 2); + memcpy(buf, spi_inbuf + 1, count); + + return spi_inbuf[0]; +} + +uint8_t nRFCMD_GetRegSize(uint8_t reg) +{ + uint8_t res; + + if (reg > 0x17) + res = 0; + else + switch (reg) + { + case RX_ADDR_P0: + case RX_ADDR_P1: + case TX_ADDR: + res = NRF_MAX_MAC_SIZE; + break; + default: + res = 1; + } + return res; +} + +void nRFCMD_ExecMacro(const uint8_t * macro) +{ + unsigned char size; + + while ((size = *macro++) != 0) + { + nRFCMD_ReadWriteBuffer(macro, NULL, size - 1); + macro += size; + } +} + +void nRFCMD_RegisterDump(void) +{ + uint8_t t, size, reg, buf[32]; + + reg = 0; + debug_printf("\nnRFCMD_RegisterDump:\n"); + while (((size = nRFCMD_GetRegSize(reg)) > 0) && (reg < 0xFF)) + { + nRFCMD_RegReadBuf(reg, buf, size); + + debug_printf("\treg[0x%02X]:", reg); + for (t = 0; t < size; t++) + debug_printf(" 0x%02X", buf[t]); + debug_printf("\n"); + + reg++; + } + debug_printf("\n"); +} + +void nRFCMD_Status(void) +{ + debug_printf(" * nRF24L01+: rxed=%u\n", g_packet_rxed); +} + +void WAKEUP_IRQHandlerPIO1_9(void) +{ + portBASE_TYPE xTaskWoken = pdFALSE; + + xTaskWoken = xSemaphoreGiveFromISR(xnRF_SemaphoreACK, &xTaskWoken); + + /* Clear pending IRQ */ + LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO1_9; + + portEND_SWITCHING_ISR (xTaskWoken); +} + +uint8_t nRFCMD_WaitRx(uint32_t ticks) +{ + if (xSemaphoreTake(xnRF_SemaphoreACK, ticks)) + { + g_packet_rxed++; + return pdTRUE; + } + else + return pdFALSE; +} + +void nRFCMD_Init(void) +{ + /* setup SPI chipselect pin */ + spi_init_pin(SPI_CS_NRF); + + /* initialize semaphores */ + vSemaphoreCreateBinary(xnRF_SemaphoreACK); + + /* setup IOs */ + /* + LPC_IOCON->PIO0_7 = 0; + GPIOSetDir(RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 0); + NVIC_EnableIRQ(WAKEUP_PIO0_7_IRQn); + LPC_SYSCON->STARTAPRP0 = (LPC_SYSCON->STARTAPRP0 & ~STARTxPRP0_PIO0_7); + LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO0_7; + LPC_SYSCON->STARTERP0 |= STARTxPRP0_PIO0_7; +*/ + GPIOSetDir(CPU_CE_RF_PORT, CPU_CE_RF_PIN, 1); + GPIOSetValue(CPU_CE_RF_PORT, CPU_CE_RF_PIN, 0); + + //LPC_IOCON->PIO0_2 = 0; + //GPIOSetDir(CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 1); + //GPIOSetValue(CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 0); +} diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/pin.c b/openbeacon/lpc13xx/openbeacon-usb2/src/pin.c new file mode 100644 index 0000000..d4fdf9e --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/src/pin.c @@ -0,0 +1,78 @@ +/*************************************************************** + * + * OpenBeacon.org - GPIO declaration + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#include +#include "pin.h" + +/* IO definitions */ +#define BUTTON0_PORT 2 +#define BUTTON0_BIT 7 +#define LED0_PORT 2 +#define LED0_BIT 5 +#define LED1_PORT 2 +#define LED1_BIT 4 +#define CPU_MODE_PMU_PORT 2 +#define CPU_MODE_PMU_BIT 8 + +void +pin_led (uint8_t led) +{ + GPIOSetValue (LED0_PORT, LED0_BIT, (led & GPIO_LED0) > 0); + GPIOSetValue (LED1_PORT, LED1_BIT, (led & GPIO_LED1) > 0); +} + +void +pin_mode_pmu (uint8_t mode) +{ + GPIOSetValue (CPU_MODE_PMU_PORT, CPU_MODE_PMU_BIT, mode); +} + +uint8_t +pin_button0 (void) +{ + return GPIOGetValue (BUTTON0_PORT, BUTTON0_BIT); +} + +void +pin_init (void) +{ + /* Initialize GPIO (sets up clock) */ + GPIOInit (); + + /* switch ISP button pin to input */ + GPIOSetDir (BUTTON0_PORT, BUTTON0_BIT, 0); + + /* Set LED0 port pin to output */ + //LPC_IOCON->JTAG_nTRST_PIO1_2 = 1; + GPIOSetDir (LED0_PORT, LED0_BIT, 1); + GPIOSetValue (LED0_PORT, LED0_BIT, 0); + + /* Set LED1 port pin to output */ + //LPC_IOCON->JTAG_TDO_PIO1_1 = 1; + GPIOSetDir (LED1_PORT, LED1_BIT, 1); + GPIOSetValue (LED1_PORT, LED1_BIT, 0); + + /* Set to PMU high power mode by default */ + //LPC_IOCON->PIO0_5 = 0; + GPIOSetDir (CPU_MODE_PMU_PORT, CPU_MODE_PMU_BIT, 1); + pin_mode_pmu (0); +} diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/pmu.c b/openbeacon/lpc13xx/openbeacon-usb2/src/pmu.c new file mode 100644 index 0000000..5854c45 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/src/pmu.c @@ -0,0 +1,78 @@ +/*************************************************************** + * + * OpenBeacon.org - Power Management + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#include +#include "pin.h" +#include "pmu.h" + +/* Watchdog oscillator control register setup */ +#define FREQSEL 1 +#define FCLKANA 500000.0 +#define DIVSEL 0x1F +#define WDT_OSC_CLK (FCLKANA/(2.0*(1+DIVSEL))) + +#define MAINCLKSEL_IRC_OSC 0 +#define MAINCLKSEL_SYS_PLL 1 +#define MAINCLKSEL_WDT_OSC 2 +#define MAINCLKSEL_SYS_PLL_OUT 3 + +static const uint32_t pmu_reason_signature = 0xDEADBEEF; + +void +deep_sleep_ms (uint32_t milliseconds) +{ + (void) milliseconds; + + /* back up current power states */ + LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; + __asm volatile ("WFI"); +} + +void +pmu_sleep (void) +{ +} + +void +pmu_off (uint32_t reason) +{ + LPC_PMU->GPREG0 = pmu_reason_signature; + LPC_PMU->GPREG1 = reason; + + LPC_SYSCON->PDSLEEPCFG = 0xFFFFFFFF; + SCB->SCR |= NVIC_LP_SLEEPDEEP; + LPC_PMU->PCON = 0x2; + pin_mode_pmu (1); + __WFI (); +} + +uint32_t +pmu_reason (void) +{ + return (LPC_PMU->GPREG0==pmu_reason_signature)?LPC_PMU->GPREG1:0; +} + +void +pmu_init (void) +{ + pin_mode_pmu (0); +} diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/storage.c b/openbeacon/lpc13xx/openbeacon-usb2/src/storage.c new file mode 100644 index 0000000..c8a93f1 --- /dev/null +++ b/openbeacon/lpc13xx/openbeacon-usb2/src/storage.c @@ -0,0 +1,110 @@ +/*************************************************************** + * + * OpenBeacon.org - virtual FAT16 file system support + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ +#include +#include "vfs.h" +#include "storage.h" + +#if DISK_SIZE>0 +#include "spi.h" + +#define LOGFILE_STORAGE_SIZE (4*1024*1024) + +void +storage_status (void) +{ + static const uint8_t cmd_jedec_read_id = 0x9F; + uint8_t rx[3]; + spi_txrx (SPI_CS_FLASH, &cmd_jedec_read_id, sizeof (cmd_jedec_read_id), rx, + sizeof (rx)); + + /* Show FLASH ID */ + debug_printf (" * FLASH: ID:%02X-%02X-%02X\n", rx[0], rx[1], rx[2]); +} + +static void +storage_logfile_read_raw (uint32_t offset, uint32_t length, const void *src, + uint8_t * dst) +{ + (void) src; + + uint8_t tx[5]; + + tx[0]=0x03; /* 25MHz Read */ + tx[1]=(uint8_t)(offset>>16); + tx[2]=(uint8_t)(offset>> 8); + tx[3]=(uint8_t)(offset); + tx[4]=0x00; + + spi_txrx (SPI_CS_FLASH, tx, sizeof(tx), dst, length); +} + +void +storage_init (void) +{ + /* last entry in file chain is volume label */ + static const TDiskFile f_volume_label = { + .name = DiskBPB.BS_VolLab, + }; + + static const TDiskFile f_logfile = { + .length = LOGFILE_STORAGE_SIZE, + .handler = storage_logfile_read_raw, + .data = &f_logfile, + .name = "LOGFILE BIN", + .next = &f_volume_label, + }; + + /* read-me.htm file that redirects to project page */ + static const char readme[] = + ""; + + static const TDiskFile f_readme = { + .length = sizeof (readme) - 1, + .handler = NULL, + .data = &readme, + .name = "READ-ME HTM", + .next = &f_logfile, + }; + + /* autorun.inf file that redirects to READ-ME.HTM */ + static const char autorun_inf[] = + "[AutoRun]\n" + "shellexecute=READ-ME.HTM\n"; + + static const TDiskFile f_autorun = { + .length = sizeof (autorun_inf) - 1, + .handler = NULL, + .data = &autorun_inf, + .name = "AUTORUN INF", + .next = &f_readme, + }; + + /* init virtual file system */ + vfs_init (&f_autorun); + + /* setup SPI chipselect pin */ + spi_init_pin (SPI_CS_FLASH); +} + +#endif /* DISK_SIZE>0 */ diff --git a/openbeacon/lpc13xx/openpcd2/Makefile b/openbeacon/lpc13xx/openpcd2/Makefile new file mode 100644 index 0000000..5a582e6 --- /dev/null +++ b/openbeacon/lpc13xx/openpcd2/Makefile @@ -0,0 +1,22 @@ +TARGET=rfid +ARCH=LPC13 +CPU=$(ARCH)42 +DEBUG=-g +OPTIM=-Os -mword-relocations + +APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS +APP_LDFLAGS=-lm + +APP_SRC= \ + src/main.c \ + src/rfid.c + +APP_SRC+=$(IMAGES_C) + +all: $(TARGET).bin + +app_clean: + find src -name '*.o' -exec rm \{\} \; + +include ../core/Makefile.rules + diff --git a/openbeacon/lpc13xx/openpcd2/inc/FreeRTOSConfig.h b/openbeacon/lpc13xx/openpcd2/inc/FreeRTOSConfig.h new file mode 100644 index 0000000..ef4ba7f --- /dev/null +++ b/openbeacon/lpc13xx/openpcd2/inc/FreeRTOSConfig.h @@ -0,0 +1,104 @@ +/* + FreeRTOS V6.0.0 - Copyright (C) 2009 Real Time Engineers Ltd. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/****************************************************************************** + See http://www.freertos.org/a00110.html for an explanation of the + definitions contained in this file. +******************************************************************************/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "LPC13xx.h" + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) SystemCoreClock ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 100 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_CO_ROUTINES 0 +#define configUSE_MUTEXES 1 + +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configQUEUE_REGISTRY_SIZE 0 +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_MALLOC_FAILED_HOOK 0 + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 + +/* Use the system definition, if there is one */ +#ifdef __NVIC_PRIO_BITS + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 5 /* 32 priority levels */ +#endif + +/* The lowest priority. */ +#define configKERNEL_INTERRUPT_PRIORITY ( 31 << (8 - configPRIO_BITS) ) +/* Priority 5, or 160 as only the top three bits are implemented. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - configPRIO_BITS) ) + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/openbeacon/lpc13xx/openpcd2/inc/config.h b/openbeacon/lpc13xx/openpcd2/inc/config.h new file mode 100644 index 0000000..ce22b9a --- /dev/null +++ b/openbeacon/lpc13xx/openpcd2/inc/config.h @@ -0,0 +1,50 @@ +/*************************************************************** + * + * OpenBeacon.org - config file + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#define LED_PORT 1 /* Port for led */ +#define LED_BIT 9 /* Bit on port for led */ +#define LED_ON 1 /* Level to set port to turn on led */ +#define LED_OFF 0 /* Level to set port to turn off led */ + +/* USB device settings */ +#define ENALBLE_USB_FULLFEATURED +#define USB_VENDOR_ID 0x2366 +#define USB_PROD_ID 0x0003 +#define USB_DEVICE 0x0100 + +/* PN532 pin definitions */ +#define PN532_RESET_PORT 1 +#define PN532_RESET_PIN 11 +#define PN532_CS_PORT 0 +#define PN532_CS_PIN 2 + + +/* FreeRTOS configuration */ +#define ENABLE_FREERTOS +#define TASK_RFID_STACK_SIZE 64 +#define TASK_RFID_PRIORITY (tskIDLE_PRIORITY + 2) + +#endif/*__CONFIG_H__*/ diff --git a/openbeacon/lpc13xx/openpcd2/inc/pn532.h b/openbeacon/lpc13xx/openpcd2/inc/pn532.h new file mode 100644 index 0000000..c5d2501 --- /dev/null +++ b/openbeacon/lpc13xx/openpcd2/inc/pn532.h @@ -0,0 +1,71 @@ +/*************************************************************** + * + * OpenBeacon.org - PN532 definitions for LPC13xx based OpenPCD2 + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ + +#ifndef __PN532_H__ +#define __PN532_H__ + +/* PN532 Hardware Settings */ +#define PN532_FIFO_SIZE 64 +#define PN532_ACK_NACK_SIZE 6 + +/* PN532 Miscellaneous command set */ +#define PN532_CMD_Diagnose 0x00 +#define PN532_CMD_GetFirmwareVersion 0x02 +#define PN532_CMD_GetGeneralStatus 0x04 +#define PN532_CMD_ReadRegister 0x06 +#define PN532_CMD_WriteRegister 0x08 +#define PN532_CMD_ReadGPIO 0x0C +#define PN532_CMD_WriteGPIO 0x0E +#define PN532_CMD_SetSerialBaudRate 0x10 +#define PN532_CMD_SetParameters 0x12 +#define PN532_CMD_SAMConfiguration 0x14 +#define PN532_CMD_PowerDown 0x16 + +/* PN532 RF Communication command set */ +#define PN532_CMD_RFConfiguration 0x32 +#define PN532_CMD_RFRegulationTest 0x58 + +/* PN532 as Initiator */ +#define PN532_CMD_InJumpForDEP 0x56 +#define PN532_CMD_InJumpForPSL 0x46 +#define PN532_CMD_InListPassiveTarget 0x4A +#define PN532_CMD_InATR 0x50 +#define PN532_CMD_InPSL 0x4E +#define PN532_CMD_InDataExchange 0x40 +#define PN532_CMD_InCommunicateThru 0x42 +#define PN532_CMD_InDeselect 0x44 +#define PN532_CMD_InRelease 0x52 +#define PN532_CMD_InSelect 0x54 +#define PN532_CMD_InAutoPoll 0x60 + +/* PN532 as Target */ +#define PN532_CMD_TgInitAsTarget 0x8C +#define PN532_CMD_TgSetGeneralBytes 0x92 +#define PN532_CMD_TgGetData 0x86 +#define PN532_CMD_TgSetData 0x8E +#define PN532_CMD_TgSetMetaData 0x94 +#define PN532_CMD_TgGetInitiatorCommand 0x88 +#define PN532_CMD_TgResponseToInitiator 0x90 +#define PN532_CMD_TgGetTargetStatus 0x8A + +#endif/*__PN532_H__*/ diff --git a/openbeacon/lpc13xx/openpcd2/inc/rfid.h b/openbeacon/lpc13xx/openpcd2/inc/rfid.h new file mode 100644 index 0000000..5cb04c1 --- /dev/null +++ b/openbeacon/lpc13xx/openpcd2/inc/rfid.h @@ -0,0 +1,30 @@ +/*************************************************************** + * + * OpenBeacon.org - PN532 routines for LPC13xx based OpenPCD2 + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#ifndef __RFID_H__ +#define __RFID_H__ + +extern void rfid_init(void); +extern int rfid_read(void *data, unsigned char size); +extern int rfid_write(const void *data, int len); + +#endif/*__RFID_H__*/ diff --git a/openbeacon/lpc13xx/openpcd2/inc/usbcfg.h b/openbeacon/lpc13xx/openpcd2/inc/usbcfg.h new file mode 100644 index 0000000..8fef7c2 --- /dev/null +++ b/openbeacon/lpc13xx/openpcd2/inc/usbcfg.h @@ -0,0 +1,157 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcfg.h + * Purpose: USB Custom Configuration + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added vendor specific support + * V1.00 Initial Version + *---------------------------------------------------------------------------*/ + +#ifndef __USBCFG_H__ +#define __USBCFG_H__ + + +//*** <<< Use Configuration Wizard in Context Menu >>> *** + + +/* +// USB Configuration +// USB Power +// Default Power Setting +// <0=> Bus-powered +// <1=> Self-powered +// Max Number of Interfaces <1-256> +// Max Number of Endpoints <1-32> +// Max Endpoint 0 Packet Size +// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes +// DMA Transfer +// Use DMA for selected Endpoints +// Endpoint 0 Out +// Endpoint 0 In +// Endpoint 1 Out +// Endpoint 1 In +// Endpoint 2 Out +// Endpoint 2 In +// Endpoint 3 Out +// Endpoint 3 In +// Endpoint 4 Out +// Endpoint 4 In +// +// +*/ + +#define USB_POWER 0 +#define USB_IF_NUM 1 +#define USB_LOGIC_EP_NUM 5 +#define USB_EP_NUM 10 +#define USB_MAX_PACKET0 64 + +/* +// USB Event Handlers +// Device Events +// Power Event +// Reset Event +// Suspend Event +// Resume Event +// Remote Wakeup Event +// Start of Frame Event +// Error Event +// +// Endpoint Events +// Endpoint 0 Event +// Endpoint 1 Event +// Endpoint 2 Event +// Endpoint 3 Event +// Endpoint 4 Event +// Endpoint 5 Event +// Endpoint 6 Event +// Endpoint 7 Event +// Endpoint 8 Event +// Endpoint 9 Event +// Endpoint 10 Event +// Endpoint 11 Event +// Endpoint 12 Event +// Endpoint 13 Event +// Endpoint 14 Event +// Endpoint 15 Event +// +// USB Core Events +// Set Configuration Event +// Set Interface Event +// Set/Clear Feature Event +// +// +*/ + +#define USB_POWER_EVENT 0 +#define USB_RESET_EVENT 1 +#define USB_SUSPEND_EVENT 1 +#define USB_RESUME_EVENT 1 +#define USB_WAKEUP_EVENT 0 +#define USB_SOF_EVENT 0 +#define USB_ERROR_EVENT 0 +#define USB_EP_EVENT 0x000B +#define USB_CONFIGURE_EVENT 1 +#define USB_INTERFACE_EVENT 0 +#define USB_FEATURE_EVENT 0 + + +/* +// USB Class Support +// enables USB Class specific Requests +// Human Interface Device (HID) +// Interface Number <0-255> +// +// Mass Storage +// Interface Number <0-255> +// +// Audio Device +// Control Interface Number <0-255> +// Streaming Interface 1 Number <0-255> +// Streaming Interface 2 Number <0-255> +// +// Communication Device +// Control Interface Number <0-255> +// Bulk Interface Number <0-255> +// Max Communication Device Buffer Size +// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes +// +// +*/ + +#define USB_CLASS 1 +#define USB_HID 0 +#define USB_HID_IF_NUM 0 +#define USB_MSC 0 +#define USB_MSC_IF_NUM 0 +#define USB_AUDIO 0 +#define USB_ADC_CIF_NUM 0 +#define USB_ADC_SIF1_NUM 1 +#define USB_ADC_SIF2_NUM 2 +#define USB_CDC 1 +#define USB_CDC_CIF_NUM 0 +#define USB_CDC_DIF_NUM 1 +#define USB_CDC_BUFSIZE 64 + +/* +// USB Vendor Support +// enables USB Vendor specific Requests +// +*/ +#define USB_VENDOR 0 + + +#endif /* __USBCFG_H__ */ diff --git a/openbeacon/lpc13xx/openpcd2/src/main.c b/openbeacon/lpc13xx/openpcd2/src/main.c new file mode 100644 index 0000000..5dbac07 --- /dev/null +++ b/openbeacon/lpc13xx/openpcd2/src/main.c @@ -0,0 +1,72 @@ +/*************************************************************** + * + * OpenBeacon.org - main file for OpenPCD2 basic demo + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#include +#include "rfid.h" + +static BOOL vTasksRunning = FALSE; + +/* + * overwrite default_putchar with USB CDC ACM + * output to enable USB support for debug_printf + */ +BOOL default_putchar(uint8_t data) +{ + if (vTasksRunning) + CDC_PutChar (data); + + /* always send out over serial port as well */ + UARTSendChar (data); + + return TRUE; +} + +int main(void) +{ + /* Initialize GPIO (sets up clock) */ + GPIOInit(); + + /* Set LED port pin to output */ + GPIOSetDir(LED_PORT, LED_BIT, LED_ON); + + /* CDC Initialization */ + CDC_Init(); + /* USB Initialization */ + USB_Init(); + /* Connect to USB port */ + USB_Connect(1); + + /* UART setup */ + UARTInit(115200, 0); + + /* Init RFID */ + rfid_init(); + + /* Update Core Clock */ + SystemCoreClockUpdate (); + + /* Start the tasks running. */ + vTasksRunning = TRUE; + vTaskStartScheduler(); + + return 0; +} diff --git a/openbeacon/lpc13xx/openpcd2/src/rfid.c b/openbeacon/lpc13xx/openpcd2/src/rfid.c new file mode 100644 index 0000000..1a9eb2b --- /dev/null +++ b/openbeacon/lpc13xx/openpcd2/src/rfid.c @@ -0,0 +1,359 @@ +/*************************************************************** + * + * OpenBeacon.org - PN532 routines for LPC13xx based OpenPCD2 + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#include +#include "pn532.h" +#include "rfid.h" + +#define BIT_REVERSE(x) ((unsigned char)(__RBIT(x)>>24)) + +static void rfid_reset(unsigned char reset) +{ + GPIOSetValue(PN532_RESET_PORT, PN532_RESET_PIN, reset ? 1 : 0); +} + +static void rfid_cs(unsigned char cs) +{ + GPIOSetValue(PN532_CS_PORT, PN532_CS_PIN, cs ? 1 : 0); +} + +static unsigned char rfid_tx(unsigned char data) +{ + while ((LPC_SSP->SR & 0x02) == 0); + LPC_SSP->DR = BIT_REVERSE (data); + while ((LPC_SSP->SR & 0x04) == 0); + data = BIT_REVERSE (LPC_SSP->DR); + return data; +} + +static unsigned char rfid_rx(void) +{ + return rfid_tx(0x00); +} + +static unsigned char rfid_status(void) +{ + unsigned char res; + + /* enable chip select */ + rfid_cs(0); + + /* transmit status request */ + rfid_tx(0x02); + res = rfid_rx(); + + /* release chip select */ + rfid_cs(1); + + return res; +} + +int rfid_read(void *data, unsigned char size) +{ + int res; + unsigned char *p, c, pkt_size, crc, prev, t; + + /* wait 100ms max till PN532 response is ready */ + t=0; + while ((rfid_status() & 1) == 0) + { + if(t++>10) + return -8; + vTaskDelay( 10 / portTICK_RATE_MS); + } + + /* enable chip select */ + rfid_cs(0); + + /* read from FIFO command */ + rfid_tx(0x03); + + /* default result */ + res = -1; + + /* find preamble */ + t = 0; + prev = rfid_rx(); + while ((!(((c = rfid_rx()) == 0xFF) && (prev == 0x00))) && (t + < PN532_FIFO_SIZE)) + { + prev = c; + t++; + } + + if (t >= PN532_FIFO_SIZE) + res = -3; + else + { + /* read packet size */ + pkt_size = rfid_rx(); + + /* special treatment for NACK and ACK */ + if ((pkt_size == 0x00) || (pkt_size == 0xFF)) + { + /* verify if second length byte is inverted */ + if (rfid_rx() != (unsigned char) (~pkt_size)) + res = -2; + else + { + /* eat Postamble */ + rfid_rx(); + /* -1 for NACK, 0 for ACK */ + res = pkt_size ? 0 : -1; + } + } + else + { + /* verify packet size against LCS */ + if (((pkt_size + rfid_rx()) & 0xFF) != 0) + res = -4; + else + { + /* remove TFI from packet size */ + pkt_size--; + /* verify if packet fits into buffer */ + if (pkt_size > size) + res = -5; + else + { + /* remember actual packet size */ + size = pkt_size; + /* verify TFI */ + if ((crc = rfid_rx()) != 0xD5) + res = -6; + else + { + /* read packet */ + p = (unsigned char *) data; + while (pkt_size--) + { + /* read data */ + c = rfid_rx(); + /* maintain crc */ + crc += c; + /* save payload */ + if (p) + *p++ = c; + } + + /* add DCS to CRC */ + crc += rfid_rx(); + /* verify CRC */ + if (crc) + res = -7; + else + { + /* eat Postamble */ + rfid_rx(); + /* return actual size as result */ + res = size; + } + } + } + } + } + } + rfid_cs(1); + + /* everything fine */ + return res; +} + +int rfid_write(const void *data, int len) +{ + int i; + static const unsigned char preamble[] = + { 0x01, 0x00, 0x00, 0xFF }; + const unsigned char *p = preamble; + unsigned char tfi = 0xD4, c; + + if (!data) + len = 0xFF; + + /* enable chip select */ + rfid_cs(0); + + p = preamble; /* Praeamble */ + for (i = 0; i < (int) sizeof(preamble); i++) + rfid_tx(*p++); + rfid_tx(len + 1); /* LEN */ + rfid_tx(0x100 - (len + 1)); /* LCS */ + rfid_tx(tfi); /* TFI */ + /* PDn */ + p = (const unsigned char *) data; + while (len--) + { + c = *p++; + rfid_tx(c); + tfi += c; + } + rfid_tx(0x100 - tfi); /* DCS */ + rfid_rx(); /* Postamble */ + + /* release chip select */ + rfid_cs(1); + + /* check for ack */ + return rfid_read(NULL, 0); +} + +static void rfid_hexdump(const void *buffer, int size) +{ + int i; + const unsigned char *p = (unsigned char *) buffer; + + for (i = 0; i < size; i++) + { + if (i && ((i & 3) == 0)) + debug_printf(" "); + debug_printf(" %02X", *p++); + } + debug_printf(" [size=%02i]\n", size); +} + +static int rfid_execute(void *data, unsigned int isize, unsigned int osize) +{ + int res; + if (rfid_write(data, isize)) + { + debug_printf("getting result\n"); + res = rfid_read(data, osize); + if (res > 0) + rfid_hexdump(data, res); + else + debug_printf("error: res=%i\n", res); + } + else + { + debug_printf("->NACK!\n"); + res = -1; + } + return res; +} + +void WriteRegister(unsigned short address, unsigned char data) +{ + unsigned char cmd[4]; + + /* write register */ + cmd[0] = 0x08; + /* high byte of address */ + cmd[1] = address >> 8; + /* low byte of address */ + cmd[2] = address & 0xFF; + /* data value */ + cmd[3] = data; + + rfid_execute(&cmd, sizeof(cmd), sizeof(data)); +} + +static +void rfid_task(void *pvParameters) +{ + int i; + static unsigned char data[80]; + + /* touch unused Parameter */ + (void) pvParameters; + + /* release reset line after 400ms */ + vTaskDelay( 400 / portTICK_RATE_MS); + rfid_reset(1); + /* wait for PN532 to boot */ + vTaskDelay( 100 / portTICK_RATE_MS); + + /* read firmware revision */ + debug_printf("\nreading firmware version...\n"); + data[0] = PN532_CMD_GetFirmwareVersion; + rfid_execute(&data, 1, sizeof(data)); + + /* enable debug output */ + debug_printf("\nenabling debug output...\n"); + WriteRegister(0x6328, 0xFC); + // select test bus signal + WriteRegister(0x6321, 6); + // select test bus type + WriteRegister(0x6322, 0x07); + + while (1) + { + /* wait 500ms */ + vTaskDelay( 500 / portTICK_RATE_MS); + + /* detect cards in field */ + GPIOSetValue(LED_PORT, LED_BIT, LED_ON); + debug_printf("\nchecking for cards...\n"); + data[0] = PN532_CMD_InListPassiveTarget; + data[1] = 0x01; /* MaxTg - maximum cards */ + data[2] = 0x00; /* BrTy - 106 kbps type A */ + if (((i = rfid_execute(&data, 3, sizeof(data))) >= 11) && (data[1] + == 0x01) && (data[2] == 0x01)) + { + debug_printf("card id: "); + rfid_hexdump(&data[7], data[6]); + } + else + debug_printf("unknown response of %i bytes\n", i); + GPIOSetValue(LED_PORT, LED_BIT, LED_OFF); + + /* turning field off */ + debug_printf("\nturning field off again...\n"); + data[0] = PN532_CMD_RFConfiguration; + data[1] = 0x01; /* CfgItem = 0x01 */ + data[2] = 0x00; /* RF Field = off */ + rfid_execute(&data, 3, sizeof(data)); + } +} + +void rfid_init(void) +{ + /* reset SSP peripheral */ + LPC_SYSCON->PRESETCTRL = 0x01; + + /* Enable SSP clock */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 11); + + // Enable SSP peripheral + LPC_IOCON->PIO0_8 = 0x01 | (0x01 << 3); /* MISO, Pulldown */ + LPC_IOCON->PIO0_9 = 0x01; /* MOSI */ + + LPC_IOCON->SCKLOC = 0x00; /* route to PIO0_10 */ + LPC_IOCON->JTAG_TCK_PIO0_10 = 0x02; /* SCK */ + + /* Set SSP clock to 4.5MHz */ + LPC_SYSCON->SSPCLKDIV = 0x01; + LPC_SSP->CR0 = 0x0707; + LPC_SSP->CR1 = 0x0002; + LPC_SSP->CPSR = 0x02; + + /* Initialize chip select line */ + rfid_cs(1); + GPIOSetDir(PN532_CS_PORT, PN532_CS_PIN, 1); + + /* Initialize RESET line */ + rfid_reset(0); + GPIOSetDir(PN532_RESET_PORT, PN532_RESET_PIN, 1); + + /* Create PN532 task */ + xTaskCreate(rfid_task, (const signed char*) "RFID", TASK_RFID_STACK_SIZE, + NULL, TASK_RFID_PRIORITY, NULL); +} diff --git a/openbeacon/lpc13xx/rtos-simple-demo/Makefile b/openbeacon/lpc13xx/rtos-simple-demo/Makefile new file mode 100644 index 0000000..d00aa79 --- /dev/null +++ b/openbeacon/lpc13xx/rtos-simple-demo/Makefile @@ -0,0 +1,21 @@ +TARGET=rtos-simple-demo +ARCH=LPC13 +CPU=$(ARCH)43 +DEBUG=-g +OPTIM=-Os -mword-relocations + +APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS +APP_LDFLAGS=-lm + +APP_SRC= \ + src/main.c + +APP_SRC+=$(IMAGES_C) + +all: $(TARGET).bin + +app_clean: + find src -name '*.o' -exec rm \{\} \; + +include ../core/Makefile.rules + diff --git a/openbeacon/lpc13xx/rtos-simple-demo/inc/FreeRTOSConfig.h b/openbeacon/lpc13xx/rtos-simple-demo/inc/FreeRTOSConfig.h new file mode 100644 index 0000000..ef4ba7f --- /dev/null +++ b/openbeacon/lpc13xx/rtos-simple-demo/inc/FreeRTOSConfig.h @@ -0,0 +1,104 @@ +/* + FreeRTOS V6.0.0 - Copyright (C) 2009 Real Time Engineers Ltd. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/****************************************************************************** + See http://www.freertos.org/a00110.html for an explanation of the + definitions contained in this file. +******************************************************************************/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "LPC13xx.h" + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) SystemCoreClock ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 100 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_CO_ROUTINES 0 +#define configUSE_MUTEXES 1 + +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configQUEUE_REGISTRY_SIZE 0 +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_MALLOC_FAILED_HOOK 0 + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 + +/* Use the system definition, if there is one */ +#ifdef __NVIC_PRIO_BITS + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 5 /* 32 priority levels */ +#endif + +/* The lowest priority. */ +#define configKERNEL_INTERRUPT_PRIORITY ( 31 << (8 - configPRIO_BITS) ) +/* Priority 5, or 160 as only the top three bits are implemented. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - configPRIO_BITS) ) + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/openbeacon/lpc13xx/rtos-simple-demo/inc/config.h b/openbeacon/lpc13xx/rtos-simple-demo/inc/config.h new file mode 100644 index 0000000..b796958 --- /dev/null +++ b/openbeacon/lpc13xx/rtos-simple-demo/inc/config.h @@ -0,0 +1,9 @@ +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#define ENABLE_FREERTOS + +#define LED_PORT 1 // Port for led +#define LED_BIT 9 // Bit on port for led + +#endif/*__CONFIG_H__*/ diff --git a/openbeacon/lpc13xx/rtos-simple-demo/src/main.c b/openbeacon/lpc13xx/rtos-simple-demo/src/main.c new file mode 100644 index 0000000..27631d8 --- /dev/null +++ b/openbeacon/lpc13xx/rtos-simple-demo/src/main.c @@ -0,0 +1,190 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + * This is a very simple demo that demonstrates task and queue usages only. + * Details of other FreeRTOS features (API functions, tracing features, + * diagnostic hook functions, memory management, etc.) can be found on the + * FreeRTOS web site (http://www.FreeRTOS.org) and in the FreeRTOS book. + * Details of this demo (what it does, how it should behave, etc.) can be found + * in the accompanying PDF application note. + * +*/ + +/* Kernel includes. */ +#include +#include +#include +#include +#include "config.h" + +/* Priorities at which the tasks are created. */ +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* The rate at which data is sent to the queue, specified in milliseconds. */ +#define mainQUEUE_SEND_FREQUENCY_MS ( 500 / portTICK_RATE_MS ) + +/* The number of items the queue can hold. This is 1 as the receive task +will remove items as they are added, meaning the send task should always find +the queue empty. */ +#define mainQUEUE_LENGTH ( 1 ) + +/* + * The tasks as described in the accompanying PDF application note. + */ +static void prvQueueReceiveTask (void *pvParameters); +static void prvQueueSendTask (void *pvParameters); + +/* The queue used by both tasks. */ +static xQueueHandle xQueue = NULL; +/*-----------------------------------------------------------*/ + +int +main (void) +{ + /* Initialize GPIO (sets up clock) */ + GPIOInit (); + /* Set LED port pin to output */ + GPIOSetDir (LED_PORT, LED_BIT, 1); + GPIOSetValue (LED_PORT, LED_BIT, 0); + + /* Create the queue. */ + xQueue = xQueueCreate (mainQUEUE_LENGTH, sizeof (unsigned long)); + + if (xQueue != NULL) + { + /* Start the two tasks as described in the accompanying application + note. */ + xTaskCreate (prvQueueReceiveTask, (signed char *) "Rx", + configMINIMAL_STACK_SIZE, NULL, + mainQUEUE_RECEIVE_TASK_PRIORITY, NULL); + xTaskCreate (prvQueueSendTask, (signed char *) "TX", + configMINIMAL_STACK_SIZE, NULL, + mainQUEUE_SEND_TASK_PRIORITY, NULL); + + /* Start the tasks running. */ + vTaskStartScheduler (); + } + + /* If all is well we will never reach here as the scheduler will now be + running. If we do reach here then it is likely that there was insufficient + heap available for the idle task to be created. */ + for (;;); +} + +/*-----------------------------------------------------------*/ + +static void +prvQueueSendTask (void *pvParameters) +{ + portTickType xNextWakeTime; + unsigned long ulValueToSend; + + (void) pvParameters; + + /* Initialise xNextWakeTime - this only needs to be done once. */ + xNextWakeTime = xTaskGetTickCount (); + + for (;;) + { + /* Place this task in the blocked state until it is time to run again. + The block state is specified in ticks, the constant used converts ticks + to ms. While in the blocked state this task will not consume any CPU + time. */ + vTaskDelayUntil (&xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS); + + /* Send to the queue - causing the queue receive task to flash its LED. + 0 is used as the block time so the sending operation will not block - + it shouldn't need to block as the queue should always be empty at this + point in the code. */ + ulValueToSend = 100; + xQueueSend (xQueue, &ulValueToSend, 0); + + /* Place this task in the blocked state until it is time to run again. + The block state is specified in ticks, the constant used converts ticks + to ms. While in the blocked state this task will not consume any CPU + time. */ + vTaskDelayUntil (&xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS); + + /* Send to the queue - causing the queue receive task to flash its LED. + 0 is used as the block time so the sending operation will not block - + it shouldn't need to block as the queue should always be empty at this + point in the code. */ + ulValueToSend = 0; + xQueueSend (xQueue, &ulValueToSend, 0); + } +} + +/*-----------------------------------------------------------*/ + +static void +prvQueueReceiveTask (void *pvParameters) +{ + unsigned long ulReceivedValue; + + (void) pvParameters; + + for (;;) + { + /* Wait until something arrives in the queue - this task will block + indefinitely provided INCLUDE_vTaskSuspend is set to 1 in + FreeRTOSConfig.h. */ + xQueueReceive (xQueue, &ulReceivedValue, portMAX_DELAY); + + /* To get here something must have been received from the queue, but + is it the expected value? If it is, toggle the LED. */ + if (ulReceivedValue == 100UL) + GPIOSetValue (LED_PORT, LED_BIT, 1); + else + GPIOSetValue (LED_PORT, LED_BIT, 0); + } +} diff --git a/openbeacon/lpc13xx/sound/Makefile b/openbeacon/lpc13xx/sound/Makefile new file mode 100644 index 0000000..41a04f5 --- /dev/null +++ b/openbeacon/lpc13xx/sound/Makefile @@ -0,0 +1,21 @@ +TARGET=sound +ARCH=LPC13 +CPU=$(ARCH)43 +DEBUG=-g +OPTIM=-Os -mword-relocations + +APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS +APP_LDFLAGS=-lm + +APP_SRC= \ + src/soundtest.c + +APP_SRC+=$(IMAGES_C) + +all: $(TARGET).bin + +app_clean: + find src -name '*.o' -exec rm \{\} \; + +include ../core/Makefile.rules + diff --git a/openbeacon/lpc13xx/sound/inc/config.h b/openbeacon/lpc13xx/sound/inc/config.h new file mode 100644 index 0000000..5c3065b --- /dev/null +++ b/openbeacon/lpc13xx/sound/inc/config.h @@ -0,0 +1,9 @@ +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#define BUT1_PORT 2 // Port for Button 1 +#define BUT1_PIN 9 // Bit on port forButton 1 +#define BUT2_PORT 1 // Port for Button 2 +#define BUT2_PIN 4 // Bit on port forButton 2 + +#endif/*__CONFIG_H__*/ diff --git a/openbeacon/lpc13xx/sound/src/soundtest.c b/openbeacon/lpc13xx/sound/src/soundtest.c new file mode 100644 index 0000000..09dada3 --- /dev/null +++ b/openbeacon/lpc13xx/sound/src/soundtest.c @@ -0,0 +1,143 @@ +#include + +#define TONES_MAX 32 +#define ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0])) + +/* 8xLED bar display */ +static void +set_led (uint8_t led) +{ + led = ~led; + LPC_GPIO2->MASKED_ACCESS[0xF0] = led; + LPC_GPIO3->MASKED_ACCESS[0x0F] = led; +} + +static void +beep (double frequency) +{ + uint32_t t; + + LPC_TMR32B1->TCR = 0; + if (frequency) + { + t = (SystemCoreClock / 2) / frequency; + + LPC_TMR32B1->MR0 = LPC_TMR32B1->MR1 = t; + + if (LPC_TMR32B1->TC >= t) + LPC_TMR32B1->TC = t; + + LPC_TMR32B1->TCR = 1; + } +} + +static double +get_frequency_for_tone (uint8_t tone) +{ + static const double frequency[] = { + 262.63, 293.66, 329.63, + 349.23, 392.00, 440.00, 493.88 + }; + return frequency[tone % ARRAY_COUNT (frequency)] * + (1 << (tone / ARRAY_COUNT (frequency))); +} + +static void +tone (uint8_t tone) +{ + static uint8_t lasttone = 0; + + if (tone != lasttone) + { + lasttone = tone; + beep (tone ? get_frequency_for_tone (tone - 1) : 0); + } +} + +int +main (void) +{ + volatile int t; + int i, mode, index, start; + + /* Get System Clock */ + SystemCoreClockUpdate (); + + /* Initialize GPIO (sets up clock) */ + GPIOInit (); + GPIOSetDir (BUT1_PORT, BUT1_PIN, 0); + GPIOSetDir (BUT2_PORT, BUT2_PIN, 0); + + /* Set LED port pin to output */ + LPC_GPIO2->DIR |= 0xF0; + LPC_GPIO3->DIR |= 0x0F; + + /* Set sound port to PIO1_1 and PIO1_2 */ + LPC_GPIO1->DIR |= 0x6; + LPC_IOCON->JTAG_TDO_PIO1_1 = 3; + LPC_IOCON->JTAG_nTRST_PIO1_2 = 3; + + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10); + LPC_TMR32B1->TCR = 2; + LPC_TMR32B1->MCR = 1 << 4; + LPC_TMR32B1->EMR = 1 | (0x3 << 4) | (0x3 << 6); + + mode = 2; + index = 24; + while (1) + { + /* BUTTON1 press cycles through tones */ + if (!GPIOGetValue (BUT1_PORT, BUT1_PIN)) + { + mode = (mode + 1) & 0x7; + /* debounce */ + for (t = 0; t < 1000000; t++); + } + + /* BUTTON2 plays tone */ + if (!GPIOGetValue (BUT2_PORT, BUT2_PIN)) + { + set_led (0xFF); + /* debounce */ + + switch (mode) + { + + case 0: + index++; + if (index > TONES_MAX) + index = 1; + tone (index); + for (t = 0; t < 2000000; t++); + break; + + case 1: + if (index > 1) + index--; + else + index = TONES_MAX; + tone (index); + for (t = 0; t < 2000000; t++); + break; + + case 2: + tone (index); + break; + + default: + start = get_frequency_for_tone (index) - 500; + for (i = 100; i > 0; i--) + { + beep (start + (i * 10)); + for (t = 0; t < (mode * 5000); t++); + } + beep (0); + break; + } + } + else if (mode <= 2) + tone (0); + + set_led (1 << mode); + } +} diff --git a/openbeacon/lpc13xx/uart/Makefile b/openbeacon/lpc13xx/uart/Makefile new file mode 100644 index 0000000..0df7138 --- /dev/null +++ b/openbeacon/lpc13xx/uart/Makefile @@ -0,0 +1,21 @@ +TARGET=uart +ARCH=LPC13 +CPU=$(ARCH)42 +DEBUG=-g +OPTIM=-Os -mword-relocations + +APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS +APP_LDFLAGS=-lm + +APP_SRC= \ + src/uarttest.c + +APP_SRC+=$(IMAGES_C) + +all: $(TARGET).bin + +app_clean: + find src -name '*.o' -exec rm \{\} \; + +include ../core/Makefile.rules + diff --git a/openbeacon/lpc13xx/uart/inc/config.h b/openbeacon/lpc13xx/uart/inc/config.h new file mode 100644 index 0000000..d522ba7 --- /dev/null +++ b/openbeacon/lpc13xx/uart/inc/config.h @@ -0,0 +1,43 @@ +/***************************************************************************** + * config.h: config file for uart example for NXP LPC13xx Family + * Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2008.07.19 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ + +/* +Overview: + This example shows how to use a timer to blink an LED. It works by using + libLPC to configure a I/O port and a 32-bit timer, then setting up a timer + interrupt to increment a counter. The main loop polls the counter to + determine when to toggle the LED state. + +User #defines: + LED_PORT I/O port driving an LED + LED_BIT I/O port bit driving an LED + LED_ON Value to set the bit to turn on the LED + LED_OFF Value to set the bit to turn off the LED + LED_TOGGLE_TICKS + Number of timer ticks per flash. The timer is configured to generate + an interrupt 100 times a second or every 10mS. + +How to use: + Click the debug toolbar button. + + * You should see an LED flashing. +*/ + +#define LED_PORT 1 // Port for led +#define LED_BIT 9 // Bit on port for led +#define LED_ON 1 // Level to set port to turn on led +#define LED_OFF 0 // Level to set port to turn off led +#define LED_TOGGLE_TICKS 100 // 100 ticks = 1 Hz flash rate + +/********************************************************************************* +** End Of File +*********************************************************************************/ diff --git a/openbeacon/lpc13xx/uart/src/uarttest.c b/openbeacon/lpc13xx/uart/src/uarttest.c new file mode 100644 index 0000000..03b897f --- /dev/null +++ b/openbeacon/lpc13xx/uart/src/uarttest.c @@ -0,0 +1,52 @@ +/***************************************************************************** + * uarttest.c: UART test C file for NXP LPC13xx Family Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2008.08.20 ver 1.00 Preliminary version, first Release + * 2010.07.21 ver 1.01 Added OpenBeacon stakc and debug_printf + * +******************************************************************************/ + +#include + +int +main (void) +{ + volatile int i; + + /* Basic chip initialization is taken care of in SystemInit() called + * from the startup code. SystemInit() and chip settings are defined + * in the CMSIS system_.c file. + */ + + /* NVIC is installed inside UARTInit file. */ + UARTInit (115200, 0); + + /* Initialize GPIO (sets up clock) */ + GPIOInit (); + + /* Set LED port pin to output */ + GPIOSetDir (LED_PORT, LED_BIT, 1); + + debug_printf ("Hello World!\n"); + + while (1) + { /* Loop forever */ + if (UARTCount != 0) + { + /* Send back everything we receive */ + UARTSend ((uint8_t *) UARTBuffer, UARTCount); + UARTCount = 0; + + /* Blink on every TX packet */ + GPIOSetValue (LED_PORT, LED_BIT, LED_OFF); + /* Small Delay to make blink visible */ + for(i=0;i<200000;i++); + /* Turn off LED on exit */ + GPIOSetValue (LED_PORT, LED_BIT, LED_ON); + } + } +} diff --git a/openbeacon/lpc13xx/usbcdc-storage/Makefile b/openbeacon/lpc13xx/usbcdc-storage/Makefile new file mode 100644 index 0000000..e2ffe82 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/Makefile @@ -0,0 +1,28 @@ +TARGET=usbcdc-storage +ARCH=LPC13 +CPU=$(ARCH)43 +DEBUG=-g +OPTIM=-Os -mword-relocations + +APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS +APP_LDFLAGS=-lm + +APP_SRC= \ + src/main.c \ + src/cdcuser.c \ + src/clkconfig.c \ + src/DiskImg.c \ + src/mscuser.c \ + src/usbcore.c \ + src/compusbdesc.c \ + src/usbhw.c \ + src/usbuser.c + +APP_SRC+=$(IMAGES_C) + +all: $(TARGET).bin + +app_clean: + find src -name '*.o' -exec rm \{\} \; + +include ../core/Makefile.rules diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/cdc.h b/openbeacon/lpc13xx/usbcdc-storage/inc/cdc.h new file mode 100644 index 0000000..d61b85b --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/cdc.h @@ -0,0 +1,241 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: CDC.h + * Purpose: USB Communication Device Class Definitions + * Version: V1.00 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __CDC_H +#define __CDC_H + +/*---------------------------------------------------------------------------- + * Definitions based on usbcdc11.pdf (www.usb.org) + *---------------------------------------------------------------------------*/ +// Communication device class specification version 1.10 +#define CDC_V1_10 0x0110 + +// Communication interface class code +// (usbcdc11.pdf, 4.2, Table 15) +#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 + +// Communication interface class subclass codes +// (usbcdc11.pdf, 4.3, Table 16) +#define CDC_DIRECT_LINE_CONTROL_MODEL 0x01 +#define CDC_ABSTRACT_CONTROL_MODEL 0x02 +#define CDC_TELEPHONE_CONTROL_MODEL 0x03 +#define CDC_MULTI_CHANNEL_CONTROL_MODEL 0x04 +#define CDC_CAPI_CONTROL_MODEL 0x05 +#define CDC_ETHERNET_NETWORKING_CONTROL_MODEL 0x06 +#define CDC_ATM_NETWORKING_CONTROL_MODEL 0x07 + +// Communication interface class control protocol codes +// (usbcdc11.pdf, 4.4, Table 17) +#define CDC_PROTOCOL_COMMON_AT_COMMANDS 0x01 + +// Data interface class code +// (usbcdc11.pdf, 4.5, Table 18) +#define CDC_DATA_INTERFACE_CLASS 0x0A + +// Data interface class protocol codes +// (usbcdc11.pdf, 4.7, Table 19) +#define CDC_PROTOCOL_ISDN_BRI 0x30 +#define CDC_PROTOCOL_HDLC 0x31 +#define CDC_PROTOCOL_TRANSPARENT 0x32 +#define CDC_PROTOCOL_Q921_MANAGEMENT 0x50 +#define CDC_PROTOCOL_Q921_DATA_LINK 0x51 +#define CDC_PROTOCOL_Q921_MULTIPLEXOR 0x52 +#define CDC_PROTOCOL_V42 0x90 +#define CDC_PROTOCOL_EURO_ISDN 0x91 +#define CDC_PROTOCOL_V24_RATE_ADAPTATION 0x92 +#define CDC_PROTOCOL_CAPI 0x93 +#define CDC_PROTOCOL_HOST_BASED_DRIVER 0xFD +#define CDC_PROTOCOL_DESCRIBED_IN_PUFD 0xFE + +// Type values for bDescriptorType field of functional descriptors +// (usbcdc11.pdf, 5.2.3, Table 24) +#define CDC_CS_INTERFACE 0x24 +#define CDC_CS_ENDPOINT 0x25 + +// Type values for bDescriptorSubtype field of functional descriptors +// (usbcdc11.pdf, 5.2.3, Table 25) +#define CDC_HEADER 0x00 +#define CDC_CALL_MANAGEMENT 0x01 +#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 +#define CDC_DIRECT_LINE_MANAGEMENT 0x03 +#define CDC_TELEPHONE_RINGER 0x04 +#define CDC_REPORTING_CAPABILITIES 0x05 +#define CDC_UNION 0x06 +#define CDC_COUNTRY_SELECTION 0x07 +#define CDC_TELEPHONE_OPERATIONAL_MODES 0x08 +#define CDC_USB_TERMINAL 0x09 +#define CDC_NETWORK_CHANNEL 0x0A +#define CDC_PROTOCOL_UNIT 0x0B +#define CDC_EXTENSION_UNIT 0x0C +#define CDC_MULTI_CHANNEL_MANAGEMENT 0x0D +#define CDC_CAPI_CONTROL_MANAGEMENT 0x0E +#define CDC_ETHERNET_NETWORKING 0x0F +#define CDC_ATM_NETWORKING 0x10 + +// CDC class-specific request codes +// (usbcdc11.pdf, 6.2, Table 46) +// see Table 45 for info about the specific requests. +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define CDC_SET_COMM_FEATURE 0x02 +#define CDC_GET_COMM_FEATURE 0x03 +#define CDC_CLEAR_COMM_FEATURE 0x04 +#define CDC_SET_AUX_LINE_STATE 0x10 +#define CDC_SET_HOOK_STATE 0x11 +#define CDC_PULSE_SETUP 0x12 +#define CDC_SEND_PULSE 0x13 +#define CDC_SET_PULSE_TIME 0x14 +#define CDC_RING_AUX_JACK 0x15 +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 +#define CDC_SEND_BREAK 0x23 +#define CDC_SET_RINGER_PARMS 0x30 +#define CDC_GET_RINGER_PARMS 0x31 +#define CDC_SET_OPERATION_PARMS 0x32 +#define CDC_GET_OPERATION_PARMS 0x33 +#define CDC_SET_LINE_PARMS 0x34 +#define CDC_GET_LINE_PARMS 0x35 +#define CDC_DIAL_DIGITS 0x36 +#define CDC_SET_UNIT_PARAMETER 0x37 +#define CDC_GET_UNIT_PARAMETER 0x38 +#define CDC_CLEAR_UNIT_PARAMETER 0x39 +#define CDC_GET_PROFILE 0x3A +#define CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define CDC_SET_ETHERNET_PMP_FILTER 0x41 +#define CDC_GET_ETHERNET_PMP_FILTER 0x42 +#define CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define CDC_GET_ETHERNET_STATISTIC 0x44 +#define CDC_SET_ATM_DATA_FORMAT 0x50 +#define CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define CDC_SET_ATM_DEFAULT_VC 0x52 +#define CDC_GET_ATM_VC_STATISTICS 0x53 + +// Communication feature selector codes +// (usbcdc11.pdf, 6.2.2..6.2.4, Table 47) +#define CDC_ABSTRACT_STATE 0x01 +#define CDC_COUNTRY_SETTING 0x02 + +// Feature Status returned for ABSTRACT_STATE Selector +// (usbcdc11.pdf, 6.2.3, Table 48) +#define CDC_IDLE_SETTING (1 << 0) +#define CDC_DATA_MULTPLEXED_STATE (1 << 1) + + +// Control signal bitmap values for the SetControlLineState request +// (usbcdc11.pdf, 6.2.14, Table 51) +#define CDC_DTE_PRESENT (1 << 0) +#define CDC_ACTIVATE_CARRIER (1 << 1) + +// CDC class-specific notification codes +// (usbcdc11.pdf, 6.3, Table 68) +// see Table 67 for Info about class-specific notifications +#define CDC_NOTIFICATION_NETWORK_CONNECTION 0x00 +#define CDC_RESPONSE_AVAILABLE 0x01 +#define CDC_AUX_JACK_HOOK_STATE 0x08 +#define CDC_RING_DETECT 0x09 +#define CDC_NOTIFICATION_SERIAL_STATE 0x20 +#define CDC_CALL_STATE_CHANGE 0x28 +#define CDC_LINE_STATE_CHANGE 0x29 +#define CDC_CONNECTION_SPEED_CHANGE 0x2A + +// UART state bitmap values (Serial state notification). +// (usbcdc11.pdf, 6.3.5, Table 69) +#define CDC_SERIAL_STATE_OVERRUN (1 << 6) // receive data overrun error has occurred +#define CDC_SERIAL_STATE_PARITY (1 << 5) // parity error has occurred +#define CDC_SERIAL_STATE_FRAMING (1 << 4) // framing error has occurred +#define CDC_SERIAL_STATE_RING (1 << 3) // state of ring signal detection +#define CDC_SERIAL_STATE_BREAK (1 << 2) // state of break detection +#define CDC_SERIAL_STATE_TX_CARRIER (1 << 1) // state of transmission carrier +#define CDC_SERIAL_STATE_RX_CARRIER (1 << 0) // state of receiver carrier + + +/*---------------------------------------------------------------------------- + * Structures based on usbcdc11.pdf (www.usb.org) + *---------------------------------------------------------------------------*/ + +// Header functional descriptor +// (usbcdc11.pdf, 5.2.3.1) +// This header must precede any list of class-specific descriptors. +typedef struct _CDC_HEADER_DESCRIPTOR +{ + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // Header functional descriptor subtype + uint16_t bcdCDC; // USB CDC specification release version +} __attribute__ ((packed)) CDC_HEADER_DESCRIPTOR; + +//Call management functional descriptor +// (usbcdc11.pdf, 5.2.3.2) +// Describes the processing of calls for the communication class interface. +typedef struct _CDC_CALL_MANAGEMENT_DESCRIPTOR +{ + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // call management functional descriptor subtype + uint8_t bmCapabilities; // capabilities that this configuration supports + uint8_t bDataInterface; // interface number of the data class interface used for call management (optional) +} __attribute__ ((packed)) CDC_CALL_MANAGEMENT_DESCRIPTOR; + +// Abstract control management functional descriptor +// (usbcdc11.pdf, 5.2.3.3) +// Describes the command supported by the communication interface class with the Abstract Control Model subclass code. +typedef struct _CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR +{ + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // abstract control management functional descriptor subtype + uint8_t bmCapabilities; // capabilities supported by this configuration +} __attribute__ ((packed)) CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR; + +// Union functional descriptors +// (usbcdc11.pdf, 5.2.3.8) +// Describes the relationship between a group of interfaces that can be considered to form a functional unit. +typedef struct _CDC_UNION_DESCRIPTOR +{ + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // union functional descriptor subtype + uint8_t bMasterInterface; // interface number designated as master +} __attribute__ ((packed)) CDC_UNION_DESCRIPTOR; + +// Union functional descriptors with one slave interface +// (usbcdc11.pdf, 5.2.3.8) +typedef struct _CDC_UNION_1SLAVE_DESCRIPTOR +{ + CDC_UNION_DESCRIPTOR sUnion; // Union functional descriptor + uint8_t bSlaveInterfaces[1]; // Slave interface 0 +} __attribute__ ((packed)) CDC_UNION_1SLAVE_DESCRIPTOR; + +// Line coding structure +// Format of the data returned when a GetLineCoding request is received +// (usbcdc11.pdf, 6.2.13) +typedef struct _CDC_LINE_CODING +{ + uint32_t dwDTERate; // Data terminal rate in bits per second + uint8_t bCharFormat; // Number of stop bits + uint8_t bParityType; // Parity bit type + uint8_t bDataBits; // Number of data bits +} __attribute__ ((packed)) CDC_LINE_CODING; + +// Notification header +// Data sent on the notification endpoint must follow this header. +// see USB_SETUP_PACKET in file usb.h +typedef USB_SETUP_PACKET CDC_NOTIFICATION_HEADER; + +#endif /* __CDC_H */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/cdcuser.h b/openbeacon/lpc13xx/usbcdc-storage/inc/cdcuser.h new file mode 100644 index 0000000..0a3c21c --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/cdcuser.h @@ -0,0 +1,62 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: cdcuser.h + * Purpose: USB Communication Device Class User module Definitions + * Version: V1.10 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __CDCUSER_H__ +#define __CDCUSER_H__ + +/* CDC buffer handling */ +extern int CDC_RdOutBuf (char *buffer, const int *length); +extern int CDC_WrOutBuf (const char *buffer, int *length); +extern int CDC_OutBufAvailChar (int *availChar); + + +/* CDC Data In/Out Endpoint Address */ +#define CDC_DEP_IN 0x83 +#define CDC_DEP_OUT 0x03 + +/* CDC Communication In Endpoint Address */ +#define CDC_CEP_IN 0x81 + +/* CDC Requests Callback Functions */ +extern uint32_t CDC_SendEncapsulatedCommand (void); +extern uint32_t CDC_GetEncapsulatedResponse (void); +extern uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_GetLineCoding (void); +extern uint32_t CDC_SetLineCoding (void); +extern uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap); +extern uint32_t CDC_SendBreak (unsigned short wDurationOfBreak); + +/* CDC Bulk Callback Functions */ +extern void CDC_BulkIn (void); +extern void CDC_BulkOut (void); + +/* CDC Notification Callback Function */ +extern void CDC_NotificationIn (void); + +/* CDC Initializtion Function */ +extern void CDC_Init (void); + +/* CDC prepare the SERAIAL_STATE */ +extern unsigned short CDC_GetSerialState (void); + +/* flow control */ +extern unsigned short CDC_DepInEmpty; // DataEndPoint IN empty + +#endif /* __CDCUSER_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/clkconfig.h b/openbeacon/lpc13xx/usbcdc-storage/inc/clkconfig.h new file mode 100644 index 0000000..33efd24 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/clkconfig.h @@ -0,0 +1,28 @@ +/***************************************************************************** + * clkconfig.h: Header file for NXP LPC13xx Family Microprocessors + * + * Copyright(C) 2009, NXP Semiconductor + * All rights reserved. + * + * History + * 2009.08.20 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ +#ifndef __CLKCONFIG_H +#define __CLKCONFIG_H + +#define WDTCLK_SRC_IRC_OSC 0 +#define WDTCLK_SRC_MAIN_CLK 1 +#define WDTCLK_SRC_WDT_OSC 2 + +#define CLKOUTCLK_SRC_IRC_OSC 0 +#define CLKOUTCLK_SRC_SYS_OSC 1 +#define CLKOUTCLK_SRC_WDT_OSC 2 +#define CLKOUTCLK_SRC_MAIN_CLK 3 + +void WDT_CLK_Setup (uint32_t timer_num); +void CLKOUT_Setup (uint32_t timer_num); +#endif /* end __CLKCONFIG_H */ +/***************************************************************************** +** End Of File +******************************************************************************/ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/compusb.h b/openbeacon/lpc13xx/usbcdc-storage/inc/compusb.h new file mode 100644 index 0000000..3032dfe --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/compusb.h @@ -0,0 +1,252 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usb.h + * Purpose: USB Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __COMPUSB_H__ +#define __COMPUSB_H__ + +typedef union +{ + uint16_t W; + struct + { + uint8_t L; + uint8_t H; + } __attribute__ ((packed)) WB; +} __attribute__ ((packed)) WORD_BYTE; + + +/* bmRequestType.Dir */ +#define REQUEST_HOST_TO_DEVICE 0 +#define REQUEST_DEVICE_TO_HOST 1 + +/* bmRequestType.Type */ +#define REQUEST_STANDARD 0 +#define REQUEST_CLASS 1 +#define REQUEST_VENDOR 2 +#define REQUEST_RESERVED 3 + +/* bmRequestType.Recipient */ +#define REQUEST_TO_DEVICE 0 +#define REQUEST_TO_INTERFACE 1 +#define REQUEST_TO_ENDPOINT 2 +#define REQUEST_TO_OTHER 3 + +/* bmRequestType Definition */ +typedef union _REQUEST_TYPE +{ + struct _BM + { + uint8_t Recipient:5; + uint8_t Type:2; + uint8_t Dir:1; + } __attribute__ ((packed)) BM; + uint8_t B; +} __attribute__ ((packed)) REQUEST_TYPE; + +/* USB Standard Request Codes */ +#define USB_REQUEST_GET_STATUS 0 +#define USB_REQUEST_CLEAR_FEATURE 1 +#define USB_REQUEST_SET_FEATURE 3 +#define USB_REQUEST_SET_ADDRESS 5 +#define USB_REQUEST_GET_DESCRIPTOR 6 +#define USB_REQUEST_SET_DESCRIPTOR 7 +#define USB_REQUEST_GET_CONFIGURATION 8 +#define USB_REQUEST_SET_CONFIGURATION 9 +#define USB_REQUEST_GET_INTERFACE 10 +#define USB_REQUEST_SET_INTERFACE 11 +#define USB_REQUEST_SYNC_FRAME 12 + +/* USB GET_STATUS Bit Values */ +#define USB_GETSTATUS_SELF_POWERED 0x01 +#define USB_GETSTATUS_REMOTE_WAKEUP 0x02 +#define USB_GETSTATUS_ENDPOINT_STALL 0x01 + +/* USB Standard Feature selectors */ +#define USB_FEATURE_ENDPOINT_STALL 0 +#define USB_FEATURE_REMOTE_WAKEUP 1 + +/* USB Default Control Pipe Setup Packet */ +typedef struct _USB_SETUP_PACKET +{ + REQUEST_TYPE bmRequestType; + uint8_t bRequest; + WORD_BYTE wValue; + WORD_BYTE wIndex; + uint16_t wLength; +} __attribute__ ((packed)) USB_SETUP_PACKET; + + +/* USB Descriptor Types */ +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_STRING_DESCRIPTOR_TYPE 3 +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 +#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6 +#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7 +#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8 +#define USB_OTG_DESCRIPTOR_TYPE 9 +#define USB_DEBUG_DESCRIPTOR_TYPE 10 +#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11 + +/* USB Device Classes */ +#define USB_DEVICE_CLASS_RESERVED 0x00 +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +#define USB_DEVICE_CLASS_MONITOR 0x04 +#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 +#define USB_DEVICE_CLASS_POWER 0x06 +#define USB_DEVICE_CLASS_PRINTER 0x07 +#define USB_DEVICE_CLASS_STORAGE 0x08 +#define USB_DEVICE_CLASS_HUB 0x09 +#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF + +/* bmAttributes in Configuration Descriptor */ +#define USB_CONFIG_POWERED_MASK 0x40 +#define USB_CONFIG_BUS_POWERED 0x80 +#define USB_CONFIG_SELF_POWERED 0xC0 +#define USB_CONFIG_REMOTE_WAKEUP 0x20 + +/* bMaxPower in Configuration Descriptor */ +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +/* bEndpointAddress in Endpoint Descriptor */ +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) + +/* bmAttributes in Endpoint Descriptor */ +#define USB_ENDPOINT_TYPE_MASK 0x03 +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_TYPE_BULK 0x02 +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 +#define USB_ENDPOINT_SYNC_MASK 0x0C +#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 +#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 +#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 +#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C +#define USB_ENDPOINT_USAGE_MASK 0x30 +#define USB_ENDPOINT_USAGE_DATA 0x00 +#define USB_ENDPOINT_USAGE_FEEDBACK 0x10 +#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 +#define USB_ENDPOINT_USAGE_RESERVED 0x30 + +/* USB Standard Device Descriptor */ +typedef struct _USB_DEVICE_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__ ((packed)) USB_DEVICE_DESCRIPTOR; + +/* USB 2.0 Device Qualifier Descriptor */ +typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} __attribute__ ((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR; + +/* USB Standard Configuration Descriptor */ +typedef struct _USB_CONFIGURATION_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} __attribute__ ((packed)) USB_CONFIGURATION_DESCRIPTOR; + +/* USB Standard Interface Association Descriptor */ +typedef struct _USB_INTERFACE_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} __attribute__ ((packed)) USB_INTERFACE_DESCRIPTOR; + +/* USB Interface Descriptor */ +typedef struct _USB_INTERFACE_ASSOCIATION_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +} __attribute__ ((packed)) USB_INTERFACE_ASSOCIATION_DESCRIPTOR; + +/* USB Standard Endpoint Descriptor */ +typedef struct _USB_ENDPOINT_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __attribute__ ((packed)) USB_ENDPOINT_DESCRIPTOR; + +/* USB String Descriptor */ +typedef struct _USB_STRING_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bString /*[] */ ; +} __attribute__ ((packed)) USB_STRING_DESCRIPTOR; + +/* USB Common Descriptor */ +typedef struct _USB_COMMON_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; +} __attribute__ ((packed)) USB_COMMON_DESCRIPTOR; + + +#endif /* __COMPUSB_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/compusbdesc.h b/openbeacon/lpc13xx/usbcdc-storage/inc/compusbdesc.h new file mode 100644 index 0000000..b1c0f5d --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/compusbdesc.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbdesc.h + * Purpose: USB Descriptors Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __COMPUSBDESC_H__ +#define __COMPUSBDESC_H__ + +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR)) +#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR)) +#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR)) +#define USB_INTERFACE_ASSOCIATION_DESC_SIZE (sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR)) +#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR)) + +extern const uint8_t USB_DeviceDescriptor[]; +extern const uint8_t USB_ConfigDescriptor[]; +extern const uint8_t USB_StringDescriptor[]; + +#endif /* __COMPUSBDESC_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/config.h b/openbeacon/lpc13xx/usbcdc-storage/inc/config.h new file mode 100644 index 0000000..0fa55fb --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/config.h @@ -0,0 +1,40 @@ +/***************************************************************************** + * config.h: config file for usbcdc example for NXP LPC13xx Family + * Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2008.07.19 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ + +/* +Overview: + This example shows how to use the USB driver to implement a CDC class USB peripheral. + To run this example, you must attach a USB cable to the board. See + the "Getting Started Guide" appendix for details. + +How to use: + Click the debug toolbar button. + Click the go button. + Plug the LPCXpresso's target side into a PC using a USB cable retrofit + or a 3rd party base board. + + * You should be able to see a new COM port on your PC. +*/ + +#define NXP_VID 0x1FC9 +#define MY_VID 0x???? + +#define USB_VENDOR_ID NXP_VID // Vendor ID +#define USB_PROD_ID 0x0003 // Product ID +#define USB_DEVICE 0x0100 // Device ID + +#define LED_PORT 1 // Port for led +#define LED_BIT 9 // Bit on port for led + +/********************************************************************************* +** End Of File +*********************************************************************************/ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/memory.h b/openbeacon/lpc13xx/usbcdc-storage/inc/memory.h new file mode 100644 index 0000000..711cf07 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/memory.h @@ -0,0 +1,20 @@ +/*---------------------------------------------------------------------------- + * Name: memory.h + * Purpose: USB Memory Storage Demo Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +/* MSC Disk Image Definitions */ +#define MSC_ImageSize 6144 + +extern const unsigned char DiskImage[MSC_ImageSize]; /* Disk Image */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/msc.h b/openbeacon/lpc13xx/usbcdc-storage/inc/msc.h new file mode 100644 index 0000000..4001850 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/msc.h @@ -0,0 +1,103 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: msc.h + * Purpose: USB Mass Storage Class Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __MSC_H__ +#define __MSC_H__ + + +/* MSC Subclass Codes */ +#define MSC_SUBCLASS_RBC 0x01 +#define MSC_SUBCLASS_SFF8020I_MMC2 0x02 +#define MSC_SUBCLASS_QIC157 0x03 +#define MSC_SUBCLASS_UFI 0x04 +#define MSC_SUBCLASS_SFF8070I 0x05 +#define MSC_SUBCLASS_SCSI 0x06 + +/* MSC Protocol Codes */ +#define MSC_PROTOCOL_CBI_INT 0x00 +#define MSC_PROTOCOL_CBI_NOINT 0x01 +#define MSC_PROTOCOL_BULK_ONLY 0x50 + + +/* MSC Request Codes */ +#define MSC_REQUEST_RESET 0xFF +#define MSC_REQUEST_GET_MAX_LUN 0xFE + + +/* MSC Bulk-only Stage */ +#define MSC_BS_CBW 0 /* Command Block Wrapper */ +#define MSC_BS_DATA_OUT 1 /* Data Out Phase */ +#define MSC_BS_DATA_IN 2 /* Data In Phase */ +#define MSC_BS_DATA_IN_LAST 3 /* Data In Last Phase */ +#define MSC_BS_DATA_IN_LAST_STALL 4 /* Data In Last Phase with Stall */ +#define MSC_BS_CSW 5 /* Command Status Wrapper */ +#define MSC_BS_ERROR 6 /* Error */ + + +/* Bulk-only Command Block Wrapper */ +typedef struct _MSC_CBW +{ + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataLength; + uint8_t bmFlags; + uint8_t bLUN; + uint8_t bCBLength; + uint8_t CB[16]; +} __attribute__ ((packed)) MSC_CBW; + +/* Bulk-only Command Status Wrapper */ +typedef struct _MSC_CSW +{ + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataResidue; + uint8_t bStatus; +} __attribute__ ((packed)) MSC_CSW; + +#define MSC_CBW_Signature 0x43425355 +#define MSC_CSW_Signature 0x53425355 + + +/* CSW Status Definitions */ +#define CSW_CMD_PASSED 0x00 +#define CSW_CMD_FAILED 0x01 +#define CSW_PHASE_ERROR 0x02 + + +/* SCSI Commands */ +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_FORMAT_UNIT 0x04 +#define SCSI_INQUIRY 0x12 +#define SCSI_MODE_SELECT6 0x15 +#define SCSI_MODE_SENSE6 0x1A +#define SCSI_START_STOP_UNIT 0x1B +#define SCSI_MEDIA_REMOVAL 0x1E +#define SCSI_READ_FORMAT_CAPACITIES 0x23 +#define SCSI_READ_CAPACITY 0x25 +#define SCSI_READ10 0x28 +#define SCSI_WRITE10 0x2A +#define SCSI_VERIFY10 0x2F +#define SCSI_READ12 0xA8 +#define SCSI_WRITE12 0xAA +#define SCSI_MODE_SELECT10 0x55 +#define SCSI_MODE_SENSE10 0x5A + + +#endif /* __MSC_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/mscuser.h b/openbeacon/lpc13xx/usbcdc-storage/inc/mscuser.h new file mode 100644 index 0000000..e889e6f --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/mscuser.h @@ -0,0 +1,47 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: mscuser.h + * Purpose: Mass Storage Class Custom User Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __MSCUSER_H__ +#define __MSCUSER_H__ + + +/* Mass Storage Memory Layout */ +#define MSC_MemorySize 6144 +#define MSC_BlockSize 512 +#define MSC_BlockCount (MSC_MemorySize / MSC_BlockSize) + + +/* Max In/Out Packet Size */ +#define MSC_MAX_PACKET 64 + +/* MSC In/Out Endpoint Address */ +#define MSC_EP_IN 0x82 +#define MSC_EP_OUT 0x02 + +/* MSC Requests Callback Functions */ +extern uint32_t MSC_Reset (void); +extern uint32_t MSC_GetMaxLUN (void); + +/* MSC Bulk Callback Functions */ +extern void MSC_GetCBW (void); +extern void MSC_SetCSW (void); +extern void MSC_BulkIn (void); +extern void MSC_BulkOut (void); + + +#endif /* __MSCUSER_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/type.h b/openbeacon/lpc13xx/usbcdc-storage/inc/type.h new file mode 100644 index 0000000..dc74760 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/type.h @@ -0,0 +1,46 @@ +/***************************************************************************** + * type.h: Type definition Header file for NXP Family + * Microprocessors + * + * Copyright(C) 2006, NXP Semiconductor + * All rights reserved. + * + * History + * 2009.04.01 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ +#ifndef __TYPE_H__ +#define __TYPE_H__ + +// CodeRed - ifdef for GNU added to avoid potential clash with stdint.h +#if defined ( __GNUC__ ) +#include +#else + +/* exact-width signed integer types */ +typedef signed char int8_t; +typedef signed short int int16_t; +typedef signed int int32_t; +typedef signed __int64 int64_t; + + /* exact-width unsigned integer types */ +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 uint64_t; + +#endif // __GNUC__ + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +#endif /* __TYPE_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/usbcfg.h b/openbeacon/lpc13xx/usbcdc-storage/inc/usbcfg.h new file mode 100644 index 0000000..49e54cf --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/usbcfg.h @@ -0,0 +1,157 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcfg.h + * Purpose: USB Custom Configuration + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added vendor specific support + * V1.00 Initial Version + *---------------------------------------------------------------------------*/ + +#ifndef __USBCFG_H__ +#define __USBCFG_H__ + + +//*** <<< Use Configuration Wizard in Context Menu >>> *** + + +/* +// USB Configuration +// USB Power +// Default Power Setting +// <0=> Bus-powered +// <1=> Self-powered +// Max Number of Interfaces <1-256> +// Max Number of Endpoints <1-32> +// Max Endpoint 0 Packet Size +// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes +// DMA Transfer +// Use DMA for selected Endpoints +// Endpoint 0 Out +// Endpoint 0 In +// Endpoint 1 Out +// Endpoint 1 In +// Endpoint 2 Out +// Endpoint 2 In +// Endpoint 3 Out +// Endpoint 3 In +// Endpoint 4 Out +// Endpoint 4 In +// +// +*/ + +#define USB_POWER 0 +#define USB_IF_NUM 1 +#define USB_LOGIC_EP_NUM 5 +#define USB_EP_NUM 10 +#define USB_MAX_PACKET0 64 + +/* +// USB Event Handlers +// Device Events +// Power Event +// Reset Event +// Suspend Event +// Resume Event +// Remote Wakeup Event +// Start of Frame Event +// Error Event +// +// Endpoint Events +// Endpoint 0 Event +// Endpoint 1 Event +// Endpoint 2 Event +// Endpoint 3 Event +// Endpoint 4 Event +// Endpoint 5 Event +// Endpoint 6 Event +// Endpoint 7 Event +// Endpoint 8 Event +// Endpoint 9 Event +// Endpoint 10 Event +// Endpoint 11 Event +// Endpoint 12 Event +// Endpoint 13 Event +// Endpoint 14 Event +// Endpoint 15 Event +// +// USB Core Events +// Set Configuration Event +// Set Interface Event +// Set/Clear Feature Event +// +// +*/ + +#define USB_POWER_EVENT 0 +#define USB_RESET_EVENT 1 +#define USB_SUSPEND_EVENT 1 +#define USB_RESUME_EVENT 1 +#define USB_WAKEUP_EVENT 0 +#define USB_SOF_EVENT 0 +#define USB_ERROR_EVENT 0 +#define USB_EP_EVENT 0x000f +#define USB_CONFIGURE_EVENT 1 +#define USB_INTERFACE_EVENT 0 +#define USB_FEATURE_EVENT 0 + + +/* +// USB Class Support +// enables USB Class specific Requests +// Human Interface Device (HID) +// Interface Number <0-255> +// +// Mass Storage +// Interface Number <0-255> +// +// Audio Device +// Control Interface Number <0-255> +// Streaming Interface 1 Number <0-255> +// Streaming Interface 2 Number <0-255> +// +// Communication Device +// Control Interface Number <0-255> +// Bulk Interface Number <0-255> +// Max Communication Device Buffer Size +// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes +// +// +*/ + +#define USB_CLASS 1 +#define USB_HID 0 +#define USB_HID_IF_NUM 0 +#define USB_MSC 1 +#define USB_MSC_IF_NUM 0 +#define USB_AUDIO 0 +#define USB_ADC_CIF_NUM 0 +#define USB_ADC_SIF1_NUM 1 +#define USB_ADC_SIF2_NUM 2 +#define USB_CDC 1 +#define USB_CDC_CIF_NUM 1 +#define USB_CDC_DIF_NUM 2 +#define USB_CDC_BUFSIZE 64 + +/* +// USB Vendor Support +// enables USB Vendor specific Requests +// +*/ +#define USB_VENDOR 0 + + +#endif /* __USBCFG_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/usbcore.h b/openbeacon/lpc13xx/usbcdc-storage/inc/usbcore.h new file mode 100644 index 0000000..6ba7838 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/usbcore.h @@ -0,0 +1,56 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcore.h + * Purpose: USB Core Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBCORE_H__ +#define __USBCORE_H__ + + +/* USB Endpoint Data Structure */ +typedef struct _USB_EP_DATA +{ + uint8_t *pData; + uint16_t Count; +} USB_EP_DATA; + +/* USB Core Global Variables */ +extern uint16_t USB_DeviceStatus; +extern uint8_t USB_DeviceAddress; +extern uint8_t USB_Configuration; +extern uint32_t USB_EndPointMask; +extern uint32_t USB_EndPointHalt; +extern uint32_t USB_EndPointStall; +extern uint8_t USB_AltSetting[USB_IF_NUM]; + +/* USB Endpoint 0 Buffer */ +extern uint8_t EP0Buf[USB_MAX_PACKET0]; + +/* USB Endpoint 0 Data Info */ +extern USB_EP_DATA EP0Data; + +/* USB Setup Packet */ +extern USB_SETUP_PACKET SetupPacket; + +/* USB Core Functions */ +extern void USB_ResetCore (void); + +/* Newer C compilers make it really difficult to add + * an integer to a pointer */ +__inline void UsbAddPtr (void **vpptr, uint32_t n); + + +#endif /* __USBCORE_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/usbhw.h b/openbeacon/lpc13xx/usbcdc-storage/inc/usbhw.h new file mode 100644 index 0000000..641a8e9 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/usbhw.h @@ -0,0 +1,62 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbhw.h + * Purpose: USB Hardware Layer Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added USB_ClearEPBuf + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ + +#ifndef __USBHW_H__ +#define __USBHW_H__ + + +/* USB Error Codes */ +#define USB_ERR_PID 0x0001 /* PID Error */ +#define USB_ERR_UEPKT 0x0002 /* Unexpected Packet */ +#define USB_ERR_DCRC 0x0004 /* Data CRC Error */ +#define USB_ERR_TIMOUT 0x0008 /* Bus Time-out Error */ +#define USB_ERR_EOP 0x0010 /* End of Packet Error */ +#define USB_ERR_B_OVRN 0x0020 /* Buffer Overrun */ +#define USB_ERR_BTSTF 0x0040 /* Bit Stuff Error */ +#define USB_ERR_TGL 0x0080 /* Toggle Bit Error */ + +/* USB Hardware Functions */ +extern void USBIOClkConfig (void); +extern void USB_Init (void); +extern void USB_Connect (uint32_t con); +extern void USB_Reset (void); +extern void USB_Suspend (void); +extern void USB_Resume (void); +extern void USB_WakeUp (void); +extern void USB_WakeUpCfg (uint32_t cfg); +extern void USB_SetAddress (uint32_t adr); +extern void USB_Configure (uint32_t cfg); +extern void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD); +extern void USB_DirCtrlEP (uint32_t dir); +extern void USB_EnableEP (uint32_t EPNum); +extern void USB_DisableEP (uint32_t EPNum); +extern void USB_ResetEP (uint32_t EPNum); +extern void USB_SetStallEP (uint32_t EPNum); +extern void USB_ClrStallEP (uint32_t EPNum); +extern void USB_ClearEPBuf (uint32_t EPNum); +extern uint32_t USB_ReadEP (uint32_t EPNum, uint8_t * pData); +extern uint32_t USB_WriteEP (uint32_t EPNum, uint8_t * pData, uint32_t cnt); +extern uint32_t USB_GetFrame (void); +extern void USB_IRQHandler (void); + + +#endif /* __USBHW_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/usbreg.h b/openbeacon/lpc13xx/usbcdc-storage/inc/usbreg.h new file mode 100644 index 0000000..f2d1000 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/usbreg.h @@ -0,0 +1,134 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: USBREG.H + * Purpose: USB Hardware Layer Definitions for NXP LPC13xx + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBREG_H +#define __USBREG_H + +/* Device Interrupt Bit Definitions */ +#define FRAME_INT (0x1<<0) +#define EP0_INT (0x1<<1) +#define EP1_INT (0x1<<2) +#define EP2_INT (0x1<<3) +#define EP3_INT (0x1<<4) +#define EP4_INT (0x1<<5) +#define EP5_INT (0x1<<6) +#define EP6_INT (0x1<<7) +#define EP7_INT (0x1<<8) +#define DEV_STAT_INT (0x1<<9) +#define CCEMTY_INT (0x1<<10) +#define CDFULL_INT (0x1<<11) +#define RxENDPKT_INT (0x1<<12) +#define TxENDPKT_INT (0x1<<13) + +/* Rx & Tx Packet Length Definitions */ +#define PKT_LNGTH_MASK 0x000003FF +#define PKT_DV 0x00000400 +#define PKT_RDY 0x00000800 + +/* USB Control Definitions */ +#define CTRL_RD_EN 0x00000001 +#define CTRL_WR_EN 0x00000002 + +/* Command Codes */ +#define CMD_SET_ADDR 0x00D00500 +#define CMD_CFG_DEV 0x00D80500 +#define CMD_SET_MODE 0x00F30500 +#define CMD_RD_INT 0x00F40500 +#define DAT_RD_INT 0x00F40200 +#define CMD_RD_FRAME 0x00F50500 +#define DAT_RD_FRAME 0x00F50200 +#define CMD_RD_CHIP_ID 0x00FD0500 +#define DAT_RD_CHIP_ID 0x00FD0200 + +#define CMD_SET_DEV_STAT 0x00FE0500 +#define CMD_GET_DEV_STAT 0x00FE0500 +#define DAT_GET_DEV_STAT 0x00FE0200 +#define CMD_GET_ERR_CODE 0x00FF0500 +#define DAT_GET_ERR_CODE 0x00FF0200 + +#define DAT_WR_BYTE(x) (0x00000100 | ((x) << 16)) +#define CMD_SEL_EP(x) (0x00000500 | ((x) << 16)) +#define DAT_SEL_EP(x) (0x00000200 | ((x) << 16)) +#define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16)) +#define DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16)) +#define CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16)) +#define CMD_CLR_BUF 0x00F20500 +#define CMD_VALID_BUF 0x00FA0500 + +/* Device Address Register Definitions */ +#define DEV_ADDR_MASK 0x7F +#define DEV_EN 0x80 + +/* Device Configure Register Definitions */ +#define CONF_DVICE 0x01 + +/* Device Mode Register Definitions */ +#define AP_CLK 0x01 +#define INAK_CI 0x02 +#define INAK_CO 0x04 +#define INAK_AI 0x08 +#define INAK_AO 0x10 + +/* Device Status Register Definitions */ +#define DEV_CON 0x01 +#define DEV_CON_CH 0x02 +#define DEV_SUS 0x04 +#define DEV_SUS_CH 0x08 +#define DEV_RST 0x10 + +/* Error Code Register Definitions */ +#define ERR_EC_MASK 0x0F +#define ERR_EA 0x10 + +/* Error Status Register Definitions */ +#define ERR_NOERROR 0x00 +#define ERR_PID_ENCODE 0x01 +#define ERR_UNKNOWN_PID 0x02 +#define ERR_UNEXPECT_PKT 0x03 +#define ERR_TCRC 0x04 +#define ERR_DCRC 0x05 +#define ERR_TIMEOUT 0x06 +#define ERR_BABBIE 0x07 +#define ERR_EOF_PKT 0x08 +#define ERR_TX_RX_NAK 0x09 +#define ERR_SENT_STALL 0x0A +#define ERR_BUF_OVERRUN 0x0B +#define ERR_SENT_EPT_PKT 0x0C +#define ERR_BIT_STUFF 0x0D +#define ERR_SYNC 0x0E +#define ERR_TOGGLE_BIT 0x0F + +/* Endpoint Select Register Definitions */ +#define EP_SEL_F 0x01 +#define EP_SEL_ST 0x02 +#define EP_SEL_STP 0x04 +#define EP_SEL_PO 0x08 +#define EP_SEL_EPN 0x10 +#define EP_SEL_B_1_FULL 0x20 +#define EP_SEL_B_2_FULL 0x40 + +/* Endpoint Status Register Definitions */ +#define EP_STAT_ST 0x01 +#define EP_STAT_DA 0x20 +#define EP_STAT_RF_MO 0x40 +#define EP_STAT_CND_ST 0x80 + +/* Clear Buffer Register Definitions */ +#define CLR_BUF_PO 0x01 + +#endif /* __USBREG_H */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/usbuser.h b/openbeacon/lpc13xx/usbcdc-storage/inc/usbuser.h new file mode 100644 index 0000000..03a429e --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/usbuser.h @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: USBUSER.H + * Purpose: USB Custom User Definitions + * Version: V1.10 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2005-2009 Keil Software. + *---------------------------------------------------------------------------*/ + +#ifndef __USBUSER_H__ +#define __USBUSER_H__ + + +/* USB Device Events Callback Functions */ +extern void USB_Power_Event (uint32_t power); +extern void USB_Reset_Event (void); +extern void USB_Suspend_Event (void); +extern void USB_Resume_Event (void); +extern void USB_WakeUp_Event (void); +extern void USB_SOF_Event (void); +extern void USB_Error_Event (uint32_t error); + +/* USB Endpoint Callback Events */ +#define USB_EVT_SETUP 1 /* Setup Packet */ +#define USB_EVT_OUT 2 /* OUT Packet */ +#define USB_EVT_IN 3 /* IN Packet */ +#define USB_EVT_OUT_NAK 4 /* OUT Packet - Not Acknowledged */ +#define USB_EVT_IN_NAK 5 /* IN Packet - Not Acknowledged */ +#define USB_EVT_OUT_STALL 6 /* OUT Packet - Stalled */ +#define USB_EVT_IN_STALL 7 /* IN Packet - Stalled */ + +/* USB Endpoint Events Callback Pointers */ +extern void (*const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event); + +/* USB Endpoint Events Callback Functions */ +extern void USB_EndPoint0 (uint32_t event); +extern void USB_EndPoint1 (uint32_t event); +extern void USB_EndPoint2 (uint32_t event); +extern void USB_EndPoint3 (uint32_t event); +extern void USB_EndPoint4 (uint32_t event); + +/* USB Core Events Callback Functions */ +extern void USB_Configure_Event (void); +extern void USB_Interface_Event (void); +extern void USB_Feature_Event (void); + + +#endif /* __USBUSER_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/vcomdemo.h b/openbeacon/lpc13xx/usbcdc-storage/inc/vcomdemo.h new file mode 100644 index 0000000..c668d7c --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/inc/vcomdemo.h @@ -0,0 +1,30 @@ +/*---------------------------------------------------------------------------- + * Name: vcomdemo.h + * Purpose: USB virtual COM port Demo Definitions + * Version: V1.02 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +/* Push Button Definitions */ +#define S2 0x00000400 /* P2.10 */ + +/* LED Definitions */ +#define LED1 0x00000001 /* P2.00 */ +#define LED2 0x00000002 /* P2.01 */ +#define LED3 0x00000004 /* P2.02 */ +#define LED4 0x00000008 /* P2.03 */ +#define LED5 0x00000010 /* P2.04 */ +#define LED6 0x00000020 /* P2.05 */ +#define LED7 0x00000040 /* P2.06 */ +#define LED8 0x00000080 /* P2.07 */ + +#define LEDMSK 0x000000FF /* P2.0..7 */ diff --git a/openbeacon/lpc13xx/usbcdc-storage/lpc134x-vcom.inf b/openbeacon/lpc13xx/usbcdc-storage/lpc134x-vcom.inf new file mode 100644 index 0000000..abc7e66 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/lpc134x-vcom.inf @@ -0,0 +1,60 @@ +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%NXP% +;LayoutFile=layout.inf +DriverVer=01/06/07 + +[Manufacturer] +%NXP%=DeviceList + +[DestinationDirs] +DefaultDestDir=12 + +[SourceDisksFiles] + +[SourceDisksNames] + +[DeviceList] +%DESCRIPTION%=LPC134xUSB, USB\VID_1FC9&PID_0003&MI_01 + +;------------------------------------------------------------------------------ +; Windows 2000/XP Sections +;------------------------------------------------------------------------------ + +[LPC134xUSB.nt] +include=mdmcpq.inf +CopyFiles=DriverCopyFiles +AddReg=LPC134xUSB.nt.AddReg + +[DriverCopyFiles] +usbser.sys,,,0x20 + +[LPC134xUSB.nt.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,usbser.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[LPC134xUSB.nt.Services] +include=mdmcpq.inf +AddService=usbser, 0x00000002, DriverService + + +[LPC134xUSB.nt.HW] +include=mdmcpq.inf + +[DriverService] +DisplayName=%DESCRIPTION% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\usbser.sys + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ + +[Strings] +NXP="NXP - Founded by Philips" +DESCRIPTION="LPC134x USB VCom Port" diff --git a/openbeacon/lpc13xx/usbcdc-storage/readme.txt b/openbeacon/lpc13xx/usbcdc-storage/readme.txt new file mode 100644 index 0000000..eb3a9ce --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/readme.txt @@ -0,0 +1,40 @@ +usbcomp_msd_cdc +===================== +This project implements a USB composite class device that includes +a mass storage device and a virtual COM device. + +To run this example, you must attach a USB cable to the board. See +the "Getting Started Guide" appendix for details. You may also +connect the LPCXpresso board to a base board from a 3rd party tool +partner. + +When downloaded to the board and executed, the PC will first recognize +a USB mass storage device and mount a new drive that contains a text +file, and then it will recognize a USB "VCOM" device and ask for a +driver. Point windows to the .inf file in the usbcomp_msd_cdc project +directory to cause Windows to install the default USB serial driver. + +At this point, you should be able to read/write files in the newly +mounted drive and send/receive characters through the USB virtual +COM port at the same time. The transmit baud rate will equal the +CDC port configured baud rate. + +One thing we have seen that can cause trouble with the USB examples +is the Windows driver install. Since the example projects all use +the same USB Vendor ID and Product ID, if you try out the HID +example and then try out the CDC example, Windows may try +to use the HID driver it had already installed with the CDC +example code. To fix this, go to the Windows Device Manager, +find the broken "HID" device and select "Uninstall." Then unplug the +device and plug it back in. Windows should correctly identify the +device as being a CDC device and install the correct +driver. + +The project makes use of code from the following library projects: +- CMSISv1p30_LPC13xx : for CMSIS 1.30 files relevant to LPC13xx + +This library project must exist in the same workspace in order +for the project to successfully build. + +For more details, read the comments in config.h and +http://www.nxp.com/documents/application_note/AN11018.pdf diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/DiskImg.c b/openbeacon/lpc13xx/usbcdc-storage/src/DiskImg.c new file mode 100644 index 0000000..01d9819 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/src/DiskImg.c @@ -0,0 +1,166 @@ +/* Disk Image */ + +#include "memory.h" + +const unsigned char DiskImage[MSC_ImageSize] = { +0xEB,0x3C,0x90,0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,0x00,0x02,0x01,0x01,0x00, +0x01,0x10,0x00,0x20,0x00,0xF8,0x02,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x74,0x19,0x02,0x27,0x4C,0x50,0x43,0x32,0x33, +0x36,0x38,0x20,0x55,0x53,0x42,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x33,0xC9, +0x8E,0xD1,0xBC,0xF0,0x7B,0x8E,0xD9,0xB8,0x00,0x20,0x8E,0xC0,0xFC,0xBD,0x00,0x7C, +0x38,0x4E,0x24,0x7D,0x24,0x8B,0xC1,0x99,0xE8,0x3C,0x01,0x72,0x1C,0x83,0xEB,0x3A, +0x66,0xA1,0x1C,0x7C,0x26,0x66,0x3B,0x07,0x26,0x8A,0x57,0xFC,0x75,0x06,0x80,0xCA, +0x02,0x88,0x56,0x02,0x80,0xC3,0x10,0x73,0xEB,0x33,0xC9,0x8A,0x46,0x10,0x98,0xF7, +0x66,0x16,0x03,0x46,0x1C,0x13,0x56,0x1E,0x03,0x46,0x0E,0x13,0xD1,0x8B,0x76,0x11, +0x60,0x89,0x46,0xFC,0x89,0x56,0xFE,0xB8,0x20,0x00,0xF7,0xE6,0x8B,0x5E,0x0B,0x03, +0xC3,0x48,0xF7,0xF3,0x01,0x46,0xFC,0x11,0x4E,0xFE,0x61,0xBF,0x00,0x00,0xE8,0xE6, +0x00,0x72,0x39,0x26,0x38,0x2D,0x74,0x17,0x60,0xB1,0x0B,0xBE,0xA1,0x7D,0xF3,0xA6, +0x61,0x74,0x32,0x4E,0x74,0x09,0x83,0xC7,0x20,0x3B,0xFB,0x72,0xE6,0xEB,0xDC,0xA0, +0xFB,0x7D,0xB4,0x7D,0x8B,0xF0,0xAC,0x98,0x40,0x74,0x0C,0x48,0x74,0x13,0xB4,0x0E, +0xBB,0x07,0x00,0xCD,0x10,0xEB,0xEF,0xA0,0xFD,0x7D,0xEB,0xE6,0xA0,0xFC,0x7D,0xEB, +0xE1,0xCD,0x16,0xCD,0x19,0x26,0x8B,0x55,0x1A,0x52,0xB0,0x01,0xBB,0x00,0x00,0xE8, +0x3B,0x00,0x72,0xE8,0x5B,0x8A,0x56,0x24,0xBE,0x0B,0x7C,0x8B,0xFC,0xC7,0x46,0xF0, +0x3D,0x7D,0xC7,0x46,0xF4,0x29,0x7D,0x8C,0xD9,0x89,0x4E,0xF2,0x89,0x4E,0xF6,0xC6, +0x06,0x96,0x7D,0xCB,0xEA,0x03,0x00,0x00,0x20,0x0F,0xB6,0xC8,0x66,0x8B,0x46,0xF8, +0x66,0x03,0x46,0x1C,0x66,0x8B,0xD0,0x66,0xC1,0xEA,0x10,0xEB,0x5E,0x0F,0xB6,0xC8, +0x4A,0x4A,0x8A,0x46,0x0D,0x32,0xE4,0xF7,0xE2,0x03,0x46,0xFC,0x13,0x56,0xFE,0xEB, +0x4A,0x52,0x50,0x06,0x53,0x6A,0x01,0x6A,0x10,0x91,0x8B,0x46,0x18,0x96,0x92,0x33, +0xD2,0xF7,0xF6,0x91,0xF7,0xF6,0x42,0x87,0xCA,0xF7,0x76,0x1A,0x8A,0xF2,0x8A,0xE8, +0xC0,0xCC,0x02,0x0A,0xCC,0xB8,0x01,0x02,0x80,0x7E,0x02,0x0E,0x75,0x04,0xB4,0x42, +0x8B,0xF4,0x8A,0x56,0x24,0xCD,0x13,0x61,0x61,0x72,0x0B,0x40,0x75,0x01,0x42,0x03, +0x5E,0x0B,0x49,0x75,0x06,0xF8,0xC3,0x41,0xBB,0x00,0x00,0x60,0x66,0x6A,0x00,0xEB, +0xB0,0x4E,0x54,0x4C,0x44,0x52,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,0x52,0x65, +0x6D,0x6F,0x76,0x65,0x20,0x64,0x69,0x73,0x6B,0x73,0x20,0x6F,0x72,0x20,0x6F,0x74, +0x68,0x65,0x72,0x20,0x6D,0x65,0x64,0x69,0x61,0x2E,0xFF,0x0D,0x0A,0x44,0x69,0x73, +0x6B,0x20,0x65,0x72,0x72,0x6F,0x72,0xFF,0x0D,0x0A,0x50,0x72,0x65,0x73,0x73,0x20, +0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x72,0x65,0x73,0x74,0x61, +0x72,0x74,0x0D,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xCB,0xD8,0x55,0xAA, +0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x4C,0x50,0x43,0x31,0x33,0x34,0x78,0x20,0x55,0x53,0x42,0x28,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x52,0x45,0x41,0x44,0x4D,0x45,0x20,0x20,0x54,0x58,0x54,0x21,0x00,0x00,0x00,0x00, +0x21,0x00,0xBB,0x32,0x00,0x00,0xDC,0x83,0xBB,0x32,0x02,0x00,0x5D,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x61,0x20,0x55,0x53,0x42,0x20,0x4D,0x65, +0x6D,0x6F,0x72,0x79,0x20,0x44,0x65,0x76,0x69,0x63,0x65,0x20,0x64,0x65,0x6D,0x6F, +0x6E,0x73,0x74,0x72,0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,0x6F,0x72,0x0D,0x0A,0x74, +0x68,0x65,0x20,0x4E,0x58,0x50,0x20,0x20,0x4E,0x58,0x50,0x31,0x33,0x58,0x58,0x20, +0x42,0x6F,0x61,0x72,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x4E,0x58,0x50,0x20,0x4C, +0x50,0x43,0x31,0x33,0x34,0x33,0x2E,0x20,0x20,0x20,0x20,0x0D,0x0A,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/cdcuser.c b/openbeacon/lpc13xx/usbcdc-storage/src/cdcuser.c new file mode 100644 index 0000000..79877c5 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/src/cdcuser.c @@ -0,0 +1,392 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: cdcuser.c + * Purpose: USB Communication Device Class User module + * Version: V1.10 + *---------------------------------------------------------------------------- +* This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#include "type.h" + +#include "usb.h" +#include "usbhw.h" +#include "usbcfg.h" +#include "usbcore.h" +#include "cdc.h" +#include "cdcuser.h" +#include "uart.h" + + +unsigned char BulkBufIn[USB_CDC_BUFSIZE]; // Buffer to store USB IN packet +unsigned char BulkBufOut[USB_CDC_BUFSIZE]; // Buffer to store USB OUT packet +unsigned char NotificationBuf[10]; + +CDC_LINE_CODING CDC_LineCoding = { 9600, 0, 0, 8 }; + +unsigned short CDC_SerialState = 0x0000; +unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty + +/*---------------------------------------------------------------------------- + We need a buffer for incomming data on USB port because USB receives + much faster than UART transmits + *---------------------------------------------------------------------------*/ +/* Buffer masks */ +#define CDC_BUF_SIZE (64) // Output buffer in bytes (power 2) + // large enough for file transfer +#define CDC_BUF_MASK (CDC_BUF_SIZE-1ul) + +/* Buffer read / write macros */ +#define CDC_BUF_RESET(cdcBuf) (cdcBuf.rdIdx = cdcBuf.wrIdx = 0) +#define CDC_BUF_WR(cdcBuf, dataIn) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.wrIdx++] = (dataIn)) +#define CDC_BUF_RD(cdcBuf) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.rdIdx++]) +#define CDC_BUF_EMPTY(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx) +#define CDC_BUF_FULL(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx+1) +#define CDC_BUF_COUNT(cdcBuf) (CDC_BUF_MASK & (cdcBuf.wrIdx - cdcBuf.rdIdx)) + + +// CDC output buffer +typedef struct __CDC_BUF_T +{ + unsigned char data[CDC_BUF_SIZE]; + unsigned int wrIdx; + unsigned int rdIdx; +} CDC_BUF_T; + +CDC_BUF_T CDC_OutBuf; // buffer for all CDC Out data + +/*---------------------------------------------------------------------------- + read data from CDC_OutBuf + *---------------------------------------------------------------------------*/ +int +CDC_RdOutBuf (char *buffer, const int *length) +{ + int bytesToRead, bytesRead; + + /* Read *length bytes, block if *bytes are not avaialable */ + bytesToRead = *length; + bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length); + bytesRead = bytesToRead; + + + // ... add code to check for underrun + + while (bytesToRead--) + { + *buffer++ = CDC_BUF_RD (CDC_OutBuf); + } + return (bytesRead); +} + +/*---------------------------------------------------------------------------- + write data to CDC_OutBuf + *---------------------------------------------------------------------------*/ +int +CDC_WrOutBuf (const char *buffer, int *length) +{ + int bytesToWrite, bytesWritten; + + // Write *length bytes + bytesToWrite = *length; + bytesWritten = bytesToWrite; + + + // ... add code to check for overwrite + + while (bytesToWrite) + { + CDC_BUF_WR (CDC_OutBuf, *buffer++); // Copy Data to buffer + bytesToWrite--; + } + + return (bytesWritten); +} + +/*---------------------------------------------------------------------------- + check if character(s) are available at CDC_OutBuf + *---------------------------------------------------------------------------*/ +int +CDC_OutBufAvailChar (int *availChar) +{ + + *availChar = CDC_BUF_COUNT (CDC_OutBuf); + + return (0); +} + +/* end Buffer handling */ + + +/*---------------------------------------------------------------------------- + CDC Initialisation + Initializes the data structures and serial port + Parameters: None + Return Value: None + *---------------------------------------------------------------------------*/ +void +CDC_Init (void) +{ + +// ser_OpenPort (); +// ser_InitPort (CDC_LineCoding.dwDTERate, CDC_LineCoding.bDataBits, CDC_LineCoding.bParityType, CDC_LineCoding.bCharFormat); + + CDC_DepInEmpty = 1; + CDC_SerialState = CDC_GetSerialState (); + + CDC_BUF_RESET (CDC_OutBuf); +} + + +/*---------------------------------------------------------------------------- + CDC SendEncapsulatedCommand Request Callback + Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_SendEncapsulatedCommand (void) +{ + + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetEncapsulatedResponse Request Callback + Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_GetEncapsulatedResponse (void) +{ + + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetCommFeature Request Callback + Called automatically on CDC Set_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_SetCommFeature (unsigned short wFeatureSelector) +{ + (void)wFeatureSelector; + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetCommFeature Request Callback + Called automatically on CDC Get_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_GetCommFeature (unsigned short wFeatureSelector) +{ + (void)wFeatureSelector; + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC ClearCommFeature Request Callback + Called automatically on CDC CLEAR_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_ClearCommFeature (unsigned short wFeatureSelector) +{ + (void)wFeatureSelector; + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetLineCoding Request Callback + Called automatically on CDC SET_LINE_CODING Request + Parameters: none (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_SetLineCoding (void) +{ + + CDC_LineCoding.dwDTERate = (EP0Buf[0] << 0) | (EP0Buf[1] << 8) | (EP0Buf[2] << 16) | (EP0Buf[3] << 24); + CDC_LineCoding.bCharFormat = EP0Buf[4]; + CDC_LineCoding.bParityType = EP0Buf[5]; + CDC_LineCoding.bDataBits = EP0Buf[6]; + +// ser_ClosePort (); +// ser_OpenPort (); +// ser_InitPort (CDC_LineCoding.dwDTERate, CDC_LineCoding.bDataBits, CDC_LineCoding.bParityType, CDC_LineCoding.bCharFormat); + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetLineCoding Request Callback + Called automatically on CDC GET_LINE_CODING Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_GetLineCoding (void) +{ + + EP0Buf[0] = (CDC_LineCoding.dwDTERate >> 0) & 0xFF; + EP0Buf[1] = (CDC_LineCoding.dwDTERate >> 8) & 0xFF; + EP0Buf[2] = (CDC_LineCoding.dwDTERate >> 16) & 0xFF; + EP0Buf[3] = (CDC_LineCoding.dwDTERate >> 24) & 0xFF; + EP0Buf[4] = CDC_LineCoding.bCharFormat; + EP0Buf[5] = CDC_LineCoding.bParityType; + EP0Buf[6] = CDC_LineCoding.bDataBits; + + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetControlLineState Request Callback + Called automatically on CDC SET_CONTROL_LINE_STATE Request + Parameters: ControlSignalBitmap + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_SetControlLineState (unsigned short wControlSignalBitmap) +{ + (void)wControlSignalBitmap; + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SendBreak Request Callback + Called automatically on CDC Set_COMM_FATURE Request + Parameters: 0xFFFF start of Break + 0x0000 stop of Break + 0x#### Duration of Break + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t +CDC_SendBreak (unsigned short wDurationOfBreak) +{ + (void)wDurationOfBreak; + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC_BulkIn call on DataIn Request + Parameters: none + Return Value: none + *---------------------------------------------------------------------------*/ +void +CDC_BulkIn (void) +{ + // send over USB + if (UARTCount > 0) + { + USB_WriteEP (CDC_DEP_IN, (uint8_t*)UARTBuffer, UARTCount); + UARTCount = 0; + } + else + { + CDC_DepInEmpty = 1; + } +} + + +/*---------------------------------------------------------------------------- + CDC_BulkOut call on DataOut Request + Parameters: none + Return Value: none + *---------------------------------------------------------------------------*/ +void +CDC_BulkOut (void) +{ + int numBytesRead; + + // get data from USB into intermediate buffer + numBytesRead = USB_ReadEP (CDC_DEP_OUT, &BulkBufOut[0]); + + // ... add code to check for overwrite + + // store data in a buffer to transmit it over serial interface + CDC_WrOutBuf ((char *) &BulkBufOut[0], &numBytesRead); + +} + + +/*---------------------------------------------------------------------------- + Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69. + Parameters: none + Return Value: SerialState as defined in usbcdc11.pdf + *---------------------------------------------------------------------------*/ +unsigned short +CDC_GetSerialState (void) +{ +// unsigned short temp; + + CDC_SerialState = 0; +/* ser_LineState (&temp); + + if (temp & 0x8000) + CDC_SerialState |= CDC_SERIAL_STATE_RX_CARRIER; + if (temp & 0x2000) + CDC_SerialState |= CDC_SERIAL_STATE_TX_CARRIER; + if (temp & 0x0010) + CDC_SerialState |= CDC_SERIAL_STATE_BREAK; + if (temp & 0x4000) + CDC_SerialState |= CDC_SERIAL_STATE_RING; + if (temp & 0x0008) + CDC_SerialState |= CDC_SERIAL_STATE_FRAMING; + if (temp & 0x0004) + CDC_SerialState |= CDC_SERIAL_STATE_PARITY; + if (temp & 0x0002) + CDC_SerialState |= CDC_SERIAL_STATE_OVERRUN;*/ + + return (CDC_SerialState); +} + + +/*---------------------------------------------------------------------------- + Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5. + *---------------------------------------------------------------------------*/ +void +CDC_NotificationIn (void) +{ + + NotificationBuf[0] = 0xA1; // bmRequestType + NotificationBuf[1] = CDC_NOTIFICATION_SERIAL_STATE; // bNotification (SERIAL_STATE) + NotificationBuf[2] = 0x00; // wValue + NotificationBuf[3] = 0x00; + NotificationBuf[4] = 0x00; // wIndex (Interface #, LSB first) + NotificationBuf[5] = 0x00; + NotificationBuf[6] = 0x02; // wLength (Data length = 2 bytes, LSB first) + NotificationBuf[7] = 0x00; + NotificationBuf[8] = (CDC_SerialState >> 0) & 0xFF; // UART State Bitmap (16bits, LSB first) + NotificationBuf[9] = (CDC_SerialState >> 8) & 0xFF; + + USB_WriteEP (CDC_CEP_IN, &NotificationBuf[0], 10); // send notification +} diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/clkconfig.c b/openbeacon/lpc13xx/usbcdc-storage/src/clkconfig.c new file mode 100644 index 0000000..786ca7e --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/src/clkconfig.c @@ -0,0 +1,61 @@ +/****************************************************************************** + * clkconfig.c: clock configuration C file for NXP LPC13xx Family + * Microprocessors + * + * Copyright(C) 2009, NXP Semiconductor + * All rights reserved. + * + * History + * 2009.08.20 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ +#include "LPC13xx.h" +#include "clkconfig.h" + +/***************************************************************************** +** Function name: WDT_CLK_Setup +** +** Descriptions: Configure WDT clock. +** parameters: clock source: irc_osc(0), main_clk(1), wdt_osc(2). +** +** Returned value: None +** +*****************************************************************************/ +void +WDT_CLK_Setup (uint32_t clksrc) +{ + /* Watchdog configuration. */ + /* Freq = 0.5Mhz, div_sel is 0, divided by 2. WDT_OSC should be 250khz */ + LPC_SYSCON->WDTOSCCTRL = (0x1 << 5) | 0x00; + LPC_SYSCON->WDTCLKSEL = clksrc; /* Select clock source */ + LPC_SYSCON->WDTCLKUEN = 0x01; /* Update clock */ + LPC_SYSCON->WDTCLKUEN = 0x00; /* Toggle update register once */ + LPC_SYSCON->WDTCLKUEN = 0x01; + while (!(LPC_SYSCON->WDTCLKUEN & 0x01)); /* Wait until updated */ + LPC_SYSCON->WDTCLKDIV = 1; /* Divided by 1 */ + LPC_SYSCON->PDRUNCFG &= ~(0x1 << 6); /* Let WDT clock run */ + return; +} + +/***************************************************************************** +** Function name: CLKOUT_Setup +** +** Descriptions: Configure CLKOUT for reference clock check. +** parameters: clock source: irc_osc(0), sys_osc(1), wdt_osc(2), +** main_clk(3). +** +** Returned value: None +** +*****************************************************************************/ +void +CLKOUT_Setup (uint32_t clksrc) +{ + /* debug PLL after configuration. */ + LPC_SYSCON->CLKOUTCLKSEL = clksrc; /* Select Main clock */ + LPC_SYSCON->CLKOUTUEN = 0x01; /* Update clock */ + LPC_SYSCON->CLKOUTUEN = 0x00; /* Toggle update register once */ + LPC_SYSCON->CLKOUTUEN = 0x01; + while (!(LPC_SYSCON->CLKOUTUEN & 0x01)); /* Wait until updated */ + LPC_SYSCON->CLKOUTDIV = 1; /* Divided by 1 */ + return; +} diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/compusbdesc.c b/openbeacon/lpc13xx/usbcdc-storage/src/compusbdesc.c new file mode 100644 index 0000000..ae5e15b --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/src/compusbdesc.c @@ -0,0 +1,273 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbdesc.c + * Purpose: USB Descriptors + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Changed string descriptor handling + * V1.00 Initial Version + *---------------------------------------------------------------------------*/ +#include "type.h" + +#include "compusb.h" +#include "cdc.h" +#include "usbcfg.h" +#include "compusbdesc.h" + +#include "msc.h" +#include "config.h" + + +/* USB Standard Device Descriptor */ +const uint8_t USB_DeviceDescriptor[] = { + USB_DEVICE_DESC_SIZE, /* bLength */ + USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL (0x0200), /* 2.0 *//* bcdUSB */ + USB_DEVICE_CLASS_MISCELLANEOUS, /* bDeviceClass */ + 0x02, /* bDeviceSubClass */ + 0x01, /* bDeviceProtocol */ + USB_MAX_PACKET0, /* bMaxPacketSize0 */ + WBVAL (USB_VENDOR_ID), /* idVendor */ + WBVAL (USB_PROD_ID), /* idProduct */ + WBVAL (USB_DEVICE), /* 1.00 *//* bcdDevice */ + 0x01, /* iManufacturer */ + 0x02, /* iProduct */ + 0x03, /* iSerialNumber */ + 0x01 /* bNumConfigurations: one possible configuration */ +}; + +/* USB Configuration Descriptor */ +/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor) */ +const uint8_t USB_ConfigDescriptor[] = { + /* Configuration 1 */ + USB_CONFIGUARTION_DESC_SIZE, /* bLength */ + USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL ( /* wTotalLength */ + 1 * USB_CONFIGUARTION_DESC_SIZE + 1 * USB_INTERFACE_DESC_SIZE + /* mass storage interface */ + 2 * USB_ENDPOINT_DESC_SIZE + /* bulk endpoints */ + 1 * USB_INTERFACE_ASSOCIATION_DESC_SIZE + /* interface association */ + 1 * USB_INTERFACE_DESC_SIZE + /* communication interface */ + 0x0013 + /* CDC functions */ + 1 * USB_ENDPOINT_DESC_SIZE + /* interrupt endpoint */ + 1 * USB_INTERFACE_DESC_SIZE + /* data interface */ + 2 * USB_ENDPOINT_DESC_SIZE + /* bulk endpoints */ + 0), + + 0x03, /* bNumInterfaces */ + 0x01, /* bConfigurationValue: 0x01 is used to select this configuration */ + 0x00, /* iConfiguration: no string to describe this configuration */ + USB_CONFIG_BUS_POWERED /*| *//* bmAttributes */ + /*USB_CONFIG_REMOTE_WAKEUP */ , + USB_CONFIG_POWER_MA (100), /* bMaxPower, device power consumption is 100 mA */ + + /* Interface 0, Alternate Setting 0, MSC Class */ + USB_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_MSC_IF_NUM, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x02, /* bNumEndpoints */ + USB_DEVICE_CLASS_STORAGE, /* bInterfaceClass */ + MSC_SUBCLASS_SCSI, /* bInterfaceSubClass */ + MSC_PROTOCOL_BULK_ONLY, /* bInterfaceProtocol */ + 0x04, /* iInterface */ + + /* Endpoint, EP2 Bulk IN */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_IN (2), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ + WBVAL (0x0040), /* wMaxPacketSize */ + 0x00, /* bInterval: ignore for Bulk transfer */ + + /* Endpoint, EP2 Bulk OUT */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_OUT (2), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ + WBVAL (0x0040), /* wMaxPacketSize */ + 0x00, /* bInterval: ignore for Bulk transfer */ + + /* IAD to associate the two CDC interfaces */ + USB_INTERFACE_ASSOCIATION_DESC_SIZE, /* bLength */ + USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_CDC_CIF_NUM, /* bFirstInterface */ + 2, /* bInterfaceCount */ + CDC_COMMUNICATION_INTERFACE_CLASS, /* bFunctionClass */ + CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */ + 0, /* bFunctionProtocol */ + 0x06, /* iFunction (Index of string descriptor describing this function) */ + + /* Interface 0, Alternate Setting 0, Communication class interface descriptor */ + USB_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_CDC_CIF_NUM, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoint used */ + CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass: Communication Interface Class */ + CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass: Abstract Control Model */ + 0x00, /* bInterfaceProtocol: no protocol used */ + 0x05, /* iInterface: */ + /*Header Functional Descriptor */ + 0x05, /* bLength: Endpoint Descriptor size */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_HEADER, /* bDescriptorSubtype: Header Func Desc */ + WBVAL (CDC_V1_10), /* 1.10 *//* bcdCDC */ + /*Call Management Functional Descriptor */ + 0x05, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_CALL_MANAGEMENT, /* bDescriptorSubtype: Call Management Func Desc */ + 0x01, /* bmCapabilities: device handles call management */ + USB_CDC_DIF_NUM, /* bDataInterface: CDC data IF ID */ + /*Abstract Control Management Functional Descriptor */ + 0x04, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */ + /*Union Functional Descriptor */ + 0x05, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_UNION, /* bDescriptorSubtype: Union func desc */ + USB_CDC_CIF_NUM, /* bMasterInterface: Communication class interface is master */ + USB_CDC_DIF_NUM, /* bSlaveInterface0: Data class interface is slave 0 */ + /*Endpoint 1 Descriptor *//* event notification (optional) */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_IN (1), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ + WBVAL (0x0010), /* wMaxPacketSize */ + 0x02, /* 2ms *//* bInterval */ + /* Interface 1, Alternate Setting 0, Data class interface descriptor */ + USB_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_CDC_DIF_NUM, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: no alternate setting */ + 0x02, /* bNumEndpoints: two endpoints used */ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass: Data Interface Class */ + 0x00, /* bInterfaceSubClass: no subclass available */ + 0x00, /* bInterfaceProtocol: no protocol used */ + 0x05, /* iInterface: */ + /* Endpoint, EP3 Bulk Out */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_OUT (3), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ + WBVAL (USB_CDC_BUFSIZE), /* wMaxPacketSize */ + 0x00, /* bInterval: ignore for Bulk transfer */ + /* Endpoint, EP3 Bulk In */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_IN (3), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ + WBVAL (USB_CDC_BUFSIZE), /* wMaxPacketSize */ + 0x00, /* bInterval: ignore for Bulk transfer */ + + /* Terminator */ + 0 /* bLength */ +}; + + +/* USB String Descriptor (optional) */ +const uint8_t USB_StringDescriptor[] = { + /* Index 0x00: LANGID Codes */ + 0x04, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL (0x0409), /* US English *//* wLANGID */ + /* Index 0x01: Manufacturer */ + (13 * 2 + 2), /* bLength (13 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'N', 0, + 'X', 0, + 'P', 0, + ' ', 0, + 'S', 0, + 'E', 0, + 'M', 0, + 'I', 0, + 'C', 0, + 'O', 0, + 'N', 0, + 'D', 0, + ' ', 0, + /* Index 0x02: Product */ + (21 * 2 + 2), /* bLength ( 21 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'N', 0, + 'X', 0, + 'P', 0, + ' ', 0, + 'L', 0, + 'P', 0, + 'C', 0, + '1', 0, + '3', 0, + 'x', 0, + 'x', 0, + ' ', 0, + 'M', 0, + 'S', 0, + 'D', 0, + '/', 0, + 'V', 0, + 'C', 0, + 'O', 0, + 'M', 0, + ' ', 0, + /* Index 0x03: Serial Number */ + (16 * 2 + 2), /* bLength (12 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'C', 0, + 'O', 0, + 'M', 0, + 'P', 0, + 'O', 0, + 'S', 0, + 'I', 0, + 'T', 0, + 'E', 0, + ' ', 0, + 'D', 0, + 'E', 0, + 'M', 0, + 'O', 0, + ' ', 0, + ' ', 0, + /* Index 0x04: Interface 0, Alternate Setting 0 */ + (6 * 2 + 2), /* bLength (6 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'M', 0, + 'e', 0, + 'm', 0, + 'o', 0, + 'r', 0, + 'y', 0, + /* Index 0x05: Interface 0, Alternate Setting 0 */ + (4 * 2 + 2), /* bLength (4 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'V', 0, + 'C', 0, + 'O', 0, + 'M', 0, + /* Index 0x05: Interface 0, Alternate Setting 0 */ + (8 * 2 + 2), /* bLength (4 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'C', 0, + 'O', 0, + 'M', 0, + '/', 0, + 'D', 0, + 'A', 0, + 'T', 0, + 'A', 0, +}; diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/main.c b/openbeacon/lpc13xx/usbcdc-storage/src/main.c new file mode 100644 index 0000000..327d9bf --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/src/main.c @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------- + * Name: vcomdemo.c + * Purpose: USB virtual COM port Demo + * Version: V1.02 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#include "LPC13xx.h" +#include "type.h" + +#include "usb.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "cdc.h" +#include "cdcuser.h" +#include "uart.h" +#include "vcomdemo.h" +#include "mscuser.h" +#include "memory.h" +#include "stdio.h" +#include "string.h" +#include "debug_printf.h" + +extern uint8_t Memory[MSC_MemorySize]; /* MSC Memory in RAM */ + +#define EN_TIMER32_1 (1<<10) +#define EN_IOCON (1<<16) +#define EN_USBREG (1<<14) + +/*---------------------------------------------------------------------------- + Initializes the VCOM port. + Call this function before using VCOM_putchar or VCOM_getchar + *---------------------------------------------------------------------------*/ +void +VCOM_Init (void) +{ + + CDC_Init (); +} + + +/*---------------------------------------------------------------------------- + Reads character from serial port buffer and writes to USB buffer + *---------------------------------------------------------------------------*/ +void +VCOM_Serial2Usb (void) +{ + int numBytesRead; + + if (UARTCount > 0) + { + if (CDC_DepInEmpty) + { + numBytesRead = (UARTCount 0) + { + numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte; + numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead); + UARTSend ((uint8_t*)&serBuf, numBytesRead); + } + +} + +/*---------------------------------------------------------------------------- + Reads character from USB buffer and writes to serial port buffer + *---------------------------------------------------------------------------*/ +void +VCOM_Usb2SerialTest (void) +{ + debug_printf("Hello World!\n"); +} + + +/*---------------------------------------------------------------------------- + checks the serial state and initiates notification + *---------------------------------------------------------------------------*/ +void +VCOM_CheckSerialState (void) +{ + unsigned short temp; + static unsigned short serialState; + + temp = CDC_GetSerialState (); + if (serialState != temp) + { + serialState = temp; + CDC_NotificationIn (); // send SERIAL_STATE notification + } +} + +/*---------------------------------------------------------------------------- + Main Program + *---------------------------------------------------------------------------*/ +int +main (void) +{ + uint32_t n; + + for (n = 0; n < MSC_ImageSize; n++) + { /* Copy Initial Disk Image */ + Memory[n] = DiskImage[n]; /* from Flash to RAM */ + } + + /* Basic chip initialization is taken care of in SystemInit() called + * from the startup code. SystemInit() and chip settings are defined + * in the CMSIS system_.c file. + */ + + /* Enable Timer32_1, IOCON, and USB blocks */ + LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG); + + + USBIOClkConfig (); + + VCOM_Init (); // VCOM Initialization + + USB_Init (); // USB Initialization + USB_Connect (TRUE); // USB Connect + + while (!USB_Configuration); // wait until USB is configured + + /* NVIC is installed inside UARTInit file. */ + SystemCoreClockUpdate (); + UARTInit (115200, 0); + + VCOM_Usb2SerialTest (); + + while (1) + { // Loop forever + VCOM_Serial2Usb (); // read serial port and initiate USB event + VCOM_CheckSerialState (); + VCOM_Usb2Serial (); + } // end while +} // end main () diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/mscuser.c b/openbeacon/lpc13xx/usbcdc-storage/src/mscuser.c new file mode 100644 index 0000000..dbf5e6e --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/src/mscuser.c @@ -0,0 +1,795 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: mscuser.c + * Purpose: Mass Storage Class Custom User Module + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added SCSI_READ12, SCSI_WRITE12 + * V1.00 Initial Version + *---------------------------------------------------------------------------*/ +#include "type.h" + +#include "usb.h" +#include "msc.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "mscuser.h" +#include "memory.h" + + +uint8_t Memory[MSC_MemorySize]; /* MSC RAM */ + +uint32_t MemOK; /* Memory OK */ + +uint32_t Offset; /* R/W Offset */ +uint32_t Length; /* R/W Length */ + +uint8_t BulkStage = MSC_BS_CBW; /* Bulk Stage */ + +uint8_t BulkBuf[MSC_MAX_PACKET] __attribute__ ((aligned (4))); /* Bulk In/Out Buffer */ +uint8_t BulkLen; /* Bulk In/Out Length */ + +MSC_CBW CBW; /* Command Block Wrapper */ +MSC_CSW CSW; /* Command Status Wrapper */ + + + +/* + * Set Stall for MSC Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +MSC_SetStallEP (uint32_t EPNum) +{ /* set EP halt status according stall status */ + USB_SetStallEP (EPNum); + USB_EndPointHalt |= (EPNum & 0x80) ? ((1 << 16) << (EPNum & 0x0F)) : (1 << EPNum); +} + + +/* + * MSC Mass Storage Reset Request Callback + * Called automatically on Mass Storage Reset Request + * Parameters: None (global SetupPacket and EP0Buf) + * Return Value: TRUE - Success, FALSE - Error + */ + +uint32_t +MSC_Reset (void) +{ + + + USB_EndPointStall = 0x00000000; /* EP must stay stalled */ + CSW.dSignature = 0; /* invalid signature */ + + BulkStage = MSC_BS_CBW; + + return (TRUE); +} + + +/* + * MSC Get Max LUN Request Callback + * Called automatically on Get Max LUN Request + * Parameters: None (global SetupPacket and EP0Buf) + * Return Value: TRUE - Success, FALSE - Error + */ + +uint32_t +MSC_GetMaxLUN (void) +{ + + EP0Buf[0] = 0; /* No LUN associated with this device */ + return (TRUE); +} + + +/* + * MSC Memory Read Callback + * Called automatically on Memory Read Event + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_MemoryRead (void) +{ + uint32_t n; + + if (Length > MSC_MAX_PACKET) + { + n = MSC_MAX_PACKET; + } + else + { + n = Length; + } + + if ((Offset + n) > MSC_MemorySize) + { + n = MSC_MemorySize - Offset; + BulkStage = MSC_BS_DATA_IN_LAST_STALL; + } + + USB_WriteEP (MSC_EP_IN, &Memory[Offset], n); + Offset += n; + Length -= n; + + CSW.dDataResidue -= n; + + if (Length == 0) + { + BulkStage = MSC_BS_DATA_IN_LAST; + } + + if (BulkStage != MSC_BS_DATA_IN) + { + CSW.bStatus = CSW_CMD_PASSED; + } +} + + +/* + * MSC Memory Write Callback + * Called automatically on Memory Write Event + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_MemoryWrite (void) +{ + uint32_t n; + + if ((Offset + BulkLen) > MSC_MemorySize) + { + BulkLen = MSC_MemorySize - Offset; + BulkStage = MSC_BS_CSW; + MSC_SetStallEP (MSC_EP_OUT); + } + + for (n = 0; n < BulkLen; n++) + { + Memory[Offset + n] = BulkBuf[n]; + } + + Offset += BulkLen; + Length -= BulkLen; + + CSW.dDataResidue -= BulkLen; + + if ((Length == 0) || (BulkStage == MSC_BS_CSW)) + { + CSW.bStatus = CSW_CMD_PASSED; + MSC_SetCSW (); + } +} + + +/* + * MSC Memory Verify Callback + * Called automatically on Memory Verify Event + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_MemoryVerify (void) +{ + uint32_t n; + + if ((Offset + BulkLen) > MSC_MemorySize) + { + BulkLen = MSC_MemorySize - Offset; + BulkStage = MSC_BS_CSW; + MSC_SetStallEP (MSC_EP_OUT); + } + + for (n = 0; n < BulkLen; n++) + { + if (Memory[Offset + n] != BulkBuf[n]) + { + MemOK = FALSE; + break; + } + } + + Offset += BulkLen; + Length -= BulkLen; + + CSW.dDataResidue -= BulkLen; + + if ((Length == 0) || (BulkStage == MSC_BS_CSW)) + { + CSW.bStatus = (MemOK) ? CSW_CMD_PASSED : CSW_CMD_FAILED; + MSC_SetCSW (); + } +} + + +/* + * MSC SCSI Read/Write Setup Callback + * Parameters: None (global variables) + * Return Value: TRUE - Success, FALSE - Error + */ + +uint32_t +MSC_RWSetup (void) +{ + uint32_t n; + + /* Logical Block Address of First Block */ + n = (CBW.CB[2] << 24) | (CBW.CB[3] << 16) | (CBW.CB[4] << 8) | (CBW.CB[5] << 0); + + Offset = n * MSC_BlockSize; + + /* Number of Blocks to transfer */ + switch (CBW.CB[0]) + { + case SCSI_READ10: + case SCSI_WRITE10: + case SCSI_VERIFY10: + n = (CBW.CB[7] << 8) | (CBW.CB[8] << 0); + break; + + case SCSI_READ12: + case SCSI_WRITE12: + n = (CBW.CB[6] << 24) | (CBW.CB[7] << 16) | (CBW.CB[8] << 8) | (CBW.CB[9] << 0); + break; + } + + Length = n * MSC_BlockSize; + + if (CBW.dDataLength == 0) + { /* host requests no data */ + CSW.bStatus = CSW_CMD_FAILED; + MSC_SetCSW (); + return (FALSE); + } + + if (CBW.dDataLength != Length) + { + if ((CBW.bmFlags & 0x80) != 0) + { /* stall appropriate EP */ + MSC_SetStallEP (MSC_EP_IN); + } + else + { + MSC_SetStallEP (MSC_EP_OUT); + } + + CSW.bStatus = CSW_CMD_FAILED; + MSC_SetCSW (); + + return (FALSE); + } + + return (TRUE); +} + + +/* + * Check Data IN Format + * Parameters: None (global variables) + * Return Value: TRUE - Success, FALSE - Error + */ + +uint32_t +DataInFormat (void) +{ + + if (CBW.dDataLength == 0) + { + CSW.bStatus = CSW_PHASE_ERROR; + MSC_SetCSW (); + return (FALSE); + } + if ((CBW.bmFlags & 0x80) == 0) + { + MSC_SetStallEP (MSC_EP_OUT); + CSW.bStatus = CSW_PHASE_ERROR; + MSC_SetCSW (); + return (FALSE); + } + return (TRUE); +} + + +/* + * Perform Data IN Transfer + * Parameters: None (global variables) + * Return Value: TRUE - Success, FALSE - Error + */ + +void +DataInTransfer (void) +{ + + if (BulkLen >= CBW.dDataLength) + BulkLen = CBW.dDataLength; + + BulkStage = MSC_BS_DATA_IN_LAST; + + USB_WriteEP (MSC_EP_IN, BulkBuf, BulkLen); + + CSW.dDataResidue -= BulkLen; + CSW.bStatus = CSW_CMD_PASSED; +} + + +/* + * MSC SCSI Test Unit Ready Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_TestUnitReady (void) +{ + + if (CBW.dDataLength != 0) + { + if ((CBW.bmFlags & 0x80) != 0) + { + MSC_SetStallEP (MSC_EP_IN); + } + else + { + MSC_SetStallEP (MSC_EP_OUT); + } + } + + CSW.bStatus = CSW_CMD_PASSED; + MSC_SetCSW (); +} + + +/* + * MSC SCSI Request Sense Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_RequestSense (void) +{ + + if (!DataInFormat ()) + return; + + BulkBuf[0] = 0x70; /* Response Code */ + BulkBuf[1] = 0x00; + BulkBuf[2] = 0x02; /* Sense Key */ + BulkBuf[3] = 0x00; + BulkBuf[4] = 0x00; + BulkBuf[5] = 0x00; + BulkBuf[6] = 0x00; + BulkBuf[7] = 0x0A; /* Additional Length */ + BulkBuf[8] = 0x00; + BulkBuf[9] = 0x00; + BulkBuf[10] = 0x00; + BulkBuf[11] = 0x00; + BulkBuf[12] = 0x30; /* ASC */ + BulkBuf[13] = 0x01; /* ASCQ */ + BulkBuf[14] = 0x00; + BulkBuf[15] = 0x00; + BulkBuf[16] = 0x00; + BulkBuf[17] = 0x00; + + BulkLen = 18; + DataInTransfer (); +} + + +/* + * MSC SCSI Inquiry Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_Inquiry (void) +{ + + if (!DataInFormat ()) + return; + + BulkBuf[0] = 0x00; /* Direct Access Device */ + BulkBuf[1] = 0x80; /* RMB = 1: Removable Medium */ + BulkBuf[2] = 0x00; /* Version: No conformance claim to standard */ + BulkBuf[3] = 0x01; + + BulkBuf[4] = 36 - 4; /* Additional Length */ + BulkBuf[5] = 0x80; /* SCCS = 1: Storage Controller Component */ + BulkBuf[6] = 0x00; + BulkBuf[7] = 0x00; + + BulkBuf[8] = 'K'; /* Vendor Identification */ + BulkBuf[9] = 'e'; + BulkBuf[10] = 'i'; + BulkBuf[11] = 'l'; + BulkBuf[12] = ' '; + BulkBuf[13] = ' '; + BulkBuf[14] = ' '; + BulkBuf[15] = ' '; + + BulkBuf[16] = 'L'; /* Product Identification */ + BulkBuf[17] = 'P'; + BulkBuf[18] = 'C'; + BulkBuf[19] = '1'; + BulkBuf[20] = '3'; + BulkBuf[21] = '4'; + BulkBuf[22] = 'x'; + BulkBuf[23] = ' '; + BulkBuf[24] = 'D'; + BulkBuf[25] = 'i'; + BulkBuf[26] = 's'; + BulkBuf[27] = 'k'; + BulkBuf[28] = ' '; + BulkBuf[29] = ' '; + BulkBuf[30] = ' '; + BulkBuf[31] = ' '; + + BulkBuf[32] = '1'; /* Product Revision Level */ + BulkBuf[33] = '.'; + BulkBuf[34] = '0'; + BulkBuf[35] = ' '; + + BulkLen = 36; + DataInTransfer (); +} + + +/* + * MSC SCSI Mode Sense (6-Byte) Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_ModeSense6 (void) +{ + + if (!DataInFormat ()) + return; + + BulkBuf[0] = 0x03; + BulkBuf[1] = 0x00; + BulkBuf[2] = 0x00; + BulkBuf[3] = 0x00; + + BulkLen = 4; + DataInTransfer (); +} + + +/* + * MSC SCSI Mode Sense (10-Byte) Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_ModeSense10 (void) +{ + + if (!DataInFormat ()) + return; + + BulkBuf[0] = 0x00; + BulkBuf[1] = 0x06; + BulkBuf[2] = 0x00; + BulkBuf[3] = 0x00; + BulkBuf[4] = 0x00; + BulkBuf[5] = 0x00; + BulkBuf[6] = 0x00; + BulkBuf[7] = 0x00; + + BulkLen = 8; + DataInTransfer (); +} + + +/* + * MSC SCSI Read Capacity Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_ReadCapacity (void) +{ + + if (!DataInFormat ()) + return; + + /* Last Logical Block */ + BulkBuf[0] = ((MSC_BlockCount - 1) >> 24) & 0xFF; + BulkBuf[1] = ((MSC_BlockCount - 1) >> 16) & 0xFF; + BulkBuf[2] = ((MSC_BlockCount - 1) >> 8) & 0xFF; + BulkBuf[3] = ((MSC_BlockCount - 1) >> 0) & 0xFF; + + /* Block Length */ + BulkBuf[4] = (MSC_BlockSize >> 24) & 0xFF; + BulkBuf[5] = (MSC_BlockSize >> 16) & 0xFF; + BulkBuf[6] = (MSC_BlockSize >> 8) & 0xFF; + BulkBuf[7] = (MSC_BlockSize >> 0) & 0xFF; + + BulkLen = 8; + DataInTransfer (); +} + + +/* + * MSC SCSI Read Format Capacity Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_ReadFormatCapacity (void) +{ + + if (!DataInFormat ()) + return; + + BulkBuf[0] = 0x00; + BulkBuf[1] = 0x00; + BulkBuf[2] = 0x00; + BulkBuf[3] = 0x08; /* Capacity List Length */ + + /* Block Count */ + BulkBuf[4] = (MSC_BlockCount >> 24) & 0xFF; + BulkBuf[5] = (MSC_BlockCount >> 16) & 0xFF; + BulkBuf[6] = (MSC_BlockCount >> 8) & 0xFF; + BulkBuf[7] = (MSC_BlockCount >> 0) & 0xFF; + + /* Block Length */ + BulkBuf[8] = 0x02; /* Descriptor Code: Formatted Media */ + BulkBuf[9] = (MSC_BlockSize >> 16) & 0xFF; + BulkBuf[10] = (MSC_BlockSize >> 8) & 0xFF; + BulkBuf[11] = (MSC_BlockSize >> 0) & 0xFF; + + BulkLen = 12; + DataInTransfer (); +} + + +/* + * MSC Get Command Block Wrapper Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_GetCBW (void) +{ + uint32_t n; + + for (n = 0; n < BulkLen; n++) + { + *((uint8_t *) & CBW + n) = BulkBuf[n]; + } + if ((BulkLen == sizeof (CBW)) && (CBW.dSignature == MSC_CBW_Signature)) + { + /* Valid CBW */ + CSW.dTag = CBW.dTag; + CSW.dDataResidue = CBW.dDataLength; + if ((CBW.bLUN != 0) || (CBW.bCBLength < 1) || (CBW.bCBLength > 16)) + { + fail: + CSW.bStatus = CSW_CMD_FAILED; + MSC_SetCSW (); + } + else + { + switch (CBW.CB[0]) + { + case SCSI_TEST_UNIT_READY: + MSC_TestUnitReady (); + break; + case SCSI_REQUEST_SENSE: + MSC_RequestSense (); + break; + case SCSI_FORMAT_UNIT: + goto fail; + case SCSI_INQUIRY: + MSC_Inquiry (); + break; + case SCSI_START_STOP_UNIT: + goto fail; + case SCSI_MEDIA_REMOVAL: + goto fail; + case SCSI_MODE_SELECT6: + goto fail; + case SCSI_MODE_SENSE6: + MSC_ModeSense6 (); + break; + case SCSI_MODE_SELECT10: + goto fail; + case SCSI_MODE_SENSE10: + MSC_ModeSense10 (); + break; + case SCSI_READ_FORMAT_CAPACITIES: + MSC_ReadFormatCapacity (); + break; + case SCSI_READ_CAPACITY: + MSC_ReadCapacity (); + break; + case SCSI_READ10: + case SCSI_READ12: + if (MSC_RWSetup ()) + { + if ((CBW.bmFlags & 0x80) != 0) + { + BulkStage = MSC_BS_DATA_IN; + MSC_MemoryRead (); + } + else + { /* direction mismatch */ + MSC_SetStallEP (MSC_EP_OUT); + CSW.bStatus = CSW_PHASE_ERROR; + MSC_SetCSW (); + } + } + break; + case SCSI_WRITE10: + case SCSI_WRITE12: + if (MSC_RWSetup ()) + { + if ((CBW.bmFlags & 0x80) == 0) + { + BulkStage = MSC_BS_DATA_OUT; + } + else + { /* direction mismatch */ + MSC_SetStallEP (MSC_EP_IN); + CSW.bStatus = CSW_PHASE_ERROR; + MSC_SetCSW (); + } + } + break; + case SCSI_VERIFY10: + if ((CBW.CB[1] & 0x02) == 0) + { + // BYTCHK = 0 -> CRC Check (not implemented) + CSW.bStatus = CSW_CMD_PASSED; + MSC_SetCSW (); + break; + } + if (MSC_RWSetup ()) + { + if ((CBW.bmFlags & 0x80) == 0) + { + BulkStage = MSC_BS_DATA_OUT; + MemOK = TRUE; + } + else + { + MSC_SetStallEP (MSC_EP_IN); + CSW.bStatus = CSW_PHASE_ERROR; + MSC_SetCSW (); + } + } + break; + default: + goto fail; + } + } + } + else + { + /* Invalid CBW */ + MSC_SetStallEP (MSC_EP_IN); + /* set EP to stay stalled */ + USB_EndPointStall |= (MSC_EP_IN & 0x80) ? ((1 << 16) << (MSC_EP_IN & 0x0F)) : (1 << MSC_EP_IN); + MSC_SetStallEP (MSC_EP_OUT); + /* set EP to stay stalled */ + USB_EndPointStall |= (MSC_EP_OUT & 0x80) ? ((1 << 16) << (MSC_EP_OUT & 0x0F)) : (1 << MSC_EP_OUT); + BulkStage = MSC_BS_ERROR; + } +} + + +/* + * MSC Set Command Status Wrapper Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_SetCSW (void) +{ + + CSW.dSignature = MSC_CSW_Signature; + USB_WriteEP (MSC_EP_IN, (uint8_t *) & CSW, sizeof (CSW)); + BulkStage = MSC_BS_CSW; +} + + +/* + * MSC Bulk In Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_BulkIn (void) +{ + + switch (BulkStage) + { + case MSC_BS_DATA_IN: + switch (CBW.CB[0]) + { + case SCSI_READ10: + case SCSI_READ12: + MSC_MemoryRead (); + break; + } + break; + case MSC_BS_DATA_IN_LAST: + MSC_SetCSW (); + break; + case MSC_BS_DATA_IN_LAST_STALL: + MSC_SetStallEP (MSC_EP_IN); + MSC_SetCSW (); + break; + case MSC_BS_CSW: + BulkStage = MSC_BS_CBW; + break; + } +} + + +/* + * MSC Bulk Out Callback + * Parameters: None (global variables) + * Return Value: None + */ + +void +MSC_BulkOut (void) +{ + + BulkLen = USB_ReadEP (MSC_EP_OUT, BulkBuf); + switch (BulkStage) + { + case MSC_BS_CBW: + MSC_GetCBW (); + break; + case MSC_BS_DATA_OUT: + switch (CBW.CB[0]) + { + case SCSI_WRITE10: + case SCSI_WRITE12: + MSC_MemoryWrite (); + break; + case SCSI_VERIFY10: + MSC_MemoryVerify (); + break; + } + break; + default: + MSC_SetStallEP (MSC_EP_OUT); + CSW.bStatus = CSW_PHASE_ERROR; + MSC_SetCSW (); + break; + } +} diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/usbcore.c b/openbeacon/lpc13xx/usbcdc-storage/src/usbcore.c new file mode 100644 index 0000000..fff47a9 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/src/usbcore.c @@ -0,0 +1,1267 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcore.c + * Purpose: USB Core Module + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added vendor specific requests + * Changed string descriptor handling + * Reworked Endpoint0 + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ +#include "type.h" + +#include "usb.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbdesc.h" +#include "usbuser.h" + +#if (USB_CLASS) + +#if (USB_AUDIO) +#include "audio.h" +#include "adcuser.h" +#endif + +#if (USB_HID) +#include "hid.h" +#include "hiduser.h" +#endif + +#if (USB_MSC) +#include "msc.h" +#include "mscuser.h" +extern MSC_CSW CSW; +#endif + +#if (USB_CDC) +#include "cdc.h" +#include "cdcuser.h" +#endif + +#endif + +#if (USB_VENDOR) +#include "vendor.h" +#endif + +uint16_t USB_DeviceStatus; +uint8_t USB_DeviceAddress; +uint8_t USB_Configuration; +uint32_t USB_EndPointMask; +uint32_t USB_EndPointHalt; +uint32_t USB_EndPointStall; /* EP must stay stalled */ +uint8_t USB_NumInterfaces; +uint8_t USB_AltSetting[USB_IF_NUM]; + +uint8_t EP0Buf[USB_MAX_PACKET0]; + + +USB_EP_DATA EP0Data; + +USB_SETUP_PACKET SetupPacket; + + +/* + * Reset USB Core + * Parameters: None + * Return Value: None + */ + +void +USB_ResetCore (void) +{ + + USB_DeviceStatus = USB_POWER; + USB_DeviceAddress = 0; + USB_Configuration = 0; + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; +} + + +/* + * USB Request - Setup Stage + * Parameters: None (global SetupPacket) + * Return Value: None + */ + +void +USB_SetupStage (void) +{ + USB_ReadEP (0x00, (uint8_t *) & SetupPacket); +} + + +/* + * USB Request - Data In Stage + * Parameters: None (global EP0Data) + * Return Value: None + */ + +void +USB_DataInStage (void) +{ + uint32_t cnt; + + if (EP0Data.Count > USB_MAX_PACKET0) + { + cnt = USB_MAX_PACKET0; + } + else + { + cnt = EP0Data.Count; + } + cnt = USB_WriteEP (0x80, EP0Data.pData, cnt); + EP0Data.pData += cnt; + EP0Data.Count -= cnt; +} + + +/* + * USB Request - Data Out Stage + * Parameters: None (global EP0Data) + * Return Value: None + */ + +void +USB_DataOutStage (void) +{ + uint32_t cnt; + + cnt = USB_ReadEP (0x00, EP0Data.pData); + EP0Data.pData += cnt; + EP0Data.Count -= cnt; +} + + +/* + * USB Request - Status In Stage + * Parameters: None + * Return Value: None + */ + +void +USB_StatusInStage (void) +{ + USB_WriteEP (0x80, NULL, 0); +} + + +/* + * USB Request - Status Out Stage + * Parameters: None + * Return Value: None + */ + +void +USB_StatusOutStage (void) +{ + USB_ReadEP (0x00, EP0Buf); +} + + +/* + * Get Status USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqGetStatus (void) +{ + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + EP0Data.pData = (uint8_t *) & USB_DeviceStatus; + break; + case REQUEST_TO_INTERFACE: + if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) + { + *((uint16_t __attribute__ ((packed)) *) EP0Buf) = 0; + EP0Data.pData = EP0Buf; + } + else + { + return (FALSE); + } + break; + case REQUEST_TO_ENDPOINT: + n = SetupPacket.wIndex.WB.L & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if (((USB_Configuration != 0) || ((n & 0x0F) == 0)) && (USB_EndPointMask & m)) + { + *((uint16_t __attribute__ ((packed)) *) EP0Buf) = (USB_EndPointHalt & m) ? 1 : 0; + EP0Data.pData = EP0Buf; + } + else + { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set/Clear Feature USB Request + * Parameters: sc: 0 - Clear, 1 - Set + * (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqSetClrFeature (uint32_t sc) +{ + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + if (SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP) + { + if (sc) + { + USB_WakeUpCfg (TRUE); + USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP; + } + else + { + USB_WakeUpCfg (FALSE); + USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP; + } + } + else + { + return (FALSE); + } + break; + case REQUEST_TO_INTERFACE: + return (FALSE); + case REQUEST_TO_ENDPOINT: + n = SetupPacket.wIndex.WB.L & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if ((USB_Configuration != 0) && ((n & 0x0F) != 0) && (USB_EndPointMask & m)) + { + if (SetupPacket.wValue.W == USB_FEATURE_ENDPOINT_STALL) + { + if (sc) + { + USB_SetStallEP (n); + USB_EndPointHalt |= m; + } + else + { + if ((USB_EndPointStall & m) != 0) + { + return (TRUE); + } + USB_ClrStallEP (n); +#if (USB_MSC) + if ((n == MSC_EP_IN) && ((USB_EndPointHalt & m) != 0)) + { + /* Compliance Test: rewrite CSW after unstall */ + if (CSW.dSignature == MSC_CSW_Signature) + { + USB_WriteEP (MSC_EP_IN, (uint8_t *) & CSW, sizeof (CSW)); + } + } +#endif + USB_EndPointHalt &= ~m; + } + } + else + { + return (FALSE); + } + } + else + { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Address USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqSetAddress (void) +{ + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + USB_DeviceAddress = 0x80 | SetupPacket.wValue.WB.L; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Get Descriptor USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqGetDescriptor (void) +{ + uint8_t *pD; + uint32_t len, n; + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + switch (SetupPacket.wValue.WB.H) + { + case USB_DEVICE_DESCRIPTOR_TYPE: + EP0Data.pData = (uint8_t *) USB_DeviceDescriptor; + len = USB_DEVICE_DESC_SIZE; + break; + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + pD = (uint8_t *) USB_ConfigDescriptor; + for (n = 0; n != SetupPacket.wValue.WB.L; n++) + { + if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bLength != 0) + { + pD += ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength; + } + } + if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bLength == 0) + { + return (FALSE); + } + EP0Data.pData = pD; + len = ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength; + break; + case USB_STRING_DESCRIPTOR_TYPE: + pD = (uint8_t *) USB_StringDescriptor; + for (n = 0; n != SetupPacket.wValue.WB.L; n++) + { + if (((USB_STRING_DESCRIPTOR *) pD)->bLength != 0) + { + pD += ((USB_STRING_DESCRIPTOR *) pD)->bLength; + } + } + if (((USB_STRING_DESCRIPTOR *) pD)->bLength == 0) + { + return (FALSE); + } + EP0Data.pData = pD; + len = ((USB_STRING_DESCRIPTOR *) EP0Data.pData)->bLength; + break; + default: + return (FALSE); + } + break; + case REQUEST_TO_INTERFACE: + switch (SetupPacket.wValue.WB.H) + { +#if USB_HID + case HID_HID_DESCRIPTOR_TYPE: + if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) + { + return (FALSE); /* Only Single HID Interface is supported */ + } + EP0Data.pData = (uint8_t *) USB_ConfigDescriptor + HID_DESC_OFFSET; + len = HID_DESC_SIZE; + break; + case HID_REPORT_DESCRIPTOR_TYPE: + if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) + { + return (FALSE); /* Only Single HID Interface is supported */ + } + EP0Data.pData = (uint8_t *) HID_ReportDescriptor; + len = HID_ReportDescSize; + break; + case HID_PHYSICAL_DESCRIPTOR_TYPE: + return (FALSE); /* HID Physical Descriptor is not supported */ +#endif + default: + return (FALSE); + } + break; + default: + return (FALSE); + } + + if (EP0Data.Count > len) + { + EP0Data.Count = len; + } + + return (TRUE); +} + + +/* + * Get Configuration USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqGetConfiguration (void) +{ + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + EP0Data.pData = &USB_Configuration; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Add a number of bytes to a pointer's address + * Harder than you might think. Some compilers say: + * Expected an lvalue -- Assignment expects its first operand to be + * an lvalue. Please note that a cast removes the lvaluedness of an + * expression. + * + * vpptr = void pointer to pointer + * n = number of bytes to add to pointer + * Call looks like: AddPtr((void **)&myPointer, 8); + */ + +__inline void +UsbAddPtr (void **vpptr, uint32_t n) +{ + /* Declare a pointer to a pointer to a byte. Only a byte pointer + * can be incremented by a number of bytes. Other pointers will + * increment by a multiple of what they point to. + */ + uint8_t **bpptr; + + /* Convert our void pointer to a pointer to a byte pointer to a pointer */ + bpptr = (uint8_t **) vpptr; + + /* Add 'n' bytes to our pointer value */ + (*bpptr) += n; +} + +/* + * Set Configuration USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqSetConfiguration (void) +{ + USB_COMMON_DESCRIPTOR *pD; + uint32_t alt = 0; + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + + if (SetupPacket.wValue.WB.L) + { + pD = (USB_COMMON_DESCRIPTOR *) USB_ConfigDescriptor; + while (pD->bLength) + { + switch (pD->bDescriptorType) + { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bConfigurationValue == SetupPacket.wValue.WB.L) + { + USB_Configuration = SetupPacket.wValue.WB.L; + USB_NumInterfaces = ((USB_CONFIGURATION_DESCRIPTOR *) pD)->bNumInterfaces; + for (n = 0; n < USB_IF_NUM; n++) + { + USB_AltSetting[n] = 0; + } + for (n = 1; n < 16; n++) + { + if (USB_EndPointMask & (1 << n)) + { + USB_DisableEP (n); + } + if (USB_EndPointMask & ((1 << 16) << n)) + { + USB_DisableEP (n | 0x80); + } + } + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; + USB_Configure (TRUE); + if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bmAttributes & USB_CONFIG_POWERED_MASK) + { + USB_DeviceStatus |= USB_GETSTATUS_SELF_POWERED; + } + else + { + USB_DeviceStatus &= ~USB_GETSTATUS_SELF_POWERED; + } + } + else + { + UsbAddPtr ((void **) &pD, ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength); + continue; + } + break; + case USB_INTERFACE_DESCRIPTOR_TYPE: + alt = ((USB_INTERFACE_DESCRIPTOR *) pD)->bAlternateSetting; + break; + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if (alt == 0) + { + n = ((USB_ENDPOINT_DESCRIPTOR *) pD)->bEndpointAddress & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + USB_EndPointMask |= m; + USB_ConfigEP ((USB_ENDPOINT_DESCRIPTOR *) pD); + USB_EnableEP (n); + USB_ResetEP (n); + } + break; + } + UsbAddPtr ((void **) &pD, pD->bLength); + } + } + else + { + USB_Configuration = 0; + for (n = 1; n < 16; n++) + { + if (USB_EndPointMask & (1 << n)) + { + USB_DisableEP (n); + } + if (USB_EndPointMask & ((1 << 16) << n)) + { + USB_DisableEP (n | 0x80); + } + } + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; + USB_Configure (FALSE); + } + + if (USB_Configuration != SetupPacket.wValue.WB.L) + { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Get Interface USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqGetInterface (void) +{ + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_INTERFACE: + if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) + { + EP0Data.pData = USB_AltSetting + SetupPacket.wIndex.WB.L; + } + else + { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Interface USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +__inline uint32_t +USB_ReqSetInterface (void) +{ + USB_COMMON_DESCRIPTOR *pD; + uint32_t ifn = 0, alt = 0, old = 0, msk = 0; + uint32_t n, m; + uint32_t set; + + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_INTERFACE: + if (USB_Configuration == 0) + return (FALSE); + set = FALSE; + pD = (USB_COMMON_DESCRIPTOR *) USB_ConfigDescriptor; + while (pD->bLength) + { + switch (pD->bDescriptorType) + { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bConfigurationValue != USB_Configuration) + { + UsbAddPtr ((void **) &pD, ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength); + continue; + } + break; + case USB_INTERFACE_DESCRIPTOR_TYPE: + ifn = ((USB_INTERFACE_DESCRIPTOR *) pD)->bInterfaceNumber; + alt = ((USB_INTERFACE_DESCRIPTOR *) pD)->bAlternateSetting; + msk = 0; + if ((ifn == SetupPacket.wIndex.WB.L) && (alt == SetupPacket.wValue.WB.L)) + { + set = TRUE; + old = USB_AltSetting[ifn]; + USB_AltSetting[ifn] = (uint8_t) alt; + } + break; + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if (ifn == SetupPacket.wIndex.WB.L) + { + n = ((USB_ENDPOINT_DESCRIPTOR *) pD)->bEndpointAddress & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if (alt == SetupPacket.wValue.WB.L) + { + USB_EndPointMask |= m; + USB_EndPointHalt &= ~m; + USB_ConfigEP ((USB_ENDPOINT_DESCRIPTOR *) pD); + USB_EnableEP (n); + USB_ResetEP (n); + msk |= m; + } + else if ((alt == old) && ((msk & m) == 0)) + { + USB_EndPointMask &= ~m; + USB_EndPointHalt &= ~m; + USB_DisableEP (n); + } + } + break; + } + UsbAddPtr ((void **) &pD, pD->bLength); + } + break; + default: + return (FALSE); + } + + return (set); +} + + +/* + * USB Endpoint 0 Event Callback + * Parameters: event + * Return Value: none + */ + +void +USB_EndPoint0 (uint32_t event) +{ + + switch (event) + { + case USB_EVT_SETUP: + USB_SetupStage (); + USB_DirCtrlEP (SetupPacket.bmRequestType.BM.Dir); + EP0Data.Count = SetupPacket.wLength; /* Number of bytes to transfer */ + switch (SetupPacket.bmRequestType.BM.Type) + { + + case REQUEST_STANDARD: + switch (SetupPacket.bRequest) + { + case USB_REQUEST_GET_STATUS: + if (!USB_ReqGetStatus ()) + { + goto stall_i; + } + USB_DataInStage (); + break; + + case USB_REQUEST_CLEAR_FEATURE: + if (!USB_ReqSetClrFeature (0)) + { + goto stall_i; + } + USB_StatusInStage (); +#if USB_FEATURE_EVENT + USB_Feature_Event (); +#endif + break; + + case USB_REQUEST_SET_FEATURE: + if (!USB_ReqSetClrFeature (1)) + { + goto stall_i; + } + USB_StatusInStage (); +#if USB_FEATURE_EVENT + USB_Feature_Event (); +#endif + break; + + case USB_REQUEST_SET_ADDRESS: + if (!USB_ReqSetAddress ()) + { + goto stall_i; + } + USB_StatusInStage (); + break; + + case USB_REQUEST_GET_DESCRIPTOR: + if (!USB_ReqGetDescriptor ()) + { + goto stall_i; + } + USB_DataInStage (); + break; + + case USB_REQUEST_SET_DESCRIPTOR: + /*stall_o: */ USB_SetStallEP (0x00); + /* not supported */ + EP0Data.Count = 0; + break; + + case USB_REQUEST_GET_CONFIGURATION: + if (!USB_ReqGetConfiguration ()) + { + goto stall_i; + } + USB_DataInStage (); + break; + + case USB_REQUEST_SET_CONFIGURATION: + if (!USB_ReqSetConfiguration ()) + { + goto stall_i; + } + USB_StatusInStage (); +#if USB_CONFIGURE_EVENT + USB_Configure_Event (); +#endif + break; + + case USB_REQUEST_GET_INTERFACE: + if (!USB_ReqGetInterface ()) + { + goto stall_i; + } + USB_DataInStage (); + break; + + case USB_REQUEST_SET_INTERFACE: + if (!USB_ReqSetInterface ()) + { + goto stall_i; + } + USB_StatusInStage (); +#if USB_INTERFACE_EVENT + USB_Interface_Event (); +#endif + break; + + default: + goto stall_i; + } + break; /* end case REQUEST_STANDARD */ + +#if USB_CLASS + case REQUEST_CLASS: + switch (SetupPacket.bmRequestType.BM.Recipient) + { + + case REQUEST_TO_DEVICE: + goto stall_i; /* not supported */ + + case REQUEST_TO_INTERFACE: +#if USB_HID + if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) + { /* IF number correct? */ + switch (SetupPacket.bRequest) + { + case HID_REQUEST_GET_REPORT: + if (HID_GetReport ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_REPORT: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + case HID_REQUEST_GET_IDLE: + if (HID_GetIdle ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_IDLE: + if (HID_SetIdle ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case HID_REQUEST_GET_PROTOCOL: + if (HID_GetProtocol ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_PROTOCOL: + if (HID_SetProtocol ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto setup_class_ok; + } + break; + } + } +#endif /* USB_HID */ +#if USB_MSC + if (SetupPacket.wIndex.WB.L == USB_MSC_IF_NUM) + { /* IF number correct? */ + switch (SetupPacket.bRequest) + { + case MSC_REQUEST_RESET: + if ((SetupPacket.wValue.W == 0) && /* RESET with invalid parameters -> STALL */ + (SetupPacket.wLength == 0)) + { + if (MSC_Reset ()) + { + USB_StatusInStage (); + goto setup_class_ok; + } + } + break; + case MSC_REQUEST_GET_MAX_LUN: + if ((SetupPacket.wValue.W == 0) && /* GET_MAX_LUN with invalid parameters -> STALL */ + (SetupPacket.wLength == 1)) + { + if (MSC_GetMaxLUN ()) + { + EP0Data.pData = EP0Buf; + USB_DataInStage (); + goto setup_class_ok; + } + } + break; + } + } +#endif /* USB_MSC */ +#if USB_AUDIO + if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) + { + switch (SetupPacket.bRequest) + { + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + if (ADC_IF_GetRequest ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + } + } +#endif /* USB_AUDIO */ +#if USB_CDC + if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM)) + { + switch (SetupPacket.bRequest) + { + case CDC_SEND_ENCAPSULATED_COMMAND: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_ENCAPSULATED_RESPONSE: + if (CDC_GetEncapsulatedResponse ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_SET_COMM_FEATURE: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_COMM_FEATURE: + if (CDC_GetCommFeature (SetupPacket.wValue.W)) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_CLEAR_COMM_FEATURE: + if (CDC_ClearCommFeature (SetupPacket.wValue.W)) + { + USB_StatusInStage (); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case CDC_SET_LINE_CODING: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_LINE_CODING: + if (CDC_GetLineCoding ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_SET_CONTROL_LINE_STATE: + if (CDC_SetControlLineState (SetupPacket.wValue.W)) + { + USB_StatusInStage (); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case CDC_SEND_BREAK: + if (CDC_SendBreak (SetupPacket.wValue.W)) + { + USB_StatusInStage (); /* send Acknowledge */ + goto setup_class_ok; + } + break; + } + } +#endif /* USB_CDC */ + goto stall_i; /* not supported */ + /* end case REQUEST_TO_INTERFACE */ + + case REQUEST_TO_ENDPOINT: +#if USB_AUDIO + switch (SetupPacket.bRequest) + { + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + if (ADC_EP_GetRequest ()) + { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage (); /* send requested data */ + goto setup_class_ok; + } + break; + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + } +#endif /* USB_AUDIO */ + goto stall_i; + /* end case REQUEST_TO_ENDPOINT */ + + default: + goto stall_i; + } + setup_class_ok: /* request finished successfully */ + break; /* end case REQUEST_CLASS */ +#endif /* USB_CLASS */ + +#if USB_VENDOR + case REQUEST_VENDOR: + switch (SetupPacket.bmRequestType.BM.Recipient) + { + + case REQUEST_TO_DEVICE: + if (!USB_ReqVendorDev (TRUE)) + { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_INTERFACE: + if (!USB_ReqVendorIF (TRUE)) + { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_ENDPOINT: + if (!USB_ReqVendorEP (TRUE)) + { + goto stall_i; /* not supported */ + } + break; + + default: + goto stall_i; + } + + if (SetupPacket.wLength) + { + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST) + { + USB_DataInStage (); + } + } + else + { + USB_StatusInStage (); + } + + break; /* end case REQUEST_VENDOR */ +#endif /* USB_VENDOR */ + + default: + stall_i:USB_SetStallEP (0x80); + EP0Data.Count = 0; + break; + } + break; /* end case USB_EVT_SETUP */ + + case USB_EVT_OUT: + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_HOST_TO_DEVICE) + { + if (EP0Data.Count) + { /* still data to receive ? */ + USB_DataOutStage (); /* receive data */ + if (EP0Data.Count == 0) + { /* data complete ? */ + switch (SetupPacket.bmRequestType.BM.Type) + { + + case REQUEST_STANDARD: + goto stall_i; /* not supported */ + +#if (USB_CLASS) + case REQUEST_CLASS: + switch (SetupPacket.bmRequestType.BM.Recipient) + { + case REQUEST_TO_DEVICE: + goto stall_i; /* not supported */ + + case REQUEST_TO_INTERFACE: +#if USB_HID + if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) + { /* IF number correct? */ + switch (SetupPacket.bRequest) + { + case HID_REQUEST_SET_REPORT: + if (HID_SetReport ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_HID */ +#if USB_AUDIO + if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) + { + switch (SetupPacket.bRequest) + { + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + if (ADC_IF_SetRequest ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_AUDIO */ +#if USB_CDC + if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM)) + { + switch (SetupPacket.bRequest) + { + case CDC_SEND_ENCAPSULATED_COMMAND: + if (CDC_SendEncapsulatedCommand ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + case CDC_SET_COMM_FEATURE: + if (CDC_SetCommFeature (SetupPacket.wValue.W)) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + case CDC_SET_LINE_CODING: + if (CDC_SetLineCoding ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_CDC */ + goto stall_i; + /* end case REQUEST_TO_INTERFACE */ + + case REQUEST_TO_ENDPOINT: +#if USB_AUDIO + switch (SetupPacket.bRequest) + { + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + if (ADC_EP_SetRequest ()) + { + USB_StatusInStage (); /* send Acknowledge */ + goto out_class_ok; + } + break; + } +#endif /* USB_AUDIO */ + goto stall_i; + /* end case REQUEST_TO_ENDPOINT */ + + default: + goto stall_i; + } + out_class_ok: /* request finished successfully */ + break; /* end case REQUEST_CLASS */ +#endif /* USB_CLASS */ + +#if USB_VENDOR + case REQUEST_VENDOR: + switch (SetupPacket.bmRequestType.BM.Recipient) + { + + case REQUEST_TO_DEVICE: + if (!USB_ReqVendorDev (FALSE)) + { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_INTERFACE: + if (!USB_ReqVendorIF (FALSE)) + { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_ENDPOINT: + if (!USB_ReqVendorEP (FALSE)) + { + goto stall_i; /* not supported */ + } + break; + + default: + goto stall_i; + } + + USB_StatusInStage (); + + break; /* end case REQUEST_VENDOR */ +#endif /* USB_VENDOR */ + + default: + goto stall_i; + } + } + } + } + else + { + USB_StatusOutStage (); /* receive Acknowledge */ + } + break; /* end case USB_EVT_OUT */ + + case USB_EVT_IN: + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST) + { + USB_DataInStage (); /* send data */ + } + else + { + if (USB_DeviceAddress & 0x80) + { + USB_DeviceAddress &= 0x7F; + USB_SetAddress (USB_DeviceAddress); + } + } + break; /* end case USB_EVT_IN */ + + case USB_EVT_OUT_STALL: + USB_ClrStallEP (0x00); + break; + + case USB_EVT_IN_STALL: + USB_ClrStallEP (0x80); + break; + + } +} diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/usbhw.c b/openbeacon/lpc13xx/usbcdc-storage/src/usbhw.c new file mode 100644 index 0000000..9687921 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/src/usbhw.c @@ -0,0 +1,630 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbhw.c + * Purpose: USB Hardware Layer Module for Philips LPC17xx + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added USB_ClearEPBuf + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ +#include "LPC13xx.h" /* LPC13xx definitions */ +#include "usb.h" +#include "usbcfg.h" +#include "usbreg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbuser.h" + + +/* + * USB and IO Clock configuration only. + * The same as call PeriClkIOInit(IOCON_USB); + * The purpose is to reduce the code space for + * overall USB project and reserve code space for + * USB debugging. + * Parameters: None + * Return Value: None + */ +void +USBIOClkConfig (void) +{ + /* Enable AHB clock to the GPIO domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6); + + LPC_IOCON->PIO0_1 &= ~0x07; + LPC_IOCON->PIO0_1 |= 0x01; /* CLK OUT */ + + /* Enable AHB clock to the USB block. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 14); + LPC_IOCON->PIO0_3 &= ~0x1F; + LPC_IOCON->PIO0_3 |= 0x01; /* Secondary function VBUS */ + LPC_IOCON->PIO0_6 &= ~0x07; + LPC_IOCON->PIO0_6 |= 0x01; /* Secondary function SoftConn */ + return; +} + +/* + * Delay number of clock cycles + * Parameters: Delay length + * Return Value: None + */ + +void +delay (uint32_t length) +{ + uint32_t i; + + for (i = 0; i < length; i++); + return; +} + +/* + * Get Endpoint Physical Address + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: Endpoint Physical Address + */ + +uint32_t +EPAdr (uint32_t EPNum) +{ + uint32_t val; + + val = (EPNum & 0x0F) << 1; + if (EPNum & 0x80) + { + val += 1; + } + return (val); +} + + +/* + * Write Command + * Parameters: cmd: Command + * Return Value: None + */ + +void +WrCmd (uint32_t cmd) +{ + + LPC_USB->DevIntClr = CCEMTY_INT; + LPC_USB->CmdCode = cmd; + while ((LPC_USB->DevIntSt & (CCEMTY_INT | DEV_STAT_INT)) == 0); +} + + +/* + * Write Command Data + * Parameters: cmd: Command + * val: Data + * Return Value: None + */ + +void +WrCmdDat (uint32_t cmd, uint32_t val) +{ + + WrCmd (cmd); + WrCmd (val); +} + + +/* + * Write Command to Endpoint + * Parameters: cmd: Command + * val: Data + * Return Value: None + */ + +void +WrCmdEP (uint32_t EPNum, uint32_t cmd) +{ + + WrCmd (CMD_SEL_EP (EPAdr (EPNum))); + WrCmd (cmd); +} + + +/* + * Read Command Data + * Parameters: cmd: Command + * Return Value: Data Value + */ + +uint32_t +RdCmdDat (uint32_t cmd) +{ + + LPC_USB->DevIntClr = CCEMTY_INT | CDFULL_INT; + LPC_USB->CmdCode = cmd; + while ((LPC_USB->DevIntSt & (CDFULL_INT | DEV_STAT_INT)) == 0); + return (LPC_USB->CmdData); +} + + +/* + * USB Initialize Function + * Called by the User to initialize USB + * Return Value: None + */ + +void +USB_Init (void) +{ + +#if USB_FIQ_EVENT + /* It's important that only BULK and FRAME(ISO) can be routed + to FIQ. */ + LPC_USB->DevFIQSel = 0x01; /* SOF Use FIQ */ + + /* Enable the USB Interrupt */ + NVIC_EnableIRQ (USB_FIQn); +#endif + + /* Enable the USB Interrupt */ + NVIC_EnableIRQ (USB_IRQn); + + USB_Reset (); + USB_SetAddress (0); + return; +} + + +/* + * USB Connect Function + * Called by the User to Connect/Disconnect USB + * Parameters: con: Connect/Disconnect + * Return Value: None + */ + +void +USB_Connect (uint32_t con) +{ + WrCmdDat (CMD_SET_DEV_STAT, DAT_WR_BYTE (con ? DEV_CON : 0)); +} + + +/* + * USB Reset Function + * Called automatically on USB Reset + * Return Value: None + */ + +void +USB_Reset (void) +{ + + LPC_USB->DevIntClr = 0x000FFFFF; + /* Enable all eight(8) EPs, note: EP won't be ready until it's + configured/enabled when device sending SetEPStatus command + to the command engine. */ + LPC_USB->DevIntEn = DEV_STAT_INT | (0xFF << 1) | (USB_SOF_EVENT ? FRAME_INT : 0); + return; +} + + +/* + * USB Suspend Function + * Called automatically on USB Suspend + * Return Value: None + */ + +void +USB_Suspend (void) +{ + /* Performed by Hardware */ +} + + +/* + * USB Resume Function + * Called automatically on USB Resume + * Return Value: None + */ + +void +USB_Resume (void) +{ + /* Performed by Hardware */ +} + + +/* + * USB Remote Wakeup Function + * Called automatically on USB Remote Wakeup + * Return Value: None + */ + +void +USB_WakeUp (void) +{ + if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP) + { + WrCmdDat (CMD_SET_DEV_STAT, DAT_WR_BYTE (DEV_CON)); + } +} + + +/* + * USB Remote Wakeup Configuration Function + * Parameters: cfg: Enable/Disable + * Return Value: None + */ + +void +USB_WakeUpCfg (uint32_t cfg) +{ + cfg = cfg; /* Not needed */ +} + + +/* + * USB Set Address Function + * Parameters: adr: USB Address + * Return Value: None + */ + +void +USB_SetAddress (uint32_t adr) +{ + WrCmdDat (CMD_SET_ADDR, DAT_WR_BYTE (DEV_EN | adr)); /* Don't wait for next */ + WrCmdDat (CMD_SET_ADDR, DAT_WR_BYTE (DEV_EN | adr)); /* Setup Status Phase */ +} + + +/* + * USB Configure Function + * Parameters: cfg: Configure/Deconfigure + * Return Value: None + */ + +void +USB_Configure (uint32_t cfg) +{ + WrCmdDat (CMD_CFG_DEV, DAT_WR_BYTE (cfg ? CONF_DVICE : 0)); + return; +} + + +/* + * Configure USB Endpoint according to Descriptor + * Parameters: pEPD: Pointer to Endpoint Descriptor + * Return Value: None + */ + +void +USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD) +{ + (void)pEPD; +} + + +/* + * Set Direction for USB Control Endpoint + * Parameters: dir: Out (dir == 0), In (dir <> 0) + * Return Value: None + */ + +void +USB_DirCtrlEP (uint32_t dir) +{ + (void)dir; +} + + +/* + * Enable USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_EnableEP (uint32_t EPNum) +{ + WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0)); +} + + +/* + * Disable USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_DisableEP (uint32_t EPNum) +{ + WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (EP_STAT_DA)); +} + + +/* + * Reset USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_ResetEP (uint32_t EPNum) +{ + WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0)); +} + + +/* + * Set Stall for USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_SetStallEP (uint32_t EPNum) +{ + WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (EP_STAT_ST)); +} + + +/* + * Clear Stall for USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_ClrStallEP (uint32_t EPNum) +{ + WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0)); +} + + +/* + * Clear USB Endpoint Buffer + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void +USB_ClearEPBuf (uint32_t EPNum) +{ + WrCmdEP (EPNum, CMD_CLR_BUF); +} + + +/* + * Read USB Endpoint Data + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * pData: Pointer to Data Buffer + * Return Value: Number of bytes read + */ + +uint32_t +USB_ReadEP (uint32_t EPNum, uint8_t * pData) +{ + uint32_t cnt, n; + + LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_RD_EN; + /* 3 clock cycles to fetch the packet length from RAM. */ + delay (5); + + do + { + cnt = LPC_USB->RxPLen; + } + while ((cnt & PKT_DV) == 0); + cnt &= PKT_LNGTH_MASK; + + for (n = 0; n < (cnt + 3) / 4; n++) + { + *((uint32_t __attribute__ ((packed)) *) pData) = LPC_USB->RxData; + pData += 4; + } + + LPC_USB->Ctrl = 0; + + if ((EPNum & 0x80) != 0x04) + { /* Non-Isochronous Endpoint */ + WrCmdEP (EPNum, CMD_CLR_BUF); + } + + return (cnt); +} + + +/* + * Write USB Endpoint Data + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * pData: Pointer to Data Buffer + * cnt: Number of bytes to write + * Return Value: Number of bytes written + */ + +uint32_t +USB_WriteEP (uint32_t EPNum, uint8_t * pData, uint32_t cnt) +{ + uint32_t n; + + LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN; + /* 3 clock cycles to fetch the packet length from RAM. */ + delay (5); + LPC_USB->TxPLen = cnt; + + for (n = 0; n < (cnt + 3) / 4; n++) + { + LPC_USB->TxData = *((uint32_t __attribute__ ((packed)) *) pData); + pData += 4; + } + + LPC_USB->Ctrl = 0; + + WrCmdEP (EPNum, CMD_VALID_BUF); + + return (cnt); +} + +/* + * Get USB Last Frame Number + * Parameters: None + * Return Value: Frame Number + */ + +uint32_t +USB_GetFrame (void) +{ + uint32_t val; + + WrCmd (CMD_RD_FRAME); + val = RdCmdDat (DAT_RD_FRAME); + val = val | (RdCmdDat (DAT_RD_FRAME) << 8); + + return (val); +} + + +/* + * USB Interrupt Service Routine + */ + +void +USB_IRQHandler (void) +{ + uint32_t disr, val, n, m; + + disr = LPC_USB->DevIntSt; /* Device Interrupt Status */ + LPC_USB->DevIntClr = disr; + + /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */ + if (disr & DEV_STAT_INT) + { + WrCmd (CMD_GET_DEV_STAT); + val = RdCmdDat (DAT_GET_DEV_STAT); /* Device Status */ + if (val & DEV_RST) + { /* Reset */ + USB_Reset (); +#if USB_RESET_EVENT + USB_Reset_Event (); +#endif + } + if (val & DEV_CON_CH) + { /* Connect change */ +#if USB_POWER_EVENT + USB_Power_Event (val & DEV_CON); +#endif + } + if (val & DEV_SUS_CH) + { /* Suspend/Resume */ + if (val & DEV_SUS) + { /* Suspend */ + USB_Suspend (); +#if USB_SUSPEND_EVENT + USB_Suspend_Event (); +#endif + } + else + { /* Resume */ + USB_Resume (); +#if USB_RESUME_EVENT + USB_Resume_Event (); +#endif + } + } + goto isr_end; + } + +#if USB_SOF_EVENT + /* Start of Frame Interrupt */ + if (disr & FRAME_INT) + { + LPC_USB->DevIntClr = FRAME_INT; + USB_SOF_Event (); + SOFIRQCount++; + } +#endif + +#if USB_ERROR_EVENT + /* NO error interrupt anymore, below code can be used + as example to get error status from command engine. */ + /* Error Interrupt */ + if (disr & ERR_INT) + { + WrCmd (CMD_RD_ERR_STAT); + val = RdCmdDat (DAT_RD_ERR_STAT); + USB_Error_Event (val); + } +#endif + + /* Endpoint's Interrupt */ + if (disr & (0xFF << 1)) + { + /* if any of the EP0 through EP7 is set, or bit 1 through 9 on disr */ + for (n = 0; n < USB_EP_NUM; n++) + { /* Check All Endpoints */ + /* skip frame interrupt at bit 0 in disr */ +// if (disr & ((1 << n)<<1)) { + if ((disr >> 1) & (1 << n)) + { + m = n >> 1; + /* clear EP interrupt by sending cmd to the command engine. */ + WrCmd (CMD_SEL_EP_CLRI (n)); + val = RdCmdDat (DAT_SEL_EP_CLRI (n)); + if ((n & 1) == 0) + { /* OUT Endpoint */ + if (n == 0) + { /* Control OUT Endpoint */ + if (val & EP_SEL_STP) + { /* Setup Packet */ + if (USB_P_EP[0]) + { + USB_P_EP[0] (USB_EVT_SETUP); + continue; + } + } + } + if (USB_P_EP[m]) + { + USB_P_EP[m] (USB_EVT_OUT); + } + } + else + { /* IN Endpoint */ + if (USB_P_EP[m]) + { + USB_P_EP[m] (USB_EVT_IN); + } + } + } + } + } +isr_end: + return; +} diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/usbuser.c b/openbeacon/lpc13xx/usbcdc-storage/src/usbuser.c new file mode 100644 index 0000000..370f088 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc-storage/src/usbuser.c @@ -0,0 +1,242 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbuser.c + * Purpose: USB Custom User Module + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ +#include "type.h" + +#include "usb.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbuser.h" +#include "cdcuser.h" +#include "mscuser.h" +#include "memory.h" + + +/* + * USB Power Event Callback + * Called automatically on USB Power Event + * Parameter: power: On(TRUE)/Off(FALSE) + */ + +#if USB_POWER_EVENT +void +USB_Power_Event (uint32_t power) +{ +} +#endif + + +/* + * USB Reset Event Callback + * Called automatically on USB Reset Event + */ + +#if USB_RESET_EVENT +void +USB_Reset_Event (void) +{ + USB_ResetCore (); +} +#endif + + +/* + * USB Suspend Event Callback + * Called automatically on USB Suspend Event + */ + +#if USB_SUSPEND_EVENT +void +USB_Suspend_Event (void) +{ +} +#endif + + +/* + * USB Resume Event Callback + * Called automatically on USB Resume Event + */ + +#if USB_RESUME_EVENT +void +USB_Resume_Event (void) +{ +} +#endif + + +/* + * USB Remote Wakeup Event Callback + * Called automatically on USB Remote Wakeup Event + */ + +#if USB_WAKEUP_EVENT +void +USB_WakeUp_Event (void) +{ +} +#endif + + +/* + * USB Start of Frame Event Callback + * Called automatically on USB Start of Frame Event + */ + +#if USB_SOF_EVENT +void +USB_SOF_Event (void) +{ +} +#endif + + +/* + * USB Error Event Callback + * Called automatically on USB Error Event + * Parameter: error: Error Code + */ + +#if USB_ERROR_EVENT +void +USB_Error_Event (uint32_t error) +{ +} +#endif + + +/* + * USB Set Configuration Event Callback + * Called automatically on USB Set Configuration Request + */ + +#if USB_CONFIGURE_EVENT +void +USB_Configure_Event (void) +{ + + if (USB_Configuration) + { /* Check if USB is configured */ + /* add your code here */ + } +} +#endif + + +/* + * USB Set Interface Event Callback + * Called automatically on USB Set Interface Request + */ + +#if USB_INTERFACE_EVENT +void +USB_Interface_Event (void) +{ +} +#endif + + +/* + * USB Set/Clear Feature Event Callback + * Called automatically on USB Set/Clear Feature Request + */ + +#if USB_FEATURE_EVENT +void +USB_Feature_Event (void) +{ +} +#endif + + +#define P_EP(n) ((USB_EP_EVENT & (1 << (n))) ? USB_EndPoint##n : NULL) + +/* USB Endpoint Events Callback Pointers */ +void (*const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event) = +{ +P_EP (0), P_EP (1), P_EP (2), P_EP (3), P_EP (4),}; + + +/* + * USB Endpoint 1 Event Callback + * Called automatically on USB Endpoint 1 Event + * Parameter: event + */ + +void +USB_EndPoint1 (uint32_t event) +{ + uint16_t temp; + static uint16_t serialState; + + switch (event) + { + case USB_EVT_IN: + temp = CDC_GetSerialState (); + if (serialState != temp) + { + serialState = temp; + CDC_NotificationIn (); /* send SERIAL_STATE notification */ + } + break; + } +} + + +/* + * USB Endpoint 2 Event Callback + * Called automatically on USB Endpoint 2 Event + * Parameter: event + */ + +void +USB_EndPoint2 (uint32_t event) +{ + + switch (event) + { + case USB_EVT_OUT: + MSC_BulkOut (); + break; + case USB_EVT_IN: + MSC_BulkIn (); + break; + } +} + + +/* + * USB Endpoint 3 Event Callback + * Called automatically on USB Endpoint 3 Event + * Parameter: event + */ + +void +USB_EndPoint3 (uint32_t event) +{ + switch (event) + { + case USB_EVT_OUT: + CDC_BulkOut (); /* data received from Host */ + break; + case USB_EVT_IN: + CDC_BulkIn (); /* data expected from Host */ + break; + } +} diff --git a/openbeacon/lpc13xx/usbcdc/Makefile b/openbeacon/lpc13xx/usbcdc/Makefile new file mode 100644 index 0000000..20e0a1a --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc/Makefile @@ -0,0 +1,20 @@ +TARGET=usbcdc +ARCH=LPC13 +CPU=$(ARCH)42 +DEBUG=-g +OPTIM=-Os -mword-relocations + +APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS +APP_LDFLAGS=-lm + +APP_SRC= \ + src/main.c \ + +APP_SRC+=$(IMAGES_C) + +all: $(TARGET).bin + +app_clean: + find src -name '*.o' -exec rm \{\} \; + +include ../core/Makefile.rules diff --git a/openbeacon/lpc13xx/usbcdc/inc/FreeRTOSConfig.h b/openbeacon/lpc13xx/usbcdc/inc/FreeRTOSConfig.h new file mode 100644 index 0000000..ef4ba7f --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc/inc/FreeRTOSConfig.h @@ -0,0 +1,104 @@ +/* + FreeRTOS V6.0.0 - Copyright (C) 2009 Real Time Engineers Ltd. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/****************************************************************************** + See http://www.freertos.org/a00110.html for an explanation of the + definitions contained in this file. +******************************************************************************/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "LPC13xx.h" + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) SystemCoreClock ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 100 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_CO_ROUTINES 0 +#define configUSE_MUTEXES 1 + +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configQUEUE_REGISTRY_SIZE 0 +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_MALLOC_FAILED_HOOK 0 + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 + +/* Use the system definition, if there is one */ +#ifdef __NVIC_PRIO_BITS + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 5 /* 32 priority levels */ +#endif + +/* The lowest priority. */ +#define configKERNEL_INTERRUPT_PRIORITY ( 31 << (8 - configPRIO_BITS) ) +/* Priority 5, or 160 as only the top three bits are implemented. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - configPRIO_BITS) ) + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/openbeacon/lpc13xx/usbcdc/inc/config.h b/openbeacon/lpc13xx/usbcdc/inc/config.h new file mode 100644 index 0000000..3d76055 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc/inc/config.h @@ -0,0 +1,43 @@ +/*************************************************************** + * + * OpenBeacon.org - config file + * + * Copyright 2010 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#define LED_PORT 1 /* Port for led */ +#define LED_BIT 9 /* Bit on port for led */ +#define LED_ON 1 /* Level to set port to turn on led */ +#define LED_OFF 0 /* Level to set port to turn off led */ + +/* USB device settings */ +#define ENALBLE_USB_FULLFEATURED +#define USB_VENDOR_ID 0x2366 +#define USB_PROD_ID 0x0003 +#define USB_DEVICE 0x0100 + +/* FreeRTOS configuration */ +#define ENABLE_FREERTOS +#define TASK_SERIAL_STACK_SIZE 64 +#define TASK_SERIAL_PRIORITY (tskIDLE_PRIORITY + 2) + +#endif/*__CONFIG_H__*/ diff --git a/openbeacon/lpc13xx/usbcdc/inc/usbcfg.h b/openbeacon/lpc13xx/usbcdc/inc/usbcfg.h new file mode 100644 index 0000000..8fef7c2 --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc/inc/usbcfg.h @@ -0,0 +1,157 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcfg.h + * Purpose: USB Custom Configuration + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added vendor specific support + * V1.00 Initial Version + *---------------------------------------------------------------------------*/ + +#ifndef __USBCFG_H__ +#define __USBCFG_H__ + + +//*** <<< Use Configuration Wizard in Context Menu >>> *** + + +/* +// USB Configuration +// USB Power +// Default Power Setting +// <0=> Bus-powered +// <1=> Self-powered +// Max Number of Interfaces <1-256> +// Max Number of Endpoints <1-32> +// Max Endpoint 0 Packet Size +// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes +// DMA Transfer +// Use DMA for selected Endpoints +// Endpoint 0 Out +// Endpoint 0 In +// Endpoint 1 Out +// Endpoint 1 In +// Endpoint 2 Out +// Endpoint 2 In +// Endpoint 3 Out +// Endpoint 3 In +// Endpoint 4 Out +// Endpoint 4 In +// +// +*/ + +#define USB_POWER 0 +#define USB_IF_NUM 1 +#define USB_LOGIC_EP_NUM 5 +#define USB_EP_NUM 10 +#define USB_MAX_PACKET0 64 + +/* +// USB Event Handlers +// Device Events +// Power Event +// Reset Event +// Suspend Event +// Resume Event +// Remote Wakeup Event +// Start of Frame Event +// Error Event +// +// Endpoint Events +// Endpoint 0 Event +// Endpoint 1 Event +// Endpoint 2 Event +// Endpoint 3 Event +// Endpoint 4 Event +// Endpoint 5 Event +// Endpoint 6 Event +// Endpoint 7 Event +// Endpoint 8 Event +// Endpoint 9 Event +// Endpoint 10 Event +// Endpoint 11 Event +// Endpoint 12 Event +// Endpoint 13 Event +// Endpoint 14 Event +// Endpoint 15 Event +// +// USB Core Events +// Set Configuration Event +// Set Interface Event +// Set/Clear Feature Event +// +// +*/ + +#define USB_POWER_EVENT 0 +#define USB_RESET_EVENT 1 +#define USB_SUSPEND_EVENT 1 +#define USB_RESUME_EVENT 1 +#define USB_WAKEUP_EVENT 0 +#define USB_SOF_EVENT 0 +#define USB_ERROR_EVENT 0 +#define USB_EP_EVENT 0x000B +#define USB_CONFIGURE_EVENT 1 +#define USB_INTERFACE_EVENT 0 +#define USB_FEATURE_EVENT 0 + + +/* +// USB Class Support +// enables USB Class specific Requests +// Human Interface Device (HID) +// Interface Number <0-255> +// +// Mass Storage +// Interface Number <0-255> +// +// Audio Device +// Control Interface Number <0-255> +// Streaming Interface 1 Number <0-255> +// Streaming Interface 2 Number <0-255> +// +// Communication Device +// Control Interface Number <0-255> +// Bulk Interface Number <0-255> +// Max Communication Device Buffer Size +// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes +// +// +*/ + +#define USB_CLASS 1 +#define USB_HID 0 +#define USB_HID_IF_NUM 0 +#define USB_MSC 0 +#define USB_MSC_IF_NUM 0 +#define USB_AUDIO 0 +#define USB_ADC_CIF_NUM 0 +#define USB_ADC_SIF1_NUM 1 +#define USB_ADC_SIF2_NUM 2 +#define USB_CDC 1 +#define USB_CDC_CIF_NUM 0 +#define USB_CDC_DIF_NUM 1 +#define USB_CDC_BUFSIZE 64 + +/* +// USB Vendor Support +// enables USB Vendor specific Requests +// +*/ +#define USB_VENDOR 0 + + +#endif /* __USBCFG_H__ */ diff --git a/openbeacon/lpc13xx/usbcdc/lpc134x-vcom.inf b/openbeacon/lpc13xx/usbcdc/lpc134x-vcom.inf new file mode 100644 index 0000000..f1f919f --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc/lpc134x-vcom.inf @@ -0,0 +1,65 @@ +; +; Keil - An ARM Company Comunication Device Class driver installation file +; (C)2007 Copyright +; + +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%Keil% +;LayoutFile=layout.inf +DriverVer=01/06/07 + +[Manufacturer] +%Keil%=DeviceList + +[DestinationDirs] +DefaultDestDir=12 + +[SourceDisksFiles] + +[SourceDisksNames] + +[DeviceList] +%DESCRIPTION%=LPC134xUSB, USB\VID_1FC9&PID_0003 + +;------------------------------------------------------------------------------ +; Windows 2000/XP Sections +;------------------------------------------------------------------------------ + +[LPC134xUSB.nt] +include=mdmcpq.inf +CopyFiles=DriverCopyFiles +AddReg=LPC134xUSB.nt.AddReg + +[DriverCopyFiles] +usbser.sys,,,0x20 + +[LPC134xUSB.nt.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,usbser.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[LPC134xUSB.nt.Services] +include=mdmcpq.inf +AddService=usbser, 0x00000002, DriverService + + +[LPC134xUSB.nt.HW] +include=mdmcpq.inf + +[DriverService] +DisplayName=%DESCRIPTION% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\usbser.sys + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ + +[Strings] +NXP="NXP - Founded by Philips" +DESCRIPTION="LPC134x USB VCom Port" diff --git a/openbeacon/lpc13xx/usbcdc/readme.txt b/openbeacon/lpc13xx/usbcdc/readme.txt new file mode 100644 index 0000000..37aa02c --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc/readme.txt @@ -0,0 +1,36 @@ +usbcdc +===================== +This project contains an CDC USB example for the LPCXpresso board +mounted with an LPC1343 Cortex-M3 part. + +To run this example, you must attach a USB cable to the board. See +the "Getting Started Guide" appendix for details. You may also +connect the LPCXpresso board to a base board from a 3rd party tool +partner. + +When downloaded to the board and executed, the PC will recognize +a USB "VCOM" device. Point windows to the .inf file in the usbcdc +project directory. Windows should install the default UART driver. +At this point, you should be able to send characters into the USB +virtual COM port and have them transmitted out of the serial port +on the LPC1343. The transmit baud rate will equal the CDC port +configured baud rate. + +One thing we have seen that can cause trouble with the USB examples +is the Windows driver install. Since the example projects all use +the same USB Vendor ID and Product ID, if you try out the HID +example and then try out the CDC example, Windows may try +to use the HID driver it had already installed with the CDC +example code. To fix this, go to the Windows Device Manager, +find the broken "HID" device and select "Uninstall." Then unplug the +device and plug it back in. Windows should correctly identify the +device as being a CDC device and install the correct +driver. + +The project makes use of code from the following library projects: +- CMSISv1p30_LPC13xx : for CMSIS 1.30 files relevant to LPC13xx + +This library project must exist in the same workspace in order +for the project to successfully build. + +For more details, read the comments in config.h diff --git a/openbeacon/lpc13xx/usbcdc/src/main.c b/openbeacon/lpc13xx/usbcdc/src/main.c new file mode 100644 index 0000000..5956b1f --- /dev/null +++ b/openbeacon/lpc13xx/usbcdc/src/main.c @@ -0,0 +1,102 @@ +/*************************************************************** + * + * OpenBeacon.org - USB CDC + FreeRTOS Pipes Demo + * + * Copyright 2011 Milosch Meriac + * + *************************************************************** + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ + +#include + +static BOOL vTasksRunning = FALSE; + +/* + * overwrite default_putchar with USB CDC ACM + * output to enable USB support for debug_printf + */ +BOOL default_putchar(uint8_t data) +{ + if (vTasksRunning) + CDC_PutChar (data); + /* always send out over serial port as well */ + UARTSendChar (data); + + return TRUE; +} + +static void serial_task(void *handle) +{ + int i; + (void) handle; + portCHAR data; + + vTasksRunning = TRUE; + + i = 0; + for (;;) + { + debug_printf("%04i: Hello Task! (%04i bytes free heap memory)\n", i++, + xPortGetFreeHeapSize()); + + GPIOSetValue(LED_PORT, LED_BIT, LED_ON); + vTaskDelay(10 / portTICK_RATE_MS); + GPIOSetValue(LED_PORT, LED_BIT, LED_OFF); + + while (CDC_Recv(&data, sizeof(data), 990)) + UARTSendChar(data); + } +} + +int main(void) +{ + /* Enable CT32B1 Timer, IOCON, and USB */ + LPC_SYSCON->SYSAHBCLKCTRL |= (EN_CT32B1 | EN_USB_REG | EN_IOCON); + + /* Initialize GPIO */ + GPIOInit(); + /* Set LED port pin to output */ + GPIOSetDir(LED_PORT, LED_BIT, 1); + GPIOSetValue(LED_PORT, LED_BIT, 0); + + /* CDC Initialization */ + CDC_Init(); + /* USB Initialization */ + USB_Init(); + /* Connect to USB port */ + USB_Connect(1); + + /* Update System Core Clock Value */ + SystemCoreClockUpdate(); + + /* NVIC is installed inside UARTInit file. */ + UARTInit(115200, 0); + + /* the following text is printed on the serial port as vTasksRunning + * is not yet set to TRUE in serial_task - which will redirect + * debug output to the CDC ACM USB serial device. + */ + debug_printf("Hello World!\n"); + + /* Create CDC ACM task */ + xTaskCreate(serial_task, (const signed char*) "Serial", TASK_SERIAL_STACK_SIZE, NULL, TASK_SERIAL_PRIORITY, NULL); + + /* Start the tasks running. */ + vTaskStartScheduler(); + + return 0; +}