From 90df9b0b00f419ea3b054439d5dbd12149567efc Mon Sep 17 00:00:00 2001 From: kh4 Date: Sun, 27 Jan 2013 13:26:15 +0200 Subject: [PATCH] Fix lenefeeds to LF (this mostly matters for Linux/OSC users). --- AeroQuad/AeroQuad.h | 2 +- AeroQuad/AeroQuad.ino | 2 +- AeroQuad/AltitudeControlProcessor.h | 2 +- AeroQuad/DataStorage.h | 2 +- AeroQuad/FlightCommandProcessor.h | 2 +- AeroQuad/FlightControlProcessor.h | 2 +- AeroQuad/GpsNavigator.h | 2 +- AeroQuad/HeadingHoldProcessor.h | 2 +- AeroQuad/MavLink.h | 2 +- AeroQuad/OSDDisplayController.h | 2 +- AeroQuad/OSDMenu.h | 1866 +- AeroQuad/PID.h | 2 +- AeroQuad/SerialCom.h | 2 +- AeroQuad/UserConfiguration.h | 2 +- AeroQuad32/AeroQuadMain.cpp | 62 +- AeroQuad32/AeroQuad_STM32.h | 78 +- AeroQuad32/MapleCompatibility/Arduino.h | 8 +- AeroQuad32/MapleCompatibility/EEPROM.cpp | 1096 +- AeroQuad32/MapleCompatibility/EEPROM.h | 198 +- AeroQuad32/MapleCompatibility/WProgram.h | 106 +- AeroQuad32/MapleCompatibility/flash_stm32.c | 12 +- AeroQuad32/MapleCompatibility/flash_stm32.h | 72 +- AeroQuad32/MapleCompatibility/flash_stm32F1.c | 406 +- AeroQuad32/MapleCompatibility/flash_stm32F2.c | 622 +- AeroQuad32/MapleCompatibility/pins_arduino.h | 2 +- AeroQuad32/SerialMapping.h | 24 +- AeroQuad32/platform_aeroquad32.h | 306 +- AeroQuad32/platform_discoveryf4.h | 274 +- AeroQuad32/platform_freeflight.h | 268 +- BuildAQ32/Makefile | 1552 +- BuildAQ32/ReadMe.txt | 24 +- Libmaple/libmaple/.dir-locals.el | 10 +- Libmaple/libmaple/.gdbinit | 18 +- Libmaple/libmaple/.gitignore | 20 +- Libmaple/libmaple/LICENSE | 200 +- Libmaple/libmaple/Makefile | 430 +- Libmaple/libmaple/README | 268 +- Libmaple/libmaple/build-targets.mk | 86 +- .../libmaple/contrib/automake/Makefile.am | 276 +- .../libmaple/contrib/automake/configure.ac | 16 +- Libmaple/libmaple/examples/blinky.cpp | 64 +- Libmaple/libmaple/examples/debug-dtrrts.cpp | 80 +- .../libmaple/examples/freertos-blinky.cpp | 86 +- .../libmaple/examples/fsmc-stress-test.cpp | 458 +- Libmaple/libmaple/examples/mini-exti-test.cpp | 502 +- .../libmaple/examples/qa-slave-shield.cpp | 132 +- Libmaple/libmaple/examples/spi_master.cpp | 154 +- Libmaple/libmaple/examples/test-bkp.cpp | 160 +- Libmaple/libmaple/examples/test-dac.cpp | 102 +- Libmaple/libmaple/examples/test-fsmc.cpp | 252 +- Libmaple/libmaple/examples/test-print.cpp | 368 +- .../examples/test-ring-buffer-insertion.cpp | 228 +- .../libmaple/examples/test-serial-flush.cpp | 76 +- Libmaple/libmaple/examples/test-serialusb.cpp | 252 +- Libmaple/libmaple/examples/test-servo.cpp | 304 +- Libmaple/libmaple/examples/test-session.cpp | 1850 +- .../libmaple/examples/test-spi-roundtrip.cpp | 384 +- Libmaple/libmaple/examples/test-systick.cpp | 98 +- Libmaple/libmaple/examples/test-timers.cpp | 594 +- Libmaple/libmaple/examples/test-usart-dma.cpp | 246 +- Libmaple/libmaple/examples/vga-leaf.cpp | 488 +- Libmaple/libmaple/examples/vga-scope.cpp | 410 +- Libmaple/libmaple/libmaple/adc.c | 400 +- Libmaple/libmaple/libmaple/adc.h | 794 +- Libmaple/libmaple/libmaple/bitband.h | 240 +- Libmaple/libmaple/libmaple/bkp.c | 258 +- Libmaple/libmaple/libmaple/bkp.h | 332 +- Libmaple/libmaple/libmaple/dac.c | 310 +- Libmaple/libmaple/libmaple/dac.h | 338 +- Libmaple/libmaple/libmaple/delay.h | 88 +- Libmaple/libmaple/libmaple/dma.c | 72 +- Libmaple/libmaple/libmaple/dma.h | 74 +- Libmaple/libmaple/libmaple/dmaF1.c | 758 +- Libmaple/libmaple/libmaple/dmaF1.h | 906 +- Libmaple/libmaple/libmaple/dmaF2.c | 476 +- Libmaple/libmaple/libmaple/dmaF2.h | 540 +- Libmaple/libmaple/libmaple/exc.S | 208 +- Libmaple/libmaple/libmaple/exti.c | 438 +- Libmaple/libmaple/libmaple/exti.h | 156 +- Libmaple/libmaple/libmaple/flash.c | 120 +- Libmaple/libmaple/libmaple/flash.h | 284 +- Libmaple/libmaple/libmaple/fsmc.c | 186 +- Libmaple/libmaple/libmaple/fsmc.h | 640 +- Libmaple/libmaple/libmaple/gpio.c | 72 +- Libmaple/libmaple/libmaple/gpio.h | 76 +- Libmaple/libmaple/libmaple/gpioF1.c | 392 +- Libmaple/libmaple/libmaple/gpioF1.h | 1060 +- Libmaple/libmaple/libmaple/gpioF2.c | 416 +- Libmaple/libmaple/libmaple/gpioF2.h | 1100 +- Libmaple/libmaple/libmaple/i2c.c | 1130 +- Libmaple/libmaple/libmaple/i2c.h | 696 +- Libmaple/libmaple/libmaple/iwdg.c | 124 +- Libmaple/libmaple/libmaple/iwdg.h | 232 +- Libmaple/libmaple/libmaple/libmaple.h | 120 +- Libmaple/libmaple/libmaple/libmaple_types.h | 112 +- Libmaple/libmaple/libmaple/nvic.c | 170 +- Libmaple/libmaple/libmaple/nvic.h | 482 +- Libmaple/libmaple/libmaple/pwr.c | 82 +- Libmaple/libmaple/libmaple/pwr.h | 170 +- Libmaple/libmaple/libmaple/rcc.c | 74 +- Libmaple/libmaple/libmaple/rcc.h | 72 +- Libmaple/libmaple/libmaple/rccF1.c | 456 +- Libmaple/libmaple/libmaple/rccF1.h | 1144 +- Libmaple/libmaple/libmaple/rccF2.c | 1366 +- Libmaple/libmaple/libmaple/rccF2.h | 1200 +- Libmaple/libmaple/libmaple/ring_buffer.h | 378 +- Libmaple/libmaple/libmaple/rules.mk | 186 +- Libmaple/libmaple/libmaple/scb.h | 130 +- Libmaple/libmaple/libmaple/spi.c | 516 +- Libmaple/libmaple/libmaple/spi.h | 918 +- Libmaple/libmaple/libmaple/stm32.h | 440 +- Libmaple/libmaple/libmaple/syscalls.c | 334 +- Libmaple/libmaple/libmaple/systick.c | 182 +- Libmaple/libmaple/libmaple/systick.h | 234 +- Libmaple/libmaple/libmaple/timer.c | 960 +- Libmaple/libmaple/libmaple/timer.h | 2054 +- Libmaple/libmaple/libmaple/usart.c | 588 +- Libmaple/libmaple/libmaple/usart.h | 712 +- Libmaple/libmaple/libmaple/usb/README | 200 +- Libmaple/libmaple/libmaple/usb/descriptors.c | 398 +- Libmaple/libmaple/libmaple/usb/descriptors.h | 450 +- Libmaple/libmaple/libmaple/usb/usb.c | 976 +- Libmaple/libmaple/libmaple/usb/usb.h | 184 +- .../libmaple/libmaple/usb/usb_callbacks.c | 664 +- .../libmaple/libmaple/usb/usb_callbacks.h | 150 +- Libmaple/libmaple/libmaple/usb/usb_config.h | 266 +- Libmaple/libmaple/libmaple/usb/usb_hardware.c | 198 +- Libmaple/libmaple/libmaple/usb/usb_hardware.h | 272 +- .../libmaple/libmaple/usb/usb_lib/usb_core.c | 2026 +- .../libmaple/libmaple/usb/usb_lib/usb_core.h | 502 +- .../libmaple/libmaple/usb/usb_lib/usb_def.h | 176 +- .../libmaple/libmaple/usb/usb_lib/usb_init.c | 128 +- .../libmaple/libmaple/usb/usb_lib/usb_init.h | 114 +- .../libmaple/libmaple/usb/usb_lib/usb_int.c | 384 +- .../libmaple/libmaple/usb/usb_lib/usb_int.h | 82 +- .../libmaple/libmaple/usb/usb_lib/usb_lib.h | 74 +- .../libmaple/libmaple/usb/usb_lib/usb_mem.c | 146 +- .../libmaple/libmaple/usb/usb_lib/usb_mem.h | 80 +- .../libmaple/libmaple/usb/usb_lib/usb_regs.c | 1496 +- .../libmaple/libmaple/usb/usb_lib/usb_regs.h | 1254 +- .../libmaple/libmaple/usb/usb_lib/usb_type.h | 154 +- .../Class/audio/inc/usbd_audio_core.h | 316 +- .../Class/audio/inc/usbd_audio_out_if.h | 234 +- .../Class/audio/src/usbd_audio_core.c | 1330 +- .../Class/audio/src/usbd_audio_out_if.c | 636 +- .../Class/cdc/inc/usbd_cdc_core.h | 274 +- .../Class/cdc/inc/usbd_cdc_if_template.h | 90 +- .../Class/cdc/src/usbd_cdc_core.c | 1738 +- .../Class/cdc/src/usbd_cdc_if_template.c | 404 +- .../Class/dfu/inc/usbd_dfu_core.h | 374 +- .../Class/dfu/inc/usbd_dfu_mal.h | 158 +- .../Class/dfu/inc/usbd_flash_if.h | 98 +- .../Class/dfu/inc/usbd_mem_if_template.h | 92 +- .../Class/dfu/inc/usbd_otp_if.h | 86 +- .../Class/dfu/src/usbd_dfu_core.c | 2092 +- .../Class/dfu/src/usbd_dfu_mal.c | 562 +- .../Class/dfu/src/usbd_flash_if.c | 442 +- .../Class/dfu/src/usbd_mem_if_template.c | 266 +- .../Class/dfu/src/usbd_otp_if.c | 240 +- .../Class/hid/inc/usbd_hid_core.h | 220 +- .../Class/hid/src/usbd_hid_core.c | 920 +- .../Class/msc/inc/usbd_msc_bot.h | 294 +- .../Class/msc/inc/usbd_msc_core.h | 144 +- .../Class/msc/inc/usbd_msc_data.h | 196 +- .../Class/msc/inc/usbd_msc_mem.h | 212 +- .../Class/msc/inc/usbd_msc_scsi.h | 378 +- .../Class/msc/src/usbd_msc_bot.c | 786 +- .../Class/msc/src/usbd_msc_core.c | 980 +- .../Class/msc/src/usbd_msc_data.c | 256 +- .../Class/msc/src/usbd_msc_scsi.c | 1444 +- .../Class/msc/src/usbd_storage_template.c | 358 +- .../Core/inc/usbd_conf_template.h | 156 +- .../Core/inc/usbd_core.h | 232 +- .../Core/inc/usbd_def.h | 298 +- .../Core/inc/usbd_ioreq.h | 230 +- .../Core/inc/usbd_req.h | 204 +- .../Core/inc/usbd_usr.h | 270 +- .../Core/src/usbd_core.c | 966 +- .../Core/src/usbd_ioreq.c | 474 +- .../Core/src/usbd_req.c | 1736 +- .../usbF4/STM32_USB_OTG_Driver/inc/usb_bsp.h | 198 +- .../inc/usb_conf_template.h | 574 +- .../usbF4/STM32_USB_OTG_Driver/inc/usb_core.h | 816 +- .../usbF4/STM32_USB_OTG_Driver/inc/usb_dcd.h | 316 +- .../STM32_USB_OTG_Driver/inc/usb_dcd_int.h | 242 +- .../STM32_USB_OTG_Driver/inc/usb_defines.h | 488 +- .../usbF4/STM32_USB_OTG_Driver/inc/usb_hcd.h | 204 +- .../STM32_USB_OTG_Driver/inc/usb_hcd_int.h | 252 +- .../usbF4/STM32_USB_OTG_Driver/inc/usb_otg.h | 188 +- .../usbF4/STM32_USB_OTG_Driver/inc/usb_regs.h | 2412 +-- .../src/usb_bsp_template.c | 400 +- .../usbF4/STM32_USB_OTG_Driver/src/usb_core.c | 4378 ++--- .../usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c | 944 +- .../STM32_USB_OTG_Driver/src/usb_dcd_int.c | 1800 +- .../usbF4/STM32_USB_OTG_Driver/src/usb_hcd.c | 512 +- .../STM32_USB_OTG_Driver/src/usb_hcd_int.c | 1664 +- .../usbF4/STM32_USB_OTG_Driver/src/usb_otg.c | 350 +- .../libmaple/libmaple/usbF4/VCP/core_cm4.h | 2756 +-- .../libmaple/usbF4/VCP/core_cmInstr.h | 1170 +- Libmaple/libmaple/libmaple/usbF4/VCP/misc.c | 512 +- Libmaple/libmaple/libmaple/usbF4/VCP/misc.h | 344 +- .../libmaple/libmaple/usbF4/VCP/usb_bsp.c | 972 +- .../libmaple/libmaple/usbF4/VCP/usb_conf.h | 524 +- .../libmaple/usbF4/VCP/usbd_cdc_vcp.c | 844 +- .../libmaple/usbF4/VCP/usbd_cdc_vcp.h | 126 +- .../libmaple/libmaple/usbF4/VCP/usbd_conf.h | 196 +- .../libmaple/libmaple/usbF4/VCP/usbd_desc.c | 632 +- .../libmaple/libmaple/usbF4/VCP/usbd_desc.h | 228 +- .../libmaple/libmaple/usbF4/VCP/usbd_usr.c | 480 +- Libmaple/libmaple/libmaple/usbF4/usb.c | 208 +- Libmaple/libmaple/libmaple/usbF4/usb.h | 102 +- Libmaple/libmaple/libmaple/util.c | 314 +- Libmaple/libmaple/libmaple/util.h | 222 +- .../libraries/FreeRTOS/MapleFreeRTOS.cpp | 88 +- .../libraries/FreeRTOS/MapleFreeRTOS.h | 80 +- .../libmaple/libraries/FreeRTOS/keywords.txt | 52 +- Libmaple/libmaple/libraries/FreeRTOS/rules.mk | 74 +- .../libraries/FreeRTOS/utility/FreeRTOS.h | 936 +- .../FreeRTOS/utility/FreeRTOSConfig.h | 252 +- .../libraries/FreeRTOS/utility/StackMacros.h | 348 +- .../libraries/FreeRTOS/utility/croutine.c | 760 +- .../libraries/FreeRTOS/utility/croutine.h | 1504 +- .../libraries/FreeRTOS/utility/heap_2.c | 556 +- .../libraries/FreeRTOS/utility/list.c | 394 +- .../libraries/FreeRTOS/utility/list.h | 628 +- .../libraries/FreeRTOS/utility/mpu_wrappers.h | 282 +- .../libraries/FreeRTOS/utility/port.c | 584 +- .../libraries/FreeRTOS/utility/portable.h | 792 +- .../libraries/FreeRTOS/utility/portmacro.h | 312 +- .../libraries/FreeRTOS/utility/projdefs.h | 166 +- .../libraries/FreeRTOS/utility/queue.c | 3078 +-- .../libraries/FreeRTOS/utility/queue.h | 2540 +-- .../libraries/FreeRTOS/utility/semphr.h | 1434 +- .../libraries/FreeRTOS/utility/task.h | 2614 +-- .../libraries/FreeRTOS/utility/tasks.c | 5044 ++--- .../libraries/FreeRTOS/utility/timers.c | 1298 +- .../libraries/FreeRTOS/utility/timers.h | 1872 +- .../libraries/LiquidCrystal/LiquidCrystal.cpp | 666 +- .../libraries/LiquidCrystal/LiquidCrystal.h | 210 +- .../libmaple/libraries/LiquidCrystal/rules.mk | 56 +- Libmaple/libmaple/libraries/Servo/Servo.cpp | 300 +- Libmaple/libmaple/libraries/Servo/Servo.h | 400 +- Libmaple/libmaple/libraries/Servo/rules.mk | 56 +- Libmaple/libmaple/libraries/Wire/README | 10 +- Libmaple/libmaple/libraries/Wire/Wire.cpp | 646 +- Libmaple/libmaple/libraries/Wire/Wire.h | 224 +- Libmaple/libmaple/libraries/Wire/rules.mk | 56 +- .../libraries/mapleSDfat/Document1.txt | 74 +- .../libraries/mapleSDfat/FatStructs.h | 840 +- .../libmaple/libraries/mapleSDfat/Sd2Card.cpp | 1430 +- .../libmaple/libraries/mapleSDfat/Sd2Card.h | 382 +- .../libmaple/libraries/mapleSDfat/Sd2PinMap.h | 714 +- .../libmaple/libraries/mapleSDfat/SdFat.h | 1096 +- .../libmaple/libraries/mapleSDfat/SdFatUtil.h | 110 +- .../libraries/mapleSDfat/SdFatWorks.h | 1110 +- .../libraries/mapleSDfat/SdFatmainpage.h | 404 +- .../libmaple/libraries/mapleSDfat/SdFile.cpp | 2532 +-- .../libmaple/libraries/mapleSDfat/SdInfo.h | 464 +- .../libraries/mapleSDfat/SdVolume.cpp | 786 +- .../SdFatAnalogLogger/SdFatAnalogLogger.pde | 244 +- .../SdFatAppend/SdFatAppend.pde | 154 +- .../SdFatBench/SdFatBench.pde | 208 +- .../Arduino Examples/SdFatCopy/SdFatCopy.pde | 164 +- .../SdFatGPSLogger_v3/SdFatGPSLogger_v3.pde | 680 +- .../SdFatGPS_CSVSensorLogger.pde | 774 +- .../Arduino Examples/SdFatInfo/SdFatInfo.pde | 360 +- .../Arduino Examples/SdFatLs/SdFatLs.pde | 126 +- .../SdFatMakeDir/SdFatMakeDir.pde | 300 +- .../SdFatPrint/SdFatPrint.pde | 142 +- .../SdFatRawWrite/SdFatRawWrite.pde | 372 +- .../Arduino Examples/SdFatRead/SdFatRead.c | 142 +- .../SdFatRemove/SdFatRemove.pde | 116 +- .../SdFatRewrite/SdFatRewrite.pde | 144 +- .../SdFatRmDir/SdFatRmDir.pde | 222 +- .../Arduino Examples/SdFatTail/SdFatTail.pde | 196 +- .../SdFatTimestamp/SdFatTimestamp.pde | 364 +- .../SdFatTruncate/SdFatTruncate.pde | 132 +- .../SdFatWrite/SdFatWrite.pde | 196 +- .../mapleSDfat/examples/FileSys/FileSys.pde | 2 +- .../libmaple/libraries/mapleSDfat/rules.mk | 56 +- Libmaple/libmaple/main.cpp.example | 86 +- Libmaple/libmaple/notes/dac.txt | 134 +- Libmaple/libmaple/notes/dma.txt | 198 +- Libmaple/libmaple/notes/exti.txt | 82 +- Libmaple/libmaple/notes/fsmc.txt | 128 +- Libmaple/libmaple/notes/pin-definitions.txt | 452 +- Libmaple/libmaple/notes/portable.txt | 66 +- Libmaple/libmaple/notes/timers.txt | 192 +- Libmaple/libmaple/notes/usb.txt | 144 +- Libmaple/libmaple/notes/vga.txt | 70 +- Libmaple/libmaple/support/gdb/gpio/gpio.gdb | 24 +- Libmaple/libmaple/support/gdb/i2c/test.gdb | 224 +- .../libmaple/support/ld/aeroquad32/flash.ld | 40 +- .../libmaple/support/ld/aeroquad32/jtag.ld | 40 +- .../libmaple/support/ld/aeroquad32/ram.ld | 40 +- .../libmaple/support/ld/aeroquad32f1/flash.ld | 42 +- .../libmaple/support/ld/aeroquad32f1/jtag.ld | 40 +- .../libmaple/support/ld/aeroquad32f1/ram.ld | 40 +- .../support/ld/aeroquad32mini/flash.ld | 56 +- .../support/ld/aeroquad32mini/jtag.ld | 58 +- .../libmaple/support/ld/aeroquad32mini/ram.ld | 54 +- Libmaple/libmaple/support/ld/common.inc | 462 +- .../libmaple/support/ld/discovery_f4/flash.ld | 40 +- .../libmaple/support/ld/discovery_f4/jtag.ld | 40 +- .../libmaple/support/ld/discovery_f4/ram.ld | 40 +- .../libmaple/support/ld/freeflight/flash.ld | 56 +- .../libmaple/support/ld/freeflight/jtag.ld | 58 +- .../libmaple/support/ld/freeflight/ram.ld | 54 +- .../support/ld/libcs3_stm32_src/Makefile | 72 +- .../support/ld/libcs3_stm32_src/start.S | 54 +- .../support/ld/libcs3_stm32_src/start_c.c | 116 +- .../support/ld/libcs3_stm32_src/stm32_isrs.S | 470 +- .../ld/libcs3_stm32_src/stm32_vector_table.S | 180 +- .../support/ld/libcs4_stm32_src/Makefile | 72 +- .../support/ld/libcs4_stm32_src/start.S | 76 +- .../support/ld/libcs4_stm32_src/start_c.c | 116 +- .../support/ld/libcs4_stm32_src/stm32_isrs.S | 646 +- .../ld/libcs4_stm32_src/stm32_vector_table.S | 226 +- Libmaple/libmaple/support/ld/maple/flash.ld | 58 +- Libmaple/libmaple/support/ld/maple/jtag.ld | 58 +- Libmaple/libmaple/support/ld/maple/ram.ld | 54 +- .../libmaple/support/ld/maple_RET6/flash.ld | 40 +- .../libmaple/support/ld/maple_RET6/jtag.ld | 40 +- .../libmaple/support/ld/maple_RET6/ram.ld | 38 +- .../libmaple/support/ld/maple_mini/flash.ld | 56 +- .../libmaple/support/ld/maple_mini/jtag.ld | 58 +- .../libmaple/support/ld/maple_mini/ram.ld | 54 +- .../libmaple/support/ld/maple_native/flash.ld | 54 +- .../libmaple/support/ld/maple_native/jtag.ld | 54 +- .../libmaple/support/ld/maple_native/ram.ld | 50 +- Libmaple/libmaple/support/ld/names.inc | 156 +- Libmaple/libmaple/support/make/build-rules.mk | 102 +- .../libmaple/support/make/build-templates.mk | 12 +- .../libmaple/support/make/target-config.mk | 224 +- .../libmaple/support/openocd/debug_0.3.cfg | 150 +- .../libmaple/support/openocd/debug_0.4.cfg | 150 +- .../libmaple/support/openocd/flash_0.3.cfg | 178 +- .../libmaple/support/openocd/flash_0.4.cfg | 190 +- .../libmaple/support/scripts/45-maple.rules | 10 +- Libmaple/libmaple/wirish/HardwareTimer.cpp | 302 +- Libmaple/libmaple/wirish/HardwareTimer.h | 674 +- Libmaple/libmaple/wirish/Print.cpp | 504 +- Libmaple/libmaple/wirish/Print.h | 134 +- Libmaple/libmaple/wirish/WProgram.h | 60 +- Libmaple/libmaple/wirish/bit_constants.h | 1158 +- Libmaple/libmaple/wirish/bits.h | 60 +- Libmaple/libmaple/wirish/boards.cpp | 360 +- Libmaple/libmaple/wirish/boards.h | 326 +- .../libmaple/wirish/boards/aeroquad32.cpp | 472 +- Libmaple/libmaple/wirish/boards/aeroquad32.h | 186 +- .../libmaple/wirish/boards/aeroquad32mini.cpp | 210 +- .../libmaple/wirish/boards/aeroquad32mini.h | 156 +- .../libmaple/wirish/boards/discovery_f4.cpp | 396 +- .../libmaple/wirish/boards/discovery_f4.h | 188 +- .../libmaple/wirish/boards/freeflight.cpp | 226 +- Libmaple/libmaple/wirish/boards/freeflight.h | 136 +- Libmaple/libmaple/wirish/boards/maple.cpp | 232 +- Libmaple/libmaple/wirish/boards/maple.h | 174 +- .../libmaple/wirish/boards/maple_RET6.cpp | 236 +- Libmaple/libmaple/wirish/boards/maple_RET6.h | 176 +- .../libmaple/wirish/boards/maple_mini.cpp | 212 +- Libmaple/libmaple/wirish/boards/maple_mini.h | 146 +- .../libmaple/wirish/boards/maple_native.cpp | 402 +- .../libmaple/wirish/boards/maple_native.h | 160 +- Libmaple/libmaple/wirish/comm/HardwareSPI.cpp | 854 +- Libmaple/libmaple/wirish/comm/HardwareSPI.h | 468 +- .../libmaple/wirish/comm/HardwareSerial.cpp | 298 +- .../libmaple/wirish/comm/HardwareSerial.h | 170 +- Libmaple/libmaple/wirish/cxxabi-compat.cpp | 12 +- Libmaple/libmaple/wirish/ext_interrupts.cpp | 168 +- Libmaple/libmaple/wirish/ext_interrupts.h | 212 +- Libmaple/libmaple/wirish/io.h | 444 +- Libmaple/libmaple/wirish/main.cxx | 80 +- Libmaple/libmaple/wirish/pwm.cpp | 88 +- Libmaple/libmaple/wirish/pwm.h | 110 +- Libmaple/libmaple/wirish/rules.mk | 108 +- Libmaple/libmaple/wirish/usb_serial.cpp | 256 +- Libmaple/libmaple/wirish/usb_serial.h | 136 +- Libmaple/libmaple/wirish/wirish.h | 150 +- Libmaple/libmaple/wirish/wirish_analog.cpp | 88 +- Libmaple/libmaple/wirish/wirish_debug.h | 108 +- Libmaple/libmaple/wirish/wirish_digital.cpp | 282 +- Libmaple/libmaple/wirish/wirish_math.cpp | 98 +- Libmaple/libmaple/wirish/wirish_math.h | 302 +- Libmaple/libmaple/wirish/wirish_shift.cpp | 80 +- Libmaple/libmaple/wirish/wirish_time.cpp | 90 +- Libmaple/libmaple/wirish/wirish_time.h | 210 +- Libmaple/libmaple/wirish/wirish_types.h | 132 +- Libmaple/maple-bootloader/.gitignore | 10 +- Libmaple/maple-bootloader/Makefile | 528 +- Libmaple/maple-bootloader/README | 76 +- Libmaple/maple-bootloader/common.h | 88 +- Libmaple/maple-bootloader/config.h | 354 +- Libmaple/maple-bootloader/config.h.old | 142 +- Libmaple/maple-bootloader/dfu.c | 744 +- Libmaple/maple-bootloader/dfu.h | 242 +- Libmaple/maple-bootloader/flash/debug.cfg | 166 +- Libmaple/maple-bootloader/flash/flash.cfg | 182 +- Libmaple/maple-bootloader/flash/openocd.cfg | 146 +- Libmaple/maple-bootloader/flash/stm32.cfg | 144 +- Libmaple/maple-bootloader/hardware.c | 818 +- Libmaple/maple-bootloader/hardware.h | 1030 +- Libmaple/maple-bootloader/main.c | 214 +- .../stm32_lib/c_only_md_RAM.ld | 338 +- .../stm32_lib/c_only_md_flash128k_ram20k.ld | 344 +- .../stm32_lib/c_only_md_flash512k_ram64k.ld | 344 +- .../stm32_lib/c_only_startup.s | 734 +- .../stm32_lib/c_only_startup_user.s | 256 +- .../stm32_lib/cortexm3_macro.h | 106 +- .../stm32_lib/cortexm3_macro.s | 624 +- .../maple-bootloader/stm32_lib/stm32f10x.h | 15702 ++++++++-------- .../stm32_lib/stm32f10x_type.h | 160 +- .../maple-bootloader/stm32_lib/stm32f2xx.h | 13742 +++++++------- Libmaple/maple-bootloader/usb.c | 1124 +- Libmaple/maple-bootloader/usb.h | 352 +- Libmaple/maple-bootloader/usb_callbacks.c | 62 +- Libmaple/maple-bootloader/usb_descriptor.c | 420 +- Libmaple/maple-bootloader/usb_descriptor.h | 80 +- Libmaple/maple-bootloader/usb_lib/usb_conf.h | 172 +- Libmaple/maple-bootloader/usb_lib/usb_core.c | 2032 +- Libmaple/maple-bootloader/usb_lib/usb_core.h | 488 +- Libmaple/maple-bootloader/usb_lib/usb_def.h | 160 +- Libmaple/maple-bootloader/usb_lib/usb_init.c | 128 +- Libmaple/maple-bootloader/usb_lib/usb_init.h | 98 +- Libmaple/maple-bootloader/usb_lib/usb_int.c | 384 +- Libmaple/maple-bootloader/usb_lib/usb_int.h | 66 +- Libmaple/maple-bootloader/usb_lib/usb_lib.h | 74 +- Libmaple/maple-bootloader/usb_lib/usb_mem.c | 146 +- Libmaple/maple-bootloader/usb_lib/usb_mem.h | 64 +- Libmaple/maple-bootloader/usb_lib/usb_regs.c | 1496 +- Libmaple/maple-bootloader/usb_lib/usb_regs.h | 1238 +- Libmaple/maple-bootloader/usb_lib/usb_type.h | 144 +- .../AQ_Accelerometer/Accelerometer_MPU6000.h | 154 +- .../Examples/Test_BMP085/Test_BMP085.ino | 2 +- .../CameraStabilizer_TXControl.h | 162 +- Libraries/AQ_Defines/GlobalDefined.h | 84 +- .../FlightControlHexPlus.h | 124 +- .../FlightControlHexX.h | 118 +- .../FlightControlQuadX.h | 118 +- Libraries/AQ_Gyroscope/Gyroscope_MPU6000.h | 238 +- Libraries/AQ_OSD/MAX7456_Config.h | 172 +- Libraries/AQ_OSD/MAX7456_RSSI.h | 130 +- Libraries/AQ_Platform_APM/APM_ADC_Optimized.h | 496 +- Libraries/AQ_RSSI/AnalogRSSIReader.h | 106 +- Libraries/AQ_RSSI/EzUHFRSSIReader.h | 100 +- Libraries/AQ_RSSI/SBUSRSSIReader.h | 112 +- Libraries/AQ_Receiver/Receiver.h | 238 +- Libraries/AQ_Receiver/Receiver_PPM.h | 160 +- Libraries/AQ_Receiver/Receiver_PPM_common.h | 74 +- Libraries/AQ_Receiver/Receiver_SBUS.h | 230 +- Libraries/AQ_Receiver/Receiver_STM32.h | 414 +- Libraries/AQ_Receiver/Receiver_STM32PPM.h | 280 +- Libraries/AQ_SPI/HardwareSPIExt.h | 160 +- Libraries/AQ_SoftModem/AQ_SoftModem.h | 270 +- 454 files changed, 104897 insertions(+), 104897 deletions(-) diff --git a/AeroQuad/AeroQuad.h b/AeroQuad/AeroQuad.h index b112bd8e..d9ba5091 100644 --- a/AeroQuad/AeroQuad.h +++ b/AeroQuad/AeroQuad.h @@ -365,4 +365,4 @@ byte fastTransfer = OFF; // Used for troubleshooting //byte testSignal = LOW; ////////////////////////////////////////////////////// -#endif // _AQ_GLOBAL_HEADER_DEFINITION_H_ +#endif // _AQ_GLOBAL_HEADER_DEFINITION_H_ diff --git a/AeroQuad/AeroQuad.ino b/AeroQuad/AeroQuad.ino index e35a18fa..80d9e75d 100644 --- a/AeroQuad/AeroQuad.ino +++ b/AeroQuad/AeroQuad.ino @@ -1615,4 +1615,4 @@ void loop () { } - + diff --git a/AeroQuad/AltitudeControlProcessor.h b/AeroQuad/AltitudeControlProcessor.h index 75ccb198..82dd28ac 100644 --- a/AeroQuad/AltitudeControlProcessor.h +++ b/AeroQuad/AltitudeControlProcessor.h @@ -117,4 +117,4 @@ void processAltitudeHold() #endif -#endif // _AQ_ALTITUDE_CONTROL_PROCESSOR_H_ +#endif // _AQ_ALTITUDE_CONTROL_PROCESSOR_H_ diff --git a/AeroQuad/DataStorage.h b/AeroQuad/DataStorage.h index 1767dd47..0784ac80 100644 --- a/AeroQuad/DataStorage.h +++ b/AeroQuad/DataStorage.h @@ -500,4 +500,4 @@ void initReceiverFromEEPROM() { } #endif // _AQ_DATA_STORAGE_H_ - + diff --git a/AeroQuad/FlightCommandProcessor.h b/AeroQuad/FlightCommandProcessor.h index a9913ec1..0544ccae 100644 --- a/AeroQuad/FlightCommandProcessor.h +++ b/AeroQuad/FlightCommandProcessor.h @@ -282,4 +282,4 @@ void readPilotCommands() { } #endif // _AQ_FLIGHT_COMMAND_READER_ - + diff --git a/AeroQuad/FlightControlProcessor.h b/AeroQuad/FlightControlProcessor.h index 830aaa58..193bab4a 100644 --- a/AeroQuad/FlightControlProcessor.h +++ b/AeroQuad/FlightControlProcessor.h @@ -346,4 +346,4 @@ void processFlightControl() { } #endif //#define _AQ_PROCESS_FLIGHT_CONTROL_H_ - + diff --git a/AeroQuad/GpsNavigator.h b/AeroQuad/GpsNavigator.h index d2a14d0a..25cf5047 100644 --- a/AeroQuad/GpsNavigator.h +++ b/AeroQuad/GpsNavigator.h @@ -410,4 +410,4 @@ void initHomeBase() { - + diff --git a/AeroQuad/HeadingHoldProcessor.h b/AeroQuad/HeadingHoldProcessor.h index 2e66028e..2a47bece 100644 --- a/AeroQuad/HeadingHoldProcessor.h +++ b/AeroQuad/HeadingHoldProcessor.h @@ -121,4 +121,4 @@ void processHeading() - + diff --git a/AeroQuad/MavLink.h b/AeroQuad/MavLink.h index a681380c..ace03f6d 100644 --- a/AeroQuad/MavLink.h +++ b/AeroQuad/MavLink.h @@ -1429,4 +1429,4 @@ void sendSerialTelemetry() { } #endif //#define _AQ_MAVLINK_H_ - + diff --git a/AeroQuad/OSDDisplayController.h b/AeroQuad/OSDDisplayController.h index 52196c73..d118e80d 100644 --- a/AeroQuad/OSDDisplayController.h +++ b/AeroQuad/OSDDisplayController.h @@ -92,4 +92,4 @@ void updateOSD() { } } -#endif +#endif diff --git a/AeroQuad/OSDMenu.h b/AeroQuad/OSDMenu.h index 301402ca..428331f1 100644 --- a/AeroQuad/OSDMenu.h +++ b/AeroQuad/OSDMenu.h @@ -1,933 +1,933 @@ -/* - AeroQuad v3.0 - December 2011 - www.AeroQuad.com - Copyright (c) 2011 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . - */ - -/* Menu system implementation, usable with OSD or SerialLCD */ - -#ifndef _AQ_OSD_MENU_ -#define _AQ_OSD_MENU_ - -//#define MENU_GOPRO // enable GoPro controls... not usable atm. - -struct MenuItem { - const byte level; // menu level the item is on - const char *text; // text to show - void (*function)(byte,byte); // handler func on leaf level - const byte mode; // data to give for handler function -}; - -extern const struct MenuItem menuData[]; - -#define MENU_INIT 0 // initial call to handler -#define MENU_UP 1 // stick up action -#define MENU_DOWN 2 // stick down action -#define MENU_SELECT 3 // stick right action -#define MENU_EXIT 4 // stick left action -#define MENU_CALLBACK 5 // timed callback -#define MENU_ABORT 6 // cleanup now (motors armed), only needs to be handled if cleanups are needed -#define MENU_HIJACK 7 // handler should interrept sticks completely !! - -#define MENU_NOFUNC 0 - -#define MENU_SYM_BOTH '\015' -#define MENU_SYM_UP '\016' -#define MENU_SYM_DOWN '\017' - -#define MENU_STICK_CENTER 1500 // center value -#define MENU_STICK_NEUTRAL 100 // less than this from center is neutral -#define MENU_STICK_ACTIVE 200 // over this is select -#define MENU_STICK_REPEAT 400 // autorepeat at extreme values - -byte menuInFunc = 0; // tells if a handler func is active - // 0 - we're in base menu - // 1 - call handler on stick actions - // 2-255 countdown and callback when it gets to 1 - no sticks -byte menuEntry = 255; // Active menu entry -byte menuAtExit = 0; // are we at the exit at the top -byte stickWaitNeutral = 1; // wait for stick to center -byte menuOwnsSticks = 0; // menu code will handle stick input (prevents arming) - -// DATA that menu functions can freely use to store state -byte menuFuncData[10]; // 10 bytes of data for funcs to use as they wish... -float menuFuncDataFloat; // float for menufuncs use - -// menuHandleSimple - handle trivial menu actions launched from menu -// -// This function will do action on MENU_INIT and optionally display a message. -// -// To display message add following two lines after doing the action -// notifyOSD(OSD_NOCLEAR|OSD_CENTER, "message"); -// menuInFunc = 10; // display time in 100ms increments - -void menuHandleSimple(byte mode, byte action) { - - menuInFunc = 0; // default to no callback - if (action == MENU_INIT) { - switch (mode) { - case 0: -#ifdef OSD - armedTime = 0; -#endif - break; -#ifdef BattMonitor - case 1: - for (int i=0; i0) { - menuFuncData[1]--; - } - } - } - else if (menuFuncData[0]==1) { - int val = (action == MENU_UP) ? 10 : -10; - switch (menuFuncData[1]) { - case 0: - cameraMode = (action==MENU_UP)?1:0; - break; - case 1: - servoCenterPitch = constrain(servoCenterPitch + val, servoMinPitch, servoMaxPitch); - break; - case 2: - servoCenterRoll = constrain(servoCenterRoll + val, servoMinRoll, servoMaxRoll); - break; - case 3: - servoCenterYaw = constrain(servoCenterYaw + val, servoMinYaw, servoMaxYaw); - break; - } - } - break; - } - - if (menuFuncData[1] == 0) { - notifyOSDmenu(OSD_NOCLEAR | OSD_CURSOR, menuFuncData[0] ? 18 : 1, menuFuncData[0] ? 18 : 16, "%cStabilizer mode: %1d", MENU_SYM_BOTH, cameraMode); - } - else { - notifyOSDmenu(OSD_NOCLEAR|OSD_CURSOR, - menuFuncData[0] ? 15 : 8, menuFuncData[0] ? 18 : 12, - "%cCenter %s: %04d", MENU_SYM_BOTH, - (menuFuncData[1] == 1)?"Pitch": - (menuFuncData[1] == 2)?"Roll ": - "Yaw ", - (menuFuncData[1] == 1) ? servoCenterPitch: - (menuFuncData[1] == 2) ? servoCenterRoll: - servoCenterYaw); - } -} -#endif - -// GoPro handling skeleton, not complete... -#ifdef MENU_GOPRO -const char *gopro_b_txt[3] = { "Shutter", "Mode", "Power" }; - -void menuHandleGoPro(byte mode, byte action) { - - switch (action) { - case MENU_ABORT: // depress I/O line immediately to avoid letting it on - case MENU_CALLBACK: - // depress I/O line... - menuInFunc=0; // exit to menu - break; - case MENU_INIT: - // activate I/O - notifyOSD(OSD_NOCLEAR|OSD_CENTER, "%s pressed", gopro_b_txt[mode]); - if (mode == 2) { - menuInFunc = 35; //3.5 sec - } - else { - menuInFunc = 10; // 1 sec - } - break; - default: - break; - } -} -#endif - -// edit digit with of form [+/-][i*#].[d*#] -// pos: 0=sign, 1-(i)=intpart, (i+1)-(i+d+1)=decimals -void menuEditFloat(float *f, byte i, byte d, byte pos, byte action, float min, float max) { - - if (pos > (1 + i + d)) { - return; - } - // if ((action!=MENU_UP)&&(action!=MENU_DOWN)) return; - if (pos == 0 && min * max < 0) { // change sign only if min/max are different sign - *f = -*f; - } - else { - *f += (action == MENU_UP ? 1.0 : -1.0) * pow(10.0, i-pos); - } - *f = constrain(*f, min, max); -} - -const char *pidNames[] = { - "RRoll", "RPitc", "RYaw ", "ARoll", "APitc", - "Headi", "AGRol", "AGPit", "B_Alt", "S_Alt", - "ZDamp", -#ifdef UseGPS - "GPS_P", "GPS_R", "GPS_Y" -#endif -}; - -#define PIDCOUNT (sizeof(pidNames)/sizeof(char*)) - -void menuHandlePidTune(byte mode, byte action) { - - switch (action) { - case MENU_INIT: - menuFuncData[0]=0; //level 0-select PID;1-select P/I/D;>=2-edit value - menuFuncData[1]=0; // PIDno - menuFuncData[2]=0; // 0=P/1=I/2=D - break; - case MENU_ABORT: - return; // nocleanup needed - case MENU_EXIT: - if (menuFuncData[0]>0) { - menuFuncData[0]--; - } - else { - menuInFunc=0; - return; - } - menuFuncData[3]=0; - break; - - case MENU_SELECT: - if (menuFuncData[0] < 9) { - menuFuncData[0]++; - } - else { - if (menuFuncData[3]) { - switch (menuFuncData[2]) { - case 0: - PID[menuFuncData[1]].P = menuFuncDataFloat; - break; - case 1: - PID[menuFuncData[1]].I = menuFuncDataFloat; - break; - case 2: - PID[menuFuncData[1]].D = menuFuncDataFloat; - break; - } - notifyOSD(OSD_NOCLEAR, "PID value saved!!"); - } - else { - notifyOSD(OSD_NOCLEAR, "PID value not saved!!"); - } - menuInFunc = 10; // callback after 1 second - menuFuncData[0] = 1; //return to P/I/D selection - return; - } - break; - - case MENU_UP: - if (menuFuncData[0] == 0) { - if (menuFuncData[1] < (PIDCOUNT-1)) menuFuncData[1]++; - } - else if (menuFuncData[0] == 1) { - if (menuFuncData[2] < 2) menuFuncData[2]++; - } - else if (menuFuncData[0] == 9) { - menuFuncData[3] = 1; - } - else { - menuEditFloat(&menuFuncDataFloat, 4, 2, menuFuncData[0]-2, MENU_UP, -1000, 1000); - } - break; - - case MENU_DOWN: - if (menuFuncData[0] < 2) { - if (menuFuncData[menuFuncData[0] +1 ] > 0) menuFuncData[menuFuncData[0] + 1]--; - } - else if (menuFuncData[0] == 9) { - menuFuncData[3] = 0; - } - else { - menuEditFloat(&menuFuncDataFloat, 4, 2, menuFuncData[0]-2, MENU_DOWN, -1000, 1000); - } - break; - } - - float old = (menuFuncData[2] == 0 ? PID[menuFuncData[1]].P: - menuFuncData[2] == 1 ? PID[menuFuncData[1]].I: - PID[menuFuncData[1]].D); - - if (menuFuncData[0] < 2) { - // update value if edited value might have changed - menuFuncDataFloat = old; - } - - if (menuFuncData[0] < 9) { - // determine 'cursor' position - // assume we are editing the number - byte cl = ((menuFuncData[0] > 6) ? 12 : 11) + menuFuncData[0]; - byte cr = cl; - byte updn = MENU_SYM_BOTH; - // check if it is something else - if (menuFuncData[0] == 0) { - // selecting PID - cl = 5; - cr = 9; - if (menuFuncData[1] == 0) updn = MENU_SYM_UP; - if (menuFuncData[1] == (PIDCOUNT-1)) updn = MENU_SYM_DOWN; - } - else if (menuFuncData[0] == 1) { - // selecting P/I/D - cl = 11; - cr = cl; - if (menuFuncData[2] == 0) updn = MENU_SYM_UP; - if (menuFuncData[2] == 2) updn = MENU_SYM_DOWN; - } - notifyOSDmenu(OSD_CURSOR | OSD_NOCLEAR, cl, cr, "%cPID %s:%c=%c%04d.%02d", - updn, pidNames[menuFuncData[1]], menuFuncData[2]==0 ? 'P' : menuFuncData[2]==1 ? 'I' : 'D', - (menuFuncDataFloat >= 0) ? '+' : '-', - (int)abs(menuFuncDataFloat), (int)abs((menuFuncDataFloat - (int)menuFuncDataFloat) * 100.0)); - } - else { - // asking confirmation for changing the value - notifyOSDmenu(OSD_CURSOR|OSD_NOCLEAR,21,21,"C %c%04d.%02d->%c%04d.%02d?%c", - (old>=0)?'+':'-',(int)abs(old),(int)abs((old-(int)old)*100.0), - (menuFuncDataFloat>=0)?'+':'-',(int)abs(menuFuncDataFloat),(int)abs((menuFuncDataFloat-(int)menuFuncDataFloat)*100.0), - menuFuncData[3] ? 'Y' : 'N'); - } -} - - -// this define is used to convert a float into (char) sign, (int) integerpart, (int) per100parts -#define PRFLOAT(x) (((x)<0.0)?'-':' '),((int)abs(x)),(abs((int)(100*(x)))%100) - -void menuSensorInfo(byte mode, byte action){ - switch (action) { - case MENU_EXIT: - case MENU_ABORT: - menuInFunc=0; - break; - case MENU_CALLBACK: - case MENU_INIT: - switch (mode) { - case 0: // Accel - notifyOSD(OSD_NOCLEAR,"Acc: X%c%d.%02d Y%c%d.%02d Z%c%d.%02d", - PRFLOAT(meterPerSecSec[XAXIS]),PRFLOAT(meterPerSecSec[YAXIS]),PRFLOAT(meterPerSecSec[ZAXIS])); - break; - case 1: // Gyro - notifyOSD(OSD_NOCLEAR,"Gyr: X%c%d.%02d Y%c%d.%02dZ %c%d.%02d", - PRFLOAT(gyroRate[XAXIS]),PRFLOAT(gyroRate[YAXIS]),PRFLOAT(gyroRate[ZAXIS])); - break; - #if defined(HeadingMagHold) - case 2: // Mag - notifyOSD(OSD_NOCLEAR,"Mag: X%5d Y%5d Z%5d", - getMagnetometerData(XAXIS),getMagnetometerData(YAXIS),getMagnetometerData(ZAXIS)); - break; - #endif - #if defined(AltitudeHoldRangeFinder) - case 3: // Rangers - notifyOSD(OSD_NOCLEAR,"US:a%df%dr%dr%dl%d cm", - (int)(rangeFinderRange[ALTITUDE_RANGE_FINDER_INDEX]*100), - (int)(rangeFinderRange[FRONT_RANGE_FINDER_INDEX]*100), - (int)(rangeFinderRange[RIGHT_RANGE_FINDER_INDEX]*100), - (int)(rangeFinderRange[REAR_RANGE_FINDER_INDEX]*100), - (int)(rangeFinderRange[LEFT_RANGE_FINDER_INDEX]*100)); - break; - #endif - } - menuInFunc=3; - break; - default: - menuInFunc=3; - } -} - -void menuHideOSD(byte mode, byte action){ - - menuInFunc=0; - menuEntry=255; - notifyOSD(OSD_NOCLEAR,NULL); - hideOSD(); -} - -#ifdef CameraControl -short savedCenterYaw, savedCenterPitch, savedCenterRoll; -byte savedCameraMode; - -// #define POWERSAVE 10 // enable to shut off servos after idle -#if defined (POWERSAVE) - byte idleCounter = POWERSAVE; -#endif - -#define ZOOMPIN 24 - - -void menuCameraPTZ(byte mode, byte action){ - - if (action == MENU_INIT) { - hideOSD(); - menuOwnsSticks = 1; - savedCenterYaw = servoCenterYaw; - savedCenterPitch = servoCenterPitch; - savedCenterRoll = servoCenterRoll; - savedCameraMode = cameraMode; - cameraMode = 0; // disable stabilizer - menuFuncDataFloat = 0.0; - #if defined (POWERSAVE) - idleCounter = POWERSAVE; - #endif - } - else if ((action == MENU_CALLBACK) || (action == MENU_ABORT)) { - digitalWrite(ZOOMPIN, LOW); // Zoom off - pinMode(ZOOMPIN, INPUT); - #if defined (POWERSAVE) - TCCR1A |= ((1< 50) { - if (yaw>0) { - yaw-=50; - } - else { - yaw+=50; - } - servoCenterYaw = constrain(servoCenterYaw + (yaw/10), servoMinYaw, servoMaxYaw); - #if defined (POWERSAVE) - idleCounter = POWERSAVE; - #endif - } - - if (abs(receiverCommand[THROTTLE] - menuFuncDataFloat) > 2) { - menuFuncDataFloat = receiverCommand[THROTTLE]; - servoCenterPitch = constrain(3000 - menuFuncDataFloat, servoMinPitch, servoMaxPitch); - #if defined (POWERSAVE) - idleCounter = POWERSAVE; - #endif - } - - if (roll > MENU_STICK_REPEAT) { - // elevator - if (pitch < -MENU_STICK_REPEAT) { - // DOWN - servoCenterRoll = servoMinRoll; - } - else if (pitch > MENU_STICK_REPEAT) { - // UP - servoCenterRoll = servoMaxRoll; - } else { - // STOP - servoCenterRoll = savedCenterRoll; - } - #if defined (POWERSAVE) - idleCounter = POWERSAVE; - #endif - - } - else { - // zoom - if (pitch < -MENU_STICK_REPEAT) { - // zoom out - pinMode(ZOOMPIN, OUTPUT); - digitalWrite(ZOOMPIN, LOW); - } - else if (pitch > MENU_STICK_REPEAT) { - // zoom in - pinMode(ZOOMPIN, OUTPUT); - digitalWrite(ZOOMPIN, HIGH); - } else { - // release zoom - digitalWrite(ZOOMPIN, LOW); // this is needed to remove the 'internal pullup' - pinMode(ZOOMPIN, INPUT); - } - } - #if defined (POWERSAVE) - if (idleCounter == POWERSAVE) { - idleCounter--; - TCCR1A |= ((1<0) { - idleCounter--; - if (idleCounter == 0) { - TCCR1A &= ~((1< menuData[menuEntry-1].level)) { - menuAtExit=1; - } - else { - for (byte i=menuEntry-1; i>=0; i--) { - if (menuData[menuEntry].level == menuData[i].level) { - menuEntry = i; - break; - } - } - } - menuShow(menuEntry); -} - -void menuDown() { - - if (255 == menuEntry) { - return; - } - if (menuInFunc) { - MENU_CALLFUNC(menuEntry, MENU_DOWN); - return; - } - if (menuAtExit) { - menuAtExit = 0; - } - else { - if (menuIsLast(menuEntry)) return; - for (byte i = menuEntry + 1; i < menuNumEntries; i++) { - if (menuData[menuEntry].level == menuData[i].level) { - menuEntry = i; - break; - } - } - } - menuShow(menuEntry); -} - -void menuSelect() { - - if (255==menuEntry) { - // enable menu - unhideOSD(); // make sure OSD is visible - menuAtExit=0; - menuEntry=0; - } - else if (menuInFunc) { - MENU_CALLFUNC(menuEntry,MENU_SELECT); - if (menuInFunc) return; // redisplay menu if we exited from handler - } - else if (menuAtExit) { - if (0==menuEntry) { - menuEntry=255; - } - else { - // leave submenu - menuEntry--; - menuAtExit=0; - } - } - else if (menuData[menuEntry].function != MENU_NOFUNC) { - menuInFunc = 1; - MENU_CALLFUNC(menuEntry, MENU_INIT); - return; - } - else if (menuData[menuEntry].level < menuData[menuEntry + 1].level) { - // enter submenu - menuEntry++; - } - menuShow(menuEntry); -} - -void menuExit() { - - if (255 == menuEntry) - return; - - if (menuInFunc) { - MENU_CALLFUNC(menuEntry, MENU_EXIT); - if (menuInFunc) - return; - } - else if ((0 == menuEntry) || (0 == menuData[menuEntry].level)) { - menuEntry = 255; - } - else { - // leave submenu - for (byte i = menuEntry-1; i>=0; i--) { - if (menuData[i].level < menuData[menuEntry].level) { - menuEntry = i; - menuAtExit = 0; - break; - } - } - } - menuShow(menuEntry); -} - -void updateOSDMenu() { - - // check for special HiJack mode - if ((menuEntry!=255) && menuOwnsSticks && menuInFunc) { - - MENU_CALLFUNC(menuEntry, MENU_HIJACK); - if (menuInFunc == 0) { - menuShow(menuEntry); - } - return; - } - - // check if armed, menu is only operational when not armed - if (motorArmed == true) { - if (menuEntry != 255) { - // BAIL OUT of menu if armed - if (menuInFunc) { - MENU_CALLFUNC(menuEntry, MENU_ABORT); - } - notifyOSD(0, NULL); // clear menuline - menuInFunc = 0; - menuEntry = 255; - } - return; - } - - // check if we're waiting for callback to happen - if (menuInFunc > 1) { - menuInFunc--; - if (menuInFunc == 1) { - // call the callback when counter hits 1 - MENU_CALLFUNC(menuEntry, MENU_CALLBACK); - // show the menu entry if the handler function 'exited' - if (menuInFunc == 0) { - menuShow(menuEntry); - } - return; - } - } - - const short roll = receiverCommand[XAXIS] - MENU_STICK_CENTER; // pitch/roll should be -500 - +500 - const short pitch = receiverCommand[YAXIS] - MENU_STICK_CENTER; - - if (abs(roll) < MENU_STICK_NEUTRAL) { - if (abs(pitch) < MENU_STICK_NEUTRAL) { - // stick at center - stickWaitNeutral = 0; - return; - } - else { - // roll at neutral, pitch not - if (abs(pitch) > MENU_STICK_REPEAT) { - // above repeat threshold so allow redoing action - stickWaitNeutral = 0; - } - - // check if we are waiting for neutral (after single action) - if (stickWaitNeutral) { - return; - } - - // call action function if stick active - if (abs(pitch) > MENU_STICK_ACTIVE) { - if (pitch > 0) { - menuUp(); - } - else { - menuDown(); - } - - // action done, further actions only after centering (or repeat) - stickWaitNeutral = 1; - } - } - } - else { - if (abs(pitch) >= MENU_STICK_NEUTRAL) { - return; // both ways active - no action - } - if (abs(roll) > MENU_STICK_ACTIVE) { - if (roll > 0) { - if (!stickWaitNeutral) { - menuSelect(); - } - } - else { - if ((!stickWaitNeutral) || (abs(roll) >= MENU_STICK_REPEAT)) { - menuExit(); - } - } - stickWaitNeutral = 1; - } - } - return; -} - -#endif // Menu_h +/* + AeroQuad v3.0 - December 2011 + www.AeroQuad.com + Copyright (c) 2011 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . + */ + +/* Menu system implementation, usable with OSD or SerialLCD */ + +#ifndef _AQ_OSD_MENU_ +#define _AQ_OSD_MENU_ + +//#define MENU_GOPRO // enable GoPro controls... not usable atm. + +struct MenuItem { + const byte level; // menu level the item is on + const char *text; // text to show + void (*function)(byte,byte); // handler func on leaf level + const byte mode; // data to give for handler function +}; + +extern const struct MenuItem menuData[]; + +#define MENU_INIT 0 // initial call to handler +#define MENU_UP 1 // stick up action +#define MENU_DOWN 2 // stick down action +#define MENU_SELECT 3 // stick right action +#define MENU_EXIT 4 // stick left action +#define MENU_CALLBACK 5 // timed callback +#define MENU_ABORT 6 // cleanup now (motors armed), only needs to be handled if cleanups are needed +#define MENU_HIJACK 7 // handler should interrept sticks completely !! + +#define MENU_NOFUNC 0 + +#define MENU_SYM_BOTH '\015' +#define MENU_SYM_UP '\016' +#define MENU_SYM_DOWN '\017' + +#define MENU_STICK_CENTER 1500 // center value +#define MENU_STICK_NEUTRAL 100 // less than this from center is neutral +#define MENU_STICK_ACTIVE 200 // over this is select +#define MENU_STICK_REPEAT 400 // autorepeat at extreme values + +byte menuInFunc = 0; // tells if a handler func is active + // 0 - we're in base menu + // 1 - call handler on stick actions + // 2-255 countdown and callback when it gets to 1 - no sticks +byte menuEntry = 255; // Active menu entry +byte menuAtExit = 0; // are we at the exit at the top +byte stickWaitNeutral = 1; // wait for stick to center +byte menuOwnsSticks = 0; // menu code will handle stick input (prevents arming) + +// DATA that menu functions can freely use to store state +byte menuFuncData[10]; // 10 bytes of data for funcs to use as they wish... +float menuFuncDataFloat; // float for menufuncs use + +// menuHandleSimple - handle trivial menu actions launched from menu +// +// This function will do action on MENU_INIT and optionally display a message. +// +// To display message add following two lines after doing the action +// notifyOSD(OSD_NOCLEAR|OSD_CENTER, "message"); +// menuInFunc = 10; // display time in 100ms increments + +void menuHandleSimple(byte mode, byte action) { + + menuInFunc = 0; // default to no callback + if (action == MENU_INIT) { + switch (mode) { + case 0: +#ifdef OSD + armedTime = 0; +#endif + break; +#ifdef BattMonitor + case 1: + for (int i=0; i0) { + menuFuncData[1]--; + } + } + } + else if (menuFuncData[0]==1) { + int val = (action == MENU_UP) ? 10 : -10; + switch (menuFuncData[1]) { + case 0: + cameraMode = (action==MENU_UP)?1:0; + break; + case 1: + servoCenterPitch = constrain(servoCenterPitch + val, servoMinPitch, servoMaxPitch); + break; + case 2: + servoCenterRoll = constrain(servoCenterRoll + val, servoMinRoll, servoMaxRoll); + break; + case 3: + servoCenterYaw = constrain(servoCenterYaw + val, servoMinYaw, servoMaxYaw); + break; + } + } + break; + } + + if (menuFuncData[1] == 0) { + notifyOSDmenu(OSD_NOCLEAR | OSD_CURSOR, menuFuncData[0] ? 18 : 1, menuFuncData[0] ? 18 : 16, "%cStabilizer mode: %1d", MENU_SYM_BOTH, cameraMode); + } + else { + notifyOSDmenu(OSD_NOCLEAR|OSD_CURSOR, + menuFuncData[0] ? 15 : 8, menuFuncData[0] ? 18 : 12, + "%cCenter %s: %04d", MENU_SYM_BOTH, + (menuFuncData[1] == 1)?"Pitch": + (menuFuncData[1] == 2)?"Roll ": + "Yaw ", + (menuFuncData[1] == 1) ? servoCenterPitch: + (menuFuncData[1] == 2) ? servoCenterRoll: + servoCenterYaw); + } +} +#endif + +// GoPro handling skeleton, not complete... +#ifdef MENU_GOPRO +const char *gopro_b_txt[3] = { "Shutter", "Mode", "Power" }; + +void menuHandleGoPro(byte mode, byte action) { + + switch (action) { + case MENU_ABORT: // depress I/O line immediately to avoid letting it on + case MENU_CALLBACK: + // depress I/O line... + menuInFunc=0; // exit to menu + break; + case MENU_INIT: + // activate I/O + notifyOSD(OSD_NOCLEAR|OSD_CENTER, "%s pressed", gopro_b_txt[mode]); + if (mode == 2) { + menuInFunc = 35; //3.5 sec + } + else { + menuInFunc = 10; // 1 sec + } + break; + default: + break; + } +} +#endif + +// edit digit with of form [+/-][i*#].[d*#] +// pos: 0=sign, 1-(i)=intpart, (i+1)-(i+d+1)=decimals +void menuEditFloat(float *f, byte i, byte d, byte pos, byte action, float min, float max) { + + if (pos > (1 + i + d)) { + return; + } + // if ((action!=MENU_UP)&&(action!=MENU_DOWN)) return; + if (pos == 0 && min * max < 0) { // change sign only if min/max are different sign + *f = -*f; + } + else { + *f += (action == MENU_UP ? 1.0 : -1.0) * pow(10.0, i-pos); + } + *f = constrain(*f, min, max); +} + +const char *pidNames[] = { + "RRoll", "RPitc", "RYaw ", "ARoll", "APitc", + "Headi", "AGRol", "AGPit", "B_Alt", "S_Alt", + "ZDamp", +#ifdef UseGPS + "GPS_P", "GPS_R", "GPS_Y" +#endif +}; + +#define PIDCOUNT (sizeof(pidNames)/sizeof(char*)) + +void menuHandlePidTune(byte mode, byte action) { + + switch (action) { + case MENU_INIT: + menuFuncData[0]=0; //level 0-select PID;1-select P/I/D;>=2-edit value + menuFuncData[1]=0; // PIDno + menuFuncData[2]=0; // 0=P/1=I/2=D + break; + case MENU_ABORT: + return; // nocleanup needed + case MENU_EXIT: + if (menuFuncData[0]>0) { + menuFuncData[0]--; + } + else { + menuInFunc=0; + return; + } + menuFuncData[3]=0; + break; + + case MENU_SELECT: + if (menuFuncData[0] < 9) { + menuFuncData[0]++; + } + else { + if (menuFuncData[3]) { + switch (menuFuncData[2]) { + case 0: + PID[menuFuncData[1]].P = menuFuncDataFloat; + break; + case 1: + PID[menuFuncData[1]].I = menuFuncDataFloat; + break; + case 2: + PID[menuFuncData[1]].D = menuFuncDataFloat; + break; + } + notifyOSD(OSD_NOCLEAR, "PID value saved!!"); + } + else { + notifyOSD(OSD_NOCLEAR, "PID value not saved!!"); + } + menuInFunc = 10; // callback after 1 second + menuFuncData[0] = 1; //return to P/I/D selection + return; + } + break; + + case MENU_UP: + if (menuFuncData[0] == 0) { + if (menuFuncData[1] < (PIDCOUNT-1)) menuFuncData[1]++; + } + else if (menuFuncData[0] == 1) { + if (menuFuncData[2] < 2) menuFuncData[2]++; + } + else if (menuFuncData[0] == 9) { + menuFuncData[3] = 1; + } + else { + menuEditFloat(&menuFuncDataFloat, 4, 2, menuFuncData[0]-2, MENU_UP, -1000, 1000); + } + break; + + case MENU_DOWN: + if (menuFuncData[0] < 2) { + if (menuFuncData[menuFuncData[0] +1 ] > 0) menuFuncData[menuFuncData[0] + 1]--; + } + else if (menuFuncData[0] == 9) { + menuFuncData[3] = 0; + } + else { + menuEditFloat(&menuFuncDataFloat, 4, 2, menuFuncData[0]-2, MENU_DOWN, -1000, 1000); + } + break; + } + + float old = (menuFuncData[2] == 0 ? PID[menuFuncData[1]].P: + menuFuncData[2] == 1 ? PID[menuFuncData[1]].I: + PID[menuFuncData[1]].D); + + if (menuFuncData[0] < 2) { + // update value if edited value might have changed + menuFuncDataFloat = old; + } + + if (menuFuncData[0] < 9) { + // determine 'cursor' position + // assume we are editing the number + byte cl = ((menuFuncData[0] > 6) ? 12 : 11) + menuFuncData[0]; + byte cr = cl; + byte updn = MENU_SYM_BOTH; + // check if it is something else + if (menuFuncData[0] == 0) { + // selecting PID + cl = 5; + cr = 9; + if (menuFuncData[1] == 0) updn = MENU_SYM_UP; + if (menuFuncData[1] == (PIDCOUNT-1)) updn = MENU_SYM_DOWN; + } + else if (menuFuncData[0] == 1) { + // selecting P/I/D + cl = 11; + cr = cl; + if (menuFuncData[2] == 0) updn = MENU_SYM_UP; + if (menuFuncData[2] == 2) updn = MENU_SYM_DOWN; + } + notifyOSDmenu(OSD_CURSOR | OSD_NOCLEAR, cl, cr, "%cPID %s:%c=%c%04d.%02d", + updn, pidNames[menuFuncData[1]], menuFuncData[2]==0 ? 'P' : menuFuncData[2]==1 ? 'I' : 'D', + (menuFuncDataFloat >= 0) ? '+' : '-', + (int)abs(menuFuncDataFloat), (int)abs((menuFuncDataFloat - (int)menuFuncDataFloat) * 100.0)); + } + else { + // asking confirmation for changing the value + notifyOSDmenu(OSD_CURSOR|OSD_NOCLEAR,21,21,"C %c%04d.%02d->%c%04d.%02d?%c", + (old>=0)?'+':'-',(int)abs(old),(int)abs((old-(int)old)*100.0), + (menuFuncDataFloat>=0)?'+':'-',(int)abs(menuFuncDataFloat),(int)abs((menuFuncDataFloat-(int)menuFuncDataFloat)*100.0), + menuFuncData[3] ? 'Y' : 'N'); + } +} + + +// this define is used to convert a float into (char) sign, (int) integerpart, (int) per100parts +#define PRFLOAT(x) (((x)<0.0)?'-':' '),((int)abs(x)),(abs((int)(100*(x)))%100) + +void menuSensorInfo(byte mode, byte action){ + switch (action) { + case MENU_EXIT: + case MENU_ABORT: + menuInFunc=0; + break; + case MENU_CALLBACK: + case MENU_INIT: + switch (mode) { + case 0: // Accel + notifyOSD(OSD_NOCLEAR,"Acc: X%c%d.%02d Y%c%d.%02d Z%c%d.%02d", + PRFLOAT(meterPerSecSec[XAXIS]),PRFLOAT(meterPerSecSec[YAXIS]),PRFLOAT(meterPerSecSec[ZAXIS])); + break; + case 1: // Gyro + notifyOSD(OSD_NOCLEAR,"Gyr: X%c%d.%02d Y%c%d.%02dZ %c%d.%02d", + PRFLOAT(gyroRate[XAXIS]),PRFLOAT(gyroRate[YAXIS]),PRFLOAT(gyroRate[ZAXIS])); + break; + #if defined(HeadingMagHold) + case 2: // Mag + notifyOSD(OSD_NOCLEAR,"Mag: X%5d Y%5d Z%5d", + getMagnetometerData(XAXIS),getMagnetometerData(YAXIS),getMagnetometerData(ZAXIS)); + break; + #endif + #if defined(AltitudeHoldRangeFinder) + case 3: // Rangers + notifyOSD(OSD_NOCLEAR,"US:a%df%dr%dr%dl%d cm", + (int)(rangeFinderRange[ALTITUDE_RANGE_FINDER_INDEX]*100), + (int)(rangeFinderRange[FRONT_RANGE_FINDER_INDEX]*100), + (int)(rangeFinderRange[RIGHT_RANGE_FINDER_INDEX]*100), + (int)(rangeFinderRange[REAR_RANGE_FINDER_INDEX]*100), + (int)(rangeFinderRange[LEFT_RANGE_FINDER_INDEX]*100)); + break; + #endif + } + menuInFunc=3; + break; + default: + menuInFunc=3; + } +} + +void menuHideOSD(byte mode, byte action){ + + menuInFunc=0; + menuEntry=255; + notifyOSD(OSD_NOCLEAR,NULL); + hideOSD(); +} + +#ifdef CameraControl +short savedCenterYaw, savedCenterPitch, savedCenterRoll; +byte savedCameraMode; + +// #define POWERSAVE 10 // enable to shut off servos after idle +#if defined (POWERSAVE) + byte idleCounter = POWERSAVE; +#endif + +#define ZOOMPIN 24 + + +void menuCameraPTZ(byte mode, byte action){ + + if (action == MENU_INIT) { + hideOSD(); + menuOwnsSticks = 1; + savedCenterYaw = servoCenterYaw; + savedCenterPitch = servoCenterPitch; + savedCenterRoll = servoCenterRoll; + savedCameraMode = cameraMode; + cameraMode = 0; // disable stabilizer + menuFuncDataFloat = 0.0; + #if defined (POWERSAVE) + idleCounter = POWERSAVE; + #endif + } + else if ((action == MENU_CALLBACK) || (action == MENU_ABORT)) { + digitalWrite(ZOOMPIN, LOW); // Zoom off + pinMode(ZOOMPIN, INPUT); + #if defined (POWERSAVE) + TCCR1A |= ((1< 50) { + if (yaw>0) { + yaw-=50; + } + else { + yaw+=50; + } + servoCenterYaw = constrain(servoCenterYaw + (yaw/10), servoMinYaw, servoMaxYaw); + #if defined (POWERSAVE) + idleCounter = POWERSAVE; + #endif + } + + if (abs(receiverCommand[THROTTLE] - menuFuncDataFloat) > 2) { + menuFuncDataFloat = receiverCommand[THROTTLE]; + servoCenterPitch = constrain(3000 - menuFuncDataFloat, servoMinPitch, servoMaxPitch); + #if defined (POWERSAVE) + idleCounter = POWERSAVE; + #endif + } + + if (roll > MENU_STICK_REPEAT) { + // elevator + if (pitch < -MENU_STICK_REPEAT) { + // DOWN + servoCenterRoll = servoMinRoll; + } + else if (pitch > MENU_STICK_REPEAT) { + // UP + servoCenterRoll = servoMaxRoll; + } else { + // STOP + servoCenterRoll = savedCenterRoll; + } + #if defined (POWERSAVE) + idleCounter = POWERSAVE; + #endif + + } + else { + // zoom + if (pitch < -MENU_STICK_REPEAT) { + // zoom out + pinMode(ZOOMPIN, OUTPUT); + digitalWrite(ZOOMPIN, LOW); + } + else if (pitch > MENU_STICK_REPEAT) { + // zoom in + pinMode(ZOOMPIN, OUTPUT); + digitalWrite(ZOOMPIN, HIGH); + } else { + // release zoom + digitalWrite(ZOOMPIN, LOW); // this is needed to remove the 'internal pullup' + pinMode(ZOOMPIN, INPUT); + } + } + #if defined (POWERSAVE) + if (idleCounter == POWERSAVE) { + idleCounter--; + TCCR1A |= ((1<0) { + idleCounter--; + if (idleCounter == 0) { + TCCR1A &= ~((1< menuData[menuEntry-1].level)) { + menuAtExit=1; + } + else { + for (byte i=menuEntry-1; i>=0; i--) { + if (menuData[menuEntry].level == menuData[i].level) { + menuEntry = i; + break; + } + } + } + menuShow(menuEntry); +} + +void menuDown() { + + if (255 == menuEntry) { + return; + } + if (menuInFunc) { + MENU_CALLFUNC(menuEntry, MENU_DOWN); + return; + } + if (menuAtExit) { + menuAtExit = 0; + } + else { + if (menuIsLast(menuEntry)) return; + for (byte i = menuEntry + 1; i < menuNumEntries; i++) { + if (menuData[menuEntry].level == menuData[i].level) { + menuEntry = i; + break; + } + } + } + menuShow(menuEntry); +} + +void menuSelect() { + + if (255==menuEntry) { + // enable menu + unhideOSD(); // make sure OSD is visible + menuAtExit=0; + menuEntry=0; + } + else if (menuInFunc) { + MENU_CALLFUNC(menuEntry,MENU_SELECT); + if (menuInFunc) return; // redisplay menu if we exited from handler + } + else if (menuAtExit) { + if (0==menuEntry) { + menuEntry=255; + } + else { + // leave submenu + menuEntry--; + menuAtExit=0; + } + } + else if (menuData[menuEntry].function != MENU_NOFUNC) { + menuInFunc = 1; + MENU_CALLFUNC(menuEntry, MENU_INIT); + return; + } + else if (menuData[menuEntry].level < menuData[menuEntry + 1].level) { + // enter submenu + menuEntry++; + } + menuShow(menuEntry); +} + +void menuExit() { + + if (255 == menuEntry) + return; + + if (menuInFunc) { + MENU_CALLFUNC(menuEntry, MENU_EXIT); + if (menuInFunc) + return; + } + else if ((0 == menuEntry) || (0 == menuData[menuEntry].level)) { + menuEntry = 255; + } + else { + // leave submenu + for (byte i = menuEntry-1; i>=0; i--) { + if (menuData[i].level < menuData[menuEntry].level) { + menuEntry = i; + menuAtExit = 0; + break; + } + } + } + menuShow(menuEntry); +} + +void updateOSDMenu() { + + // check for special HiJack mode + if ((menuEntry!=255) && menuOwnsSticks && menuInFunc) { + + MENU_CALLFUNC(menuEntry, MENU_HIJACK); + if (menuInFunc == 0) { + menuShow(menuEntry); + } + return; + } + + // check if armed, menu is only operational when not armed + if (motorArmed == true) { + if (menuEntry != 255) { + // BAIL OUT of menu if armed + if (menuInFunc) { + MENU_CALLFUNC(menuEntry, MENU_ABORT); + } + notifyOSD(0, NULL); // clear menuline + menuInFunc = 0; + menuEntry = 255; + } + return; + } + + // check if we're waiting for callback to happen + if (menuInFunc > 1) { + menuInFunc--; + if (menuInFunc == 1) { + // call the callback when counter hits 1 + MENU_CALLFUNC(menuEntry, MENU_CALLBACK); + // show the menu entry if the handler function 'exited' + if (menuInFunc == 0) { + menuShow(menuEntry); + } + return; + } + } + + const short roll = receiverCommand[XAXIS] - MENU_STICK_CENTER; // pitch/roll should be -500 - +500 + const short pitch = receiverCommand[YAXIS] - MENU_STICK_CENTER; + + if (abs(roll) < MENU_STICK_NEUTRAL) { + if (abs(pitch) < MENU_STICK_NEUTRAL) { + // stick at center + stickWaitNeutral = 0; + return; + } + else { + // roll at neutral, pitch not + if (abs(pitch) > MENU_STICK_REPEAT) { + // above repeat threshold so allow redoing action + stickWaitNeutral = 0; + } + + // check if we are waiting for neutral (after single action) + if (stickWaitNeutral) { + return; + } + + // call action function if stick active + if (abs(pitch) > MENU_STICK_ACTIVE) { + if (pitch > 0) { + menuUp(); + } + else { + menuDown(); + } + + // action done, further actions only after centering (or repeat) + stickWaitNeutral = 1; + } + } + } + else { + if (abs(pitch) >= MENU_STICK_NEUTRAL) { + return; // both ways active - no action + } + if (abs(roll) > MENU_STICK_ACTIVE) { + if (roll > 0) { + if (!stickWaitNeutral) { + menuSelect(); + } + } + else { + if ((!stickWaitNeutral) || (abs(roll) >= MENU_STICK_REPEAT)) { + menuExit(); + } + } + stickWaitNeutral = 1; + } + } + return; +} + +#endif // Menu_h diff --git a/AeroQuad/PID.h b/AeroQuad/PID.h index 579bbe5f..92634d0b 100644 --- a/AeroQuad/PID.h +++ b/AeroQuad/PID.h @@ -96,4 +96,4 @@ void zeroIntegralError() { #endif // _AQ_PID_H_ - + diff --git a/AeroQuad/SerialCom.h b/AeroQuad/SerialCom.h index eeb4a36d..b72fc6a0 100644 --- a/AeroQuad/SerialCom.h +++ b/AeroQuad/SerialCom.h @@ -1088,4 +1088,4 @@ void reportVehicleState() { } #endif // SlowTelemetry -#endif // _AQ_SERIAL_COMM_ +#endif // _AQ_SERIAL_COMM_ diff --git a/AeroQuad/UserConfiguration.h b/AeroQuad/UserConfiguration.h index 66ef2724..68ef6e2a 100644 --- a/AeroQuad/UserConfiguration.h +++ b/AeroQuad/UserConfiguration.h @@ -213,4 +213,4 @@ ********************* End of User Definition Section *********************** **************************************************************************** **************************************************************************** - ****************************************************************************/ + ****************************************************************************/ diff --git a/AeroQuad32/AeroQuadMain.cpp b/AeroQuad32/AeroQuadMain.cpp index 5426048a..846b0413 100644 --- a/AeroQuad32/AeroQuadMain.cpp +++ b/AeroQuad32/AeroQuadMain.cpp @@ -1,31 +1,31 @@ -#include <../AeroQuad/UserConfiguration.h> -#include -#include - -__attribute__(( constructor )) void premain() { - init(); -} - -extern "C"{ - void _init(){}; -} - -// Uncomment this if compiling on OS X -/*extern "C"{ - void _init(){}; // dummy _init function for support of GNU toolchain from https://launchpad.net/gcc-arm-embedded -}*/ - -int main(void) -{ - //init(); - setup(); - - for (;;) - loop(); - - return 0; -} - - -#include "../AeroQuad/AeroQuad.ino" - +#include <../AeroQuad/UserConfiguration.h> +#include +#include + +__attribute__(( constructor )) void premain() { + init(); +} + +extern "C"{ + void _init(){}; +} + +// Uncomment this if compiling on OS X +/*extern "C"{ + void _init(){}; // dummy _init function for support of GNU toolchain from https://launchpad.net/gcc-arm-embedded +}*/ + +int main(void) +{ + //init(); + setup(); + + for (;;) + loop(); + + return 0; +} + + +#include "../AeroQuad/AeroQuad.ino" + diff --git a/AeroQuad32/AeroQuad_STM32.h b/AeroQuad32/AeroQuad_STM32.h index d7f110fe..68ea0d04 100644 --- a/AeroQuad32/AeroQuad_STM32.h +++ b/AeroQuad32/AeroQuad_STM32.h @@ -1,39 +1,39 @@ -#ifndef _AEROQUAD_STM32_H_ - #define _AEROQUAD_STM32_H_ - - #define __STM32__ - #define DEBUG_INIT - tSerial &Serial = SERIAL_VAR; - - #define ADC_NUMBER_OF_BITS 12 - - // Receiver Declaration - #if defined (ReceiverPPM) || defined (ReceiverHWPPM) - #undef ReceiverPPM - #undef ReceiverHWPPM - #define RECEIVER_STM32PPM - #elif defined (ReceiverSBUS) - #else - #define RECEIVER_STM32 - #endif - - // Motor declaration - #define MOTOR_STM32 - - - #ifdef CameraControl - #define CameraControl_STM32 - #endif - - - #if defined(BOARD_aeroquad32) - #include "platform_aeroquad32.h" - #elif defined(BOARD_freeflight) - #include "platform_freeflight.h" - #elif defined(BOARD_discovery_f4) - #include "platform_discoveryf4.h" - #else - #error "No motor pinout defined for this STM32 board" - #endif -#endif - +#ifndef _AEROQUAD_STM32_H_ + #define _AEROQUAD_STM32_H_ + + #define __STM32__ + #define DEBUG_INIT + tSerial &Serial = SERIAL_VAR; + + #define ADC_NUMBER_OF_BITS 12 + + // Receiver Declaration + #if defined (ReceiverPPM) || defined (ReceiverHWPPM) + #undef ReceiverPPM + #undef ReceiverHWPPM + #define RECEIVER_STM32PPM + #elif defined (ReceiverSBUS) + #else + #define RECEIVER_STM32 + #endif + + // Motor declaration + #define MOTOR_STM32 + + + #ifdef CameraControl + #define CameraControl_STM32 + #endif + + + #if defined(BOARD_aeroquad32) + #include "platform_aeroquad32.h" + #elif defined(BOARD_freeflight) + #include "platform_freeflight.h" + #elif defined(BOARD_discovery_f4) + #include "platform_discoveryf4.h" + #else + #error "No motor pinout defined for this STM32 board" + #endif +#endif + diff --git a/AeroQuad32/MapleCompatibility/Arduino.h b/AeroQuad32/MapleCompatibility/Arduino.h index b9067f00..7278f899 100644 --- a/AeroQuad32/MapleCompatibility/Arduino.h +++ b/AeroQuad32/MapleCompatibility/Arduino.h @@ -1,4 +1,4 @@ -#ifndef Arduino_h -#define Arduino_h -#include "WProgram.h" -#endif +#ifndef Arduino_h +#define Arduino_h +#include "WProgram.h" +#endif diff --git a/AeroQuad32/MapleCompatibility/EEPROM.cpp b/AeroQuad32/MapleCompatibility/EEPROM.cpp index a9e99ad0..61062b51 100644 --- a/AeroQuad32/MapleCompatibility/EEPROM.cpp +++ b/AeroQuad32/MapleCompatibility/EEPROM.cpp @@ -1,548 +1,548 @@ -#include "wirish.h" -#include "EEPROM.h" - -/** - * @brief Check page for blank - * @param page base address - * @retval Success or error - * EEPROM_BAD_FLASH: page not empty after erase - * EEPROM_OK: page blank - */ -uint16 EEPROMClass::EE_CheckPage(uint32 pageBase, uint16 status) -{ - uint32 pageEnd = pageBase + (uint32)PageSize; - - // Page Status not EEPROM_ERASED and not a "state" - if ((*(__io uint16*)pageBase) != EEPROM_ERASED && (*(__io uint16*)pageBase) != status) - return EEPROM_BAD_FLASH; - for(pageBase += 4; pageBase < pageEnd; pageBase += 4) - if ((*(__io uint32*)pageBase) != 0xFFFFFFFF) // Verify if slot is empty - return EEPROM_BAD_FLASH; - return EEPROM_OK; -} - -/** - * @brief Erase page with increment erase counter (page + 2) - * @param page base address - * @retval Success or error - * FLASH_COMPLETE: success erase - * - Flash error code: on write Flash error - */ -FLASH_Status EEPROMClass::EE_ErasePage(uint32 pageBase) -{ - FLASH_Status FlashStatus; - uint16 data = (*(__io uint16*)(pageBase)); - if ((data == EEPROM_ERASED) || (data == EEPROM_VALID_PAGE) || (data == EEPROM_RECEIVE_DATA)) - data = (*(__io uint16*)(pageBase + 2)) + 1; - else - data = 0; - - FlashStatus = FLASH_ErasePage(pageBase); - if (FlashStatus == FLASH_COMPLETE) - FlashStatus = FLASH_ProgramHalfWord(pageBase + 2, data); - - return FlashStatus; -} - -/** - * @brief Check page for blank and erase it - * @param page base address - * @retval Success or error - * - Flash error code: on write Flash error - * - EEPROM_BAD_FLASH: page not empty after erase - * - EEPROM_OK: page blank - */ -uint16 EEPROMClass::EE_CheckErasePage(uint32 pageBase, uint16 status) -{ - uint16 FlashStatus; - if (EE_CheckPage(pageBase, status) != EEPROM_OK) - { - FlashStatus = EE_ErasePage(pageBase); - if (FlashStatus != FLASH_COMPLETE) - return FlashStatus; - return EE_CheckPage(pageBase, status); - } - return EEPROM_OK; -} - -/** - * @brief Find valid Page for write or read operation - * @param Page0: Page0 base address - * Page1: Page1 base address - * @retval Valid page address (PAGE0 or PAGE1) or NULL in case of no valid page was found - */ -uint32 EEPROMClass::EE_FindValidPage(void) -{ - uint16 status0 = (*(__io uint16*)PageBase0); // Get Page0 actual status - uint16 status1 = (*(__io uint16*)PageBase1); // Get Page1 actual status - - if (status0 == EEPROM_VALID_PAGE && status1 == EEPROM_ERASED) - return PageBase0; - if (status1 == EEPROM_VALID_PAGE && status0 == EEPROM_ERASED) - return PageBase1; - - return 0; -} - -/** - * @brief Calculate unique variables in EEPROM - * @param start: address of first slot to check (page + 4) - * @param end: page end address - * @param address: 16 bit virtual address of the variable to excluse (or 0XFFFF) - * @retval count of variables - */ -uint16 EEPROMClass::EE_GetVariablesCount(uint32 pageBase, uint16 skipAddress) -{ - uint16 varAddress, nextAddress; - uint32 idx; - uint32 pageEnd = pageBase + (uint32)PageSize; - uint16 count = 0; - - for (pageBase += 6; pageBase < pageEnd; pageBase += 4) - { - varAddress = (*(__io uint16*)pageBase); - if (varAddress == 0xFFFF || varAddress == skipAddress) - continue; - - count++; - for(idx = pageBase + 4; idx < pageEnd; idx += 4) - { - nextAddress = (*(__io uint16*)idx); - if (nextAddress == varAddress) - { - count--; - break; - } - } - } - return count; -} - -/** - * @brief Transfers last updated variables data from the full Page to an empty one. - * @param newPage: new page base address - * @param oldPage: old page base address - * @param SkipAddress: 16 bit virtual address of the variable (or 0xFFFF) - * @retval Success or error status: - * - FLASH_COMPLETE: on success - * - EEPROM_OUT_SIZE: if valid new page is full - * - Flash error code: on write Flash error - */ -uint16 EEPROMClass::EE_PageTransfer(uint32 newPage, uint32 oldPage, uint16 SkipAddress) -{ - uint32 oldEnd, newEnd; - uint32 oldIdx, newIdx, idx; - uint16 address, data, found; - FLASH_Status FlashStatus; - - // Transfer process: transfer variables from old to the new active page - newEnd = newPage + ((uint32)PageSize); - - // Find first free element in new page - for (newIdx = newPage + 4; newIdx < newEnd; newIdx += 4) - if ((*(__io uint32*)newIdx) == 0xFFFFFFFF) // Verify if element - break; // contents are 0xFFFFFFFF - if (newIdx >= newEnd) - return EEPROM_OUT_SIZE; - - oldEnd = oldPage + 4; - oldIdx = oldPage + (uint32)(PageSize - 2); - - for (; oldIdx > oldEnd; oldIdx -= 4) - { - address = *(__io uint16*)oldIdx; - if (address == 0xFFFF || address == SkipAddress) - continue; // it's means that power off after write data - - found = 0; - for (idx = newPage + 6; idx < newIdx; idx += 4) - if ((*(__io uint16*)(idx)) == address) - { - found = 1; - break; - } - - if (found) - continue; - - if (newIdx < newEnd) - { - data = (*(__io uint16*)(oldIdx - 2)); - - FlashStatus = FLASH_ProgramHalfWord(newIdx, data); - if (FlashStatus != FLASH_COMPLETE) - return FlashStatus; - - FlashStatus = FLASH_ProgramHalfWord(newIdx + 2, address); - if (FlashStatus != FLASH_COMPLETE) - return FlashStatus; - - newIdx += 4; - } - else - return EEPROM_OUT_SIZE; - } - - // Erase the old Page: Set old Page status to EEPROM_EEPROM_ERASED status - data = EE_CheckErasePage(oldPage, EEPROM_ERASED); - if (data != EEPROM_OK) - return data; - - // Set new Page status - FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_VALID_PAGE); - if (FlashStatus != FLASH_COMPLETE) - return FlashStatus; - - return EEPROM_OK; -} - -/** - * @brief Verify if active page is full and Writes variable in EEPROM. - * @param Address: 16 bit virtual address of the variable - * @param Data: 16 bit data to be written as variable value - * @retval Success or error status: - * - FLASH_COMPLETE: on success - * - EEPROM_PAGE_FULL: if valid page is full (need page transfer) - * - EEPROM_NO_VALID_PAGE: if no valid page was found - * - EEPROM_OUT_SIZE: if EEPROM size exceeded - * - Flash error code: on write Flash error - */ -uint16 EEPROMClass::EE_VerifyPageFullWriteVariable(uint16 Address, uint16 Data) -{ - FLASH_Status FlashStatus; - uint32 idx, pageBase, pageEnd, newPage; - uint16 count; - - // Get valid Page for write operation - pageBase = EE_FindValidPage(); - if (pageBase == 0) - return EEPROM_NO_VALID_PAGE; - - // Get the valid Page end Address - pageEnd = pageBase + PageSize; // Set end of page - - for (idx = pageEnd - 2; idx > pageBase; idx -= 4) - { - if ((*(__io uint16*)idx) == Address) // Find last value for address - { - count = (*(__io uint16*)(idx - 2)); // Read last data - if (count == Data) - return EEPROM_OK; - if (count == 0xFFFF) - { - FlashStatus = FLASH_ProgramHalfWord(idx - 2, Data); // Set variable data - if (FlashStatus == FLASH_COMPLETE) - return EEPROM_OK; - } - break; - } - } - - // Check each active page address starting from begining - for (idx = pageBase + 4; idx < pageEnd; idx += 4) - if ((*(__io uint32*)idx) == 0xFFFFFFFF) // Verify if element - { // contents are 0xFFFFFFFF - FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data - if (FlashStatus != FLASH_COMPLETE) - return FlashStatus; - FlashStatus = FLASH_ProgramHalfWord(idx + 2, Address); // Set variable virtual address - if (FlashStatus != FLASH_COMPLETE) - return FlashStatus; - return EEPROM_OK; - } - - // Empty slot not found, need page transfer - // Calculate unique variables in page - count = EE_GetVariablesCount(pageBase, Address) + 1; - if (count >= (PageSize / 4 - 1)) - return EEPROM_OUT_SIZE; - - if (pageBase == PageBase1) - newPage = PageBase0; // New page address where variable will be moved to - else - newPage = PageBase1; - - // Set the new Page status to RECEIVE_DATA status - FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_RECEIVE_DATA); - if (FlashStatus != FLASH_COMPLETE) - return FlashStatus; - - // Write the variable passed as parameter in the new active page - FlashStatus = FLASH_ProgramHalfWord(newPage + 4, Data); - if (FlashStatus != FLASH_COMPLETE) - return FlashStatus; - - FlashStatus = FLASH_ProgramHalfWord(newPage + 6, Address); - if (FlashStatus != FLASH_COMPLETE) - return FlashStatus; - - return EE_PageTransfer(newPage, pageBase, Address); -} - -EEPROMClass::EEPROMClass(void) -{ - PageBase0 = EEPROM_PAGE0_BASE; - PageBase1 = EEPROM_PAGE1_BASE; - PageSize = EEPROM_PAGE_SIZE; - Status = EEPROM_NOT_INIT; -} - -uint16 EEPROMClass::init(uint32 pageBase0, uint32 pageBase1, uint32 pageSize) -{ - PageBase0 = pageBase0; - PageBase1 = pageBase1; - PageSize = pageSize; - return init(); -} - -uint16 EEPROMClass::init(void) -{ - uint16 status0, status1; - FLASH_Status FlashStatus; - - FLASH_Unlock(); - Status = EEPROM_NO_VALID_PAGE; - - status0 = (*(__io uint16 *)PageBase0); - status1 = (*(__io uint16 *)PageBase1); - - switch (status0) - { -/* - Page0 Page1 - ----- ----- - EEPROM_ERASED EEPROM_VALID_PAGE Page1 valid, Page0 erased - EEPROM_RECEIVE_DATA Page1 need set to valid, Page0 erased - EEPROM_ERASED make EE_Format - any Error: EEPROM_NO_VALID_PAGE -*/ - case EEPROM_ERASED: - if (status1 == EEPROM_VALID_PAGE) // Page0 erased, Page1 valid - Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); - else if (status1 == EEPROM_RECEIVE_DATA) // Page0 erased, Page1 receive - { - FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE); - if (FlashStatus != FLASH_COMPLETE) - Status = FlashStatus; - else - Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); - } - else if (status1 == EEPROM_ERASED) // Both in erased state so format EEPROM - Status = format(); - break; -/* - Page0 Page1 - ----- ----- - EEPROM_RECEIVE_DATA EEPROM_VALID_PAGE Transfer Page1 to Page0 - EEPROM_ERASED Page0 need set to valid, Page1 erased - any EEPROM_NO_VALID_PAGE -*/ - case EEPROM_RECEIVE_DATA: - if (status1 == EEPROM_VALID_PAGE) // Page0 receive, Page1 valid - Status = EE_PageTransfer(PageBase0, PageBase1, 0xFFFF); - else if (status1 == EEPROM_ERASED) // Page0 receive, Page1 erased - { - Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED); - if (Status == EEPROM_OK) - { - FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE); - if (FlashStatus != FLASH_COMPLETE) - Status = FlashStatus; - else - Status = EEPROM_OK; - } - } - break; -/* - Page0 Page1 - ----- ----- - EEPROM_VALID_PAGE EEPROM_VALID_PAGE Error: EEPROM_NO_VALID_PAGE - EEPROM_RECEIVE_DATA Transfer Page0 to Page1 - any Page0 valid, Page1 erased -*/ - case EEPROM_VALID_PAGE: - if (status1 == EEPROM_VALID_PAGE) // Both pages valid - Status = EEPROM_NO_VALID_PAGE; - else if (status1 == EEPROM_RECEIVE_DATA) - Status = EE_PageTransfer(PageBase1, PageBase0, 0xFFFF); - else - Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED); - break; -/* - Page0 Page1 - ----- ----- - any EEPROM_VALID_PAGE Page1 valid, Page0 erased - EEPROM_RECEIVE_DATA Page1 valid, Page0 erased - any EEPROM_NO_VALID_PAGE -*/ - default: - if (status1 == EEPROM_VALID_PAGE) - Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); // Check/Erase Page0 - else if (status1 == EEPROM_RECEIVE_DATA) - { - FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE); - if (FlashStatus != FLASH_COMPLETE) - Status = FlashStatus; - else - Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); - } - break; - } - return Status; -} - -/** - * @brief Erases PAGE0 and PAGE1 and writes EEPROM_VALID_PAGE / 0 header to PAGE0 - * @param PAGE0 and PAGE1 base addresses - * @retval Status of the last operation (Flash write or erase) done during EEPROM formating - */ -uint16 EEPROMClass::format(void) -{ - uint16 status; - FLASH_Status FlashStatus; - - FLASH_Unlock(); - - // Erase Page0 - status = EE_CheckErasePage(PageBase0, EEPROM_VALID_PAGE); - if (status != EEPROM_OK) - return status; - if ((*(__io uint16*)PageBase0) == EEPROM_ERASED) - { - // Set Page0 as valid page: Write VALID_PAGE at Page0 base address - FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE); - if (FlashStatus != FLASH_COMPLETE) - return FlashStatus; - } - // Erase Page1 - return EE_CheckErasePage(PageBase1, EEPROM_ERASED); -} - -/** - * @brief Returns the erase counter for current page - * @param Data: Global variable contains the read variable value - * @retval Success or error status: - * - EEPROM_OK: if erases counter return. - * - EEPROM_NO_VALID_PAGE: if no valid page was found. - */ -uint16 EEPROMClass::erases(uint16 *Erases) -{ - uint32 pageBase; - if (Status != EEPROM_OK) - if (init() != EEPROM_OK) - return Status; - - // Get active Page for read operation - pageBase = EE_FindValidPage(); - if (pageBase == 0) - return EEPROM_NO_VALID_PAGE; - - *Erases = (*(__io uint16*)pageBase+2); - return EEPROM_OK; -} - -/** - * @brief Returns the last stored variable data, if found, - * which correspond to the passed virtual address - * @param Address: Variable virtual address - * @retval Data for variable or EEPROM_DEFAULT_DATA, if any errors - */ -uint16 EEPROMClass::read (uint16 Address) -{ - uint16 data; - read(Address, &data); - return data; -} - -/** - * @brief Returns the last stored variable data, if found, - * which correspond to the passed virtual address - * @param Address: Variable virtual address - * @param Data: Pointer to data variable - * @retval Success or error status: - * - EEPROM_OK: if variable was found - * - EEPROM_BAD_ADDRESS: if the variable was not found - * - EEPROM_NO_VALID_PAGE: if no valid page was found. - */ -uint16 EEPROMClass::read(uint16 Address, uint16 *Data) -{ - uint32 pageBase, pageEnd; - - // Set default data (empty EEPROM) - *Data = EEPROM_DEFAULT_DATA; - - if (Status == EEPROM_NOT_INIT) - if (init() != EEPROM_OK) - return Status; - - // Get active Page for read operation - pageBase = EE_FindValidPage(); - if (pageBase == 0) - return EEPROM_NO_VALID_PAGE; - - // Get the valid Page end Address - pageEnd = pageBase + ((uint32)(PageSize - 2)); - - // Check each active page address starting from end - for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4) - if ((*(__io uint16*)pageEnd) == Address) // Compare the read address with the virtual address - { - *Data = (*(__io uint16*)(pageEnd - 2)); // Get content of Address-2 which is variable value - return EEPROM_OK; - } - - // Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) - return EEPROM_BAD_ADDRESS; -} - -/** - * @brief Writes/upadtes variable data in EEPROM. - * @param VirtAddress: Variable virtual address - * @param Data: 16 bit data to be written - * @retval Success or error status: - * - FLASH_COMPLETE: on success - * - EEPROM_BAD_ADDRESS: if address = 0xFFFF - * - EEPROM_PAGE_FULL: if valid page is full - * - EEPROM_NO_VALID_PAGE: if no valid page was found - * - EEPROM_OUT_SIZE: if no empty EEPROM variables - * - Flash error code: on write Flash error - */ -uint16 EEPROMClass::write(uint16 Address, uint16 Data) -{ - if (Status == EEPROM_NOT_INIT) - if (init() != EEPROM_OK) - return Status; - - if (Address == 0xFFFF) - return EEPROM_BAD_ADDRESS; - - // Write the variable virtual address and value in the EEPROM - uint16 status = EE_VerifyPageFullWriteVariable(Address, Data); - return status; -} - -/** - * @brief Return number of variable - * @retval Number of variables - */ -uint16 EEPROMClass::count(uint16 *Count) -{ - if (Status == EEPROM_NOT_INIT) - if (init() != EEPROM_OK) - return Status; - - // Get valid Page for write operation - uint32 pageBase = EE_FindValidPage(); - if (pageBase == 0) - return EEPROM_NO_VALID_PAGE; // No valid page, return max. numbers - - *Count = EE_GetVariablesCount(pageBase, 0xFFFF); - return EEPROM_OK; -} - -uint16 EEPROMClass::maxcount(void) -{ - return ((PageSize / 4)-1); -} - -EEPROMClass EEPROM; +#include "wirish.h" +#include "EEPROM.h" + +/** + * @brief Check page for blank + * @param page base address + * @retval Success or error + * EEPROM_BAD_FLASH: page not empty after erase + * EEPROM_OK: page blank + */ +uint16 EEPROMClass::EE_CheckPage(uint32 pageBase, uint16 status) +{ + uint32 pageEnd = pageBase + (uint32)PageSize; + + // Page Status not EEPROM_ERASED and not a "state" + if ((*(__io uint16*)pageBase) != EEPROM_ERASED && (*(__io uint16*)pageBase) != status) + return EEPROM_BAD_FLASH; + for(pageBase += 4; pageBase < pageEnd; pageBase += 4) + if ((*(__io uint32*)pageBase) != 0xFFFFFFFF) // Verify if slot is empty + return EEPROM_BAD_FLASH; + return EEPROM_OK; +} + +/** + * @brief Erase page with increment erase counter (page + 2) + * @param page base address + * @retval Success or error + * FLASH_COMPLETE: success erase + * - Flash error code: on write Flash error + */ +FLASH_Status EEPROMClass::EE_ErasePage(uint32 pageBase) +{ + FLASH_Status FlashStatus; + uint16 data = (*(__io uint16*)(pageBase)); + if ((data == EEPROM_ERASED) || (data == EEPROM_VALID_PAGE) || (data == EEPROM_RECEIVE_DATA)) + data = (*(__io uint16*)(pageBase + 2)) + 1; + else + data = 0; + + FlashStatus = FLASH_ErasePage(pageBase); + if (FlashStatus == FLASH_COMPLETE) + FlashStatus = FLASH_ProgramHalfWord(pageBase + 2, data); + + return FlashStatus; +} + +/** + * @brief Check page for blank and erase it + * @param page base address + * @retval Success or error + * - Flash error code: on write Flash error + * - EEPROM_BAD_FLASH: page not empty after erase + * - EEPROM_OK: page blank + */ +uint16 EEPROMClass::EE_CheckErasePage(uint32 pageBase, uint16 status) +{ + uint16 FlashStatus; + if (EE_CheckPage(pageBase, status) != EEPROM_OK) + { + FlashStatus = EE_ErasePage(pageBase); + if (FlashStatus != FLASH_COMPLETE) + return FlashStatus; + return EE_CheckPage(pageBase, status); + } + return EEPROM_OK; +} + +/** + * @brief Find valid Page for write or read operation + * @param Page0: Page0 base address + * Page1: Page1 base address + * @retval Valid page address (PAGE0 or PAGE1) or NULL in case of no valid page was found + */ +uint32 EEPROMClass::EE_FindValidPage(void) +{ + uint16 status0 = (*(__io uint16*)PageBase0); // Get Page0 actual status + uint16 status1 = (*(__io uint16*)PageBase1); // Get Page1 actual status + + if (status0 == EEPROM_VALID_PAGE && status1 == EEPROM_ERASED) + return PageBase0; + if (status1 == EEPROM_VALID_PAGE && status0 == EEPROM_ERASED) + return PageBase1; + + return 0; +} + +/** + * @brief Calculate unique variables in EEPROM + * @param start: address of first slot to check (page + 4) + * @param end: page end address + * @param address: 16 bit virtual address of the variable to excluse (or 0XFFFF) + * @retval count of variables + */ +uint16 EEPROMClass::EE_GetVariablesCount(uint32 pageBase, uint16 skipAddress) +{ + uint16 varAddress, nextAddress; + uint32 idx; + uint32 pageEnd = pageBase + (uint32)PageSize; + uint16 count = 0; + + for (pageBase += 6; pageBase < pageEnd; pageBase += 4) + { + varAddress = (*(__io uint16*)pageBase); + if (varAddress == 0xFFFF || varAddress == skipAddress) + continue; + + count++; + for(idx = pageBase + 4; idx < pageEnd; idx += 4) + { + nextAddress = (*(__io uint16*)idx); + if (nextAddress == varAddress) + { + count--; + break; + } + } + } + return count; +} + +/** + * @brief Transfers last updated variables data from the full Page to an empty one. + * @param newPage: new page base address + * @param oldPage: old page base address + * @param SkipAddress: 16 bit virtual address of the variable (or 0xFFFF) + * @retval Success or error status: + * - FLASH_COMPLETE: on success + * - EEPROM_OUT_SIZE: if valid new page is full + * - Flash error code: on write Flash error + */ +uint16 EEPROMClass::EE_PageTransfer(uint32 newPage, uint32 oldPage, uint16 SkipAddress) +{ + uint32 oldEnd, newEnd; + uint32 oldIdx, newIdx, idx; + uint16 address, data, found; + FLASH_Status FlashStatus; + + // Transfer process: transfer variables from old to the new active page + newEnd = newPage + ((uint32)PageSize); + + // Find first free element in new page + for (newIdx = newPage + 4; newIdx < newEnd; newIdx += 4) + if ((*(__io uint32*)newIdx) == 0xFFFFFFFF) // Verify if element + break; // contents are 0xFFFFFFFF + if (newIdx >= newEnd) + return EEPROM_OUT_SIZE; + + oldEnd = oldPage + 4; + oldIdx = oldPage + (uint32)(PageSize - 2); + + for (; oldIdx > oldEnd; oldIdx -= 4) + { + address = *(__io uint16*)oldIdx; + if (address == 0xFFFF || address == SkipAddress) + continue; // it's means that power off after write data + + found = 0; + for (idx = newPage + 6; idx < newIdx; idx += 4) + if ((*(__io uint16*)(idx)) == address) + { + found = 1; + break; + } + + if (found) + continue; + + if (newIdx < newEnd) + { + data = (*(__io uint16*)(oldIdx - 2)); + + FlashStatus = FLASH_ProgramHalfWord(newIdx, data); + if (FlashStatus != FLASH_COMPLETE) + return FlashStatus; + + FlashStatus = FLASH_ProgramHalfWord(newIdx + 2, address); + if (FlashStatus != FLASH_COMPLETE) + return FlashStatus; + + newIdx += 4; + } + else + return EEPROM_OUT_SIZE; + } + + // Erase the old Page: Set old Page status to EEPROM_EEPROM_ERASED status + data = EE_CheckErasePage(oldPage, EEPROM_ERASED); + if (data != EEPROM_OK) + return data; + + // Set new Page status + FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_VALID_PAGE); + if (FlashStatus != FLASH_COMPLETE) + return FlashStatus; + + return EEPROM_OK; +} + +/** + * @brief Verify if active page is full and Writes variable in EEPROM. + * @param Address: 16 bit virtual address of the variable + * @param Data: 16 bit data to be written as variable value + * @retval Success or error status: + * - FLASH_COMPLETE: on success + * - EEPROM_PAGE_FULL: if valid page is full (need page transfer) + * - EEPROM_NO_VALID_PAGE: if no valid page was found + * - EEPROM_OUT_SIZE: if EEPROM size exceeded + * - Flash error code: on write Flash error + */ +uint16 EEPROMClass::EE_VerifyPageFullWriteVariable(uint16 Address, uint16 Data) +{ + FLASH_Status FlashStatus; + uint32 idx, pageBase, pageEnd, newPage; + uint16 count; + + // Get valid Page for write operation + pageBase = EE_FindValidPage(); + if (pageBase == 0) + return EEPROM_NO_VALID_PAGE; + + // Get the valid Page end Address + pageEnd = pageBase + PageSize; // Set end of page + + for (idx = pageEnd - 2; idx > pageBase; idx -= 4) + { + if ((*(__io uint16*)idx) == Address) // Find last value for address + { + count = (*(__io uint16*)(idx - 2)); // Read last data + if (count == Data) + return EEPROM_OK; + if (count == 0xFFFF) + { + FlashStatus = FLASH_ProgramHalfWord(idx - 2, Data); // Set variable data + if (FlashStatus == FLASH_COMPLETE) + return EEPROM_OK; + } + break; + } + } + + // Check each active page address starting from begining + for (idx = pageBase + 4; idx < pageEnd; idx += 4) + if ((*(__io uint32*)idx) == 0xFFFFFFFF) // Verify if element + { // contents are 0xFFFFFFFF + FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data + if (FlashStatus != FLASH_COMPLETE) + return FlashStatus; + FlashStatus = FLASH_ProgramHalfWord(idx + 2, Address); // Set variable virtual address + if (FlashStatus != FLASH_COMPLETE) + return FlashStatus; + return EEPROM_OK; + } + + // Empty slot not found, need page transfer + // Calculate unique variables in page + count = EE_GetVariablesCount(pageBase, Address) + 1; + if (count >= (PageSize / 4 - 1)) + return EEPROM_OUT_SIZE; + + if (pageBase == PageBase1) + newPage = PageBase0; // New page address where variable will be moved to + else + newPage = PageBase1; + + // Set the new Page status to RECEIVE_DATA status + FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_RECEIVE_DATA); + if (FlashStatus != FLASH_COMPLETE) + return FlashStatus; + + // Write the variable passed as parameter in the new active page + FlashStatus = FLASH_ProgramHalfWord(newPage + 4, Data); + if (FlashStatus != FLASH_COMPLETE) + return FlashStatus; + + FlashStatus = FLASH_ProgramHalfWord(newPage + 6, Address); + if (FlashStatus != FLASH_COMPLETE) + return FlashStatus; + + return EE_PageTransfer(newPage, pageBase, Address); +} + +EEPROMClass::EEPROMClass(void) +{ + PageBase0 = EEPROM_PAGE0_BASE; + PageBase1 = EEPROM_PAGE1_BASE; + PageSize = EEPROM_PAGE_SIZE; + Status = EEPROM_NOT_INIT; +} + +uint16 EEPROMClass::init(uint32 pageBase0, uint32 pageBase1, uint32 pageSize) +{ + PageBase0 = pageBase0; + PageBase1 = pageBase1; + PageSize = pageSize; + return init(); +} + +uint16 EEPROMClass::init(void) +{ + uint16 status0, status1; + FLASH_Status FlashStatus; + + FLASH_Unlock(); + Status = EEPROM_NO_VALID_PAGE; + + status0 = (*(__io uint16 *)PageBase0); + status1 = (*(__io uint16 *)PageBase1); + + switch (status0) + { +/* + Page0 Page1 + ----- ----- + EEPROM_ERASED EEPROM_VALID_PAGE Page1 valid, Page0 erased + EEPROM_RECEIVE_DATA Page1 need set to valid, Page0 erased + EEPROM_ERASED make EE_Format + any Error: EEPROM_NO_VALID_PAGE +*/ + case EEPROM_ERASED: + if (status1 == EEPROM_VALID_PAGE) // Page0 erased, Page1 valid + Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); + else if (status1 == EEPROM_RECEIVE_DATA) // Page0 erased, Page1 receive + { + FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE); + if (FlashStatus != FLASH_COMPLETE) + Status = FlashStatus; + else + Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); + } + else if (status1 == EEPROM_ERASED) // Both in erased state so format EEPROM + Status = format(); + break; +/* + Page0 Page1 + ----- ----- + EEPROM_RECEIVE_DATA EEPROM_VALID_PAGE Transfer Page1 to Page0 + EEPROM_ERASED Page0 need set to valid, Page1 erased + any EEPROM_NO_VALID_PAGE +*/ + case EEPROM_RECEIVE_DATA: + if (status1 == EEPROM_VALID_PAGE) // Page0 receive, Page1 valid + Status = EE_PageTransfer(PageBase0, PageBase1, 0xFFFF); + else if (status1 == EEPROM_ERASED) // Page0 receive, Page1 erased + { + Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED); + if (Status == EEPROM_OK) + { + FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE); + if (FlashStatus != FLASH_COMPLETE) + Status = FlashStatus; + else + Status = EEPROM_OK; + } + } + break; +/* + Page0 Page1 + ----- ----- + EEPROM_VALID_PAGE EEPROM_VALID_PAGE Error: EEPROM_NO_VALID_PAGE + EEPROM_RECEIVE_DATA Transfer Page0 to Page1 + any Page0 valid, Page1 erased +*/ + case EEPROM_VALID_PAGE: + if (status1 == EEPROM_VALID_PAGE) // Both pages valid + Status = EEPROM_NO_VALID_PAGE; + else if (status1 == EEPROM_RECEIVE_DATA) + Status = EE_PageTransfer(PageBase1, PageBase0, 0xFFFF); + else + Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED); + break; +/* + Page0 Page1 + ----- ----- + any EEPROM_VALID_PAGE Page1 valid, Page0 erased + EEPROM_RECEIVE_DATA Page1 valid, Page0 erased + any EEPROM_NO_VALID_PAGE +*/ + default: + if (status1 == EEPROM_VALID_PAGE) + Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); // Check/Erase Page0 + else if (status1 == EEPROM_RECEIVE_DATA) + { + FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE); + if (FlashStatus != FLASH_COMPLETE) + Status = FlashStatus; + else + Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); + } + break; + } + return Status; +} + +/** + * @brief Erases PAGE0 and PAGE1 and writes EEPROM_VALID_PAGE / 0 header to PAGE0 + * @param PAGE0 and PAGE1 base addresses + * @retval Status of the last operation (Flash write or erase) done during EEPROM formating + */ +uint16 EEPROMClass::format(void) +{ + uint16 status; + FLASH_Status FlashStatus; + + FLASH_Unlock(); + + // Erase Page0 + status = EE_CheckErasePage(PageBase0, EEPROM_VALID_PAGE); + if (status != EEPROM_OK) + return status; + if ((*(__io uint16*)PageBase0) == EEPROM_ERASED) + { + // Set Page0 as valid page: Write VALID_PAGE at Page0 base address + FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE); + if (FlashStatus != FLASH_COMPLETE) + return FlashStatus; + } + // Erase Page1 + return EE_CheckErasePage(PageBase1, EEPROM_ERASED); +} + +/** + * @brief Returns the erase counter for current page + * @param Data: Global variable contains the read variable value + * @retval Success or error status: + * - EEPROM_OK: if erases counter return. + * - EEPROM_NO_VALID_PAGE: if no valid page was found. + */ +uint16 EEPROMClass::erases(uint16 *Erases) +{ + uint32 pageBase; + if (Status != EEPROM_OK) + if (init() != EEPROM_OK) + return Status; + + // Get active Page for read operation + pageBase = EE_FindValidPage(); + if (pageBase == 0) + return EEPROM_NO_VALID_PAGE; + + *Erases = (*(__io uint16*)pageBase+2); + return EEPROM_OK; +} + +/** + * @brief Returns the last stored variable data, if found, + * which correspond to the passed virtual address + * @param Address: Variable virtual address + * @retval Data for variable or EEPROM_DEFAULT_DATA, if any errors + */ +uint16 EEPROMClass::read (uint16 Address) +{ + uint16 data; + read(Address, &data); + return data; +} + +/** + * @brief Returns the last stored variable data, if found, + * which correspond to the passed virtual address + * @param Address: Variable virtual address + * @param Data: Pointer to data variable + * @retval Success or error status: + * - EEPROM_OK: if variable was found + * - EEPROM_BAD_ADDRESS: if the variable was not found + * - EEPROM_NO_VALID_PAGE: if no valid page was found. + */ +uint16 EEPROMClass::read(uint16 Address, uint16 *Data) +{ + uint32 pageBase, pageEnd; + + // Set default data (empty EEPROM) + *Data = EEPROM_DEFAULT_DATA; + + if (Status == EEPROM_NOT_INIT) + if (init() != EEPROM_OK) + return Status; + + // Get active Page for read operation + pageBase = EE_FindValidPage(); + if (pageBase == 0) + return EEPROM_NO_VALID_PAGE; + + // Get the valid Page end Address + pageEnd = pageBase + ((uint32)(PageSize - 2)); + + // Check each active page address starting from end + for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4) + if ((*(__io uint16*)pageEnd) == Address) // Compare the read address with the virtual address + { + *Data = (*(__io uint16*)(pageEnd - 2)); // Get content of Address-2 which is variable value + return EEPROM_OK; + } + + // Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) + return EEPROM_BAD_ADDRESS; +} + +/** + * @brief Writes/upadtes variable data in EEPROM. + * @param VirtAddress: Variable virtual address + * @param Data: 16 bit data to be written + * @retval Success or error status: + * - FLASH_COMPLETE: on success + * - EEPROM_BAD_ADDRESS: if address = 0xFFFF + * - EEPROM_PAGE_FULL: if valid page is full + * - EEPROM_NO_VALID_PAGE: if no valid page was found + * - EEPROM_OUT_SIZE: if no empty EEPROM variables + * - Flash error code: on write Flash error + */ +uint16 EEPROMClass::write(uint16 Address, uint16 Data) +{ + if (Status == EEPROM_NOT_INIT) + if (init() != EEPROM_OK) + return Status; + + if (Address == 0xFFFF) + return EEPROM_BAD_ADDRESS; + + // Write the variable virtual address and value in the EEPROM + uint16 status = EE_VerifyPageFullWriteVariable(Address, Data); + return status; +} + +/** + * @brief Return number of variable + * @retval Number of variables + */ +uint16 EEPROMClass::count(uint16 *Count) +{ + if (Status == EEPROM_NOT_INIT) + if (init() != EEPROM_OK) + return Status; + + // Get valid Page for write operation + uint32 pageBase = EE_FindValidPage(); + if (pageBase == 0) + return EEPROM_NO_VALID_PAGE; // No valid page, return max. numbers + + *Count = EE_GetVariablesCount(pageBase, 0xFFFF); + return EEPROM_OK; +} + +uint16 EEPROMClass::maxcount(void) +{ + return ((PageSize / 4)-1); +} + +EEPROMClass EEPROM; diff --git a/AeroQuad32/MapleCompatibility/EEPROM.h b/AeroQuad32/MapleCompatibility/EEPROM.h index c572f673..913e71f2 100644 --- a/AeroQuad32/MapleCompatibility/EEPROM.h +++ b/AeroQuad32/MapleCompatibility/EEPROM.h @@ -1,99 +1,99 @@ -#ifndef __EEPROM_H -#define __EEPROM_H - -#define EEPROM_USES_16BIT_WORDS - -#include "wirish.h" -#include "flash_stm32.h" - -#ifndef EEPROM_PAGE_SIZE - #if defined (MCU_STM32F103RB) || defined (MCU_STM32F103CB) - #define EEPROM_PAGE_SIZE (uint16)0x400 /* Page size = 1KByte */ - #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103VE) || defined (MCU_STM32F103RE) - #define EEPROM_PAGE_SIZE (uint16)0x800 /* Page size = 2KByte */ - #elif defined (MCU_STM32F205VE) || defined (MCU_STM32F406VG) - #define EEPROM_PAGE_SIZE (uint16)0x4000 /* Page size = 16KByte */ - #else - #error "No MCU type specified. Add something like -DMCU_STM32F103RB " \ - "to your compiler arguments (probably in a Makefile)." - #endif -#endif - -#ifndef EEPROM_PAGE_SIZE -#endif - -#ifndef EEPROM_START_ADDRESS - #if defined BOARD_freeflight - #define EEPROM_START_ADDRESS ((uint32)(0x8020000 - 2 * EEPROM_PAGE_SIZE)) - #elif defined (MCU_STM32F103RB) || defined (MCU_STM32F103CB) - #define EEPROM_START_ADDRESS ((uint32)(0x8005000 - 2 * EEPROM_PAGE_SIZE)) - #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103VE) || defined (MCU_STM32F103RE) - //#define EEPROM_START_ADDRESS ((uint32)(0x8080000 - 2 * EEPROM_PAGE_SIZE)) - #define EEPROM_START_ADDRESS ((uint32)(0x8005000 - 2 * EEPROM_PAGE_SIZE)) - #elif defined (MCU_STM32F205VE) || defined (MCU_STM32F406VG) - #define EEPROM_START_ADDRESS ((uint32)(0x8010000 - 2 * EEPROM_PAGE_SIZE)) - #else - #error "No MCU type specified. Add something like -DMCU_STM32F103RB " \ - "to your compiler arguments (probably in a Makefile)." - #endif -#endif - -/* Pages 0 and 1 base and end addresses */ -#define EEPROM_PAGE0_BASE ((uint32)(EEPROM_START_ADDRESS)) -#define EEPROM_PAGE1_BASE ((uint32)(EEPROM_START_ADDRESS + EEPROM_PAGE_SIZE)) - -/* Page status definitions */ -#define EEPROM_ERASED ((uint16)0xFFFF) /* PAGE is empty */ -#define EEPROM_RECEIVE_DATA ((uint16)0xEEEE) /* PAGE is marked to receive data */ -#define EEPROM_VALID_PAGE ((uint16)0x0000) /* PAGE containing valid data */ - -/* Page full define */ -enum //: uint16 -{ - EEPROM_OK = ((uint16)0x0000), - EEPROM_OUT_SIZE = ((uint16)0x0081), - EEPROM_BAD_ADDRESS = ((uint16)0x0082), - EEPROM_BAD_FLASH = ((uint16)0x0083), - EEPROM_NOT_INIT = ((uint16)0x0084), - EEPROM_NO_VALID_PAGE = ((uint16)0x00AB) -}; - -#define EEPROM_DEFAULT_DATA 0xFFFF - - -class EEPROMClass -{ -public: - EEPROMClass(void); - - uint16 init(void); - uint16 init(uint32, uint32, uint32); - - uint16 format(void); - - uint16 erases(uint16 *); - uint16 read (uint16 address); - uint16 read (uint16 address, uint16 *data); - uint16 write(uint16 address, uint16 data); - uint16 count(uint16 *); - uint16 maxcount(void); - - uint32 PageBase0; - uint32 PageBase1; - uint32 PageSize; - uint16 Status; -private: - FLASH_Status EE_ErasePage(uint32); - - uint16 EE_CheckPage(uint32, uint16); - uint16 EE_CheckErasePage(uint32, uint16); - uint16 EE_Format(void); - uint32 EE_FindValidPage(void); - uint16 EE_GetVariablesCount(uint32, uint16); - uint16 EE_PageTransfer(uint32, uint32, uint16); - uint16 EE_VerifyPageFullWriteVariable(uint16, uint16); -}; - -extern EEPROMClass EEPROM; - -#endif /* __EEPROM_H */ +#ifndef __EEPROM_H +#define __EEPROM_H + +#define EEPROM_USES_16BIT_WORDS + +#include "wirish.h" +#include "flash_stm32.h" + +#ifndef EEPROM_PAGE_SIZE + #if defined (MCU_STM32F103RB) || defined (MCU_STM32F103CB) + #define EEPROM_PAGE_SIZE (uint16)0x400 /* Page size = 1KByte */ + #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103VE) || defined (MCU_STM32F103RE) + #define EEPROM_PAGE_SIZE (uint16)0x800 /* Page size = 2KByte */ + #elif defined (MCU_STM32F205VE) || defined (MCU_STM32F406VG) + #define EEPROM_PAGE_SIZE (uint16)0x4000 /* Page size = 16KByte */ + #else + #error "No MCU type specified. Add something like -DMCU_STM32F103RB " \ + "to your compiler arguments (probably in a Makefile)." + #endif +#endif + +#ifndef EEPROM_PAGE_SIZE +#endif + +#ifndef EEPROM_START_ADDRESS + #if defined BOARD_freeflight + #define EEPROM_START_ADDRESS ((uint32)(0x8020000 - 2 * EEPROM_PAGE_SIZE)) + #elif defined (MCU_STM32F103RB) || defined (MCU_STM32F103CB) + #define EEPROM_START_ADDRESS ((uint32)(0x8005000 - 2 * EEPROM_PAGE_SIZE)) + #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103VE) || defined (MCU_STM32F103RE) + //#define EEPROM_START_ADDRESS ((uint32)(0x8080000 - 2 * EEPROM_PAGE_SIZE)) + #define EEPROM_START_ADDRESS ((uint32)(0x8005000 - 2 * EEPROM_PAGE_SIZE)) + #elif defined (MCU_STM32F205VE) || defined (MCU_STM32F406VG) + #define EEPROM_START_ADDRESS ((uint32)(0x8010000 - 2 * EEPROM_PAGE_SIZE)) + #else + #error "No MCU type specified. Add something like -DMCU_STM32F103RB " \ + "to your compiler arguments (probably in a Makefile)." + #endif +#endif + +/* Pages 0 and 1 base and end addresses */ +#define EEPROM_PAGE0_BASE ((uint32)(EEPROM_START_ADDRESS)) +#define EEPROM_PAGE1_BASE ((uint32)(EEPROM_START_ADDRESS + EEPROM_PAGE_SIZE)) + +/* Page status definitions */ +#define EEPROM_ERASED ((uint16)0xFFFF) /* PAGE is empty */ +#define EEPROM_RECEIVE_DATA ((uint16)0xEEEE) /* PAGE is marked to receive data */ +#define EEPROM_VALID_PAGE ((uint16)0x0000) /* PAGE containing valid data */ + +/* Page full define */ +enum //: uint16 +{ + EEPROM_OK = ((uint16)0x0000), + EEPROM_OUT_SIZE = ((uint16)0x0081), + EEPROM_BAD_ADDRESS = ((uint16)0x0082), + EEPROM_BAD_FLASH = ((uint16)0x0083), + EEPROM_NOT_INIT = ((uint16)0x0084), + EEPROM_NO_VALID_PAGE = ((uint16)0x00AB) +}; + +#define EEPROM_DEFAULT_DATA 0xFFFF + + +class EEPROMClass +{ +public: + EEPROMClass(void); + + uint16 init(void); + uint16 init(uint32, uint32, uint32); + + uint16 format(void); + + uint16 erases(uint16 *); + uint16 read (uint16 address); + uint16 read (uint16 address, uint16 *data); + uint16 write(uint16 address, uint16 data); + uint16 count(uint16 *); + uint16 maxcount(void); + + uint32 PageBase0; + uint32 PageBase1; + uint32 PageSize; + uint16 Status; +private: + FLASH_Status EE_ErasePage(uint32); + + uint16 EE_CheckPage(uint32, uint16); + uint16 EE_CheckErasePage(uint32, uint16); + uint16 EE_Format(void); + uint32 EE_FindValidPage(void); + uint16 EE_GetVariablesCount(uint32, uint16); + uint16 EE_PageTransfer(uint32, uint32, uint16); + uint16 EE_VerifyPageFullWriteVariable(uint16, uint16); +}; + +extern EEPROMClass EEPROM; + +#endif /* __EEPROM_H */ diff --git a/AeroQuad32/MapleCompatibility/WProgram.h b/AeroQuad32/MapleCompatibility/WProgram.h index 098451c8..7d77c527 100644 --- a/AeroQuad32/MapleCompatibility/WProgram.h +++ b/AeroQuad32/MapleCompatibility/WProgram.h @@ -1,53 +1,53 @@ -#ifndef WProgram_h - #define WProgram_h - //#define USE_USB_SERIAL - - - extern void setup(); - extern void loop(); - - #include - #include - #include - #include - - #include - #define cli() nvic_globalirq_disable() - #define sei() nvic_globalirq_enable() - - #ifdef __cplusplus - #ifdef BOARD_freeflight - #undef USE_USB_SERIAL - #endif - #ifdef USE_USB_SERIAL - #define SERIAL_VAR SerialUSB - typedef USBSerial tSerial; - #else - #ifdef BOARD_discovery_f4 - #define SERIAL_VAR Serial3 - #else - #define SERIAL_VAR Serial1 - #endif - typedef HardwareSerial tSerial; - #endif - - extern tSerial &Serial; - extern USBSerial SerialUSB; - - uint16_t makeWord(uint16_t w); - uint16_t makeWord(byte h, byte l); - - #define word(...) makeWord(__VA_ARGS__) - - unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); - - void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); - void noTone(uint8_t _pin); - - // WMath prototypes - long random(long); - long random(long, long); - void randomSeed(unsigned int); - long map(long, long, long, long, long); - #endif -#endif +#ifndef WProgram_h + #define WProgram_h + //#define USE_USB_SERIAL + + + extern void setup(); + extern void loop(); + + #include + #include + #include + #include + + #include + #define cli() nvic_globalirq_disable() + #define sei() nvic_globalirq_enable() + + #ifdef __cplusplus + #ifdef BOARD_freeflight + #undef USE_USB_SERIAL + #endif + #ifdef USE_USB_SERIAL + #define SERIAL_VAR SerialUSB + typedef USBSerial tSerial; + #else + #ifdef BOARD_discovery_f4 + #define SERIAL_VAR Serial3 + #else + #define SERIAL_VAR Serial1 + #endif + typedef HardwareSerial tSerial; + #endif + + extern tSerial &Serial; + extern USBSerial SerialUSB; + + uint16_t makeWord(uint16_t w); + uint16_t makeWord(byte h, byte l); + + #define word(...) makeWord(__VA_ARGS__) + + unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); + + void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); + void noTone(uint8_t _pin); + + // WMath prototypes + long random(long); + long random(long, long); + void randomSeed(unsigned int); + long map(long, long, long, long, long); + #endif +#endif diff --git a/AeroQuad32/MapleCompatibility/flash_stm32.c b/AeroQuad32/MapleCompatibility/flash_stm32.c index 83f8c2c8..84bdcd98 100644 --- a/AeroQuad32/MapleCompatibility/flash_stm32.c +++ b/AeroQuad32/MapleCompatibility/flash_stm32.c @@ -1,6 +1,6 @@ -#if defined (MCU_STM32F205VE) || defined (MCU_STM32F406VG) - #include "flash_stm32F2.c" -#else - #include "flash_stm32F1.c" -#endif - +#if defined (MCU_STM32F205VE) || defined (MCU_STM32F406VG) + #include "flash_stm32F2.c" +#else + #include "flash_stm32F1.c" +#endif + diff --git a/AeroQuad32/MapleCompatibility/flash_stm32.h b/AeroQuad32/MapleCompatibility/flash_stm32.h index f6d7750f..78fa1a31 100644 --- a/AeroQuad32/MapleCompatibility/flash_stm32.h +++ b/AeroQuad32/MapleCompatibility/flash_stm32.h @@ -1,36 +1,36 @@ -#ifndef __FLASH_STM32_H -#define __FLASH_STM32_H - -#ifdef __cplusplus - extern "C" { -#endif - -typedef enum - { - FLASH_BUSY = 1, - FLASH_ERROR_PG, - FLASH_ERROR_WRP, - FLASH_ERROR_OPT, - FLASH_COMPLETE, - FLASH_TIMEOUT, - FLASH_BAD_ADDRESS, - FLASH_ERROR_PGS, - FLASH_ERROR_PGP, - FLASH_ERROR_PGA, - FLASH_ERROR_PROGRAM, - FLASH_ERROR_OPERATION -} FLASH_Status; - -#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF)) - -FLASH_Status FLASH_WaitForLastOperation(uint32 Timeout); -FLASH_Status FLASH_ErasePage(uint32 Page_Address); -FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data); -void FLASH_Unlock(void); -void FLASH_Lock(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __FLASH_STM32_H */ +#ifndef __FLASH_STM32_H +#define __FLASH_STM32_H + +#ifdef __cplusplus + extern "C" { +#endif + +typedef enum + { + FLASH_BUSY = 1, + FLASH_ERROR_PG, + FLASH_ERROR_WRP, + FLASH_ERROR_OPT, + FLASH_COMPLETE, + FLASH_TIMEOUT, + FLASH_BAD_ADDRESS, + FLASH_ERROR_PGS, + FLASH_ERROR_PGP, + FLASH_ERROR_PGA, + FLASH_ERROR_PROGRAM, + FLASH_ERROR_OPERATION +} FLASH_Status; + +#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF)) + +FLASH_Status FLASH_WaitForLastOperation(uint32 Timeout); +FLASH_Status FLASH_ErasePage(uint32 Page_Address); +FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data); +void FLASH_Unlock(void); +void FLASH_Lock(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __FLASH_STM32_H */ diff --git a/AeroQuad32/MapleCompatibility/flash_stm32F1.c b/AeroQuad32/MapleCompatibility/flash_stm32F1.c index 9b96b8b6..2d0b7b44 100644 --- a/AeroQuad32/MapleCompatibility/flash_stm32F1.c +++ b/AeroQuad32/MapleCompatibility/flash_stm32F1.c @@ -1,203 +1,203 @@ -#include "libmaple.h" -#include "util.h" -#include "flash.h" -#include "flash_stm32.h" - -#ifndef __get_bits -// add macros missing in maple 0.0.12 -#define __set_bits(addr, mask) (*(volatile uint32*)(addr) |= (uint32)(mask)) -#define __clear_bits(addr, mask) (*(volatile uint32*)(addr) &= (uint32)~(mask)) -#define __get_bits(addr, mask) (*(volatile uint32*)(addr) & (uint32)(mask)) - -#define __read(reg) (*(volatile uint32*)(reg)) -#define __write(reg, value) (*(volatile uint32*)(reg) = (value)) -#endif - -#undef FLASH_BASE -#define FLASH_BASE 0x40022000 -#define FLASH_SR (FLASH_BASE + 0x0C) - // FLASH_ACR + 0x00 -#define FLASH_KEYR (FLASH_BASE + 0x04) - // FLASH_OPTKEYR + 0x08 -#define FLASH_CR (FLASH_BASE + 0x10) -#define FLASH_AR (FLASH_BASE + 0x14) - // FLASH_RESERVED + 0x18 - // FLASH_OBR + 0x1C - // FLASH_WRPR + 0x20 - -#define FLASH_FLAG_BSY ((uint32)0x00000001) /*!< FLASH Busy flag */ -#define FLASH_FLAG_PGERR ((uint32)0x00000004) /*!< FLASH Program error flag */ -#define FLASH_FLAG_WRPRTERR ((uint32)0x00000010) /*!< FLASH Write protected error flag */ -#define FLASH_FLAG_EOP ((uint32)0x00000020) /*!< FLASH End of Operation flag */ -#define FLASH_FLAG_OPTERR ((uint32)0x00000001) /*!< FLASH Option Byte error flag */ - -/* Flash Control Register bits */ -#define CR_PG_Set ((uint32)0x00000001) -#define CR_PG_Reset ((uint32)0x00001FFE) -#define CR_PER_Set ((uint32)0x00000002) -#define CR_PER_Reset ((uint32)0x00001FFD) -//#define CR_MER_Set ((uint32)0x00000004) -//#define CR_MER_Reset ((uint32)0x00001FFB) -//#define CR_OPTPG_Set ((uint32)0x00000010) -//#define CR_OPTPG_Reset ((uint32)0x00001FEF) -//#define CR_OPTER_Set ((uint32)0x00000020) -//#define CR_OPTER_Reset ((uint32)0x00001FDF) -#define CR_STRT_Set ((uint32)0x00000040) -#define CR_LOCK_Set ((uint32)0x00000080) - -#define FLASH_KEY1 ((uint32)0x45670123) -#define FLASH_KEY2 ((uint32)0xCDEF89AB) - -/* Delay definition */ -#define EraseTimeout ((uint32)0x00000FFF) -#define ProgramTimeout ((uint32)0x0000001F) - -/** - * @brief Inserts a time delay. - * @param None - * @retval None - */ -static void delay(void) -{ - __io uint32 i = 0; - for(i = 0xFF; i != 0; i--) { } -} - -/** - * @brief Returns the FLASH Status. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, - * FLASH_ERROR_WRP or FLASH_COMPLETE - */ -FLASH_Status FLASH_GetStatus(void) -{ - if(__get_bits(FLASH_SR, FLASH_FLAG_BSY) == FLASH_FLAG_BSY) - return FLASH_BUSY; - - if(__get_bits(FLASH_SR, FLASH_FLAG_PGERR) != 0) - return FLASH_ERROR_PG; - - if(__get_bits(FLASH_SR, FLASH_FLAG_WRPRTERR) != 0 ) - return FLASH_ERROR_WRP; - - if(__get_bits(FLASH_SR, FLASH_FLAG_OPTERR) != 0 ) - return FLASH_ERROR_OPT; - - return FLASH_COMPLETE; -} - -/** - * @brief Waits for a Flash operation to complete or a TIMEOUT to occur. - * @param Timeout: FLASH progamming Timeout - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_WaitForLastOperation(uint32 Timeout) -{ - FLASH_Status status; - - /* Check for the Flash Status */ - status = FLASH_GetStatus(); - /* Wait for a Flash operation to complete or a TIMEOUT to occur */ - while((status == FLASH_BUSY) && (Timeout != 0x00)) - { - delay(); - status = FLASH_GetStatus(); - Timeout--; - } - if (Timeout == 0) - status = FLASH_TIMEOUT; - /* Return the operation status */ - return status; -} - -/** - * @brief Erases a specified FLASH page. - * @param Page_Address: The page address to be erased. - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_ErasePage(uint32 Page_Address) -{ - FLASH_Status status = FLASH_COMPLETE; - /* Check the parameters */ - ASSERT(IS_FLASH_ADDRESS(Page_Address)); - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase the page */ - __set_bits(FLASH_CR, CR_PER_Set); - __write(FLASH_AR, Page_Address); - __set_bits(FLASH_CR, CR_STRT_Set); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the erase operation is completed, disable the PER Bit */ - __clear_bits(FLASH_CR, ~CR_PER_Reset); - } - __write(FLASH_SR, (FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR)); - } - /* Return the Erase Status */ - return status; -} - -/** - * @brief Programs a half word at a specified address. - * @param Address: specifies the address to be programmed. - * @param Data: specifies the data to be programmed. - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data) -{ - FLASH_Status status = FLASH_BAD_ADDRESS; - - if (IS_FLASH_ADDRESS(Address)) - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new data */ - __set_bits(FLASH_CR, CR_PG_Set); - *(__io uint16*)Address = Data; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the PG Bit */ - __clear_bits(FLASH_CR, ~CR_PG_Reset); - } - __write(FLASH_SR, (FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR)); - } - } - return status; -} - -/** - * @brief Unlocks the FLASH Program Erase Controller. - * @param None - * @retval None - */ -void FLASH_Unlock(void) -{ - /* Authorize the FPEC Access */ - __write(FLASH_KEYR, FLASH_KEY1); - __write(FLASH_KEYR, FLASH_KEY2); -} - -/** - * @brief Locks the FLASH Program Erase Controller. - * @param None - * @retval None - */ -void FLASH_Lock(void) -{ - /* Set the Lock Bit to lock the FPEC and the FCR */ - __set_bits(FLASH_CR, CR_LOCK_Set); -} - +#include "libmaple.h" +#include "util.h" +#include "flash.h" +#include "flash_stm32.h" + +#ifndef __get_bits +// add macros missing in maple 0.0.12 +#define __set_bits(addr, mask) (*(volatile uint32*)(addr) |= (uint32)(mask)) +#define __clear_bits(addr, mask) (*(volatile uint32*)(addr) &= (uint32)~(mask)) +#define __get_bits(addr, mask) (*(volatile uint32*)(addr) & (uint32)(mask)) + +#define __read(reg) (*(volatile uint32*)(reg)) +#define __write(reg, value) (*(volatile uint32*)(reg) = (value)) +#endif + +#undef FLASH_BASE +#define FLASH_BASE 0x40022000 +#define FLASH_SR (FLASH_BASE + 0x0C) + // FLASH_ACR + 0x00 +#define FLASH_KEYR (FLASH_BASE + 0x04) + // FLASH_OPTKEYR + 0x08 +#define FLASH_CR (FLASH_BASE + 0x10) +#define FLASH_AR (FLASH_BASE + 0x14) + // FLASH_RESERVED + 0x18 + // FLASH_OBR + 0x1C + // FLASH_WRPR + 0x20 + +#define FLASH_FLAG_BSY ((uint32)0x00000001) /*!< FLASH Busy flag */ +#define FLASH_FLAG_PGERR ((uint32)0x00000004) /*!< FLASH Program error flag */ +#define FLASH_FLAG_WRPRTERR ((uint32)0x00000010) /*!< FLASH Write protected error flag */ +#define FLASH_FLAG_EOP ((uint32)0x00000020) /*!< FLASH End of Operation flag */ +#define FLASH_FLAG_OPTERR ((uint32)0x00000001) /*!< FLASH Option Byte error flag */ + +/* Flash Control Register bits */ +#define CR_PG_Set ((uint32)0x00000001) +#define CR_PG_Reset ((uint32)0x00001FFE) +#define CR_PER_Set ((uint32)0x00000002) +#define CR_PER_Reset ((uint32)0x00001FFD) +//#define CR_MER_Set ((uint32)0x00000004) +//#define CR_MER_Reset ((uint32)0x00001FFB) +//#define CR_OPTPG_Set ((uint32)0x00000010) +//#define CR_OPTPG_Reset ((uint32)0x00001FEF) +//#define CR_OPTER_Set ((uint32)0x00000020) +//#define CR_OPTER_Reset ((uint32)0x00001FDF) +#define CR_STRT_Set ((uint32)0x00000040) +#define CR_LOCK_Set ((uint32)0x00000080) + +#define FLASH_KEY1 ((uint32)0x45670123) +#define FLASH_KEY2 ((uint32)0xCDEF89AB) + +/* Delay definition */ +#define EraseTimeout ((uint32)0x00000FFF) +#define ProgramTimeout ((uint32)0x0000001F) + +/** + * @brief Inserts a time delay. + * @param None + * @retval None + */ +static void delay(void) +{ + __io uint32 i = 0; + for(i = 0xFF; i != 0; i--) { } +} + +/** + * @brief Returns the FLASH Status. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, + * FLASH_ERROR_WRP or FLASH_COMPLETE + */ +FLASH_Status FLASH_GetStatus(void) +{ + if(__get_bits(FLASH_SR, FLASH_FLAG_BSY) == FLASH_FLAG_BSY) + return FLASH_BUSY; + + if(__get_bits(FLASH_SR, FLASH_FLAG_PGERR) != 0) + return FLASH_ERROR_PG; + + if(__get_bits(FLASH_SR, FLASH_FLAG_WRPRTERR) != 0 ) + return FLASH_ERROR_WRP; + + if(__get_bits(FLASH_SR, FLASH_FLAG_OPTERR) != 0 ) + return FLASH_ERROR_OPT; + + return FLASH_COMPLETE; +} + +/** + * @brief Waits for a Flash operation to complete or a TIMEOUT to occur. + * @param Timeout: FLASH progamming Timeout + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_WaitForLastOperation(uint32 Timeout) +{ + FLASH_Status status; + + /* Check for the Flash Status */ + status = FLASH_GetStatus(); + /* Wait for a Flash operation to complete or a TIMEOUT to occur */ + while((status == FLASH_BUSY) && (Timeout != 0x00)) + { + delay(); + status = FLASH_GetStatus(); + Timeout--; + } + if (Timeout == 0) + status = FLASH_TIMEOUT; + /* Return the operation status */ + return status; +} + +/** + * @brief Erases a specified FLASH page. + * @param Page_Address: The page address to be erased. + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ErasePage(uint32 Page_Address) +{ + FLASH_Status status = FLASH_COMPLETE; + /* Check the parameters */ + ASSERT(IS_FLASH_ADDRESS(Page_Address)); + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase the page */ + __set_bits(FLASH_CR, CR_PER_Set); + __write(FLASH_AR, Page_Address); + __set_bits(FLASH_CR, CR_STRT_Set); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the erase operation is completed, disable the PER Bit */ + __clear_bits(FLASH_CR, ~CR_PER_Reset); + } + __write(FLASH_SR, (FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR)); + } + /* Return the Erase Status */ + return status; +} + +/** + * @brief Programs a half word at a specified address. + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data) +{ + FLASH_Status status = FLASH_BAD_ADDRESS; + + if (IS_FLASH_ADDRESS(Address)) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new data */ + __set_bits(FLASH_CR, CR_PG_Set); + *(__io uint16*)Address = Data; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the PG Bit */ + __clear_bits(FLASH_CR, ~CR_PG_Reset); + } + __write(FLASH_SR, (FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR)); + } + } + return status; +} + +/** + * @brief Unlocks the FLASH Program Erase Controller. + * @param None + * @retval None + */ +void FLASH_Unlock(void) +{ + /* Authorize the FPEC Access */ + __write(FLASH_KEYR, FLASH_KEY1); + __write(FLASH_KEYR, FLASH_KEY2); +} + +/** + * @brief Locks the FLASH Program Erase Controller. + * @param None + * @retval None + */ +void FLASH_Lock(void) +{ + /* Set the Lock Bit to lock the FPEC and the FCR */ + __set_bits(FLASH_CR, CR_LOCK_Set); +} + diff --git a/AeroQuad32/MapleCompatibility/flash_stm32F2.c b/AeroQuad32/MapleCompatibility/flash_stm32F2.c index e6e46252..1d0791db 100644 --- a/AeroQuad32/MapleCompatibility/flash_stm32F2.c +++ b/AeroQuad32/MapleCompatibility/flash_stm32F2.c @@ -1,311 +1,311 @@ -#include "libmaple.h" -#include "util.h" -//#include "flash.h" -#include "flash_stm32.h" - - - -typedef struct -{ - __io uint32 ACR; /*!< FLASH access control register, Address offset: 0x00 */ - __io uint32 KEYR; /*!< FLASH key register, Address offset: 0x04 */ - __io uint32 OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ - __io uint32 SR; /*!< FLASH status register, Address offset: 0x0C */ - __io uint32 CR; /*!< FLASH control register, Address offset: 0x10 */ - __io uint32 OPTCR; /*!< FLASH option control register, Address offset: 0x14 */ -} FLASH_TypeDef; - -#define PERIPH_BASE ((uint32)0x40000000) /*!< Peripheral base address in the alias region */ -#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) -#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) -#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) - -#define FLASH_FLAG_EOP ((uint32)0x00000001) /*!< FLASH End of Operation flag */ -#define FLASH_FLAG_OPERR ((uint32)0x00000002) /*!< FLASH operation Error flag */ -#define FLASH_FLAG_WRPERR ((uint32)0x00000010) /*!< FLASH Write protected error flag */ -#define FLASH_FLAG_PGAERR ((uint32)0x00000020) /*!< FLASH Programming Alignment error flag */ -#define FLASH_FLAG_PGPERR ((uint32)0x00000040) /*!< FLASH Programming Parallelism error flag */ -#define FLASH_FLAG_PGSERR ((uint32)0x00000080) /*!< FLASH Programming Sequence error flag */ -#define FLASH_FLAG_BSY ((uint32)0x00010000) /*!< FLASH Busy flag */ - -#define FLASH_PSIZE_BYTE ((uint32)0x00000000) -#define FLASH_PSIZE_HALF_WORD ((uint32)0x00000100) -#define FLASH_PSIZE_WORD ((uint32)0x00000200) -#define FLASH_PSIZE_DOUBLE_WORD ((uint32)0x00000300) -#define CR_PSIZE_MASK ((uint32)0xFFFFFCFF) - -#define SECTOR_MASK ((uint32)0xFFFFFF07) - -/******************* Bits definition for FLASH_CR register ******************/ -#define FLASH_CR_PG ((uint32)0x00000001) -#define FLASH_CR_SER ((uint32)0x00000002) -#define FLASH_CR_MER ((uint32)0x00000004) -#define FLASH_CR_SNB_0 ((uint32)0x00000008) -#define FLASH_CR_SNB_1 ((uint32)0x00000010) -#define FLASH_CR_SNB_2 ((uint32)0x00000020) -#define FLASH_CR_SNB_3 ((uint32)0x00000040) -#define FLASH_CR_PSIZE_0 ((uint32)0x00000100) -#define FLASH_CR_PSIZE_1 ((uint32)0x00000200) -#define FLASH_CR_STRT ((uint32)0x00010000) -#define FLASH_CR_EOPIE ((uint32)0x01000000) -#define FLASH_CR_LOCK ((uint32)0x80000000) - -#define FLASH_KEY1 ((uint32)0x45670123) -#define FLASH_KEY2 ((uint32)0xCDEF89AB) - -/* Delay definition */ -#define EraseTimeout ((uint32)0x00000FFF) -#define ProgramTimeout ((uint32)0x0000001F) - -#define VoltageRange_1 ((uint8)0x00) /*!< Device operating range: 1.8V to 2.1V */ -#define VoltageRange_2 ((uint8)0x01) /*!SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) - { - flashstatus = FLASH_BUSY; - } - else - { - if((FLASH->SR & FLASH_FLAG_WRPERR) != 0) - { - flashstatus = FLASH_ERROR_WRP; - } - else - { - if((FLASH->SR & 0xEF) != 0) - { - flashstatus = FLASH_ERROR_PROGRAM; - } - else - { - if((FLASH->SR & FLASH_FLAG_OPERR) != 0) - { - flashstatus = FLASH_ERROR_OPERATION; - } - else - { - flashstatus = FLASH_COMPLETE; - } - } - } - } - /* Return the FLASH Status */ - return flashstatus; -} - - -/** - * @brief Waits for a Flash operation to complete or a TIMEOUT to occur. - * @param Timeout: FLASH progamming Timeout - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_WaitForLastOperation(uint32 Timeout) -{ - FLASH_Status status; - - /* Check for the Flash Status */ - status = FLASH_GetStatus(); - /* Wait for a Flash operation to complete or a TIMEOUT to occur */ - while((status == FLASH_BUSY) && (Timeout != 0x00)) - { - delay(); - status = FLASH_GetStatus(); - Timeout--; - } - if (Timeout == 0) - status = FLASH_TIMEOUT; - /* Return the operation status */ - return status; -} - - - -/** - * @brief Erases a specified FLASH Sector. - * - * @param FLASH_Sector: The Sector number to be erased. - * This parameter can be a value between FLASH_Sector_0 and FLASH_Sector_11 - * - * @param VoltageRange: The device voltage range which defines the erase parallelism. - * This parameter can be one of the following values: - * @arg VoltageRange_1: when the device voltage range is 1.8V to 2.1V, - * the operation will be done by byte (8-bit) - * @arg VoltageRange_2: when the device voltage range is 2.1V to 2.7V, - * the operation will be done by half word (16-bit) - * @arg VoltageRange_3: when the device voltage range is 2.7V to 3.6V, - * the operation will be done by word (32-bit) - * @arg VoltageRange_4: when the device voltage range is 2.7V to 3.6V + External Vpp, - * the operation will be done by double word (64-bit) - * - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_EraseSector(uint32 FLASH_Sector, uint8 VoltageRange) -{ - uint32 tmp_psize = 0x0; - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - //assert_param(IS_FLASH_SECTOR(FLASH_Sector)); - //assert_param(IS_VOLTAGERANGE(VoltageRange)); - - if(VoltageRange == VoltageRange_1) - { - tmp_psize = FLASH_PSIZE_BYTE; - } - else if(VoltageRange == VoltageRange_2) - { - tmp_psize = FLASH_PSIZE_HALF_WORD; - } - else if(VoltageRange == VoltageRange_3) - { - tmp_psize = FLASH_PSIZE_WORD; - } - else - { - tmp_psize = FLASH_PSIZE_DOUBLE_WORD; - } - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase the sector */ - FLASH->CR &= CR_PSIZE_MASK; - FLASH->CR |= tmp_psize; - FLASH->CR &= SECTOR_MASK; - FLASH->CR |= FLASH_CR_SER | FLASH_Sector; - FLASH->CR |= FLASH_CR_STRT; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - - /* if the erase operation is completed, disable the SER Bit */ - FLASH->CR &= (~FLASH_CR_SER); - FLASH->CR &= SECTOR_MASK; - } - /* Return the Erase Status */ - return status; -} - -/** - * @brief Erases a specified FLASH page. - * @param Page_Address: The page address to be erased. - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_ErasePage(uint32 Page_Address) -{ - int Page_Offset = Page_Address - 0x08000000; - uint32 FLASH_Sector; - - if(Page_Offset < 0x10000) { - FLASH_Sector = Page_Offset / 0x4000; - } else if(Page_Offset < 0x20000) { - FLASH_Sector = 4; - } else { - FLASH_Sector = 4 + Page_Offset / 0x20000; - } - - return FLASH_EraseSector(8 * FLASH_Sector, VoltageRange_4); -} - - - -/** - * @brief Programs a half word (16-bit) at a specified address. - * @note This function must be used when the device voltage range is from 2.1V to 3.6V. - * @param Address: specifies the address to be programmed. - * This parameter can be any address in Program memory zone or in OTP zone. - * @param Data: specifies the data to be programmed. - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data) -{ - FLASH_Status status = FLASH_BAD_ADDRESS; - - if (IS_FLASH_ADDRESS(Address)) - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new data */ - FLASH->CR &= CR_PSIZE_MASK; - FLASH->CR |= FLASH_PSIZE_HALF_WORD; - FLASH->CR |= FLASH_CR_PG; - - *(__io uint16*)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the PG Bit */ - FLASH->CR &= (~FLASH_CR_PG); - } - } - } - - /* Return the Program Status */ - return status; -} - - -/** - * @brief Unlocks the FLASH control register access - * @param None - * @retval None - */ -void FLASH_Unlock(void) -{ - if((FLASH->CR & FLASH_CR_LOCK) != 0) - { - /* Authorize the FLASH Registers access */ - FLASH->KEYR = FLASH_KEY1; - FLASH->KEYR = FLASH_KEY2; - } -} - -/** - * @brief Locks the FLASH control register access - * @param None - * @retval None - */ -void FLASH_Lock(void) -{ - /* Set the LOCK Bit to lock the FLASH Registers access */ - FLASH->CR |= FLASH_CR_LOCK; -} +#include "libmaple.h" +#include "util.h" +//#include "flash.h" +#include "flash_stm32.h" + + + +typedef struct +{ + __io uint32 ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __io uint32 KEYR; /*!< FLASH key register, Address offset: 0x04 */ + __io uint32 OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ + __io uint32 SR; /*!< FLASH status register, Address offset: 0x0C */ + __io uint32 CR; /*!< FLASH control register, Address offset: 0x10 */ + __io uint32 OPTCR; /*!< FLASH option control register, Address offset: 0x14 */ +} FLASH_TypeDef; + +#define PERIPH_BASE ((uint32)0x40000000) /*!< Peripheral base address in the alias region */ +#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) +#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) + +#define FLASH_FLAG_EOP ((uint32)0x00000001) /*!< FLASH End of Operation flag */ +#define FLASH_FLAG_OPERR ((uint32)0x00000002) /*!< FLASH operation Error flag */ +#define FLASH_FLAG_WRPERR ((uint32)0x00000010) /*!< FLASH Write protected error flag */ +#define FLASH_FLAG_PGAERR ((uint32)0x00000020) /*!< FLASH Programming Alignment error flag */ +#define FLASH_FLAG_PGPERR ((uint32)0x00000040) /*!< FLASH Programming Parallelism error flag */ +#define FLASH_FLAG_PGSERR ((uint32)0x00000080) /*!< FLASH Programming Sequence error flag */ +#define FLASH_FLAG_BSY ((uint32)0x00010000) /*!< FLASH Busy flag */ + +#define FLASH_PSIZE_BYTE ((uint32)0x00000000) +#define FLASH_PSIZE_HALF_WORD ((uint32)0x00000100) +#define FLASH_PSIZE_WORD ((uint32)0x00000200) +#define FLASH_PSIZE_DOUBLE_WORD ((uint32)0x00000300) +#define CR_PSIZE_MASK ((uint32)0xFFFFFCFF) + +#define SECTOR_MASK ((uint32)0xFFFFFF07) + +/******************* Bits definition for FLASH_CR register ******************/ +#define FLASH_CR_PG ((uint32)0x00000001) +#define FLASH_CR_SER ((uint32)0x00000002) +#define FLASH_CR_MER ((uint32)0x00000004) +#define FLASH_CR_SNB_0 ((uint32)0x00000008) +#define FLASH_CR_SNB_1 ((uint32)0x00000010) +#define FLASH_CR_SNB_2 ((uint32)0x00000020) +#define FLASH_CR_SNB_3 ((uint32)0x00000040) +#define FLASH_CR_PSIZE_0 ((uint32)0x00000100) +#define FLASH_CR_PSIZE_1 ((uint32)0x00000200) +#define FLASH_CR_STRT ((uint32)0x00010000) +#define FLASH_CR_EOPIE ((uint32)0x01000000) +#define FLASH_CR_LOCK ((uint32)0x80000000) + +#define FLASH_KEY1 ((uint32)0x45670123) +#define FLASH_KEY2 ((uint32)0xCDEF89AB) + +/* Delay definition */ +#define EraseTimeout ((uint32)0x00000FFF) +#define ProgramTimeout ((uint32)0x0000001F) + +#define VoltageRange_1 ((uint8)0x00) /*!< Device operating range: 1.8V to 2.1V */ +#define VoltageRange_2 ((uint8)0x01) /*!SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) + { + flashstatus = FLASH_BUSY; + } + else + { + if((FLASH->SR & FLASH_FLAG_WRPERR) != 0) + { + flashstatus = FLASH_ERROR_WRP; + } + else + { + if((FLASH->SR & 0xEF) != 0) + { + flashstatus = FLASH_ERROR_PROGRAM; + } + else + { + if((FLASH->SR & FLASH_FLAG_OPERR) != 0) + { + flashstatus = FLASH_ERROR_OPERATION; + } + else + { + flashstatus = FLASH_COMPLETE; + } + } + } + } + /* Return the FLASH Status */ + return flashstatus; +} + + +/** + * @brief Waits for a Flash operation to complete or a TIMEOUT to occur. + * @param Timeout: FLASH progamming Timeout + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_WaitForLastOperation(uint32 Timeout) +{ + FLASH_Status status; + + /* Check for the Flash Status */ + status = FLASH_GetStatus(); + /* Wait for a Flash operation to complete or a TIMEOUT to occur */ + while((status == FLASH_BUSY) && (Timeout != 0x00)) + { + delay(); + status = FLASH_GetStatus(); + Timeout--; + } + if (Timeout == 0) + status = FLASH_TIMEOUT; + /* Return the operation status */ + return status; +} + + + +/** + * @brief Erases a specified FLASH Sector. + * + * @param FLASH_Sector: The Sector number to be erased. + * This parameter can be a value between FLASH_Sector_0 and FLASH_Sector_11 + * + * @param VoltageRange: The device voltage range which defines the erase parallelism. + * This parameter can be one of the following values: + * @arg VoltageRange_1: when the device voltage range is 1.8V to 2.1V, + * the operation will be done by byte (8-bit) + * @arg VoltageRange_2: when the device voltage range is 2.1V to 2.7V, + * the operation will be done by half word (16-bit) + * @arg VoltageRange_3: when the device voltage range is 2.7V to 3.6V, + * the operation will be done by word (32-bit) + * @arg VoltageRange_4: when the device voltage range is 2.7V to 3.6V + External Vpp, + * the operation will be done by double word (64-bit) + * + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_EraseSector(uint32 FLASH_Sector, uint8 VoltageRange) +{ + uint32 tmp_psize = 0x0; + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + //assert_param(IS_FLASH_SECTOR(FLASH_Sector)); + //assert_param(IS_VOLTAGERANGE(VoltageRange)); + + if(VoltageRange == VoltageRange_1) + { + tmp_psize = FLASH_PSIZE_BYTE; + } + else if(VoltageRange == VoltageRange_2) + { + tmp_psize = FLASH_PSIZE_HALF_WORD; + } + else if(VoltageRange == VoltageRange_3) + { + tmp_psize = FLASH_PSIZE_WORD; + } + else + { + tmp_psize = FLASH_PSIZE_DOUBLE_WORD; + } + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase the sector */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= tmp_psize; + FLASH->CR &= SECTOR_MASK; + FLASH->CR |= FLASH_CR_SER | FLASH_Sector; + FLASH->CR |= FLASH_CR_STRT; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + + /* if the erase operation is completed, disable the SER Bit */ + FLASH->CR &= (~FLASH_CR_SER); + FLASH->CR &= SECTOR_MASK; + } + /* Return the Erase Status */ + return status; +} + +/** + * @brief Erases a specified FLASH page. + * @param Page_Address: The page address to be erased. + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ErasePage(uint32 Page_Address) +{ + int Page_Offset = Page_Address - 0x08000000; + uint32 FLASH_Sector; + + if(Page_Offset < 0x10000) { + FLASH_Sector = Page_Offset / 0x4000; + } else if(Page_Offset < 0x20000) { + FLASH_Sector = 4; + } else { + FLASH_Sector = 4 + Page_Offset / 0x20000; + } + + return FLASH_EraseSector(8 * FLASH_Sector, VoltageRange_4); +} + + + +/** + * @brief Programs a half word (16-bit) at a specified address. + * @note This function must be used when the device voltage range is from 2.1V to 3.6V. + * @param Address: specifies the address to be programmed. + * This parameter can be any address in Program memory zone or in OTP zone. + * @param Data: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, + * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. + */ +FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data) +{ + FLASH_Status status = FLASH_BAD_ADDRESS; + + if (IS_FLASH_ADDRESS(Address)) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new data */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= FLASH_PSIZE_HALF_WORD; + FLASH->CR |= FLASH_CR_PG; + + *(__io uint16*)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the PG Bit */ + FLASH->CR &= (~FLASH_CR_PG); + } + } + } + + /* Return the Program Status */ + return status; +} + + +/** + * @brief Unlocks the FLASH control register access + * @param None + * @retval None + */ +void FLASH_Unlock(void) +{ + if((FLASH->CR & FLASH_CR_LOCK) != 0) + { + /* Authorize the FLASH Registers access */ + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; + } +} + +/** + * @brief Locks the FLASH control register access + * @param None + * @retval None + */ +void FLASH_Lock(void) +{ + /* Set the LOCK Bit to lock the FLASH Registers access */ + FLASH->CR |= FLASH_CR_LOCK; +} diff --git a/AeroQuad32/MapleCompatibility/pins_arduino.h b/AeroQuad32/MapleCompatibility/pins_arduino.h index 5acd7ec0..aedd8188 100644 --- a/AeroQuad32/MapleCompatibility/pins_arduino.h +++ b/AeroQuad32/MapleCompatibility/pins_arduino.h @@ -1 +1 @@ -// dummy file, nothing to do here +// dummy file, nothing to do here diff --git a/AeroQuad32/SerialMapping.h b/AeroQuad32/SerialMapping.h index 797a6f1f..50676adb 100644 --- a/AeroQuad32/SerialMapping.h +++ b/AeroQuad32/SerialMapping.h @@ -1,12 +1,12 @@ -#ifndef _AQ32_SERIAL_MAPPING_h -#define _AQ32_SERIAL_MAPPING_h - -// set USE_USB_SERIAL if communication should be do via USB -// otherwise communication is done on Serial1 -// see WProgram.h for implementation details - -#if !defined (WirelessTelemetry) - #define USE_USB_SERIAL -#endif - -#endif +#ifndef _AQ32_SERIAL_MAPPING_h +#define _AQ32_SERIAL_MAPPING_h + +// set USE_USB_SERIAL if communication should be do via USB +// otherwise communication is done on Serial1 +// see WProgram.h for implementation details + +#if !defined (WirelessTelemetry) + #define USE_USB_SERIAL +#endif + +#endif diff --git a/AeroQuad32/platform_aeroquad32.h b/AeroQuad32/platform_aeroquad32.h index a949ee67..9ff55165 100644 --- a/AeroQuad32/platform_aeroquad32.h +++ b/AeroQuad32/platform_aeroquad32.h @@ -1,153 +1,153 @@ -#ifndef _PLATFORM_AEROQUAD32_H_ - -#define _PLATFORM_AEROQUAD32_H_ - -static byte __attribute__((unused)) stm32_motor_mapping[] = { - Port2Pin('C', 9), - Port2Pin('C', 8), - Port2Pin('C', 7), - Port2Pin('C', 6), - Port2Pin('A', 15), - Port2Pin('B', 3), - Port2Pin('B', 4), - Port2Pin('B', 5) -}; - -static byte __attribute__((unused)) stm32_motor_mapping_tri[] = { - Port2Pin('A', 15), // note this must be on separate timer device !! - Port2Pin('C', 8), - Port2Pin('C', 7), - Port2Pin('C', 6), -}; - -#ifdef RECEIVER_STM32PPM - static byte receiverPinPPM = Port2Pin('D', 15); -#elif defined ReceiverSBUS - // Do nothing -#else - static byte receiverPin[] = { - Port2Pin('D', 12), - Port2Pin('D', 13), - Port2Pin('D', 14), - Port2Pin('D', 15), - Port2Pin('E', 9), - Port2Pin('E', 11), - Port2Pin('E', 13), - Port2Pin('E', 14) - }; -#endif - -#define STM32_BOARD_TYPE "aeroquad32" -#define LED_Green Port2Pin('E', 6) -#define LED_Red Port2Pin('E', 5) -#define LED_Yellow LED_Red - -#define BATT_ANALOG_INPUT Port2Pin('C', 0) -#define A1 Port2Pin('B',0) -#define A2 Port2Pin('C',4) -#define A3 Port2Pin('B',1) -#define A4 Port2Pin('C',5) -#define A5 Port2Pin('C',2) -#define A6 Port2Pin('C',3) - -// external LED drivers -#define PLED1 Port2Pin('D', 7) -#define PLED2 Port2Pin('E', 0) -#define PLED3 Port2Pin('E', 1) -#define PLED4 Port2Pin('D', 4) - -#include - -#include -#include - -// heading mag hold declaration -#ifdef HeadingMagHold - #include - #define HMC5883L -#endif - -// Altitude declaration -#ifdef AltitudeHoldBaro - #define MS5611 -#endif - -#ifdef AltitudeHoldRangeFinder - #define XLMAXSONAR -#endif - -// Battery Monitor declaration -#ifdef BattMonitor - #define BATT_AREF 3.3 // V - #define BATT_R_HIGH 10.0 // kOhm - #define BATT_R_LOW 1.5 // kOhm - #define BATT_DIODE_LOSS 0.0 - #define BattDefaultConfig DEFINE_BATTERY(0, BATT_ANALOG_INPUT, (BATT_AREF * (BATT_R_HIGH + BATT_R_LOW) / BATT_R_LOW), BATT_DIODE_LOSS, BM_NOPIN, 0, 0) -#endif - -#ifdef OSD - #define MAX7456_OSD -#endif - -#ifdef CameraControl - #define CameraControl_STM32 -#endif - -void initPlatform() { - pinMode(LED_Green, OUTPUT); - for(byte ledloop=0; ledloop<10; ledloop++) { - digitalWrite(LED_Green, ledloop & 1); - delay(50); - } - - pinMode(LED_Red, OUTPUT); - digitalWrite(LED_Red, LOW); - pinMode(LED_Yellow, OUTPUT); - digitalWrite(LED_Yellow, LOW); - - pinMode(BATT_ANALOG_INPUT, INPUT_ANALOG); - pinMode(A1, INPUT_ANALOG); - pinMode(A2, INPUT_ANALOG); - pinMode(A3, INPUT_ANALOG); - pinMode(A4, INPUT_ANALOG); - pinMode(A5, INPUT_ANALOG); - pinMode(A6, INPUT_ANALOG); - - pinMode(PLED1, OUTPUT); - pinMode(PLED2, OUTPUT); - pinMode(PLED3, OUTPUT); - pinMode(PLED4, OUTPUT); - - // I2C setup - Wire.begin(Port2Pin('B', 7), Port2Pin('B', 6)); // I2C1_SDA PB7, I2C1_SCL PB6 - - #if !defined(USE_USB_SERIAL) - SerialUSB.begin(); - #endif -} - -// called when eeprom is initialized -void initializePlatformSpecificAccelCalibration() { - // Kenny default value, a real accel calibration is strongly recommended - accelScaleFactor[XAXIS] = 0.0011970000; - accelScaleFactor[YAXIS] = -0.0012050000; - accelScaleFactor[ZAXIS] = -0.0011770000; - #ifdef HeadingMagHold - magBias[XAXIS] = 152.000000; - magBias[YAXIS] = 24.000000; - magBias[ZAXIS] = 16.500000; - #endif - -} - -unsigned long previousMeasureCriticalSensorsTime = 0; -void measureCriticalSensors() { - // read sensors not faster than every 1 ms - if (currentTime - previousMeasureCriticalSensorsTime >= 1000) { - measureGyroSum(); - measureAccelSum(); - previousMeasureCriticalSensorsTime = currentTime; - } -} - -#endif +#ifndef _PLATFORM_AEROQUAD32_H_ + +#define _PLATFORM_AEROQUAD32_H_ + +static byte __attribute__((unused)) stm32_motor_mapping[] = { + Port2Pin('C', 9), + Port2Pin('C', 8), + Port2Pin('C', 7), + Port2Pin('C', 6), + Port2Pin('A', 15), + Port2Pin('B', 3), + Port2Pin('B', 4), + Port2Pin('B', 5) +}; + +static byte __attribute__((unused)) stm32_motor_mapping_tri[] = { + Port2Pin('A', 15), // note this must be on separate timer device !! + Port2Pin('C', 8), + Port2Pin('C', 7), + Port2Pin('C', 6), +}; + +#ifdef RECEIVER_STM32PPM + static byte receiverPinPPM = Port2Pin('D', 15); +#elif defined ReceiverSBUS + // Do nothing +#else + static byte receiverPin[] = { + Port2Pin('D', 12), + Port2Pin('D', 13), + Port2Pin('D', 14), + Port2Pin('D', 15), + Port2Pin('E', 9), + Port2Pin('E', 11), + Port2Pin('E', 13), + Port2Pin('E', 14) + }; +#endif + +#define STM32_BOARD_TYPE "aeroquad32" +#define LED_Green Port2Pin('E', 6) +#define LED_Red Port2Pin('E', 5) +#define LED_Yellow LED_Red + +#define BATT_ANALOG_INPUT Port2Pin('C', 0) +#define A1 Port2Pin('B',0) +#define A2 Port2Pin('C',4) +#define A3 Port2Pin('B',1) +#define A4 Port2Pin('C',5) +#define A5 Port2Pin('C',2) +#define A6 Port2Pin('C',3) + +// external LED drivers +#define PLED1 Port2Pin('D', 7) +#define PLED2 Port2Pin('E', 0) +#define PLED3 Port2Pin('E', 1) +#define PLED4 Port2Pin('D', 4) + +#include + +#include +#include + +// heading mag hold declaration +#ifdef HeadingMagHold + #include + #define HMC5883L +#endif + +// Altitude declaration +#ifdef AltitudeHoldBaro + #define MS5611 +#endif + +#ifdef AltitudeHoldRangeFinder + #define XLMAXSONAR +#endif + +// Battery Monitor declaration +#ifdef BattMonitor + #define BATT_AREF 3.3 // V + #define BATT_R_HIGH 10.0 // kOhm + #define BATT_R_LOW 1.5 // kOhm + #define BATT_DIODE_LOSS 0.0 + #define BattDefaultConfig DEFINE_BATTERY(0, BATT_ANALOG_INPUT, (BATT_AREF * (BATT_R_HIGH + BATT_R_LOW) / BATT_R_LOW), BATT_DIODE_LOSS, BM_NOPIN, 0, 0) +#endif + +#ifdef OSD + #define MAX7456_OSD +#endif + +#ifdef CameraControl + #define CameraControl_STM32 +#endif + +void initPlatform() { + pinMode(LED_Green, OUTPUT); + for(byte ledloop=0; ledloop<10; ledloop++) { + digitalWrite(LED_Green, ledloop & 1); + delay(50); + } + + pinMode(LED_Red, OUTPUT); + digitalWrite(LED_Red, LOW); + pinMode(LED_Yellow, OUTPUT); + digitalWrite(LED_Yellow, LOW); + + pinMode(BATT_ANALOG_INPUT, INPUT_ANALOG); + pinMode(A1, INPUT_ANALOG); + pinMode(A2, INPUT_ANALOG); + pinMode(A3, INPUT_ANALOG); + pinMode(A4, INPUT_ANALOG); + pinMode(A5, INPUT_ANALOG); + pinMode(A6, INPUT_ANALOG); + + pinMode(PLED1, OUTPUT); + pinMode(PLED2, OUTPUT); + pinMode(PLED3, OUTPUT); + pinMode(PLED4, OUTPUT); + + // I2C setup + Wire.begin(Port2Pin('B', 7), Port2Pin('B', 6)); // I2C1_SDA PB7, I2C1_SCL PB6 + + #if !defined(USE_USB_SERIAL) + SerialUSB.begin(); + #endif +} + +// called when eeprom is initialized +void initializePlatformSpecificAccelCalibration() { + // Kenny default value, a real accel calibration is strongly recommended + accelScaleFactor[XAXIS] = 0.0011970000; + accelScaleFactor[YAXIS] = -0.0012050000; + accelScaleFactor[ZAXIS] = -0.0011770000; + #ifdef HeadingMagHold + magBias[XAXIS] = 152.000000; + magBias[YAXIS] = 24.000000; + magBias[ZAXIS] = 16.500000; + #endif + +} + +unsigned long previousMeasureCriticalSensorsTime = 0; +void measureCriticalSensors() { + // read sensors not faster than every 1 ms + if (currentTime - previousMeasureCriticalSensorsTime >= 1000) { + measureGyroSum(); + measureAccelSum(); + previousMeasureCriticalSensorsTime = currentTime; + } +} + +#endif diff --git a/AeroQuad32/platform_discoveryf4.h b/AeroQuad32/platform_discoveryf4.h index 7f8112c7..7f9c4acd 100644 --- a/AeroQuad32/platform_discoveryf4.h +++ b/AeroQuad32/platform_discoveryf4.h @@ -1,137 +1,137 @@ -#ifndef _PLATFORM_DISCOVERYF4_H_ - -#define _PLATFORM_DISCOVERYF4_H_ - -static byte stm32_motor_mapping[] = { - Port2Pin('C', 9), - Port2Pin('C', 8), - Port2Pin('C', 7), - Port2Pin('C', 6), - // pin mapping for motor 5-8 not specified, yet - Port2Pin('A', 15), - Port2Pin('B', 3), - Port2Pin('B', 4), - Port2Pin('B', 5) -}; - -#ifdef RECEIVER_STM32PPM - static byte receiverPinPPM = Port2Pin('E', 9); -#else - static byte receiverPin[] = { - Port2Pin('E', 9), - Port2Pin('E', 11), - Port2Pin('E', 13), - Port2Pin('E', 14), - Port2Pin('B', 4), - Port2Pin('B', 5), - Port2Pin('B', 0), - Port2Pin('B', 1) - }; -#endif - -#define STM32_BOARD_TYPE "Discovery F4" -#define LED_Green Port2Pin('D', 12) -#define LED_Red Port2Pin('D', 14) -#define LED_Yellow Port2Pin('D', 13) - -#include - -//#include -#include - -//#include -#include - -// heading mag hold declaration -#ifdef HeadingMagHold - #define HMC5883L -#endif - -// Altitude declaration -#ifdef AltitudeHoldBaro - //#define BMP085 - #define MS5611 -#endif - -// Battery Monitor declaration -#ifdef BattMonitor - #define BATT_AREF 3.3 // V - - #define BATT_R_HIGH 10.0 // kOhm - #define BATT_R_LOW 1.5 // kOhm - #define BATT_ANALOG_INPUT Port2Pin('C', 0) - #define BATT_DIODE_LOSS 0.0 - #define BattDefaultConfig DEFINE_BATTERY(0, BATT_ANALOG_INPUT, (BATT_AREF * (BATT_R_HIGH + BATT_R_LOW) / BATT_R_LOW), BATT_DIODE_LOSS, BM_NOPIN, 0, 0) -#endif - - -void HardCodedAxisCalibration() -{ - initSensorsZeroFromEEPROM(); - if((accelScaleFactor[XAXIS] == 1.0 && accelScaleFactor[YAXIS] == 1.0 && accelScaleFactor[ZAXIS] == 1.0) || - (accelScaleFactor[XAXIS] == 0.0 && accelScaleFactor[YAXIS] == 0.0 && accelScaleFactor[ZAXIS] == 0.0)) { - #ifdef _AEROQUAD_PLATFORM_MPU6000_H_ - accelScaleFactor[XAXIS] = accelScaleFactor[YAXIS] = accelScaleFactor[ZAXIS] = 0.00119; - #else - accelScaleFactor[XAXIS] = accelScaleFactor[YAXIS] = accelScaleFactor[ZAXIS] = 0.0048; - #endif - accelScaleFactor[YAXIS] *= -1; - accelScaleFactor[ZAXIS] *= -1; - } -} - - - -/** - * Put Discovery F4 specific initialization need here - */ -void initPlatform() { - pinMode(LED_Green, OUTPUT); - for(byte ledloop=0; ledloop<10; ledloop++) { - digitalWrite(LED_Green, ledloop & 1); - delay(50); - } - - pinMode(LED_Red, OUTPUT); - digitalWrite(LED_Red, LOW); - pinMode(LED_Yellow, OUTPUT); - digitalWrite(LED_Yellow, LOW); - - #ifdef BattMonitor - pinMode(BATT_ANALOG_INPUT, INPUT_ANALOG); - #endif - - // I2C setup - Wire.begin(Port2Pin('B', 9), Port2Pin('B', 6)); // I2C1_SDA PB9, I2C1_SCL PB6 - - HardCodedAxisCalibration(); - - #if !defined(USE_USB_SERIAL) - SerialUSB.begin(); - #endif -} - -// called when eeprom is initialized -void initializePlatformSpecificAccelCalibration() { -// Accel Cal - accelScaleFactor[XAXIS] = 1.0; - runTimeAccelBias[XAXIS] = 0.0; - accelScaleFactor[YAXIS] = 1.0; - runTimeAccelBias[YAXIS] = 0.0; - accelScaleFactor[ZAXIS] = 1.0; - runTimeAccelBias[ZAXIS] = 0.0; -} - - -unsigned long previousMeasureCriticalSensorsTime = 0; -void measureCriticalSensors() { - // read sensors not faster than every 1 ms - if (currentTime - previousMeasureCriticalSensorsTime >= 1000) { - measureGyroSum(); - measureAccelSum(); - - previousMeasureCriticalSensorsTime = currentTime; - } -} - -#endif +#ifndef _PLATFORM_DISCOVERYF4_H_ + +#define _PLATFORM_DISCOVERYF4_H_ + +static byte stm32_motor_mapping[] = { + Port2Pin('C', 9), + Port2Pin('C', 8), + Port2Pin('C', 7), + Port2Pin('C', 6), + // pin mapping for motor 5-8 not specified, yet + Port2Pin('A', 15), + Port2Pin('B', 3), + Port2Pin('B', 4), + Port2Pin('B', 5) +}; + +#ifdef RECEIVER_STM32PPM + static byte receiverPinPPM = Port2Pin('E', 9); +#else + static byte receiverPin[] = { + Port2Pin('E', 9), + Port2Pin('E', 11), + Port2Pin('E', 13), + Port2Pin('E', 14), + Port2Pin('B', 4), + Port2Pin('B', 5), + Port2Pin('B', 0), + Port2Pin('B', 1) + }; +#endif + +#define STM32_BOARD_TYPE "Discovery F4" +#define LED_Green Port2Pin('D', 12) +#define LED_Red Port2Pin('D', 14) +#define LED_Yellow Port2Pin('D', 13) + +#include + +//#include +#include + +//#include +#include + +// heading mag hold declaration +#ifdef HeadingMagHold + #define HMC5883L +#endif + +// Altitude declaration +#ifdef AltitudeHoldBaro + //#define BMP085 + #define MS5611 +#endif + +// Battery Monitor declaration +#ifdef BattMonitor + #define BATT_AREF 3.3 // V + + #define BATT_R_HIGH 10.0 // kOhm + #define BATT_R_LOW 1.5 // kOhm + #define BATT_ANALOG_INPUT Port2Pin('C', 0) + #define BATT_DIODE_LOSS 0.0 + #define BattDefaultConfig DEFINE_BATTERY(0, BATT_ANALOG_INPUT, (BATT_AREF * (BATT_R_HIGH + BATT_R_LOW) / BATT_R_LOW), BATT_DIODE_LOSS, BM_NOPIN, 0, 0) +#endif + + +void HardCodedAxisCalibration() +{ + initSensorsZeroFromEEPROM(); + if((accelScaleFactor[XAXIS] == 1.0 && accelScaleFactor[YAXIS] == 1.0 && accelScaleFactor[ZAXIS] == 1.0) || + (accelScaleFactor[XAXIS] == 0.0 && accelScaleFactor[YAXIS] == 0.0 && accelScaleFactor[ZAXIS] == 0.0)) { + #ifdef _AEROQUAD_PLATFORM_MPU6000_H_ + accelScaleFactor[XAXIS] = accelScaleFactor[YAXIS] = accelScaleFactor[ZAXIS] = 0.00119; + #else + accelScaleFactor[XAXIS] = accelScaleFactor[YAXIS] = accelScaleFactor[ZAXIS] = 0.0048; + #endif + accelScaleFactor[YAXIS] *= -1; + accelScaleFactor[ZAXIS] *= -1; + } +} + + + +/** + * Put Discovery F4 specific initialization need here + */ +void initPlatform() { + pinMode(LED_Green, OUTPUT); + for(byte ledloop=0; ledloop<10; ledloop++) { + digitalWrite(LED_Green, ledloop & 1); + delay(50); + } + + pinMode(LED_Red, OUTPUT); + digitalWrite(LED_Red, LOW); + pinMode(LED_Yellow, OUTPUT); + digitalWrite(LED_Yellow, LOW); + + #ifdef BattMonitor + pinMode(BATT_ANALOG_INPUT, INPUT_ANALOG); + #endif + + // I2C setup + Wire.begin(Port2Pin('B', 9), Port2Pin('B', 6)); // I2C1_SDA PB9, I2C1_SCL PB6 + + HardCodedAxisCalibration(); + + #if !defined(USE_USB_SERIAL) + SerialUSB.begin(); + #endif +} + +// called when eeprom is initialized +void initializePlatformSpecificAccelCalibration() { +// Accel Cal + accelScaleFactor[XAXIS] = 1.0; + runTimeAccelBias[XAXIS] = 0.0; + accelScaleFactor[YAXIS] = 1.0; + runTimeAccelBias[YAXIS] = 0.0; + accelScaleFactor[ZAXIS] = 1.0; + runTimeAccelBias[ZAXIS] = 0.0; +} + + +unsigned long previousMeasureCriticalSensorsTime = 0; +void measureCriticalSensors() { + // read sensors not faster than every 1 ms + if (currentTime - previousMeasureCriticalSensorsTime >= 1000) { + measureGyroSum(); + measureAccelSum(); + + previousMeasureCriticalSensorsTime = currentTime; + } +} + +#endif diff --git a/AeroQuad32/platform_freeflight.h b/AeroQuad32/platform_freeflight.h index 23b32b12..e6fb2a3c 100644 --- a/AeroQuad32/platform_freeflight.h +++ b/AeroQuad32/platform_freeflight.h @@ -1,134 +1,134 @@ -#ifndef _PLATFORM_FREEFLIGHT_H_ - #define _PLATFORM_FREEFLIGHT_H_ - - static byte stm32_motor_mapping[] = { - Port2Pin('B', 6), - Port2Pin('B', 7), - Port2Pin('B', 8), - Port2Pin('B', 9), - Port2Pin('A', 8), - Port2Pin('A', 11) - }; - -#ifdef RECEIVER_STM32PPM - static byte receiverPinPPM = Port2Pin('A', 0); -#else - static byte receiverPin[] = { - Port2Pin('A', 0), - Port2Pin('A', 1), - Port2Pin('A', 2), - Port2Pin('A', 3), - Port2Pin('A', 6), - Port2Pin('A', 7), - Port2Pin('B', 0), - Port2Pin('B', 1) - }; -#endif - - - #define STM32_BOARD_TYPE "Free Flight" - #define LED_Green Port2Pin('B', 4) - #define LED_Red Port2Pin('B', 3) - #define LED_Yellow LED_Red - #define ITG3200_ADDRESS_ALTERNATE - - - #include - - #include - #include - - - // heading mag hold declaration - #ifdef HeadingMagHold - #define HMC5883L - #endif - - // Altitude declaration - #ifdef AltitudeHoldBaro - #define BMP085 - #endif - - - // Battery Monitor declaration - #ifdef BattMonitor - #define BATT_AREF 3.3 // V - - #define BATT_R_HIGH 10.0 // kOhm - #define BATT_R_LOW 1.0 // kOhm - #define BATT_ANALOG_INPUT Port2Pin('A', 4) - #define BATT_DIODE_LOSS 0.76 - #define BattDefaultConfig DEFINE_BATTERY(0, BATT_ANALOG_INPUT, (BATT_AREF * (BATT_R_HIGH + BATT_R_LOW) / BATT_R_LOW), BATT_DIODE_LOSS, BM_NOPIN, 0, 0) - #endif - - - void HardCodedAxisCalibration() - { - initSensorsZeroFromEEPROM(); - if( (accelScaleFactor[XAXIS] == 1.0 && accelScaleFactor[YAXIS] == 1.0 && accelScaleFactor[ZAXIS] == 1.0) - || (accelScaleFactor[XAXIS] == 0.0 && accelScaleFactor[YAXIS] == 0.0 && accelScaleFactor[ZAXIS] == 0.0) - ) { - accelScaleFactor[XAXIS] = accelScaleFactor[YAXIS] = accelScaleFactor[ZAXIS] = -0.038; - //accelScaleFactor[YAXIS] *= -1; - //accelScaleFactor[ZAXIS] *= -1; - - storeSensorsZeroToEEPROM(); - } - } - - - - /** - * Put FreeFlight specific initialization need here - */ - void initPlatform() { - pinMode(LED_Green, OUTPUT); - for(byte ledloop=0; ledloop<10; ledloop++) { - digitalWrite(LED_Green, ledloop & 1); - delay(50); - } - - pinMode(LED_Red, OUTPUT); - digitalWrite(LED_Red, LOW); - pinMode(LED_Yellow, OUTPUT); - digitalWrite(LED_Yellow, LOW); - - #ifdef BattMonitor - pinMode(BATT_ANALOG_INPUT, INPUT_ANALOG); - #endif - - - #ifdef DEBUG_INIT - Serial.println("\r\nAeroQuad STM32, board type " STM32_BOARD_TYPE ", build date " __DATE__ " "__TIME__); - #endif - - - // I2C setup - Wire.begin(Port2Pin('B', 11), Port2Pin('B', 10)); // I2C1_SDA PB11, I2C1_SCL PB10 - - - HardCodedAxisCalibration(); - - #ifdef DEBUG_INIT - Serial.println("STM32 init done\r\n"); - #endif - } - - - void SignalAlive(int frameCounter) { - digitalWrite(LED_Green, (frameCounter/50) & 1); - } - - unsigned long previousMeasureCriticalSensorsTime = 0; - void measureCriticalSensors() { - // read sensors not faster than every 1 ms - if (currentTime - previousMeasureCriticalSensorsTime >= 1000) { - measureGyroSum(); - measureAccelSum(); - - SignalAlive(frameCounter); - - previousMeasureCriticalSensorsTime = currentTime; - } - } -#endif +#ifndef _PLATFORM_FREEFLIGHT_H_ + #define _PLATFORM_FREEFLIGHT_H_ + + static byte stm32_motor_mapping[] = { + Port2Pin('B', 6), + Port2Pin('B', 7), + Port2Pin('B', 8), + Port2Pin('B', 9), + Port2Pin('A', 8), + Port2Pin('A', 11) + }; + +#ifdef RECEIVER_STM32PPM + static byte receiverPinPPM = Port2Pin('A', 0); +#else + static byte receiverPin[] = { + Port2Pin('A', 0), + Port2Pin('A', 1), + Port2Pin('A', 2), + Port2Pin('A', 3), + Port2Pin('A', 6), + Port2Pin('A', 7), + Port2Pin('B', 0), + Port2Pin('B', 1) + }; +#endif + + + #define STM32_BOARD_TYPE "Free Flight" + #define LED_Green Port2Pin('B', 4) + #define LED_Red Port2Pin('B', 3) + #define LED_Yellow LED_Red + #define ITG3200_ADDRESS_ALTERNATE + + + #include + + #include + #include + + + // heading mag hold declaration + #ifdef HeadingMagHold + #define HMC5883L + #endif + + // Altitude declaration + #ifdef AltitudeHoldBaro + #define BMP085 + #endif + + + // Battery Monitor declaration + #ifdef BattMonitor + #define BATT_AREF 3.3 // V + + #define BATT_R_HIGH 10.0 // kOhm + #define BATT_R_LOW 1.0 // kOhm + #define BATT_ANALOG_INPUT Port2Pin('A', 4) + #define BATT_DIODE_LOSS 0.76 + #define BattDefaultConfig DEFINE_BATTERY(0, BATT_ANALOG_INPUT, (BATT_AREF * (BATT_R_HIGH + BATT_R_LOW) / BATT_R_LOW), BATT_DIODE_LOSS, BM_NOPIN, 0, 0) + #endif + + + void HardCodedAxisCalibration() + { + initSensorsZeroFromEEPROM(); + if( (accelScaleFactor[XAXIS] == 1.0 && accelScaleFactor[YAXIS] == 1.0 && accelScaleFactor[ZAXIS] == 1.0) + || (accelScaleFactor[XAXIS] == 0.0 && accelScaleFactor[YAXIS] == 0.0 && accelScaleFactor[ZAXIS] == 0.0) + ) { + accelScaleFactor[XAXIS] = accelScaleFactor[YAXIS] = accelScaleFactor[ZAXIS] = -0.038; + //accelScaleFactor[YAXIS] *= -1; + //accelScaleFactor[ZAXIS] *= -1; + + storeSensorsZeroToEEPROM(); + } + } + + + + /** + * Put FreeFlight specific initialization need here + */ + void initPlatform() { + pinMode(LED_Green, OUTPUT); + for(byte ledloop=0; ledloop<10; ledloop++) { + digitalWrite(LED_Green, ledloop & 1); + delay(50); + } + + pinMode(LED_Red, OUTPUT); + digitalWrite(LED_Red, LOW); + pinMode(LED_Yellow, OUTPUT); + digitalWrite(LED_Yellow, LOW); + + #ifdef BattMonitor + pinMode(BATT_ANALOG_INPUT, INPUT_ANALOG); + #endif + + + #ifdef DEBUG_INIT + Serial.println("\r\nAeroQuad STM32, board type " STM32_BOARD_TYPE ", build date " __DATE__ " "__TIME__); + #endif + + + // I2C setup + Wire.begin(Port2Pin('B', 11), Port2Pin('B', 10)); // I2C1_SDA PB11, I2C1_SCL PB10 + + + HardCodedAxisCalibration(); + + #ifdef DEBUG_INIT + Serial.println("STM32 init done\r\n"); + #endif + } + + + void SignalAlive(int frameCounter) { + digitalWrite(LED_Green, (frameCounter/50) & 1); + } + + unsigned long previousMeasureCriticalSensorsTime = 0; + void measureCriticalSensors() { + // read sensors not faster than every 1 ms + if (currentTime - previousMeasureCriticalSensorsTime >= 1000) { + measureGyroSum(); + measureAccelSum(); + + SignalAlive(frameCounter); + + previousMeasureCriticalSensorsTime = currentTime; + } + } +#endif diff --git a/BuildAQ32/Makefile b/BuildAQ32/Makefile index 1535a7a2..1842d59c 100644 --- a/BuildAQ32/Makefile +++ b/BuildAQ32/Makefile @@ -1,777 +1,777 @@ -# Hey Emacs, this is a -*- makefile -*- -#---------------------------------------------------------------------------- -# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al. -# -# Released to the Public Domain -# -# Additional material for this makefile was written by: -# Peter Fleury -# Tim Henigan -# Colin O'Flynn -# Reiner Patommel -# Markus Pfaff -# Sander Pool -# Frederik Rouleau -# Carlos Lamas -# -#---------------------------------------------------------------------------- -# On command line: -# -# make all = Make software. -# -# make clean = Clean out built project files. -# -# make coff = Convert ELF to AVR COFF. -# -# make extcoff = Convert ELF to AVR Extended COFF. -# -# make program = Download the hex file to the device, using avrdude. -# Please customize the avrdude settings below first! -# -# make debug = Start either simulavr or avarice as specified for debugging, -# with avr-gdb or avr-insight as the front end for debugging. -# -# make filename.s = Just compile filename.c into the assembler code only. -# -# make filename.i = Create a preprocessed source file for use in submitting -# bug reports to the GCC project. -# -# To rebuild project do "make clean" then "make all". -#---------------------------------------------------------------------------- - -BUILDTYPE ?= STM32 -#BUILDTYPE ?= XMEGA - -BOARD ?= aeroquad32 -#BOARD ?= aeroquad32f1 -#BOARD ?= aeroquad32mini -#BOARD = discovery_f4 -#BOARD ?= freeflight - -V=1 - -ADDITIONALDEFINES = -#ADDITIONALDEFINES = -DSENSORBOARD_ALA42 - -ifeq ($(BUILDTYPE), XMEGA) - # MCU name - BUILDPREFIX=avr - MCU = atxmega128a1 - AVRDUDE_MCU = atxmega128a1 - CPUCLASS=XMEGA - F_CPU = 32000000 - DEFINECPU = -mmcu=$(MCU) - EXTRAINCDIRS = ../arduinoXMega ../arduinoXMega/Libraries - RUNTIMELIB = ../arduinoXMega/libAVRArduino.a -endif - -ifeq ($(BUILDTYPE), STM32) - BUILDPREFIX= arm-none-eabi - CPUCLASS=STM32 - F_CPU = 72000000 - MEMORY_TARGET ?= flash - MCU_OPTIONS = -mcpu=cortex-m3 -mthumb - #-fshort-double - - # Guess the MCU based on the BOARD (can be overridden ) - ifeq ($(BOARD), maple) - MCU_FAMILY := STM32F1 - MCU := STM32F103RB - PRODUCT_ID := 0003 - endif - ifeq ($(BOARD), aeroquad32f1) - MCU_FAMILY := STM32F1 - MCU := STM32F103VE - DENSITY := STM32_HIGH_DENSITY - PRODUCT_ID := 0003 - MCU_OPTIONS += -DBOARD_aeroquad32 - endif - ifeq ($(BOARD), aeroquad32) - MCU_FAMILY := STM32F2 - MCU := STM32F406VG - DENSITY := STM32_HIGH_DENSITY - PRODUCT_ID := 0003 - MCU_OPTIONS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp - F_CPU = 168000000 - endif - ifeq ($(BOARD), aeroquad32mini) - MCU_FAMILY := STM32F1 - MCU := STM32F103CB - DENSITY := STM32_MEDIUM_DENSITY - PRODUCT_ID := 0003 - endif - ifeq ($(BOARD), freeflight) - MCU_FAMILY := STM32F1 - MCU := STM32F103CB - DENSITY := STM32_MEDIUM_DENSITY - PRODUCT_ID := 0003 - endif - ifeq ($(BOARD), maple_native) - MCU_FAMILY := STM32F1 - MCU := STM32F103ZE - DENSITY := STM32_HIGH_DENSITY - PRODUCT_ID := 0003 - endif - ifeq ($(BOARD), maple_mini) - MCU_FAMILY := STM32F1 - MCU := STM32F103CB - DENSITY := STM32_MEDIUM_DENSITY - PRODUCT_ID := 0003 - endif - ifeq ($(BOARD), discovery_f4) - MCU_FAMILY := STM32F2 - MCU := STM32F406VG - DENSITY := STM32_HIGH_DENSITY - PRODUCT_ID := 0003 - MCU_OPTIONS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp - F_CPU = 168000000 - endif - - LIB_MAPLE_HOME = ../Libmaple/libmaple - SRCROOT := $(LIB_MAPLE_HOME) - SUPPORT_PATH := $(SRCROOT)/support +# Hey Emacs, this is a -*- makefile -*- +#---------------------------------------------------------------------------- +# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al. +# +# Released to the Public Domain +# +# Additional material for this makefile was written by: +# Peter Fleury +# Tim Henigan +# Colin O'Flynn +# Reiner Patommel +# Markus Pfaff +# Sander Pool +# Frederik Rouleau +# Carlos Lamas +# +#---------------------------------------------------------------------------- +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF. +# +# make extcoff = Convert ELF to AVR Extended COFF. +# +# make program = Download the hex file to the device, using avrdude. +# Please customize the avrdude settings below first! +# +# make debug = Start either simulavr or avarice as specified for debugging, +# with avr-gdb or avr-insight as the front end for debugging. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# make filename.i = Create a preprocessed source file for use in submitting +# bug reports to the GCC project. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +BUILDTYPE ?= STM32 +#BUILDTYPE ?= XMEGA + +BOARD ?= aeroquad32 +#BOARD ?= aeroquad32f1 +#BOARD ?= aeroquad32mini +#BOARD = discovery_f4 +#BOARD ?= freeflight + +V=1 + +ADDITIONALDEFINES = +#ADDITIONALDEFINES = -DSENSORBOARD_ALA42 + +ifeq ($(BUILDTYPE), XMEGA) + # MCU name + BUILDPREFIX=avr + MCU = atxmega128a1 + AVRDUDE_MCU = atxmega128a1 + CPUCLASS=XMEGA + F_CPU = 32000000 + DEFINECPU = -mmcu=$(MCU) + EXTRAINCDIRS = ../arduinoXMega ../arduinoXMega/Libraries + RUNTIMELIB = ../arduinoXMega/libAVRArduino.a +endif + +ifeq ($(BUILDTYPE), STM32) + BUILDPREFIX= arm-none-eabi + CPUCLASS=STM32 + F_CPU = 72000000 + MEMORY_TARGET ?= flash + MCU_OPTIONS = -mcpu=cortex-m3 -mthumb + #-fshort-double + + # Guess the MCU based on the BOARD (can be overridden ) + ifeq ($(BOARD), maple) + MCU_FAMILY := STM32F1 + MCU := STM32F103RB + PRODUCT_ID := 0003 + endif + ifeq ($(BOARD), aeroquad32f1) + MCU_FAMILY := STM32F1 + MCU := STM32F103VE + DENSITY := STM32_HIGH_DENSITY + PRODUCT_ID := 0003 + MCU_OPTIONS += -DBOARD_aeroquad32 + endif + ifeq ($(BOARD), aeroquad32) + MCU_FAMILY := STM32F2 + MCU := STM32F406VG + DENSITY := STM32_HIGH_DENSITY + PRODUCT_ID := 0003 + MCU_OPTIONS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp + F_CPU = 168000000 + endif + ifeq ($(BOARD), aeroquad32mini) + MCU_FAMILY := STM32F1 + MCU := STM32F103CB + DENSITY := STM32_MEDIUM_DENSITY + PRODUCT_ID := 0003 + endif + ifeq ($(BOARD), freeflight) + MCU_FAMILY := STM32F1 + MCU := STM32F103CB + DENSITY := STM32_MEDIUM_DENSITY + PRODUCT_ID := 0003 + endif + ifeq ($(BOARD), maple_native) + MCU_FAMILY := STM32F1 + MCU := STM32F103ZE + DENSITY := STM32_HIGH_DENSITY + PRODUCT_ID := 0003 + endif + ifeq ($(BOARD), maple_mini) + MCU_FAMILY := STM32F1 + MCU := STM32F103CB + DENSITY := STM32_MEDIUM_DENSITY + PRODUCT_ID := 0003 + endif + ifeq ($(BOARD), discovery_f4) + MCU_FAMILY := STM32F2 + MCU := STM32F406VG + DENSITY := STM32_HIGH_DENSITY + PRODUCT_ID := 0003 + MCU_OPTIONS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp + F_CPU = 168000000 + endif + + LIB_MAPLE_HOME = ../Libmaple/libmaple + SRCROOT := $(LIB_MAPLE_HOME) + SUPPORT_PATH := $(SRCROOT)/support LDDIR := $(SUPPORT_PATH)/ld -##### Uncomment the -nostartfiles if compiling on OS X ##### - LDFLAGSSTM32 = -T$(LDDIR)/$(LDSCRIPT) -L$(LDDIR) -Xlinker --gc-sections -lc -nostartfiles - -# Set up build rules and some useful templates -include $(SUPPORT_PATH)/make/build-rules.mk -include $(SUPPORT_PATH)/make/build-templates.mk - -# Some target specific things -ifeq ($(MEMORY_TARGET), ram) - LDSCRIPT := $(BOARD)/ram.ld - VECT_BASE_ADDR := VECT_TAB_RAM -endif -ifeq ($(MEMORY_TARGET), flash) - LDSCRIPT := $(BOARD)/flash.ld - VECT_BASE_ADDR := VECT_TAB_FLASH -endif -ifeq ($(MEMORY_TARGET), jtag) - LDSCRIPT := $(BOARD)/jtag.ld - VECT_BASE_ADDR := VECT_TAB_BASE -endif - -DEFINECPU = $(MCU_OPTIONS) -DBOARD_$(BOARD) -DMCU_$(MCU) -D$(MCU_FAMILY) -D$(DENSITY) -fno-exceptions -EXTRACPPFLAGS = -fno-rtti -RUNTIMELIB = $(LIB_MAPLE_HOME)/build/libmaple.a -MAPLEINCDIRS = $(LIB_MAPLE_HOME) $(LIB_MAPLE_HOME)/libmaple $(LIB_MAPLE_HOME)/wirish $(LIB_MAPLE_HOME)/wirish/comm $(LIB_MAPLE_HOME)/wirish/boards $(LIB_MAPLE_HOME)/libraries/Wire -EXTRAINCDIRS = $(MCDIR) $(SRCDIRAQ32) $(MAPLEINCDIRS) -endif - -EXTRAINCDIRS += $(LIBDIR)/AQ_Accelerometer $(LIBDIR)/AQ_BarometricSensor $(LIBDIR)/AQ_BatteryMonitor \ - $(LIBDIR)/AQ_CameraStabilizer $(LIBDIR)/AQ_Compass $(LIBDIR)/AQ_Defines \ - $(LIBDIR)/AQ_FlightControlProcessor $(LIBDIR)/ $(LIBDIR)/AQ_Gps $(LIBDIR)/AQ_Gyroscope \ - $(LIBDIR)/AQ_I2C $(LIBDIR)/AQ_Kinematics $(LIBDIR)/AQ_Math $(LIBDIR)/AQ_Motors \ - $(LIBDIR)/AQ_OSD $(LIBDIR)/AQ_Platform_APM $(LIBDIR)/AQ_Platform_CHR6DM \ - $(LIBDIR)/AQ_Platform_MPU6000 $(LIBDIR)/AQ_Platform_Wii $(LIBDIR)/AQ_RangeFinder \ - $(LIBDIR)/AQ_Receiver $(LIBDIR)/AQ_SPI $(LIBDIR)/AQ_RSSI $(LIBDIR)/AQ_SoftModem \ - $(LIBDIR)/AQ_RSCode - - -# Processor frequency. -# This will define a symbol, F_CPU, in all source code files equal to the -# processor frequency. You can then use this symbol in your source code to -# calculate timings. Do NOT tack on a 'UL' at the end, this will be done -# automatically to create a 32-bit value in your source code. -# Typical values are: -# F_CPU = 1000000 -# F_CPU = 1843200 -# F_CPU = 2000000 -# F_CPU = 3686400 -# F_CPU = 4000000 -# F_CPU = 7372800 -# F_CPU = 8000000 -# F_CPU = 11059200 -# F_CPU = 14745600 -# F_CPU = 16000000 -# F_CPU = 18432000 -# F_CPU = 20000000 - - -# Output format. (can be srec, ihex, binary) -FORMAT = ihex - -# Object files directory -# To put object files in current directory, use a dot (.), do NOT make -# this an empty or blank macro! -OBJDIRBASE = obj$(CPUCLASS) -# added a dummy directory as BASEDIR is .. -OBJDIR = $(OBJDIRBASE)/dummy - -# Target file name (without extension). -TARGETSOURCE = $(SRCDIRAQ32)/AeroQuadMain -TARGET = $(OBJDIR)/$(TARGETSOURCE) - -DEPENDENCIES = $(SRCDIRAQ32)/AeroQuad_STM32.h - -# List C source files here. (C dependencies are automatically generated.) -SRC = - -BASEDIR = .. -SRCDIR = $(BASEDIR)/AeroQuad -LIBDIR = $(BASEDIR)/Libraries -SRCDIRAQ32 = $(BASEDIR)/AeroQuad32 -MCDIR = $(SRCDIRAQ32)/MapleCompatibility - -# List C++ source files here. (C dependencies are automatically generated.) -CPPSRC = $(TARGETSOURCE).cpp -#CPPSRC += #$(SRCDIR)/Median.cpp $(SRCDIR)/Smooth.cpp $(SRCDIR)/MS561101BA.cpp -#CPPSRC += $(SRCDIR)/MS561101BA.cpp -CPPSRC += $(MCDIR)/EEPROM.cpp -CPPSRC += $(LIBDIR)/AQ_I2C/Device_I2C.cpp -#CPPSRC += $(LIBDIR)/AQ_Gps/TinyGPS.cpp -CPPSRC += $(LIBDIR)/AQ_Math/AQMath.cpp -SRC += $(MCDIR)/flash_stm32.c - -# List Assembler source files here. -# Make them always end in a capital .S. Files ending in a lowercase .s -# will not be considered source files but generated files (assembler -# output from the compiler), and will be deleted upon "make clean"! -# Even though the DOS/Win* filesystem matches both .s and .S the same, -# it will preserve the spelling of the filenames, and gcc itself does -# care about how the name is spelled on its command-line. -ASRC = - - -# Optimization level, can be [0, 1, 2, 3, s]. -# 0 = turn off optimization. s = optimize for size. -# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) -OPT = s - - -# Debugging format. -# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. -# AVR Studio 4.10 requires dwarf-2. -# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run. -DEBUG = dwarf-2 - - -# List any extra directories to look for include files here. -# Each directory must be seperated by a space. -# Use forward slashes for directory separators. -# For a directory that has spaces, enclose it in quotes. -#EXTRAINCDIRS = arduinoXMega arduinoXMega/Libraries - - -# Compiler flag to set the C Standard level. -# c89 = "ANSI" C -# gnu89 = c89 plus GCC extensions -# c99 = ISO C99 standard (not yet fully implemented) -# gnu99 = c99 plus GCC extensions -CSTANDARD = -std=gnu99 - - -# Place -D or -U options here for C sources -CDEFS = -DF_CPU=$(F_CPU)UL -CDEFS += $(ADDITIONALDEFINES) - -# Place -D or -U options here for ASM sources -ADEFS = -DF_CPU=$(F_CPU) - - -# Place -D or -U options here for C++ sources -CPPDEFS = -DF_CPU=$(F_CPU)UL -CPPDEFS += $(ADDITIONALDEFINES) -#CPPDEFS += -D__STDC_LIMIT_MACROS -#CPPDEFS += -D__STDC_CONSTANT_MACROS - - - -#---------------- Compiler Options C ---------------- -# -g*: generate debugging information -# -O*: optimization level -# -f...: tuning, see GCC manual and avr-libc documentation -# -Wall...: warning level -# -Wa,...: tell GCC to pass this to the assembler. -# -adhlns...: create assembler listing -CFLAGS = -g$(DEBUG) -CFLAGS += $(CDEFS) -CFLAGS += -O$(OPT) -CFLAGS += -ffunction-sections -CFLAGS += -fdata-sections -CFLAGS += -funsigned-char -CFLAGS += -funsigned-bitfields -CFLAGS += -fsingle-precision-constant -#CFLAGS += -fpack-struct -CFLAGS += -fshort-enums -CFLAGS += -Wall -CFLAGS += -Wstrict-prototypes -#CFLAGS += -mshort-calls -#CFLAGS += -fno-unit-at-a-time -#CFLAGS += -Wundef -#CFLAGS += -Wunreachable-code -#CFLAGS += -Wsign-compare - -#CFLAGS += -mcall-prologues - -CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) -CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) -CFLAGS += $(CSTANDARD) - - -#---------------- Compiler Options C++ ---------------- -# -g*: generate debugging information -# -O*: optimization level -# -f...: tuning, see GCC manual and avr-libc documentation -# -Wall...: warning level -# -Wa,...: tell GCC to pass this to the assembler. -# -adhlns...: create assembler listing -CPPFLAGS = -g$(DEBUG) -CPPFLAGS += $(CPPDEFS) -CPPFLAGS += -O$(OPT) -CPPFLAGS += -ffunction-sections -CPPFLAGS += -fdata-sections -CPPFLAGS += -funsigned-char -CPPFLAGS += -funsigned-bitfields -CPPFLAGS += -fsingle-precision-constant -#CPPFLAGS += -fpack-struct -CPPFLAGS += -fshort-enums -CPPFLAGS += -fno-exceptions -CPPFLAGS += -Wall -CPPFLAGS += -Wundef - -# -gdwarf-2 -MD -MP -MT Print.o -MF dep/Print.o.d -c ../arduinoXMega/Print.cpp - -#CPPFLAGS += -mshort-calls -#CPPFLAGS += -fno-unit-at-a-time -#CPPFLAGS += -Wstrict-prototypes -#CPPFLAGS += -Wunreachable-code -#CPPFLAGS += -Wsign-compare - -#CPPFLAGS += -mcall-prologues - -CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst) -CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) -#CPPFLAGS += $(CSTANDARD) - - -#---------------- Assembler Options ---------------- -# -Wa,...: tell GCC to pass this to the assembler. -# -adhlns: create listing -# -gstabs: have the assembler create line number information; note that -# for use in COFF files, additional information about filenames -# and function names needs to be present in the assembler source -# files -- see avr-libc docs [FIXME: not yet described there] -# -listing-cont-lines: Sets the maximum number of continuation lines of hex -# dump that will be displayed for a given single line of source input. -ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100 - - -#---------------- Library Options ---------------- -# Minimalistic printf version -PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min - -# Floating point printf version (requires MATH_LIB = -lm below) -PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt - -# If this is left blank, then it will use the Standard printf version. -#PRINTF_LIB = -#PRINTF_LIB = $(PRINTF_LIB_MIN) -PRINTF_LIB = $(PRINTF_LIB_FLOAT) - - -# Minimalistic scanf version -SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min - -# Floating point + %[ scanf version (requires MATH_LIB = -lm below) -SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt - -# If this is left blank, then it will use the Standard scanf version. -SCANF_LIB = -#SCANF_LIB = $(SCANF_LIB_MIN) -#SCANF_LIB = $(SCANF_LIB_FLOAT) - - -MATH_LIB = -lc -lm -lc - - -# List any extra directories to look for libraries here. -# Each directory must be seperated by a space. -# Use forward slashes for directory separators. -# For a directory that has spaces, enclose it in quotes. -EXTRALIBDIRS = ../arduinoXMega - - - - - -#---------------- Linker Options ---------------- -# -Wl,...: tell GCC to pass this to linker. -# -Map: create map file -# --cref: add cross reference to map file -LDFLAGS = -Wl,--gc-section,-Map=$(TARGET).map,--cref,--relax -LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) -LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) -#LDFLAGS += -T linker_script.x - -ifeq ($(BUILDTYPE), STM32) - LDFLAGS = $(LDFLAGSSTM32) -endif - - - -#---------------- Programming Options (avrdude) ---------------- - -# Programming hardware -# Type: avrdude -c ? -# to get a full listing. -# -AVRDUDE_PROGRAMMER = usbasp - -# com1 = serial port. Use lpt1 to connect to parallel port. -AVRDUDE_PORT = usb - -AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex:i -AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep - -AVRDUDE_WRITE_FUSES = -U lfuse:w:0xf7:m -U hfuse:w:0xd7:m -U efuse:w:0x07:m -AVRDUDE_READ_FUSES = -U lfuse:r:-:i -U hfuse:r:-:i -U efuse:r:-:i - -# Uncomment the following if you want avrdude's erase cycle counter. -# Note that this counter needs to be initialized first using -Yn, -# see avrdude manual. -#AVRDUDE_ERASE_COUNTER = -y - -# Uncomment the following if you do /not/ wish a verification to be -# performed after programming the device. -#AVRDUDE_NO_VERIFY = -V - -# Increase verbosity level. Please use this when submitting bug -# reports about avrdude. See -# to submit bug reports. -#AVRDUDE_VERBOSE = -v -v - -AVRDUDE_FLAGS = -p $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) -AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) -AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) - - - -#---------------- Debugging Options ---------------- - -# For simulavr only - target MCU frequency. -DEBUG_MFREQ = $(F_CPU) - -# Set the DEBUG_UI to either gdb or insight. -# DEBUG_UI = gdb -DEBUG_UI = insight - -# Set the debugging back-end to either avarice, simulavr. -DEBUG_BACKEND = avarice -#DEBUG_BACKEND = simulavr - -# GDB Init Filename. -GDBINIT_FILE = __avr_gdbinit - -# When using avarice settings for the JTAG -JTAG_DEV = /dev/com1 - -# Debugging port used to communicate between GDB / avarice / simulavr. -DEBUG_PORT = 4242 - -# Debugging host used to communicate between GDB / avarice / simulavr, normally -# just set to localhost unless doing some sort of crazy debugging when -# avarice is running on a different computer. -DEBUG_HOST = localhost - - - -#============================================================================ - -# Define programs and commands. -SHELL = sh -CC = $(BUILDPREFIX)-gcc -OBJCOPY = $(BUILDPREFIX)-objcopy -OBJDUMP = $(BUILDPREFIX)-objdump -SIZE = $(BUILDPREFIX)-size -AR = $(BUILDPREFIX)-ar rcs -NM = $(BUILDPREFIX)-nm -AVRDUDE = avrdude -REMOVE = rm -f -REMOVEDIR = rm -rf -COPY = cp -WINSHELL = cmd - - -# Define Messages -# English -MSG_ERRORS_NONE = Errors: none -MSG_BEGIN = -------- begin -------- -MSG_END = -------- end -------- -MSG_SIZE_BEFORE = Size before: -MSG_SIZE_AFTER = Size after: -MSG_COFF = Converting to AVR COFF: -MSG_EXTENDED_COFF = Converting to AVR Extended COFF: -MSG_FLASH = Creating load file for Flash: -MSG_EEPROM = Creating load file for EEPROM: -MSG_EXTENDED_LISTING = Creating Extended Listing: -MSG_SYMBOL_TABLE = Creating Symbol Table: -MSG_LINKING = Linking: -MSG_COMPILING = Compiling C: -MSG_COMPILING_CPP = Compiling C++: -MSG_ASSEMBLING = Assembling: -MSG_CLEANING = Cleaning project: -MSG_CREATING_LIBRARY = Creating library: - - - - -# Define all object files. -OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o) - -# Define all listing files. -LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst) - - -# Compiler flags to generate dependency files. -GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d - - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -ALL_CFLAGS = $(DEFINECPU) -I. $(CFLAGS) $(GENDEPFLAGS) -ALL_CPPFLAGS = $(DEFINECPU) -I. -x c++ $(CPPFLAGS) $(EXTRACPPFLAGS) $(GENDEPFLAGS) -ALL_ASFLAGS = $(DEFINECPU) -I. -x assembler-with-cpp $(ASFLAGS) - - - - - -# Default target. -#all: begin gccversion sizebefore build sizeafter end -all: sizebefore build sizeafter - -# Change the build target to build a HEX file or a library. -build: elf bin hex eep lss sym -#build: lib - -AeroQuadMain.cpp: $(DEPENDENCIES) -elf: $(TARGET).elf -bin: $(TARGET).bin -hex: $(TARGET).hex -eep: $(TARGET).eep -lss: $(TARGET).lss -sym: $(TARGET).sym -LIBNAME=lib$(TARGET).a -lib: $(LIBNAME) - -# Eye candy. -# AVR Studio 3.x does not check make's exit code but relies on -# the following magic strings to be generated by the compile job. -begin: - @echo - @echo $(MSG_BEGIN) - -end: - @echo $(MSG_END) - @echo - - -# Display size of file. -HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex -ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf -ELFSIZE = $(SIZE) $(TARGET).elf - -sizebefore: - @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); 2>/dev/null; echo; fi - -sizeafter: - @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); 2>/dev/null; echo; fi - - - -# Display compiler version information. -gccversion : - @$(CC) --version - - - -# Program the device. -program: - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) - -# Set device fuses -write-fuses: - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES) - -# Read device fuses -read-fuses: - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES) - -# Un brick the device with a 1 MHz crystal connected to pin7 (XTAL1 -unbrick: - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES) -B 100 - - -# Generate avr-gdb config/init file which does the following: -# define the reset signal, load the target file, connect to target, and set -# a breakpoint at main(). -gdb-config: - @$(REMOVE) $(GDBINIT_FILE) - @echo define reset >> $(GDBINIT_FILE) - @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) - @echo end >> $(GDBINIT_FILE) - @echo file $(TARGET).elf >> $(GDBINIT_FILE) - @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) -ifeq ($(DEBUG_BACKEND),simulavr) - @echo load >> $(GDBINIT_FILE) -endif - @echo break main >> $(GDBINIT_FILE) - -debug: gdb-config $(TARGET).elf -ifeq ($(DEBUG_BACKEND), avarice) - @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. - @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ - $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) - @$(WINSHELL) /c pause - -else - @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ - $(DEBUG_MFREQ) --port $(DEBUG_PORT) -endif - @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) - - - - -# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. -COFFCONVERT = $(OBJCOPY) --debugging -COFFCONVERT += --change-section-address .data-0x800000 -COFFCONVERT += --change-section-address .bss-0x800000 -COFFCONVERT += --change-section-address .noinit-0x800000 -COFFCONVERT += --change-section-address .eeprom-0x810000 - - - -coff: $(TARGET).elf - @echo - @echo $(MSG_COFF) $(TARGET).cof - @$(COFFCONVERT) -O coff-avr $< $(TARGET).cof - - -extcoff: $(TARGET).elf - @echo - @echo $(MSG_EXTENDED_COFF) $(TARGET).cof - @$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof - - - -# Create final output files (.hex, .eep) from ELF output file. -%.bin: %.elf - @echo - @echo $(MSG_FLASH) binary $@ - $(OBJCOPY) -v -Obinary $< $@ - -%.hex: %.elf - @echo - @echo $(MSG_FLASH) $@ - $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@ - -%.eep: %.elf - @echo - @echo $(MSG_EEPROM) $@ - @-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 - -# Create extended listing file from ELF output file. -%.lss: %.elf - @echo - @echo $(MSG_EXTENDED_LISTING) $@ - @$(OBJDUMP) -h -S -z $< > $@ - -# Create a symbol table from ELF output file. -%.sym: %.elf - @echo - @echo $(MSG_SYMBOL_TABLE) $@ - @$(NM) -n $< > $@ - - - -# Create library from object files. -.SECONDARY : $(TARGET).a -.PRECIOUS : $(OBJ) -%.a: $(OBJ) - @echo - @echo $(MSG_CREATING_LIBRARY) $@ - $(AR) $@ $(OBJ) - - -# Link: create ELF output file from object files. -.SECONDARY : $(TARGET).elf -.PRECIOUS : $(OBJ) -%.elf: $(OBJ) $(RUNTIMELIB) - @echo - @echo $(MSG_LINKING) $@ - @$(CC) $(ALL_CFLAGS) $^ $(RUNTIMELIB) $(LIB_MAPLE_HOME)/build/libmaple/syscalls.o --output $@ $(LDFLAGS) -# @$(CC) $(ALL_CFLAGS) $^ AeroQuad32/libm.a $(RUNTIMELIB) $(LIB_MAPLE_HOME)/build/libmaple/syscalls.o --output $@ $(LDFLAGS) - - -# Compile: create object files from C source files. -#@$(CC) -c $(ALL_CFLAGS) $< -o $@ -$(OBJDIR)/%.o : %.c - @echo - @echo $(MSG_COMPILING) $< - @$(CC) -c $(ALL_CFLAGS) $(abspath $<) -o $@ $(VS_TRIM_ERRORS) - - -# Compile: create object files from C++ source files. -#@$(CC) -c $(ALL_CPPFLAGS) $< -o $@ -#$(CC) -c $(ALL_CPPFLAGS) $(abspath $<) -o $@ $(VS_TRIM_ERRORS) -$(OBJDIR)/%.o : %.cpp - @echo - @echo $(MSG_COMPILING_CPP) $< - @$(CC) -c $(ALL_CPPFLAGS) $(abspath $<) -o $@ $(VS_TRIM_ERRORS) - - -# Compile: create assembler files from C source files. -%.s : %.c - $(CC) -S $(ALL_CFLAGS) $< -o $@ - - -# Compile: create assembler files from C++ source files. -%.s : %.cpp - $(CC) -S $(ALL_CPPFLAGS) $< -o $@ - - -# Assemble: create object files from assembler source files. -$(OBJDIR)/%.o : %.S - @echo - @echo $(MSG_ASSEMBLING) $< - $(CC) -c $(ALL_ASFLAGS) $< -o $@ - - -# Create preprocessed source for use in sending a bug report. -%.i : %.c - $(CC) -E $(DEFINECPU) -I. $(CFLAGS) $< -o $@ - - -# Target: clean project. -clean: begin clean_list end - -clean_list : - @echo - @echo $(MSG_CLEANING) - $(REMOVEDIR) .dep - -$(REMOVEDIR) $(OBJDIRBASE) - - -# Create object files directory -ifeq ($(BUILDTYPE), XMEGA) -$(shell mkdir -p $(OBJDIR)/arduinoXMega/Libraries 2>/dev/null) -endif -ifeq ($(BUILDTYPE), STM32) -$(shell mkdir -p $(OBJDIR)/$(SRCDIRAQ32) $(OBJDIR)/$(MCDIR) 2>/dev/null) -endif -#$(shell mkdir -p $(OBJDIR) $(OBJDIR)/$(SRCDIR) $(OBJDIR)/$(SRCDIRAQ32) $(OBJDIR)/$(MCDIR) $(OBJDIR)/arduinoXMega $(OBJDIR)/arduinoXMega/Libraries $(OBJDIR)/$(LIBDIR) $(OBJDIR)/$(LIBDIR)/AQ_Gps $(OBJDIR)/$(LIBDIR)/AQ_I2C $(OBJDIR)/$(LIBDIR)/AQ_Math 2>/dev/null) -$(shell mkdir -p $(OBJDIR) $(OBJDIR)/$(SRCDIR) $(OBJDIR)/$(LIBDIR) $(OBJDIR)/$(LIBDIR)/AQ_Gps $(OBJDIR)/$(LIBDIR)/AQ_I2C $(OBJDIR)/$(LIBDIR)/AQ_Math 2>/dev/null) - -# Include the dependency files. --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - - -# Listing of phony targets. -.PHONY : all begin finish end sizebefore sizeafter gccversion build elf hex eep lss sym coff extcoff clean clean_list program debug gdb-config - - +##### Uncomment the -nostartfiles if compiling on OS X ##### + LDFLAGSSTM32 = -T$(LDDIR)/$(LDSCRIPT) -L$(LDDIR) -Xlinker --gc-sections -lc -nostartfiles + +# Set up build rules and some useful templates +include $(SUPPORT_PATH)/make/build-rules.mk +include $(SUPPORT_PATH)/make/build-templates.mk + +# Some target specific things +ifeq ($(MEMORY_TARGET), ram) + LDSCRIPT := $(BOARD)/ram.ld + VECT_BASE_ADDR := VECT_TAB_RAM +endif +ifeq ($(MEMORY_TARGET), flash) + LDSCRIPT := $(BOARD)/flash.ld + VECT_BASE_ADDR := VECT_TAB_FLASH +endif +ifeq ($(MEMORY_TARGET), jtag) + LDSCRIPT := $(BOARD)/jtag.ld + VECT_BASE_ADDR := VECT_TAB_BASE +endif + +DEFINECPU = $(MCU_OPTIONS) -DBOARD_$(BOARD) -DMCU_$(MCU) -D$(MCU_FAMILY) -D$(DENSITY) -fno-exceptions +EXTRACPPFLAGS = -fno-rtti +RUNTIMELIB = $(LIB_MAPLE_HOME)/build/libmaple.a +MAPLEINCDIRS = $(LIB_MAPLE_HOME) $(LIB_MAPLE_HOME)/libmaple $(LIB_MAPLE_HOME)/wirish $(LIB_MAPLE_HOME)/wirish/comm $(LIB_MAPLE_HOME)/wirish/boards $(LIB_MAPLE_HOME)/libraries/Wire +EXTRAINCDIRS = $(MCDIR) $(SRCDIRAQ32) $(MAPLEINCDIRS) +endif + +EXTRAINCDIRS += $(LIBDIR)/AQ_Accelerometer $(LIBDIR)/AQ_BarometricSensor $(LIBDIR)/AQ_BatteryMonitor \ + $(LIBDIR)/AQ_CameraStabilizer $(LIBDIR)/AQ_Compass $(LIBDIR)/AQ_Defines \ + $(LIBDIR)/AQ_FlightControlProcessor $(LIBDIR)/ $(LIBDIR)/AQ_Gps $(LIBDIR)/AQ_Gyroscope \ + $(LIBDIR)/AQ_I2C $(LIBDIR)/AQ_Kinematics $(LIBDIR)/AQ_Math $(LIBDIR)/AQ_Motors \ + $(LIBDIR)/AQ_OSD $(LIBDIR)/AQ_Platform_APM $(LIBDIR)/AQ_Platform_CHR6DM \ + $(LIBDIR)/AQ_Platform_MPU6000 $(LIBDIR)/AQ_Platform_Wii $(LIBDIR)/AQ_RangeFinder \ + $(LIBDIR)/AQ_Receiver $(LIBDIR)/AQ_SPI $(LIBDIR)/AQ_RSSI $(LIBDIR)/AQ_SoftModem \ + $(LIBDIR)/AQ_RSCode + + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# Typical values are: +# F_CPU = 1000000 +# F_CPU = 1843200 +# F_CPU = 2000000 +# F_CPU = 3686400 +# F_CPU = 4000000 +# F_CPU = 7372800 +# F_CPU = 8000000 +# F_CPU = 11059200 +# F_CPU = 14745600 +# F_CPU = 16000000 +# F_CPU = 18432000 +# F_CPU = 20000000 + + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIRBASE = obj$(CPUCLASS) +# added a dummy directory as BASEDIR is .. +OBJDIR = $(OBJDIRBASE)/dummy + +# Target file name (without extension). +TARGETSOURCE = $(SRCDIRAQ32)/AeroQuadMain +TARGET = $(OBJDIR)/$(TARGETSOURCE) + +DEPENDENCIES = $(SRCDIRAQ32)/AeroQuad_STM32.h + +# List C source files here. (C dependencies are automatically generated.) +SRC = + +BASEDIR = .. +SRCDIR = $(BASEDIR)/AeroQuad +LIBDIR = $(BASEDIR)/Libraries +SRCDIRAQ32 = $(BASEDIR)/AeroQuad32 +MCDIR = $(SRCDIRAQ32)/MapleCompatibility + +# List C++ source files here. (C dependencies are automatically generated.) +CPPSRC = $(TARGETSOURCE).cpp +#CPPSRC += #$(SRCDIR)/Median.cpp $(SRCDIR)/Smooth.cpp $(SRCDIR)/MS561101BA.cpp +#CPPSRC += $(SRCDIR)/MS561101BA.cpp +CPPSRC += $(MCDIR)/EEPROM.cpp +CPPSRC += $(LIBDIR)/AQ_I2C/Device_I2C.cpp +#CPPSRC += $(LIBDIR)/AQ_Gps/TinyGPS.cpp +CPPSRC += $(LIBDIR)/AQ_Math/AQMath.cpp +SRC += $(MCDIR)/flash_stm32.c + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# Debugging format. +# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. +# AVR Studio 4.10 requires dwarf-2. +# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run. +DEBUG = dwarf-2 + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +# Use forward slashes for directory separators. +# For a directory that has spaces, enclose it in quotes. +#EXTRAINCDIRS = arduinoXMega arduinoXMega/Libraries + + +# Compiler flag to set the C Standard level. +# c89 = "ANSI" C +# gnu89 = c89 plus GCC extensions +# c99 = ISO C99 standard (not yet fully implemented) +# gnu99 = c99 plus GCC extensions +CSTANDARD = -std=gnu99 + + +# Place -D or -U options here for C sources +CDEFS = -DF_CPU=$(F_CPU)UL +CDEFS += $(ADDITIONALDEFINES) + +# Place -D or -U options here for ASM sources +ADEFS = -DF_CPU=$(F_CPU) + + +# Place -D or -U options here for C++ sources +CPPDEFS = -DF_CPU=$(F_CPU)UL +CPPDEFS += $(ADDITIONALDEFINES) +#CPPDEFS += -D__STDC_LIMIT_MACROS +#CPPDEFS += -D__STDC_CONSTANT_MACROS + + + +#---------------- Compiler Options C ---------------- +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CFLAGS = -g$(DEBUG) +CFLAGS += $(CDEFS) +CFLAGS += -O$(OPT) +CFLAGS += -ffunction-sections +CFLAGS += -fdata-sections +CFLAGS += -funsigned-char +CFLAGS += -funsigned-bitfields +CFLAGS += -fsingle-precision-constant +#CFLAGS += -fpack-struct +CFLAGS += -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +#CFLAGS += -mshort-calls +#CFLAGS += -fno-unit-at-a-time +#CFLAGS += -Wundef +#CFLAGS += -Wunreachable-code +#CFLAGS += -Wsign-compare + +#CFLAGS += -mcall-prologues + +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + + +#---------------- Compiler Options C++ ---------------- +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CPPFLAGS = -g$(DEBUG) +CPPFLAGS += $(CPPDEFS) +CPPFLAGS += -O$(OPT) +CPPFLAGS += -ffunction-sections +CPPFLAGS += -fdata-sections +CPPFLAGS += -funsigned-char +CPPFLAGS += -funsigned-bitfields +CPPFLAGS += -fsingle-precision-constant +#CPPFLAGS += -fpack-struct +CPPFLAGS += -fshort-enums +CPPFLAGS += -fno-exceptions +CPPFLAGS += -Wall +CPPFLAGS += -Wundef + +# -gdwarf-2 -MD -MP -MT Print.o -MF dep/Print.o.d -c ../arduinoXMega/Print.cpp + +#CPPFLAGS += -mshort-calls +#CPPFLAGS += -fno-unit-at-a-time +#CPPFLAGS += -Wstrict-prototypes +#CPPFLAGS += -Wunreachable-code +#CPPFLAGS += -Wsign-compare + +#CPPFLAGS += -mcall-prologues + +CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst) +CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +#CPPFLAGS += $(CSTANDARD) + + +#---------------- Assembler Options ---------------- +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +# -listing-cont-lines: Sets the maximum number of continuation lines of hex +# dump that will be displayed for a given single line of source input. +ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100 + + +#---------------- Library Options ---------------- +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt + +# If this is left blank, then it will use the Standard printf version. +#PRINTF_LIB = +#PRINTF_LIB = $(PRINTF_LIB_MIN) +PRINTF_LIB = $(PRINTF_LIB_FLOAT) + + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +# If this is left blank, then it will use the Standard scanf version. +SCANF_LIB = +#SCANF_LIB = $(SCANF_LIB_MIN) +#SCANF_LIB = $(SCANF_LIB_FLOAT) + + +MATH_LIB = -lc -lm -lc + + +# List any extra directories to look for libraries here. +# Each directory must be seperated by a space. +# Use forward slashes for directory separators. +# For a directory that has spaces, enclose it in quotes. +EXTRALIBDIRS = ../arduinoXMega + + + + + +#---------------- Linker Options ---------------- +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,--gc-section,-Map=$(TARGET).map,--cref,--relax +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +#LDFLAGS += -T linker_script.x + +ifeq ($(BUILDTYPE), STM32) + LDFLAGS = $(LDFLAGSSTM32) +endif + + + +#---------------- Programming Options (avrdude) ---------------- + +# Programming hardware +# Type: avrdude -c ? +# to get a full listing. +# +AVRDUDE_PROGRAMMER = usbasp + +# com1 = serial port. Use lpt1 to connect to parallel port. +AVRDUDE_PORT = usb + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex:i +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVRDUDE_WRITE_FUSES = -U lfuse:w:0xf7:m -U hfuse:w:0xd7:m -U efuse:w:0x07:m +AVRDUDE_READ_FUSES = -U lfuse:r:-:i -U hfuse:r:-:i -U efuse:r:-:i + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +#---------------- Debugging Options ---------------- + +# For simulavr only - target MCU frequency. +DEBUG_MFREQ = $(F_CPU) + +# Set the DEBUG_UI to either gdb or insight. +# DEBUG_UI = gdb +DEBUG_UI = insight + +# Set the debugging back-end to either avarice, simulavr. +DEBUG_BACKEND = avarice +#DEBUG_BACKEND = simulavr + +# GDB Init Filename. +GDBINIT_FILE = __avr_gdbinit + +# When using avarice settings for the JTAG +JTAG_DEV = /dev/com1 + +# Debugging port used to communicate between GDB / avarice / simulavr. +DEBUG_PORT = 4242 + +# Debugging host used to communicate between GDB / avarice / simulavr, normally +# just set to localhost unless doing some sort of crazy debugging when +# avarice is running on a different computer. +DEBUG_HOST = localhost + + + +#============================================================================ + +# Define programs and commands. +SHELL = sh +CC = $(BUILDPREFIX)-gcc +OBJCOPY = $(BUILDPREFIX)-objcopy +OBJDUMP = $(BUILDPREFIX)-objdump +SIZE = $(BUILDPREFIX)-size +AR = $(BUILDPREFIX)-ar rcs +NM = $(BUILDPREFIX)-nm +AVRDUDE = avrdude +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_COMPILING_CPP = Compiling C++: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + + + + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = $(DEFINECPU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_CPPFLAGS = $(DEFINECPU) -I. -x c++ $(CPPFLAGS) $(EXTRACPPFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = $(DEFINECPU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +#all: begin gccversion sizebefore build sizeafter end +all: sizebefore build sizeafter + +# Change the build target to build a HEX file or a library. +build: elf bin hex eep lss sym +#build: lib + +AeroQuadMain.cpp: $(DEPENDENCIES) +elf: $(TARGET).elf +bin: $(TARGET).bin +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf +ELFSIZE = $(SIZE) $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); 2>/dev/null; echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + +# Program the device. +program: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + +# Set device fuses +write-fuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES) + +# Read device fuses +read-fuses: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES) + +# Un brick the device with a 1 MHz crystal connected to pin7 (XTAL1 +unbrick: + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES) -B 100 + + +# Generate avr-gdb config/init file which does the following: +# define the reset signal, load the target file, connect to target, and set +# a breakpoint at main(). +gdb-config: + @$(REMOVE) $(GDBINIT_FILE) + @echo define reset >> $(GDBINIT_FILE) + @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) + @echo end >> $(GDBINIT_FILE) + @echo file $(TARGET).elf >> $(GDBINIT_FILE) + @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) +ifeq ($(DEBUG_BACKEND),simulavr) + @echo load >> $(GDBINIT_FILE) +endif + @echo break main >> $(GDBINIT_FILE) + +debug: gdb-config $(TARGET).elf +ifeq ($(DEBUG_BACKEND), avarice) + @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. + @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ + $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) + @$(WINSHELL) /c pause + +else + @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ + $(DEBUG_MFREQ) --port $(DEBUG_PORT) +endif + @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT = $(OBJCOPY) --debugging +COFFCONVERT += --change-section-address .data-0x800000 +COFFCONVERT += --change-section-address .bss-0x800000 +COFFCONVERT += --change-section-address .noinit-0x800000 +COFFCONVERT += --change-section-address .eeprom-0x810000 + + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + @$(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + @$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.bin: %.elf + @echo + @echo $(MSG_FLASH) binary $@ + $(OBJCOPY) -v -Obinary $< $@ + +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + @-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + @$(OBJDUMP) -h -S -z $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + @$(NM) -n $< > $@ + + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) $(RUNTIMELIB) + @echo + @echo $(MSG_LINKING) $@ + @$(CC) $(ALL_CFLAGS) $^ $(RUNTIMELIB) $(LIB_MAPLE_HOME)/build/libmaple/syscalls.o --output $@ $(LDFLAGS) +# @$(CC) $(ALL_CFLAGS) $^ AeroQuad32/libm.a $(RUNTIMELIB) $(LIB_MAPLE_HOME)/build/libmaple/syscalls.o --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +#@$(CC) -c $(ALL_CFLAGS) $< -o $@ +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + @$(CC) -c $(ALL_CFLAGS) $(abspath $<) -o $@ $(VS_TRIM_ERRORS) + + +# Compile: create object files from C++ source files. +#@$(CC) -c $(ALL_CPPFLAGS) $< -o $@ +#$(CC) -c $(ALL_CPPFLAGS) $(abspath $<) -o $@ $(VS_TRIM_ERRORS) +$(OBJDIR)/%.o : %.cpp + @echo + @echo $(MSG_COMPILING_CPP) $< + @$(CC) -c $(ALL_CPPFLAGS) $(abspath $<) -o $@ $(VS_TRIM_ERRORS) + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C++ source files. +%.s : %.cpp + $(CC) -S $(ALL_CPPFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +$(OBJDIR)/%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + +# Create preprocessed source for use in sending a bug report. +%.i : %.c + $(CC) -E $(DEFINECPU) -I. $(CFLAGS) $< -o $@ + + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVEDIR) .dep + -$(REMOVEDIR) $(OBJDIRBASE) + + +# Create object files directory +ifeq ($(BUILDTYPE), XMEGA) +$(shell mkdir -p $(OBJDIR)/arduinoXMega/Libraries 2>/dev/null) +endif +ifeq ($(BUILDTYPE), STM32) +$(shell mkdir -p $(OBJDIR)/$(SRCDIRAQ32) $(OBJDIR)/$(MCDIR) 2>/dev/null) +endif +#$(shell mkdir -p $(OBJDIR) $(OBJDIR)/$(SRCDIR) $(OBJDIR)/$(SRCDIRAQ32) $(OBJDIR)/$(MCDIR) $(OBJDIR)/arduinoXMega $(OBJDIR)/arduinoXMega/Libraries $(OBJDIR)/$(LIBDIR) $(OBJDIR)/$(LIBDIR)/AQ_Gps $(OBJDIR)/$(LIBDIR)/AQ_I2C $(OBJDIR)/$(LIBDIR)/AQ_Math 2>/dev/null) +$(shell mkdir -p $(OBJDIR) $(OBJDIR)/$(SRCDIR) $(OBJDIR)/$(LIBDIR) $(OBJDIR)/$(LIBDIR)/AQ_Gps $(OBJDIR)/$(LIBDIR)/AQ_I2C $(OBJDIR)/$(LIBDIR)/AQ_Math 2>/dev/null) + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion build elf hex eep lss sym coff extcoff clean clean_list program debug gdb-config + + diff --git a/BuildAQ32/ReadMe.txt b/BuildAQ32/ReadMe.txt index 8e45f539..8262aa31 100644 --- a/BuildAQ32/ReadMe.txt +++ b/BuildAQ32/ReadMe.txt @@ -1,12 +1,12 @@ -Build.bat : batch file to build the project -ReBuild.bat : batch file to rebuild the project - -FlashDFUSeF4.bat : batch file to flash using F4 CPU build in bootloader using USB - -Other batchfiles -FlashDFU.bat : batch file to flash using standard maple bootloader for F1 CPUs using USB -FlashV2.bat : batch file to flash using STLink-V2 debugger -FlashV2_LowMem.bat : batch file to flash using STLink-V2 debugger to low memory base when no boot loader is used, e.g. FreeFlight board -ListDFUSeDevices.bat : Lists the DFUSe devices found - - +Build.bat : batch file to build the project +ReBuild.bat : batch file to rebuild the project + +FlashDFUSeF4.bat : batch file to flash using F4 CPU build in bootloader using USB + +Other batchfiles +FlashDFU.bat : batch file to flash using standard maple bootloader for F1 CPUs using USB +FlashV2.bat : batch file to flash using STLink-V2 debugger +FlashV2_LowMem.bat : batch file to flash using STLink-V2 debugger to low memory base when no boot loader is used, e.g. FreeFlight board +ListDFUSeDevices.bat : Lists the DFUSe devices found + + diff --git a/Libmaple/libmaple/.dir-locals.el b/Libmaple/libmaple/.dir-locals.el index fb1539fe..aed97bb8 100644 --- a/Libmaple/libmaple/.dir-locals.el +++ b/Libmaple/libmaple/.dir-locals.el @@ -1,6 +1,6 @@ -((c-mode . ((c-basic-offset . 4) - (indent-tabs-mode . nil) - (tab-width . 50))) ; display tabs badly on purpose - (c++-mode . ((c-basic-offset . 4) - (indent-tabs-mode . nil) +((c-mode . ((c-basic-offset . 4) + (indent-tabs-mode . nil) + (tab-width . 50))) ; display tabs badly on purpose + (c++-mode . ((c-basic-offset . 4) + (indent-tabs-mode . nil) (tab-width . 50)))) ; display tabs badly on purpose \ No newline at end of file diff --git a/Libmaple/libmaple/.gdbinit b/Libmaple/libmaple/.gdbinit index f371530d..9e88d090 100644 --- a/Libmaple/libmaple/.gdbinit +++ b/Libmaple/libmaple/.gdbinit @@ -1,9 +1,9 @@ -target remote localhost:3333 -symbol-file build/maple.elf -source test.gdb -delete breakpoints -##break main.cpp:setup() -##monitor reset halt -#display/i $pc -# display/x *0xe000ed2c -# display/x *0xE000ED28 +target remote localhost:3333 +symbol-file build/maple.elf +source test.gdb +delete breakpoints +##break main.cpp:setup() +##monitor reset halt +#display/i $pc +# display/x *0xe000ed2c +# display/x *0xE000ED28 diff --git a/Libmaple/libmaple/.gitignore b/Libmaple/libmaple/.gitignore index 18a08caf..33e77e7a 100644 --- a/Libmaple/libmaple/.gitignore +++ b/Libmaple/libmaple/.gitignore @@ -1,10 +1,10 @@ -build/ -doxygen/ -main.cpp -libmaple.layout -tags -TAGS -*~ -*.swp -arm -cscope* +build/ +doxygen/ +main.cpp +libmaple.layout +tags +TAGS +*~ +*.swp +arm +cscope* diff --git a/Libmaple/libmaple/LICENSE b/Libmaple/libmaple/LICENSE index 96ab374b..2d4b51d5 100644 --- a/Libmaple/libmaple/LICENSE +++ b/Libmaple/libmaple/LICENSE @@ -1,100 +1,100 @@ -------------------------------------------------------------------------------- -All code in /libmaple/usb/usb_lib/ is from v2.0.2 of the standard peripheral -library from STMicroelectronics, which is released with the following notice: - -THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - -------------------------------------------------------------------------------- -Unless otherwise noted in the header, all code in /libmaple/ and /wirish/ is -copyright LeafLabs LLC and are released under the MIT License: - -Copyright (c) 2009-2010 LeafLabs LLC - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -See http://creativecommons.org/licenses/MIT/ for more information. - -------------------------------------------------------------------------------- -Some of files in /support/ld/ were written by 'lanchon' and posted in the -STMicroelectronics forum at: - -https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/STM32%20CC%2B%2B%20build%20environment%20using%20CodeSourcery%20Sourcery%20G%2B%2B¤tviews=18152 - -These files are stated to be in the public domain. Other files in /stm32conf/ -are from CodeSourcery, Inc with the following notice: - -Copyright (c) 2006, 2007 CodeSourcery Inc - -The authors hereby grant permission to use, copy, modify, distribute, -and license this software and its documentation for any purpose, provided -that existing copyright notices are retained in all copies and that this -notice is included verbatim in any distributions. No written agreement, -license, or royalty fee is required for any of the authorized uses. -Modifications to this software may be copyrighted by their authors -and need not follow the licensing terms described here, provided that -the new terms are clearly indicated on the first page of each file where -they apply. - -------------------------------------------------------------------------------- -The ./support/stm32loader.py python script is GPL (see -http://www.gnu.org/licenses/ for a copy) and comes with the following info: - - Author: Ivan A-R - Project page: http://tuxotronic.org/wiki/projects/stm32loader - -------------------------------------------------------------------------------- - -Note on contributing patches: - -If contributing patches, please add a Signed-off-by: line certifying -your Developer Certificate of Origin (DCO). You should include this -line at the bottom of any Git commits you want merged in, or along -with any email you submit. By including this line, you are certifying -the following: - - Developer's Certificate of Origin 1.1 - - By making a contribution to this project, I certify that: - - (a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - - (b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - - (c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - - (d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. +------------------------------------------------------------------------------- +All code in /libmaple/usb/usb_lib/ is from v2.0.2 of the standard peripheral +library from STMicroelectronics, which is released with the following notice: + +THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + +------------------------------------------------------------------------------- +Unless otherwise noted in the header, all code in /libmaple/ and /wirish/ is +copyright LeafLabs LLC and are released under the MIT License: + +Copyright (c) 2009-2010 LeafLabs LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +See http://creativecommons.org/licenses/MIT/ for more information. + +------------------------------------------------------------------------------- +Some of files in /support/ld/ were written by 'lanchon' and posted in the +STMicroelectronics forum at: + +https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/STM32%20CC%2B%2B%20build%20environment%20using%20CodeSourcery%20Sourcery%20G%2B%2B¤tviews=18152 + +These files are stated to be in the public domain. Other files in /stm32conf/ +are from CodeSourcery, Inc with the following notice: + +Copyright (c) 2006, 2007 CodeSourcery Inc + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +------------------------------------------------------------------------------- +The ./support/stm32loader.py python script is GPL (see +http://www.gnu.org/licenses/ for a copy) and comes with the following info: + + Author: Ivan A-R + Project page: http://tuxotronic.org/wiki/projects/stm32loader + +------------------------------------------------------------------------------- + +Note on contributing patches: + +If contributing patches, please add a Signed-off-by: line certifying +your Developer Certificate of Origin (DCO). You should include this +line at the bottom of any Git commits you want merged in, or along +with any email you submit. By including this line, you are certifying +the following: + + Developer's Certificate of Origin 1.1 + + By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. diff --git a/Libmaple/libmaple/Makefile b/Libmaple/libmaple/Makefile index ab357660..6e5e83f4 100644 --- a/Libmaple/libmaple/Makefile +++ b/Libmaple/libmaple/Makefile @@ -1,215 +1,215 @@ -# Try "make help" for more information on BOARD and MEMORY_TARGET; -# these default to a Maple Flash build. -#BOARD ?= maple -BOARD ?= aeroquad32 -#BOARD ?= aeroquad32f1 -#BOARD ?= discovery_f4 -#BOARD ?= aeroquad32mini -#BOARD ?= freeflight - -#V=1 - -.DEFAULT_GOAL := sketch - -## -## Useful paths, constants, etc. -## - -ifeq ($(LIB_MAPLE_HOME),) -SRCROOT := . -else -SRCROOT := $(LIB_MAPLE_HOME) -endif -BUILD_PATH = build -LIBMAPLE_PATH := $(SRCROOT)/libmaple -WIRISH_PATH := $(SRCROOT)/wirish -SUPPORT_PATH := $(SRCROOT)/support -# Support files for linker -LDDIR := $(SUPPORT_PATH)/ld -# Support files for this Makefile -MAKEDIR := $(SUPPORT_PATH)/make - -# USB ID for DFU upload -VENDOR_ID := 1EAF -PRODUCT_ID := 0003 - -## -## Target-specific configuration. This determines some compiler and -## linker options/flags. -## - -MEMORY_TARGET ?= flash - -# $(BOARD)- and $(MEMORY_TARGET)-specific configuration -include $(MAKEDIR)/target-config.mk - -## -## Compilation flags -## - -GLOBAL_FLAGS := -D$(VECT_BASE_ADDR) \ - -DBOARD_$(BOARD) -DMCU_$(MCU) \ - -DERROR_LED_PORT=$(ERROR_LED_PORT) \ - -DERROR_LED_PIN=$(ERROR_LED_PIN) \ - -D$(DENSITY) -D$(MCU_FAMILY) - -ifeq ($(BOARD), freeflight) -GLOBAL_FLAGS += -DDISABLEUSB -endif - -ifeq ($(BOARD), aeroquad32) -GLOBAL_FLAGS += -DF_CPU=168000000UL -endif - -ifeq ($(BOARD), discovery_f4) -GLOBAL_FLAGS += -DF_CPU=168000000UL -endif - -ifeq ($(MCU_FAMILY), STM32F2) - EXTRAINCDIRS += \ - libmaple/usbF4/STM32_USB_Device_Library/Core/inc \ - libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc \ - libmaple/usbF4/STM32_USB_OTG_Driver/inc \ - libmaple/usbF4/VCP -endif - - -#GLOBAL_FLAGS += -DDISABLEUSB -#GLOBAL_FLAGS += -DUSB_DISC_OD - -GLOBAL_CFLAGS := -Os -g3 -gdwarf-2 -mcpu=cortex-m3 -mthumb -march=armv7-m \ - -nostdlib -ffunction-sections -fdata-sections \ - -Wl,--gc-sections $(GLOBAL_FLAGS) -GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions -Wall $(GLOBAL_FLAGS) -GLOBAL_ASFLAGS := -mcpu=cortex-m3 -march=armv7-m -mthumb \ - -x assembler-with-cpp $(GLOBAL_FLAGS) -LDFLAGS = -T$(LDDIR)/$(LDSCRIPT) -L$(LDDIR) \ - -mcpu=cortex-m3 -mthumb -Xlinker \ - --gc-sections --print-gc-sections --march=armv7-m -Wall - -## -## Build rules and useful templates -## - -include $(SUPPORT_PATH)/make/build-rules.mk -include $(SUPPORT_PATH)/make/build-templates.mk - -## -## Set all submodules here -## - -# Try to keep LIBMAPLE_MODULES a simply-expanded variable -ifeq ($(LIBMAPLE_MODULES),) - LIBMAPLE_MODULES := $(SRCROOT)/libmaple -else - LIBMAPLE_MODULES += $(SRCROOT)/libmaple -endif -LIBMAPLE_MODULES += $(SRCROOT)/wirish -# Official libraries: -LIBMAPLE_MODULES += $(SRCROOT)/libraries/Servo -LIBMAPLE_MODULES += $(SRCROOT)/libraries/LiquidCrystal -LIBMAPLE_MODULES += $(SRCROOT)/libraries/Wire - -# Experimental libraries: -LIBMAPLE_MODULES += $(SRCROOT)/libraries/FreeRTOS -LIBMAPLE_MODULES += $(SRCROOT)/libraries/mapleSDfat - -# Call each module's rules.mk: -$(foreach m,$(LIBMAPLE_MODULES),$(eval $(call LIBMAPLE_MODULE_template,$(m)))) - -## -## Targets -## - -# main target -include $(SRCROOT)/build-targets.mk - -.PHONY: install sketch clean help debug cscope tags ctags ram flash jtag doxygen mrproper - -# Target upload commands -UPLOAD_ram := $(SUPPORT_PATH)/scripts/reset.py && \ - sleep 1 && \ - $(DFU) -a0 -d $(VENDOR_ID):$(PRODUCT_ID) -D $(BUILD_PATH)/$(BOARD).bin -R -UPLOAD_flash := $(SUPPORT_PATH)/scripts/reset.py && \ - sleep 1 && \ - $(DFU) -a1 -d $(VENDOR_ID):$(PRODUCT_ID) -D $(BUILD_PATH)/$(BOARD).bin -R -UPLOAD_jtag := $(OPENOCD_WRAPPER) flash - -all: library - -# Conditionally upload to whatever the last build was -install: INSTALL_TARGET = $(shell cat $(BUILD_PATH)/build-type 2>/dev/null) -install: $(BUILD_PATH)/$(BOARD).bin - @echo Install target: $(INSTALL_TARGET) - $(UPLOAD_$(INSTALL_TARGET)) - -# Force a rebuild if the target changed -PREV_BUILD_TYPE = $(shell cat $(BUILD_PATH)/build-type 2>/dev/null) -build-check: -ifneq ($(PREV_BUILD_TYPE), $(MEMORY_TARGET)) - $(shell rm -rf $(BUILD_PATH)) -endif - -sketch: build-check MSG_INFO $(BUILD_PATH)/$(BOARD).bin - -clean: - rm -rf build - -mrproper: clean - rm -rf doxygen - -help: - @echo "" - @echo " libmaple Makefile help" - @echo " ----------------------" - @echo " " - @echo " Programming targets:" - @echo " sketch: Compile for BOARD to MEMORY_TARGET (default)." - @echo " install: Compile and upload code over USB, using Maple bootloader" - @echo " " - @echo " You *must* set BOARD if not compiling for Maple (e.g." - @echo " use BOARD=maple_mini for mini, etc.), and MEMORY_TARGET" - @echo " if not compiling to Flash." - @echo " " - @echo " Valid BOARDs:" - @echo " maple, maple_mini, maple_RET6, maple_native" - @echo " " - @echo " Valid MEMORY_TARGETs (default=flash):" - @echo " ram: Compile sketch code to ram" - @echo " flash: Compile sketch code to flash" - @echo " jtag: Compile sketch code for jtag; overwrites bootloader" - @echo " " - @echo " Other targets:" - @echo " debug: Start OpenOCD gdb server on port 3333, telnet on port 4444" - @echo " clean: Remove all build and object files" - @echo " help: Show this message" - @echo " doxygen: Build Doxygen HTML and XML documentation" - @echo " mrproper: Remove all generated files" - @echo " " - -debug: - $(OPENOCD_WRAPPER) debug - -cscope: - rm -rf *.cscope - find . -name '*.[hcS]' -o -name '*.cpp' | xargs cscope -b - -tags: - etags `find . -name "*.c" -o -name "*.cpp" -o -name "*.h"` - @echo "Made TAGS file for EMACS code browsing" - -ctags: - ctags-exuberant -R . - @echo "Made tags file for VIM code browsing" - -ram: - @$(MAKE) MEMORY_TARGET=ram --no-print-directory sketch - -flash: - @$(MAKE) MEMORY_TARGET=flash --no-print-directory sketch - -jtag: - @$(MAKE) MEMORY_TARGET=jtag --no-print-directory sketch - -doxygen: - doxygen $(SUPPORT_PATH)/doxygen/Doxyfile +# Try "make help" for more information on BOARD and MEMORY_TARGET; +# these default to a Maple Flash build. +#BOARD ?= maple +BOARD ?= aeroquad32 +#BOARD ?= aeroquad32f1 +#BOARD ?= discovery_f4 +#BOARD ?= aeroquad32mini +#BOARD ?= freeflight + +#V=1 + +.DEFAULT_GOAL := sketch + +## +## Useful paths, constants, etc. +## + +ifeq ($(LIB_MAPLE_HOME),) +SRCROOT := . +else +SRCROOT := $(LIB_MAPLE_HOME) +endif +BUILD_PATH = build +LIBMAPLE_PATH := $(SRCROOT)/libmaple +WIRISH_PATH := $(SRCROOT)/wirish +SUPPORT_PATH := $(SRCROOT)/support +# Support files for linker +LDDIR := $(SUPPORT_PATH)/ld +# Support files for this Makefile +MAKEDIR := $(SUPPORT_PATH)/make + +# USB ID for DFU upload +VENDOR_ID := 1EAF +PRODUCT_ID := 0003 + +## +## Target-specific configuration. This determines some compiler and +## linker options/flags. +## + +MEMORY_TARGET ?= flash + +# $(BOARD)- and $(MEMORY_TARGET)-specific configuration +include $(MAKEDIR)/target-config.mk + +## +## Compilation flags +## + +GLOBAL_FLAGS := -D$(VECT_BASE_ADDR) \ + -DBOARD_$(BOARD) -DMCU_$(MCU) \ + -DERROR_LED_PORT=$(ERROR_LED_PORT) \ + -DERROR_LED_PIN=$(ERROR_LED_PIN) \ + -D$(DENSITY) -D$(MCU_FAMILY) + +ifeq ($(BOARD), freeflight) +GLOBAL_FLAGS += -DDISABLEUSB +endif + +ifeq ($(BOARD), aeroquad32) +GLOBAL_FLAGS += -DF_CPU=168000000UL +endif + +ifeq ($(BOARD), discovery_f4) +GLOBAL_FLAGS += -DF_CPU=168000000UL +endif + +ifeq ($(MCU_FAMILY), STM32F2) + EXTRAINCDIRS += \ + libmaple/usbF4/STM32_USB_Device_Library/Core/inc \ + libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc \ + libmaple/usbF4/STM32_USB_OTG_Driver/inc \ + libmaple/usbF4/VCP +endif + + +#GLOBAL_FLAGS += -DDISABLEUSB +#GLOBAL_FLAGS += -DUSB_DISC_OD + +GLOBAL_CFLAGS := -Os -g3 -gdwarf-2 -mcpu=cortex-m3 -mthumb -march=armv7-m \ + -nostdlib -ffunction-sections -fdata-sections \ + -Wl,--gc-sections $(GLOBAL_FLAGS) +GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions -Wall $(GLOBAL_FLAGS) +GLOBAL_ASFLAGS := -mcpu=cortex-m3 -march=armv7-m -mthumb \ + -x assembler-with-cpp $(GLOBAL_FLAGS) +LDFLAGS = -T$(LDDIR)/$(LDSCRIPT) -L$(LDDIR) \ + -mcpu=cortex-m3 -mthumb -Xlinker \ + --gc-sections --print-gc-sections --march=armv7-m -Wall + +## +## Build rules and useful templates +## + +include $(SUPPORT_PATH)/make/build-rules.mk +include $(SUPPORT_PATH)/make/build-templates.mk + +## +## Set all submodules here +## + +# Try to keep LIBMAPLE_MODULES a simply-expanded variable +ifeq ($(LIBMAPLE_MODULES),) + LIBMAPLE_MODULES := $(SRCROOT)/libmaple +else + LIBMAPLE_MODULES += $(SRCROOT)/libmaple +endif +LIBMAPLE_MODULES += $(SRCROOT)/wirish +# Official libraries: +LIBMAPLE_MODULES += $(SRCROOT)/libraries/Servo +LIBMAPLE_MODULES += $(SRCROOT)/libraries/LiquidCrystal +LIBMAPLE_MODULES += $(SRCROOT)/libraries/Wire + +# Experimental libraries: +LIBMAPLE_MODULES += $(SRCROOT)/libraries/FreeRTOS +LIBMAPLE_MODULES += $(SRCROOT)/libraries/mapleSDfat + +# Call each module's rules.mk: +$(foreach m,$(LIBMAPLE_MODULES),$(eval $(call LIBMAPLE_MODULE_template,$(m)))) + +## +## Targets +## + +# main target +include $(SRCROOT)/build-targets.mk + +.PHONY: install sketch clean help debug cscope tags ctags ram flash jtag doxygen mrproper + +# Target upload commands +UPLOAD_ram := $(SUPPORT_PATH)/scripts/reset.py && \ + sleep 1 && \ + $(DFU) -a0 -d $(VENDOR_ID):$(PRODUCT_ID) -D $(BUILD_PATH)/$(BOARD).bin -R +UPLOAD_flash := $(SUPPORT_PATH)/scripts/reset.py && \ + sleep 1 && \ + $(DFU) -a1 -d $(VENDOR_ID):$(PRODUCT_ID) -D $(BUILD_PATH)/$(BOARD).bin -R +UPLOAD_jtag := $(OPENOCD_WRAPPER) flash + +all: library + +# Conditionally upload to whatever the last build was +install: INSTALL_TARGET = $(shell cat $(BUILD_PATH)/build-type 2>/dev/null) +install: $(BUILD_PATH)/$(BOARD).bin + @echo Install target: $(INSTALL_TARGET) + $(UPLOAD_$(INSTALL_TARGET)) + +# Force a rebuild if the target changed +PREV_BUILD_TYPE = $(shell cat $(BUILD_PATH)/build-type 2>/dev/null) +build-check: +ifneq ($(PREV_BUILD_TYPE), $(MEMORY_TARGET)) + $(shell rm -rf $(BUILD_PATH)) +endif + +sketch: build-check MSG_INFO $(BUILD_PATH)/$(BOARD).bin + +clean: + rm -rf build + +mrproper: clean + rm -rf doxygen + +help: + @echo "" + @echo " libmaple Makefile help" + @echo " ----------------------" + @echo " " + @echo " Programming targets:" + @echo " sketch: Compile for BOARD to MEMORY_TARGET (default)." + @echo " install: Compile and upload code over USB, using Maple bootloader" + @echo " " + @echo " You *must* set BOARD if not compiling for Maple (e.g." + @echo " use BOARD=maple_mini for mini, etc.), and MEMORY_TARGET" + @echo " if not compiling to Flash." + @echo " " + @echo " Valid BOARDs:" + @echo " maple, maple_mini, maple_RET6, maple_native" + @echo " " + @echo " Valid MEMORY_TARGETs (default=flash):" + @echo " ram: Compile sketch code to ram" + @echo " flash: Compile sketch code to flash" + @echo " jtag: Compile sketch code for jtag; overwrites bootloader" + @echo " " + @echo " Other targets:" + @echo " debug: Start OpenOCD gdb server on port 3333, telnet on port 4444" + @echo " clean: Remove all build and object files" + @echo " help: Show this message" + @echo " doxygen: Build Doxygen HTML and XML documentation" + @echo " mrproper: Remove all generated files" + @echo " " + +debug: + $(OPENOCD_WRAPPER) debug + +cscope: + rm -rf *.cscope + find . -name '*.[hcS]' -o -name '*.cpp' | xargs cscope -b + +tags: + etags `find . -name "*.c" -o -name "*.cpp" -o -name "*.h"` + @echo "Made TAGS file for EMACS code browsing" + +ctags: + ctags-exuberant -R . + @echo "Made tags file for VIM code browsing" + +ram: + @$(MAKE) MEMORY_TARGET=ram --no-print-directory sketch + +flash: + @$(MAKE) MEMORY_TARGET=flash --no-print-directory sketch + +jtag: + @$(MAKE) MEMORY_TARGET=jtag --no-print-directory sketch + +doxygen: + doxygen $(SUPPORT_PATH)/doxygen/Doxyfile diff --git a/Libmaple/libmaple/README b/Libmaple/libmaple/README index 51249f17..f66ad038 100644 --- a/Libmaple/libmaple/README +++ b/Libmaple/libmaple/README @@ -1,134 +1,134 @@ - - _ _ _ _ - | (_) |__ _ __ ___ __ _ _ __ | | ___ - | | | '_ \| '_ ` _ \ / _` | '_ \| |/ _ \ - | | | |_) | | | | | | (_| | |_) | | __/ - |_|_|_.__/|_| |_| |_|\__,_| .__/|_|\___| - |_| by LeafLabs! - leaflabs.com - - -The latest version of this repository can be found here: - - https://github.com/leaflabs/libmaple - -General information ------------------------------------------------------------------------------- - -libmaple is a library for programming ST's STM32 line of Cortex M3 -microcontrollers. It has a pure C layer, libmaple proper, which does -most of the work, and a C++ layer, Wirish, which provides high-level -convenience functions and a Wiring/Arduino-compatible interface. - -libmaple's primary purpose is for use with LeafLabs' Maple line of -microcontroller development boards (hence the name). However, it is -portable across a variety of medium- and high-density STM32F1xx chips. -For example, libmaple has successfully been ported to the ST Discovery -kits. - -Using libmaple ------------------------------------------------------------------------------- - -The easiest way to use libmaple is in concert with the Maple IDE. -Maple IDE, a sister project from LeafLabs, is an Arduino IDE fork -usable for programming Maple boards, which includes libmaple and a -compilation and upload toolchain: - - http://leaflabs.com/docs/maple-ide-install.html - -Additionally, a HOWTO on setting up this library for use from the -command line in a Unix environment is available in our online HTML -documentation: - - http://leaflabs.com/docs/unix-toolchain.html - -Documentation, Etc. ------------------------------------------------------------------------------- - -HTML documentation for the latest release of libmaple/Maple IDE is -available here: - - http://leaflabs.com/docs/ - -libmaple is well documented via Doxygen comments. The HTML -documentation referenced above (which also includes the Doxygen -output) is automatically generated from the source files in the -leaflabs-docs repository. In order to obtain the leaflabs-docs -repository, visit: - - http://github.com/leaflabs/leaflabs-docs/ - -Our bugtracker is available at: - - http://code.google.com/p/leaflabs/issues/list - -For changes that block official releases, see our wiki: - - http://wiki.leaflabs.com/index.php?title=Blocking_Changes - -Repository Layout ------------------------------------------------------------------------------- - -/build/ - - Compiler output - -/contrib/ - - Community-contributed resources. LeafLabs doesn't maintain the - contents of this directory, so it may get stale. - -/examples/ - - Example code and test programs. Copy these to /main.cpp to compile them. - -/libmaple/ - - This is the meat of the library. C only, no C++. The - Arduino-like compatibility layer (in C++) is in /wirish/. - -/libraries/ - - Special-purpose libraries that don't merit inclusion in the - /libmaple/ and /wirish/ directories, which are intended for - general use. Arduino-compatible libraries go here. - -/LICENSE - - Licensing and copyright information. - -/main.cpp.example - - main.cpp is required for a successful build but is non-existent by - default; use this file as a template for building your program. By - default, just blinks an LED. - -/Makefile - - libmaple build instructions for GNU Make. - -/notes/ - - Unstructured text notes that may be useful. - -/README - - This file. - -/support/ - - Support files and scripts for various purposes. - - gdb/ GDB scripts. - ld/ Linker scripts. - make/ Additional scripts used by the top-level Makefile. - openocd/ OpenOCD scripts for JTAG debugging. - scripts/ Miscellany. - doxygen/ Doxygen configuration. - stm32loader.py Script for uploading via the built-in USART bootloader. - -/wirish/ - - Extra wrappers and functionality around the lower level code in - /libmaple/. These files implement an Arduino "Wiring"-like - library. + + _ _ _ _ + | (_) |__ _ __ ___ __ _ _ __ | | ___ + | | | '_ \| '_ ` _ \ / _` | '_ \| |/ _ \ + | | | |_) | | | | | | (_| | |_) | | __/ + |_|_|_.__/|_| |_| |_|\__,_| .__/|_|\___| + |_| by LeafLabs! + leaflabs.com + + +The latest version of this repository can be found here: + + https://github.com/leaflabs/libmaple + +General information +------------------------------------------------------------------------------ + +libmaple is a library for programming ST's STM32 line of Cortex M3 +microcontrollers. It has a pure C layer, libmaple proper, which does +most of the work, and a C++ layer, Wirish, which provides high-level +convenience functions and a Wiring/Arduino-compatible interface. + +libmaple's primary purpose is for use with LeafLabs' Maple line of +microcontroller development boards (hence the name). However, it is +portable across a variety of medium- and high-density STM32F1xx chips. +For example, libmaple has successfully been ported to the ST Discovery +kits. + +Using libmaple +------------------------------------------------------------------------------ + +The easiest way to use libmaple is in concert with the Maple IDE. +Maple IDE, a sister project from LeafLabs, is an Arduino IDE fork +usable for programming Maple boards, which includes libmaple and a +compilation and upload toolchain: + + http://leaflabs.com/docs/maple-ide-install.html + +Additionally, a HOWTO on setting up this library for use from the +command line in a Unix environment is available in our online HTML +documentation: + + http://leaflabs.com/docs/unix-toolchain.html + +Documentation, Etc. +------------------------------------------------------------------------------ + +HTML documentation for the latest release of libmaple/Maple IDE is +available here: + + http://leaflabs.com/docs/ + +libmaple is well documented via Doxygen comments. The HTML +documentation referenced above (which also includes the Doxygen +output) is automatically generated from the source files in the +leaflabs-docs repository. In order to obtain the leaflabs-docs +repository, visit: + + http://github.com/leaflabs/leaflabs-docs/ + +Our bugtracker is available at: + + http://code.google.com/p/leaflabs/issues/list + +For changes that block official releases, see our wiki: + + http://wiki.leaflabs.com/index.php?title=Blocking_Changes + +Repository Layout +------------------------------------------------------------------------------ + +/build/ + + Compiler output + +/contrib/ + + Community-contributed resources. LeafLabs doesn't maintain the + contents of this directory, so it may get stale. + +/examples/ + + Example code and test programs. Copy these to /main.cpp to compile them. + +/libmaple/ + + This is the meat of the library. C only, no C++. The + Arduino-like compatibility layer (in C++) is in /wirish/. + +/libraries/ + + Special-purpose libraries that don't merit inclusion in the + /libmaple/ and /wirish/ directories, which are intended for + general use. Arduino-compatible libraries go here. + +/LICENSE + + Licensing and copyright information. + +/main.cpp.example + + main.cpp is required for a successful build but is non-existent by + default; use this file as a template for building your program. By + default, just blinks an LED. + +/Makefile + + libmaple build instructions for GNU Make. + +/notes/ + + Unstructured text notes that may be useful. + +/README + + This file. + +/support/ + + Support files and scripts for various purposes. + + gdb/ GDB scripts. + ld/ Linker scripts. + make/ Additional scripts used by the top-level Makefile. + openocd/ OpenOCD scripts for JTAG debugging. + scripts/ Miscellany. + doxygen/ Doxygen configuration. + stm32loader.py Script for uploading via the built-in USART bootloader. + +/wirish/ + + Extra wrappers and functionality around the lower level code in + /libmaple/. These files implement an Arduino "Wiring"-like + library. diff --git a/Libmaple/libmaple/build-targets.mk b/Libmaple/libmaple/build-targets.mk index f383fba0..207d324e 100644 --- a/Libmaple/libmaple/build-targets.mk +++ b/Libmaple/libmaple/build-targets.mk @@ -1,43 +1,43 @@ -# main project target -$(BUILD_PATH)/main.o: main.cpp - $(SILENT_CXX) $(CXX) $(CFLAGS) $(CXXFLAGS) $(LIBMAPLE_INCLUDES) $(WIRISH_INCLUDES) -o $@ -c $< - -$(BUILD_PATH)/libmaple.a: $(BUILDDIRS) $(TGT_BIN) - - rm -f $@ - $(AR) crv $(BUILD_PATH)/libmaple.a $(TGT_BIN) - -library: $(BUILD_PATH)/libmaple.a - -.PHONY: library - -$(BUILD_PATH)/$(BOARD).elf: $(BUILDDIRS) $(TGT_BIN) $(BUILD_PATH)/main.o - $(SILENT_LD) $(CXX) $(LDFLAGS) -o $@ $(TGT_BIN) $(BUILD_PATH)/main.o -Wl,-Map,$(BUILD_PATH)/$(BOARD).map - -$(BUILD_PATH)/$(BOARD).bin: $(BUILD_PATH)/$(BOARD).elf - $(SILENT_OBJCOPY) $(OBJCOPY) -v -Obinary $(BUILD_PATH)/$(BOARD).elf $@ 1>/dev/null - $(SILENT_DISAS) $(DISAS) -d $(BUILD_PATH)/$(BOARD).elf > $(BUILD_PATH)/$(BOARD).disas - @echo " " - @echo "Object file sizes:" - @find $(BUILD_PATH) -iname *.o | xargs $(SIZE) -t > $(BUILD_PATH)/$(BOARD).sizes - @cat $(BUILD_PATH)/$(BOARD).sizes - @echo " " - @echo "Final Size:" - @$(SIZE) $< - @echo $(MEMORY_TARGET) > $(BUILD_PATH)/build-type - -$(BUILDDIRS): - @mkdir -p $@ - -MSG_INFO: - @echo "================================================================================" - @echo "" - @echo " Build info:" - @echo " BOARD: " $(BOARD) - @echo " MCU: " $(MCU) - @echo " MEMORY_TARGET: " $(MEMORY_TARGET) - @echo "" - @echo " See 'make help' for all possible targets" - @echo "" - @echo "================================================================================" - @echo - +# main project target +$(BUILD_PATH)/main.o: main.cpp + $(SILENT_CXX) $(CXX) $(CFLAGS) $(CXXFLAGS) $(LIBMAPLE_INCLUDES) $(WIRISH_INCLUDES) -o $@ -c $< + +$(BUILD_PATH)/libmaple.a: $(BUILDDIRS) $(TGT_BIN) + - rm -f $@ + $(AR) crv $(BUILD_PATH)/libmaple.a $(TGT_BIN) + +library: $(BUILD_PATH)/libmaple.a + +.PHONY: library + +$(BUILD_PATH)/$(BOARD).elf: $(BUILDDIRS) $(TGT_BIN) $(BUILD_PATH)/main.o + $(SILENT_LD) $(CXX) $(LDFLAGS) -o $@ $(TGT_BIN) $(BUILD_PATH)/main.o -Wl,-Map,$(BUILD_PATH)/$(BOARD).map + +$(BUILD_PATH)/$(BOARD).bin: $(BUILD_PATH)/$(BOARD).elf + $(SILENT_OBJCOPY) $(OBJCOPY) -v -Obinary $(BUILD_PATH)/$(BOARD).elf $@ 1>/dev/null + $(SILENT_DISAS) $(DISAS) -d $(BUILD_PATH)/$(BOARD).elf > $(BUILD_PATH)/$(BOARD).disas + @echo " " + @echo "Object file sizes:" + @find $(BUILD_PATH) -iname *.o | xargs $(SIZE) -t > $(BUILD_PATH)/$(BOARD).sizes + @cat $(BUILD_PATH)/$(BOARD).sizes + @echo " " + @echo "Final Size:" + @$(SIZE) $< + @echo $(MEMORY_TARGET) > $(BUILD_PATH)/build-type + +$(BUILDDIRS): + @mkdir -p $@ + +MSG_INFO: + @echo "================================================================================" + @echo "" + @echo " Build info:" + @echo " BOARD: " $(BOARD) + @echo " MCU: " $(MCU) + @echo " MEMORY_TARGET: " $(MEMORY_TARGET) + @echo "" + @echo " See 'make help' for all possible targets" + @echo "" + @echo "================================================================================" + @echo + diff --git a/Libmaple/libmaple/contrib/automake/Makefile.am b/Libmaple/libmaple/contrib/automake/Makefile.am index a9b43d01..58275cfd 100644 --- a/Libmaple/libmaple/contrib/automake/Makefile.am +++ b/Libmaple/libmaple/contrib/automake/Makefile.am @@ -1,138 +1,138 @@ -# Top level Makefile for libmaple - -CROSS_COMPILE = arm-none-eabi- -CC = $(CROSS_COMPILE)gcc -CXX = $(CROSS_COMPILE)g++ -LD = $(CROSS_COMPILE)ld - -# The main library -lib_LIBRARIES = \ - libmaple.a \ - libmapleusb.a - -# libwirish.a - -# noinst_PROGRAMS = \ -# main - -# main_SOURCES = \ -# startup2.c \ -# main.cpp - -main_LDFLAGS = \ - --gc-sections \ - -Map=main.map - -main_LDADD = libmaple.a - -# Main library -libmaple_a_SOURCES = \ - libmaple/adc.c \ - libmaple/bkp.c \ - libmaple/dac.c \ - libmaple/dma.c \ - libmaple/exti.c \ - libmaple/flash.c \ - libmaple/fsmc.c \ - libmaple/gpio.c \ - libmaple/iwdg.c \ - libmaple/nvic.c \ - libmaple/pwr.c \ - libmaple/i2c.c \ - libmaple/rcc.c \ - libmaple/spi.c \ - libmaple/syscalls.c \ - libmaple/systick.c \ - libmaple/timer.c \ - libmaple/usart.c \ - libmaple/util.c - -nobase_include_HEADERS = \ - libmaple/adc.h \ - libmaple/bitband.h \ - libmaple/bkp.h \ - libmaple/dac.h \ - libmaple/delay.h \ - libmaple/dma.h \ - libmaple/exti.h \ - libmaple/flash.h \ - libmaple/fsmc.h \ - libmaple/gpio.h \ - libmaple/i2c.h \ - libmaple/iwdg.h \ - libmaple/libmaple.h \ - libmaple/libmaple_types.h \ - libmaple/nvic.h \ - libmaple/pwr.h \ - libmaple/rcc.h \ - libmaple/ring_buffer.h \ - libmaple/scb.h \ - libmaple/spi.h \ - libmaple/stm32.h \ - libmaple/systick.h \ - libmaple/timer.h \ - libmaple/usart.h \ - libmaple/util.h \ - libmaple/usb/descriptors.h \ - libmaple/usb/usb.h \ - libmaple/usb/usb_callbacks.h \ - libmaple/usb/usb_config.h \ - libmaple/usb/usb_hardware.h \ - libmaple/usb/usb_lib/usb_core.h \ - libmaple/usb/usb_lib/usb_def.h \ - libmaple/usb/usb_lib/usb_init.h \ - libmaple/usb/usb_lib/usb_int.h \ - libmaple/usb/usb_lib/usb_lib.h \ - libmaple/usb/usb_lib/usb_mem.h \ - libmaple/usb/usb_lib/usb_regs.h \ - libmaple/usb/usb_lib/usb_type.h - -libmapleusb_a_SOURCES = \ - libmaple/usb/descriptors.c \ - libmaple/usb/usb.c \ - libmaple/usb/usb_callbacks.c \ - libmaple/usb/usb_hardware.c \ - libmaple/usb/usb_lib/usb_core.c \ - libmaple/usb/usb_lib/usb_init.c \ - libmaple/usb/usb_lib/usb_int.c \ - libmaple/usb/usb_lib/usb_mem.c \ - libmaple/usb/usb_lib/usb_regs.c - -libwirish_a_SOURCES = \ - wirish/wirish_math.cpp \ - wirish/Print.cpp \ - wirish/boards.cpp \ - wirish/boards/maple.cpp \ - wirish/boards/maple_mini.cpp \ - wirish/boards/maple_native.cpp \ - wirish/boards/maple_RET6.cpp \ - wirish/comm/HardwareSerial.cpp \ - wirish/comm/HardwareSPI.cpp \ - wirish/HardwareTimer.cpp \ - wirish/usb_serial.cpp \ - wirish/cxxabi-compat.cpp \ - wirish/wirish_shift.cpp \ - wirish/wirish_analog.cpp \ - wirish/wirish_time.cpp \ - wirish/pwm.cpp \ - wirish/ext_interrupts.cpp \ - wirish/wirish_digital.cpp - -MCU := STM32F103RB -BOARD ?= maple -DENSITY = STM32_MEDIUM_DENSITY - -FLAGS = \ - -Os -ggdb -nostdlib -Wall \ - -ffunction-sections -fdata-sections -Wl,--gc-sections \ - -mcpu=cortex-m3 -mthumb -fshort-enums -mfloat-abi=soft \ - -DBOARD_$(BOARD) -DMCU_$(MCU) -D$(DENSITY) -DVECT_TAB_BASE \ - -I$(srcdir)/libmaple \ - -I$(srcdir)/libmaple/usb \ - -I$(srcdir)/libmaple/usb/usb_lib - -AM_CFLAGS = $(FLAGS) -std=gnu99 - -AM_CXXFLAGS = $(FLAGS) \ - -I$(srcdir)/wirish -I$(srcdir)/wirish/comm -I$(srcdir)/wirish/boards \ - -fno-rtti -fno-exceptions +# Top level Makefile for libmaple + +CROSS_COMPILE = arm-none-eabi- +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +LD = $(CROSS_COMPILE)ld + +# The main library +lib_LIBRARIES = \ + libmaple.a \ + libmapleusb.a + +# libwirish.a + +# noinst_PROGRAMS = \ +# main + +# main_SOURCES = \ +# startup2.c \ +# main.cpp + +main_LDFLAGS = \ + --gc-sections \ + -Map=main.map + +main_LDADD = libmaple.a + +# Main library +libmaple_a_SOURCES = \ + libmaple/adc.c \ + libmaple/bkp.c \ + libmaple/dac.c \ + libmaple/dma.c \ + libmaple/exti.c \ + libmaple/flash.c \ + libmaple/fsmc.c \ + libmaple/gpio.c \ + libmaple/iwdg.c \ + libmaple/nvic.c \ + libmaple/pwr.c \ + libmaple/i2c.c \ + libmaple/rcc.c \ + libmaple/spi.c \ + libmaple/syscalls.c \ + libmaple/systick.c \ + libmaple/timer.c \ + libmaple/usart.c \ + libmaple/util.c + +nobase_include_HEADERS = \ + libmaple/adc.h \ + libmaple/bitband.h \ + libmaple/bkp.h \ + libmaple/dac.h \ + libmaple/delay.h \ + libmaple/dma.h \ + libmaple/exti.h \ + libmaple/flash.h \ + libmaple/fsmc.h \ + libmaple/gpio.h \ + libmaple/i2c.h \ + libmaple/iwdg.h \ + libmaple/libmaple.h \ + libmaple/libmaple_types.h \ + libmaple/nvic.h \ + libmaple/pwr.h \ + libmaple/rcc.h \ + libmaple/ring_buffer.h \ + libmaple/scb.h \ + libmaple/spi.h \ + libmaple/stm32.h \ + libmaple/systick.h \ + libmaple/timer.h \ + libmaple/usart.h \ + libmaple/util.h \ + libmaple/usb/descriptors.h \ + libmaple/usb/usb.h \ + libmaple/usb/usb_callbacks.h \ + libmaple/usb/usb_config.h \ + libmaple/usb/usb_hardware.h \ + libmaple/usb/usb_lib/usb_core.h \ + libmaple/usb/usb_lib/usb_def.h \ + libmaple/usb/usb_lib/usb_init.h \ + libmaple/usb/usb_lib/usb_int.h \ + libmaple/usb/usb_lib/usb_lib.h \ + libmaple/usb/usb_lib/usb_mem.h \ + libmaple/usb/usb_lib/usb_regs.h \ + libmaple/usb/usb_lib/usb_type.h + +libmapleusb_a_SOURCES = \ + libmaple/usb/descriptors.c \ + libmaple/usb/usb.c \ + libmaple/usb/usb_callbacks.c \ + libmaple/usb/usb_hardware.c \ + libmaple/usb/usb_lib/usb_core.c \ + libmaple/usb/usb_lib/usb_init.c \ + libmaple/usb/usb_lib/usb_int.c \ + libmaple/usb/usb_lib/usb_mem.c \ + libmaple/usb/usb_lib/usb_regs.c + +libwirish_a_SOURCES = \ + wirish/wirish_math.cpp \ + wirish/Print.cpp \ + wirish/boards.cpp \ + wirish/boards/maple.cpp \ + wirish/boards/maple_mini.cpp \ + wirish/boards/maple_native.cpp \ + wirish/boards/maple_RET6.cpp \ + wirish/comm/HardwareSerial.cpp \ + wirish/comm/HardwareSPI.cpp \ + wirish/HardwareTimer.cpp \ + wirish/usb_serial.cpp \ + wirish/cxxabi-compat.cpp \ + wirish/wirish_shift.cpp \ + wirish/wirish_analog.cpp \ + wirish/wirish_time.cpp \ + wirish/pwm.cpp \ + wirish/ext_interrupts.cpp \ + wirish/wirish_digital.cpp + +MCU := STM32F103RB +BOARD ?= maple +DENSITY = STM32_MEDIUM_DENSITY + +FLAGS = \ + -Os -ggdb -nostdlib -Wall \ + -ffunction-sections -fdata-sections -Wl,--gc-sections \ + -mcpu=cortex-m3 -mthumb -fshort-enums -mfloat-abi=soft \ + -DBOARD_$(BOARD) -DMCU_$(MCU) -D$(DENSITY) -DVECT_TAB_BASE \ + -I$(srcdir)/libmaple \ + -I$(srcdir)/libmaple/usb \ + -I$(srcdir)/libmaple/usb/usb_lib + +AM_CFLAGS = $(FLAGS) -std=gnu99 + +AM_CXXFLAGS = $(FLAGS) \ + -I$(srcdir)/wirish -I$(srcdir)/wirish/comm -I$(srcdir)/wirish/boards \ + -fno-rtti -fno-exceptions diff --git a/Libmaple/libmaple/contrib/automake/configure.ac b/Libmaple/libmaple/contrib/automake/configure.ac index abdfaa07..9f072dbf 100644 --- a/Libmaple/libmaple/contrib/automake/configure.ac +++ b/Libmaple/libmaple/contrib/automake/configure.ac @@ -1,8 +1,8 @@ -AC_INIT(libmaple, 0.11+git) -AM_INIT_AUTOMAKE(foreign subdir-objects color-tests) -AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_FILES(Makefile) -AM_PROG_AS -AC_PROG_CXX -AM_PROG_LIBTOOL -AC_OUTPUT +AC_INIT(libmaple, 0.11+git) +AM_INIT_AUTOMAKE(foreign subdir-objects color-tests) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_FILES(Makefile) +AM_PROG_AS +AC_PROG_CXX +AM_PROG_LIBTOOL +AC_OUTPUT diff --git a/Libmaple/libmaple/examples/blinky.cpp b/Libmaple/libmaple/examples/blinky.cpp index 91d1a478..dd725148 100644 --- a/Libmaple/libmaple/examples/blinky.cpp +++ b/Libmaple/libmaple/examples/blinky.cpp @@ -1,32 +1,32 @@ -// Blinks the built-in LED - -#include "wirish.h" - -void setup() { - pinMode(BOARD_LED_PIN, OUTPUT); -} - -int toggle = 1; - -void loop() { - // You could just use toggleLED() instead, but this illustrates - // the use of digitalWrite(): - digitalWrite(BOARD_LED_PIN, toggle); - toggle ^= 1; - delay(100); -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +// Blinks the built-in LED + +#include "wirish.h" + +void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); +} + +int toggle = 1; + +void loop() { + // You could just use toggleLED() instead, but this illustrates + // the use of digitalWrite(): + digitalWrite(BOARD_LED_PIN, toggle); + toggle ^= 1; + delay(100); +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/debug-dtrrts.cpp b/Libmaple/libmaple/examples/debug-dtrrts.cpp index 7ea799f6..38292081 100644 --- a/Libmaple/libmaple/examples/debug-dtrrts.cpp +++ b/Libmaple/libmaple/examples/debug-dtrrts.cpp @@ -1,40 +1,40 @@ -// Test sketch for figuring out DTR/RTS behavior on different platforms. - -#include "wirish.h" -#include "usb.h" - -void setup() { - /* Set up the LED to blink */ - pinMode(BOARD_LED_PIN, OUTPUT); - - /* Send a message out USART2 */ - Serial2.begin(9600); - Serial2.println("Debugging DTR/RTS..."); - -} - -void loop() { - toggleLED(); - delay(100); - - Serial2.print("DTR: "); - Serial2.print(usbGetDTR(), DEC); - Serial2.print("\tRTS: "); - Serial2.println(usbGetRTS(), DEC); -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (1) { - loop(); - } - return 0; -} - +// Test sketch for figuring out DTR/RTS behavior on different platforms. + +#include "wirish.h" +#include "usb.h" + +void setup() { + /* Set up the LED to blink */ + pinMode(BOARD_LED_PIN, OUTPUT); + + /* Send a message out USART2 */ + Serial2.begin(9600); + Serial2.println("Debugging DTR/RTS..."); + +} + +void loop() { + toggleLED(); + delay(100); + + Serial2.print("DTR: "); + Serial2.print(usbGetDTR(), DEC); + Serial2.print("\tRTS: "); + Serial2.println(usbGetRTS(), DEC); +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (1) { + loop(); + } + return 0; +} + diff --git a/Libmaple/libmaple/examples/freertos-blinky.cpp b/Libmaple/libmaple/examples/freertos-blinky.cpp index f6dd682b..6f82d71c 100644 --- a/Libmaple/libmaple/examples/freertos-blinky.cpp +++ b/Libmaple/libmaple/examples/freertos-blinky.cpp @@ -1,43 +1,43 @@ -#include "wirish.h" -#include "libraries/FreeRTOS/MapleFreeRTOS.h" - -static void vLEDFlashTask(void *pvParameters) { - for (;;) { - vTaskDelay(1000); - digitalWrite(BOARD_LED_PIN, HIGH); - vTaskDelay(50); - digitalWrite(BOARD_LED_PIN, LOW); - } -} - -void setup() { - // initialize the digital pin as an output: - pinMode(BOARD_LED_PIN, OUTPUT); - - xTaskCreate(vLEDFlashTask, - (signed portCHAR *)"Task1", - configMINIMAL_STACK_SIZE, - NULL, - tskIDLE_PRIORITY + 2, - NULL); - vTaskStartScheduler(); -} - -void loop() { - // Insert background code here -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +#include "wirish.h" +#include "libraries/FreeRTOS/MapleFreeRTOS.h" + +static void vLEDFlashTask(void *pvParameters) { + for (;;) { + vTaskDelay(1000); + digitalWrite(BOARD_LED_PIN, HIGH); + vTaskDelay(50); + digitalWrite(BOARD_LED_PIN, LOW); + } +} + +void setup() { + // initialize the digital pin as an output: + pinMode(BOARD_LED_PIN, OUTPUT); + + xTaskCreate(vLEDFlashTask, + (signed portCHAR *)"Task1", + configMINIMAL_STACK_SIZE, + NULL, + tskIDLE_PRIORITY + 2, + NULL); + vTaskStartScheduler(); +} + +void loop() { + // Insert background code here +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/fsmc-stress-test.cpp b/Libmaple/libmaple/examples/fsmc-stress-test.cpp index 5b98f1ae..509a02fa 100644 --- a/Libmaple/libmaple/examples/fsmc-stress-test.cpp +++ b/Libmaple/libmaple/examples/fsmc-stress-test.cpp @@ -1,229 +1,229 @@ -/* - - A low-level stress test of SRAM functionality. Uses slow-ish timing - by default (DATAST = ADDSET = 0xF). - - Copyright 2011 LeafLabs, LLC. - - This code is released into the public domain. - - */ - -#include -#include - -#include "wirish.h" -#include "rcc.h" -#include "fsmc.h" - -// -- SRAM config ------------------------------------------------------------- - -// Timing configuration -#define DATAST 0xF -#define ADDSET 0xF - -// Number of SRAM chips to test -#define N 1 - -// How much of each to test -#define MEM_SIZE 0x3FFF - -// Their start addresses in FSMC bank 1 -__io uint16 *const starts[N] = { - // (__io uint16 *const)FSMC_NOR_PSRAM_REGION1, - // (__io uint16 *const)FSMC_NOR_PSRAM_REGION2, - (__io uint16 *const)FSMC_NOR_PSRAM_REGION3, - // (__io uint16 *const)FSMC_NOR_PSRAM_REGION4, -}; - -// Corresponding FSMC configuration registers -__io uint32 *const bcrs[N] = { - // &FSMC_NOR_PSRAM1_BASE->BCR, - // &FSMC_NOR_PSRAM2_BASE->BCR, - &FSMC_NOR_PSRAM3_BASE->BCR, - // &FSMC_NOR_PSRAM4_BASE->BCR, -}; - -// Corresponding FSMC timing registers -__io uint32 *const btrs[N] = { - // &FSMC_NOR_PSRAM1_BASE->BTR, - // &FSMC_NOR_PSRAM2_BASE->BTR, - &FSMC_NOR_PSRAM3_BASE->BTR, - // &FSMC_NOR_PSRAM4_BASE->BTR, -}; - -// -- Pseudorandom number generation ----------------------------------------- - -const uint32 seed = 0xDEADBEEF; - -uint32 num_rand_calls = 0; - -uint32 rand(long n) { - num_rand_calls++; - return random(n); -} - -// -- Printing ---------------------------------------------------------------- - -// For snprintf() -char snprintf_buf[200]; - -#define ERR(fmt, ...) do { \ - snprintf(snprintf_buf, sizeof snprintf_buf, \ - "ERROR: " fmt " (seed %d, ncalls %d, line %d)", \ - __VA_ARGS__, seed, num_rand_calls, __LINE__); \ - SerialUSB.println(snprintf_buf); \ - } while (0) - -// Set to 1 for more output -#define VERBOSE 0 - -// -- setup()/loop() ---------------------------------------------------------- - -void setup() { - fsmc_sram_init_gpios(); - rcc_clk_enable(RCC_FSMC); - - for (int i = 0; i < N; i++) { - *bcrs[i] = (FSMC_BCR_WREN | - FSMC_BCR_MTYP_SRAM | - FSMC_BCR_MWID_16BITS | - FSMC_BCR_MBKEN); - *btrs[i] = (DATAST << 8) | ADDSET; - } - - randomSeed(seed); - - SerialUSB.read(); - SerialUSB.println("Starting test"); -} - -// stress_test() and simple_roundtrip() are the available test routines -bool stress_test(void); -bool simple_roundtrip(void); - -void loop() { - uint32 last; - - last = millis(); - while (true) { - if (!stress_test()) { - SerialUSB.println("Halting due to error."); - throb(); - } else { - uint32 now = millis(); - if (now - last > 500) { - snprintf(snprintf_buf, sizeof snprintf_buf, - "everything ok so far, timestamp %d ms", now); - SerialUSB.println(snprintf_buf); - last = now; - } - } - } -} - -// -- Test routines ----------------------------------------------------------- - -bool random_trips(); -bool sequential_trips(); - -bool stress_test(void) { - static int i = 0; - i = !i; - - switch (i) { - case 0: - return random_trips(); - default: - return sequential_trips(); - } -} - -bool simple_roundtrip(void) { - uint16 wval = 0xAB; - - for (int i = 0; i < N; i++) { - __io uint16 *addr = starts[i] + 4; - snprintf(snprintf_buf, sizeof snprintf_buf, "round-trip 0x%x at %p", - wval, addr); - SerialUSB.println(snprintf_buf); - - *addr = wval; - uint16 rval = *addr; - - if (rval != wval) { - ERR("wrote 0x%x, read 0x%x, timestamp %d", wval, rval, millis()); - return false; - } else { - snprintf(snprintf_buf, sizeof snprintf_buf, "got back 0x%x", rval); - SerialUSB.println(snprintf_buf); - } - } - - return true; -} - -bool random_trips(void) { -#if VERBOSE - SerialUSB.println("[random]"); -#endif - for (int n = 0; n < N; n++) { - __io uint16 *const start = starts[n]; - - for (int i = 0; i < 1000; i++) { - uint32 offset = rand(MEM_SIZE); - uint32 wval = rand(0xFFFF); - - *(start + offset) = wval; - uint32 rval = *(start + offset); - - if (rval != wval) { - ERR("wrote 0x%x to 0x%x, read 0x%x", wval, offset, rval); - return false; - } - } - } - return true; -} - -bool sequential_trips(void) { - static const uint32 seq_length = 300; -#if VERBOSE - SerialUSB.println("[seq]"); -#endif - for (int n = 0; n < N; n++) { - __io uint16 *const start = starts[n]; - - for (int i = 0; i < 100; i++) { - uint32 start_offset = rand(MEM_SIZE - seq_length); - - for (uint32 w = 0; w < seq_length; w++) { - uint32 offset = start_offset + w; - - *(start + offset) = w; - uint32 r = *(start + offset); - - if (w != r) { - ERR("wrote 0x%x to 0x%x, read 0x%x", w, offset, r); - return false; - } - } - } - } - return true; -} - -// ---------------------------------------------------------------------------- - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - while (true) { - loop(); - } - return 0; -} - +/* + + A low-level stress test of SRAM functionality. Uses slow-ish timing + by default (DATAST = ADDSET = 0xF). + + Copyright 2011 LeafLabs, LLC. + + This code is released into the public domain. + + */ + +#include +#include + +#include "wirish.h" +#include "rcc.h" +#include "fsmc.h" + +// -- SRAM config ------------------------------------------------------------- + +// Timing configuration +#define DATAST 0xF +#define ADDSET 0xF + +// Number of SRAM chips to test +#define N 1 + +// How much of each to test +#define MEM_SIZE 0x3FFF + +// Their start addresses in FSMC bank 1 +__io uint16 *const starts[N] = { + // (__io uint16 *const)FSMC_NOR_PSRAM_REGION1, + // (__io uint16 *const)FSMC_NOR_PSRAM_REGION2, + (__io uint16 *const)FSMC_NOR_PSRAM_REGION3, + // (__io uint16 *const)FSMC_NOR_PSRAM_REGION4, +}; + +// Corresponding FSMC configuration registers +__io uint32 *const bcrs[N] = { + // &FSMC_NOR_PSRAM1_BASE->BCR, + // &FSMC_NOR_PSRAM2_BASE->BCR, + &FSMC_NOR_PSRAM3_BASE->BCR, + // &FSMC_NOR_PSRAM4_BASE->BCR, +}; + +// Corresponding FSMC timing registers +__io uint32 *const btrs[N] = { + // &FSMC_NOR_PSRAM1_BASE->BTR, + // &FSMC_NOR_PSRAM2_BASE->BTR, + &FSMC_NOR_PSRAM3_BASE->BTR, + // &FSMC_NOR_PSRAM4_BASE->BTR, +}; + +// -- Pseudorandom number generation ----------------------------------------- + +const uint32 seed = 0xDEADBEEF; + +uint32 num_rand_calls = 0; + +uint32 rand(long n) { + num_rand_calls++; + return random(n); +} + +// -- Printing ---------------------------------------------------------------- + +// For snprintf() +char snprintf_buf[200]; + +#define ERR(fmt, ...) do { \ + snprintf(snprintf_buf, sizeof snprintf_buf, \ + "ERROR: " fmt " (seed %d, ncalls %d, line %d)", \ + __VA_ARGS__, seed, num_rand_calls, __LINE__); \ + SerialUSB.println(snprintf_buf); \ + } while (0) + +// Set to 1 for more output +#define VERBOSE 0 + +// -- setup()/loop() ---------------------------------------------------------- + +void setup() { + fsmc_sram_init_gpios(); + rcc_clk_enable(RCC_FSMC); + + for (int i = 0; i < N; i++) { + *bcrs[i] = (FSMC_BCR_WREN | + FSMC_BCR_MTYP_SRAM | + FSMC_BCR_MWID_16BITS | + FSMC_BCR_MBKEN); + *btrs[i] = (DATAST << 8) | ADDSET; + } + + randomSeed(seed); + + SerialUSB.read(); + SerialUSB.println("Starting test"); +} + +// stress_test() and simple_roundtrip() are the available test routines +bool stress_test(void); +bool simple_roundtrip(void); + +void loop() { + uint32 last; + + last = millis(); + while (true) { + if (!stress_test()) { + SerialUSB.println("Halting due to error."); + throb(); + } else { + uint32 now = millis(); + if (now - last > 500) { + snprintf(snprintf_buf, sizeof snprintf_buf, + "everything ok so far, timestamp %d ms", now); + SerialUSB.println(snprintf_buf); + last = now; + } + } + } +} + +// -- Test routines ----------------------------------------------------------- + +bool random_trips(); +bool sequential_trips(); + +bool stress_test(void) { + static int i = 0; + i = !i; + + switch (i) { + case 0: + return random_trips(); + default: + return sequential_trips(); + } +} + +bool simple_roundtrip(void) { + uint16 wval = 0xAB; + + for (int i = 0; i < N; i++) { + __io uint16 *addr = starts[i] + 4; + snprintf(snprintf_buf, sizeof snprintf_buf, "round-trip 0x%x at %p", + wval, addr); + SerialUSB.println(snprintf_buf); + + *addr = wval; + uint16 rval = *addr; + + if (rval != wval) { + ERR("wrote 0x%x, read 0x%x, timestamp %d", wval, rval, millis()); + return false; + } else { + snprintf(snprintf_buf, sizeof snprintf_buf, "got back 0x%x", rval); + SerialUSB.println(snprintf_buf); + } + } + + return true; +} + +bool random_trips(void) { +#if VERBOSE + SerialUSB.println("[random]"); +#endif + for (int n = 0; n < N; n++) { + __io uint16 *const start = starts[n]; + + for (int i = 0; i < 1000; i++) { + uint32 offset = rand(MEM_SIZE); + uint32 wval = rand(0xFFFF); + + *(start + offset) = wval; + uint32 rval = *(start + offset); + + if (rval != wval) { + ERR("wrote 0x%x to 0x%x, read 0x%x", wval, offset, rval); + return false; + } + } + } + return true; +} + +bool sequential_trips(void) { + static const uint32 seq_length = 300; +#if VERBOSE + SerialUSB.println("[seq]"); +#endif + for (int n = 0; n < N; n++) { + __io uint16 *const start = starts[n]; + + for (int i = 0; i < 100; i++) { + uint32 start_offset = rand(MEM_SIZE - seq_length); + + for (uint32 w = 0; w < seq_length; w++) { + uint32 offset = start_offset + w; + + *(start + offset) = w; + uint32 r = *(start + offset); + + if (w != r) { + ERR("wrote 0x%x to 0x%x, read 0x%x", w, offset, r); + return false; + } + } + } + } + return true; +} + +// ---------------------------------------------------------------------------- + +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + while (true) { + loop(); + } + return 0; +} + diff --git a/Libmaple/libmaple/examples/mini-exti-test.cpp b/Libmaple/libmaple/examples/mini-exti-test.cpp index baaaf22b..84b323ef 100644 --- a/Libmaple/libmaple/examples/mini-exti-test.cpp +++ b/Libmaple/libmaple/examples/mini-exti-test.cpp @@ -1,251 +1,251 @@ -/* - * EXTI test (Maple Mini only). - * - * Setup: For i from 0 to N_EXTI-1 (see below), connect exti_pins[i] - * to src_pins[i]. Connect via SerialUSB and press a key to perform a - * test run. In the printed results For each EXTI within a test run, - * the number triggered should match the number handled. - */ - -#include -#include - -#include "wirish.h" - -// test routines -void run_exti_test(void); -void print_test_results(void); - -// -- State ------------------------------------------------------------------- - -// Test using EXTI lines 0 -- (N_EXTI - 1). -#define N_EXTI 6 - -// src_pins[i] determines the line level for EXTI i. these *must* be -// in GPIOA. if you want to change them, make sure they don't -// conflict with exti_pins[]. -// -// src_pins[0] = D5 = PA6 -// src_pins[1] = D4 = PA7 -// src_pins[2] = D27 = PA8 -// src_pins[3] = D26 = PA9 -// src_pins[4] = D25 = PA10 -// src_pins[5] = D22 = PA13 -#define SRC0 5 -#define SRC0_BIT BIT(6) -#define SRC1 4 -#define SRC1_BIT BIT(7) -#define SRC2 27 -#define SRC2_BIT BIT(8) -#define SRC3 26 -#define SRC3_BIT BIT(9) -#define SRC4 25 -#define SRC4_BIT BIT(10) -#define SRC5 22 -#define SRC5_BIT BIT(13) -// Setting a bit in GPIOA_SRC_MSK means that the given src pin will -// actually trigger interrupts. Useful for experimenting. -#define GPIOA_SRC_MSK \ - (SRC0_BIT | SRC1_BIT | SRC2_BIT | SRC3_BIT | SRC4_BIT | SRC5_BIT) -const int src_pins[N_EXTI] = { - SRC0, - SRC1, - SRC2, - SRC3, - SRC4, - SRC5, -}; -const int src_gpioa_msks[N_EXTI] = { - SRC0_BIT, - SRC1_BIT, - SRC2_BIT, - SRC3_BIT, - SRC4_BIT, - SRC5_BIT, -}; - -// exti_pins[i] <-> EXTI line i. make sure these don't conflict with -// src_pins. -const int exti_pins[N_EXTI] = { - D3, // PB0 - D10, // PA1 - D2, // PB2 - D19, // PB3 - D7, // PA4 - D6, // PA5 -}; - -// EXTI handlers -void exti_0_handler(void); -void exti_1_handler(void); -void exti_2_handler(void); -void exti_3_handler(void); -void exti_4_handler(void); -void exti_5_handler(void); -voidFuncPtr exti_handlers[N_EXTI] = { - exti_0_handler, - exti_1_handler, - exti_2_handler, - exti_3_handler, - exti_4_handler, - exti_5_handler, -}; - -// index i = number of times we've triggered EXTI line n -static uint32 n_triggered[N_EXTI]; - -// index i = number of times we've handled EXTI line n -volatile static uint32 n_handled[N_EXTI]; - -// -- setup() ----------------------------------------------------------------- - -void setup(void) { - // Set up pin modes and get line levels stable - for (int i = 0; i < N_EXTI; i++) { - pinMode(src_pins[i], OUTPUT); - digitalWrite(src_pins[i], LOW); - pinMode(exti_pins[i], INPUT); - } - - // Delay to ensure src_pins are all LOW before proceeding - delay(1); - - // Attach interrupts - for (int i = 0; i < N_EXTI; i++) { - attachInterrupt(exti_pins[i], exti_handlers[i], RISING); - } -} - -// -- loop() ------------------------------------------------------------------ - -void loop(void) { - // Wait for user to send a byte before starting - while (!SerialUSB.available()) - ; - while (SerialUSB.available()) { - SerialUSB.read(); - } - - // Run the test, print the results - run_exti_test(); - print_test_results(); - - // Clear out the triggered/handled state - for (int i = 0; i < N_EXTI; i++) { - n_triggered[i] = 0; - n_handled[i] = 0; - } - - SerialUSB.println(); - SerialUSB.println(); - SerialUSB.println(); -} - -// -- Test routines ----------------------------------------------------------- - -#define N_RUNS 100 -void run_exti_test(void) { - for (int run = 0; run < N_RUNS; run++) { - // Trigger EXTIs simultaneously - GPIOA_BASE->BSRR = GPIOA_SRC_MSK; - - // Reset line levels - GPIOA_BASE->BSRR = GPIOA_SRC_MSK << 16; - - // Update number of times triggered - for (int i = 0; i < N_EXTI; i++) { - if (GPIOA_SRC_MSK & src_gpioa_msks[i]) { - n_triggered[i]++; - } - } - } -} - -// string handling boilerplate -void resetl(void); -void appendl(const char str[]); -void appendl(uint32 n); -void printl(void); - -void print_test_results(void) { - SerialUSB.println("Results:"); - - resetl(); - appendl("EXTI"); - appendl("# Triggered"); - appendl("# Handled"); - printl(); - resetl(); - - for (uint32 i = 0; i < N_EXTI; i++) { - appendl(i); - appendl(n_triggered[i]); - appendl(n_handled[i]); - printl(); - resetl(); - } -} - -// -- EXTI handlers ----------------------------------------------------------- - -void exti_0_handler(void) { - n_handled[0]++; -} - -void exti_1_handler(void) { - n_handled[1]++; -} - -void exti_2_handler(void) { - n_handled[2]++; -} - -void exti_3_handler(void) { - n_handled[3]++; -} - -void exti_4_handler(void) { - n_handled[4]++; -} - -void exti_5_handler(void) { - n_handled[5]++; -} - -// -- String handling --------------------------------------------------------- - -#define C_SIZ 20 -#define LIN_SIZ 80 -char l[LIN_SIZ + 1]; -char tmp[C_SIZ + 1]; - -void resetl(void) { - l[0] = '\0'; -} - -void appendl(const char str[]) { - snprintf(tmp, C_SIZ, "%-*s", C_SIZ, str); - strncat(l, tmp, LIN_SIZ - strlen(tmp)); -} - -void appendl(uint32 n) { - snprintf(tmp, C_SIZ, "%-*u", C_SIZ, n); - strncat(l, tmp, LIN_SIZ - strlen(tmp)); -} - -void printl(void) { - SerialUSB.println(l); -} - -// -- init()/main() ----------------------------------------------------------- - -__attribute__((constructor)) void premain() { init(); } - -int main(void) { - setup(); - - while (true) - loop(); - - return 0; -} +/* + * EXTI test (Maple Mini only). + * + * Setup: For i from 0 to N_EXTI-1 (see below), connect exti_pins[i] + * to src_pins[i]. Connect via SerialUSB and press a key to perform a + * test run. In the printed results For each EXTI within a test run, + * the number triggered should match the number handled. + */ + +#include +#include + +#include "wirish.h" + +// test routines +void run_exti_test(void); +void print_test_results(void); + +// -- State ------------------------------------------------------------------- + +// Test using EXTI lines 0 -- (N_EXTI - 1). +#define N_EXTI 6 + +// src_pins[i] determines the line level for EXTI i. these *must* be +// in GPIOA. if you want to change them, make sure they don't +// conflict with exti_pins[]. +// +// src_pins[0] = D5 = PA6 +// src_pins[1] = D4 = PA7 +// src_pins[2] = D27 = PA8 +// src_pins[3] = D26 = PA9 +// src_pins[4] = D25 = PA10 +// src_pins[5] = D22 = PA13 +#define SRC0 5 +#define SRC0_BIT BIT(6) +#define SRC1 4 +#define SRC1_BIT BIT(7) +#define SRC2 27 +#define SRC2_BIT BIT(8) +#define SRC3 26 +#define SRC3_BIT BIT(9) +#define SRC4 25 +#define SRC4_BIT BIT(10) +#define SRC5 22 +#define SRC5_BIT BIT(13) +// Setting a bit in GPIOA_SRC_MSK means that the given src pin will +// actually trigger interrupts. Useful for experimenting. +#define GPIOA_SRC_MSK \ + (SRC0_BIT | SRC1_BIT | SRC2_BIT | SRC3_BIT | SRC4_BIT | SRC5_BIT) +const int src_pins[N_EXTI] = { + SRC0, + SRC1, + SRC2, + SRC3, + SRC4, + SRC5, +}; +const int src_gpioa_msks[N_EXTI] = { + SRC0_BIT, + SRC1_BIT, + SRC2_BIT, + SRC3_BIT, + SRC4_BIT, + SRC5_BIT, +}; + +// exti_pins[i] <-> EXTI line i. make sure these don't conflict with +// src_pins. +const int exti_pins[N_EXTI] = { + D3, // PB0 + D10, // PA1 + D2, // PB2 + D19, // PB3 + D7, // PA4 + D6, // PA5 +}; + +// EXTI handlers +void exti_0_handler(void); +void exti_1_handler(void); +void exti_2_handler(void); +void exti_3_handler(void); +void exti_4_handler(void); +void exti_5_handler(void); +voidFuncPtr exti_handlers[N_EXTI] = { + exti_0_handler, + exti_1_handler, + exti_2_handler, + exti_3_handler, + exti_4_handler, + exti_5_handler, +}; + +// index i = number of times we've triggered EXTI line n +static uint32 n_triggered[N_EXTI]; + +// index i = number of times we've handled EXTI line n +volatile static uint32 n_handled[N_EXTI]; + +// -- setup() ----------------------------------------------------------------- + +void setup(void) { + // Set up pin modes and get line levels stable + for (int i = 0; i < N_EXTI; i++) { + pinMode(src_pins[i], OUTPUT); + digitalWrite(src_pins[i], LOW); + pinMode(exti_pins[i], INPUT); + } + + // Delay to ensure src_pins are all LOW before proceeding + delay(1); + + // Attach interrupts + for (int i = 0; i < N_EXTI; i++) { + attachInterrupt(exti_pins[i], exti_handlers[i], RISING); + } +} + +// -- loop() ------------------------------------------------------------------ + +void loop(void) { + // Wait for user to send a byte before starting + while (!SerialUSB.available()) + ; + while (SerialUSB.available()) { + SerialUSB.read(); + } + + // Run the test, print the results + run_exti_test(); + print_test_results(); + + // Clear out the triggered/handled state + for (int i = 0; i < N_EXTI; i++) { + n_triggered[i] = 0; + n_handled[i] = 0; + } + + SerialUSB.println(); + SerialUSB.println(); + SerialUSB.println(); +} + +// -- Test routines ----------------------------------------------------------- + +#define N_RUNS 100 +void run_exti_test(void) { + for (int run = 0; run < N_RUNS; run++) { + // Trigger EXTIs simultaneously + GPIOA_BASE->BSRR = GPIOA_SRC_MSK; + + // Reset line levels + GPIOA_BASE->BSRR = GPIOA_SRC_MSK << 16; + + // Update number of times triggered + for (int i = 0; i < N_EXTI; i++) { + if (GPIOA_SRC_MSK & src_gpioa_msks[i]) { + n_triggered[i]++; + } + } + } +} + +// string handling boilerplate +void resetl(void); +void appendl(const char str[]); +void appendl(uint32 n); +void printl(void); + +void print_test_results(void) { + SerialUSB.println("Results:"); + + resetl(); + appendl("EXTI"); + appendl("# Triggered"); + appendl("# Handled"); + printl(); + resetl(); + + for (uint32 i = 0; i < N_EXTI; i++) { + appendl(i); + appendl(n_triggered[i]); + appendl(n_handled[i]); + printl(); + resetl(); + } +} + +// -- EXTI handlers ----------------------------------------------------------- + +void exti_0_handler(void) { + n_handled[0]++; +} + +void exti_1_handler(void) { + n_handled[1]++; +} + +void exti_2_handler(void) { + n_handled[2]++; +} + +void exti_3_handler(void) { + n_handled[3]++; +} + +void exti_4_handler(void) { + n_handled[4]++; +} + +void exti_5_handler(void) { + n_handled[5]++; +} + +// -- String handling --------------------------------------------------------- + +#define C_SIZ 20 +#define LIN_SIZ 80 +char l[LIN_SIZ + 1]; +char tmp[C_SIZ + 1]; + +void resetl(void) { + l[0] = '\0'; +} + +void appendl(const char str[]) { + snprintf(tmp, C_SIZ, "%-*s", C_SIZ, str); + strncat(l, tmp, LIN_SIZ - strlen(tmp)); +} + +void appendl(uint32 n) { + snprintf(tmp, C_SIZ, "%-*u", C_SIZ, n); + strncat(l, tmp, LIN_SIZ - strlen(tmp)); +} + +void printl(void) { + SerialUSB.println(l); +} + +// -- init()/main() ----------------------------------------------------------- + +__attribute__((constructor)) void premain() { init(); } + +int main(void) { + setup(); + + while (true) + loop(); + + return 0; +} diff --git a/Libmaple/libmaple/examples/qa-slave-shield.cpp b/Libmaple/libmaple/examples/qa-slave-shield.cpp index c4242050..2da1c04d 100644 --- a/Libmaple/libmaple/examples/qa-slave-shield.cpp +++ b/Libmaple/libmaple/examples/qa-slave-shield.cpp @@ -1,66 +1,66 @@ -// Slave mode for Quality Assurance test - -#include "wirish.h" - -#define INTER_TOGGLE_DELAY_NORMAL 5 -#define INTER_TOGGLE_DELAY_SLOW 80 - -void interToggleDelay(void); - -void setup() { - pinMode(BOARD_LED_PIN, OUTPUT); - pinMode(BOARD_BUTTON_PIN, INPUT); - - // All unused pins start out low. - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(i, OUTPUT); - digitalWrite(i, LOW); - } - SerialUSB.println("OK, starting..."); -} - -void loop() { - toggleLED(); - delay(100); - toggleLED(); - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - - // Bring just this pin high. - digitalWrite(i, HIGH); - // Give the master time to detect if any other pins also went high. - interToggleDelay(); - // Bring this pin back low again; all pins should now be low. - digitalWrite(i, LOW); - // Give the master time to detect if any pins are still high. - interToggleDelay(); - } -} - -void interToggleDelay(void) { - if (digitalRead(BOARD_BUTTON_PIN)) { // don't pay the debouncing time - delay(INTER_TOGGLE_DELAY_SLOW); - } else { - delay(INTER_TOGGLE_DELAY_NORMAL); - } - } - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} - +// Slave mode for Quality Assurance test + +#include "wirish.h" + +#define INTER_TOGGLE_DELAY_NORMAL 5 +#define INTER_TOGGLE_DELAY_SLOW 80 + +void interToggleDelay(void); + +void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); + pinMode(BOARD_BUTTON_PIN, INPUT); + + // All unused pins start out low. + for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) + continue; + pinMode(i, OUTPUT); + digitalWrite(i, LOW); + } + SerialUSB.println("OK, starting..."); +} + +void loop() { + toggleLED(); + delay(100); + toggleLED(); + + for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) + continue; + + // Bring just this pin high. + digitalWrite(i, HIGH); + // Give the master time to detect if any other pins also went high. + interToggleDelay(); + // Bring this pin back low again; all pins should now be low. + digitalWrite(i, LOW); + // Give the master time to detect if any pins are still high. + interToggleDelay(); + } +} + +void interToggleDelay(void) { + if (digitalRead(BOARD_BUTTON_PIN)) { // don't pay the debouncing time + delay(INTER_TOGGLE_DELAY_SLOW); + } else { + delay(INTER_TOGGLE_DELAY_NORMAL); + } + } + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} + diff --git a/Libmaple/libmaple/examples/spi_master.cpp b/Libmaple/libmaple/examples/spi_master.cpp index af3e709c..100fc53f 100644 --- a/Libmaple/libmaple/examples/spi_master.cpp +++ b/Libmaple/libmaple/examples/spi_master.cpp @@ -1,77 +1,77 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief Sample main.cpp file. Sends "Hello world!" out SPI1. - * - * SPI1 is set up to be a master transmitter at 4.5MHz, little - * endianness, and SPI mode 0. - * - * Pin 10 is used as slave select. - */ - -#include "wirish.h" - -#define NSS 10 - -byte buf[] = "Hello world!"; - -HardwareSPI spi1(1); - -void setup() { - /* Set up chip select as output */ - pinMode(NSS, OUTPUT); - - /* NSS is usually active LOW, so initialize it HIGH */ - digitalWrite(NSS, HIGH); - - /* Initialize SPI */ - spi1.begin(SPI_4_5MHZ, LSBFIRST, 0); -} - -void loop() { - /* Send message */ - digitalWrite(NSS, LOW); - spi1.write(buf, sizeof buf); - digitalWrite(NSS, HIGH); - delay(1000); -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief Sample main.cpp file. Sends "Hello world!" out SPI1. + * + * SPI1 is set up to be a master transmitter at 4.5MHz, little + * endianness, and SPI mode 0. + * + * Pin 10 is used as slave select. + */ + +#include "wirish.h" + +#define NSS 10 + +byte buf[] = "Hello world!"; + +HardwareSPI spi1(1); + +void setup() { + /* Set up chip select as output */ + pinMode(NSS, OUTPUT); + + /* NSS is usually active LOW, so initialize it HIGH */ + digitalWrite(NSS, HIGH); + + /* Initialize SPI */ + spi1.begin(SPI_4_5MHZ, LSBFIRST, 0); +} + +void loop() { + /* Send message */ + digitalWrite(NSS, LOW); + spi1.write(buf, sizeof buf); + digitalWrite(NSS, HIGH); + delay(1000); +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} + diff --git a/Libmaple/libmaple/examples/test-bkp.cpp b/Libmaple/libmaple/examples/test-bkp.cpp index ce032ff5..f5957b71 100644 --- a/Libmaple/libmaple/examples/test-bkp.cpp +++ b/Libmaple/libmaple/examples/test-bkp.cpp @@ -1,80 +1,80 @@ -#include // for snprintf() - -#include "wirish.h" -#include "bkp.h" -#include "iwdg.h" - -void print_bkp_contents(); -void write_to_bkp(uint16 val); - -#define comm Serial2 - -void setup() { - pinMode(BOARD_BUTTON_PIN, INPUT); - - comm.begin(9600); - comm.println("*** Beginning BKP test"); - - comm.println("Init..."); - bkp_init(); - comm.println("Done."); - - print_bkp_contents(); - write_to_bkp(10); - print_bkp_contents(); - - comm.println("Enabling backup writes."); - bkp_enable_writes(); - write_to_bkp(20); - print_bkp_contents(); - - comm.println("Disabling backup writes."); - bkp_disable_writes(); - write_to_bkp(30); - print_bkp_contents(); - - comm.println("Done testing backup registers; press button to enable " - "independent watchdog (in order to cause a reset)."); - waitForButtonPress(0); - iwdg_init(IWDG_PRE_4, 1); - comm.println(); -} - -void loop() { -} - -void print_bkp_contents() { - comm.println("Backup data register contents:"); - char buf[100]; - for (int i = 1; i <= BKP_NR_DATA_REGS; i++) { - snprintf(buf, sizeof buf, "DR%d: %d ", i, bkp_read(i)); - comm.print(buf); - if (i % 5 == 0) comm.println(); - } - comm.println(); -} - -void write_to_bkp(uint16 val) { - comm.print("Attempting to write "); - comm.print(val); - comm.println(" to backup registers..."); - for (int i = 1; i <= BKP_NR_DATA_REGS; i++) { - bkp_write(i, val); - } - comm.println("Done."); -} - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - init(); - setup(); - - while (1) { - loop(); - } - return 0; -} - +#include // for snprintf() + +#include "wirish.h" +#include "bkp.h" +#include "iwdg.h" + +void print_bkp_contents(); +void write_to_bkp(uint16 val); + +#define comm Serial2 + +void setup() { + pinMode(BOARD_BUTTON_PIN, INPUT); + + comm.begin(9600); + comm.println("*** Beginning BKP test"); + + comm.println("Init..."); + bkp_init(); + comm.println("Done."); + + print_bkp_contents(); + write_to_bkp(10); + print_bkp_contents(); + + comm.println("Enabling backup writes."); + bkp_enable_writes(); + write_to_bkp(20); + print_bkp_contents(); + + comm.println("Disabling backup writes."); + bkp_disable_writes(); + write_to_bkp(30); + print_bkp_contents(); + + comm.println("Done testing backup registers; press button to enable " + "independent watchdog (in order to cause a reset)."); + waitForButtonPress(0); + iwdg_init(IWDG_PRE_4, 1); + comm.println(); +} + +void loop() { +} + +void print_bkp_contents() { + comm.println("Backup data register contents:"); + char buf[100]; + for (int i = 1; i <= BKP_NR_DATA_REGS; i++) { + snprintf(buf, sizeof buf, "DR%d: %d ", i, bkp_read(i)); + comm.print(buf); + if (i % 5 == 0) comm.println(); + } + comm.println(); +} + +void write_to_bkp(uint16 val) { + comm.print("Attempting to write "); + comm.print(val); + comm.println(" to backup registers..."); + for (int i = 1; i <= BKP_NR_DATA_REGS; i++) { + bkp_write(i, val); + } + comm.println("Done."); +} + +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + init(); + setup(); + + while (1) { + loop(); + } + return 0; +} + diff --git a/Libmaple/libmaple/examples/test-dac.cpp b/Libmaple/libmaple/examples/test-dac.cpp index 4d8de9d5..40ae5d5f 100644 --- a/Libmaple/libmaple/examples/test-dac.cpp +++ b/Libmaple/libmaple/examples/test-dac.cpp @@ -1,51 +1,51 @@ -/* - * Simple DAC test. - * - * Author: Marti Bolivar - * - * This file is released into the public domain. - */ - -#include "wirish.h" -#include "dac.h" - -uint16 count = 0; - -void setup() { - pinMode(BOARD_LED_PIN, OUTPUT); - digitalWrite(BOARD_LED_PIN, HIGH); - - Serial1.begin(9600); - Serial1.println("**** Beginning DAC test"); - - Serial1.print("Init... "); - dac_init(DAC, DAC_CH1 | DAC_CH2); - Serial1.println("Done."); -} - -void loop() { - toggleLED(); - delay(100); - - count += 100; - if (count > 4095) { - count = 0; - } - - dac_write_channel(DAC, 1, 4095 - count); - dac_write_channel(DAC, 2, count); -} - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} - +/* + * Simple DAC test. + * + * Author: Marti Bolivar + * + * This file is released into the public domain. + */ + +#include "wirish.h" +#include "dac.h" + +uint16 count = 0; + +void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); + digitalWrite(BOARD_LED_PIN, HIGH); + + Serial1.begin(9600); + Serial1.println("**** Beginning DAC test"); + + Serial1.print("Init... "); + dac_init(DAC, DAC_CH1 | DAC_CH2); + Serial1.println("Done."); +} + +void loop() { + toggleLED(); + delay(100); + + count += 100; + if (count > 4095) { + count = 0; + } + + dac_write_channel(DAC, 1, 4095 - count); + dac_write_channel(DAC, 2, count); +} + +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} + diff --git a/Libmaple/libmaple/examples/test-fsmc.cpp b/Libmaple/libmaple/examples/test-fsmc.cpp index 03efd35a..9102be69 100644 --- a/Libmaple/libmaple/examples/test-fsmc.cpp +++ b/Libmaple/libmaple/examples/test-fsmc.cpp @@ -1,126 +1,126 @@ -#include // for ptrdiff_t - -#include "wirish.h" -#include "fsmc.h" - -#ifndef BOARD_maple_native -#error "Sorry, this example only works on Maple Native." -#endif - -// Start of FSMC SRAM bank 1 -static uint16 *const sram_start = (uint16*)0x60000000; -// End of Maple Native SRAM chip address space (512K 16-bit words) -static uint16 *const sram_end = (uint16*)0x60100000; - -void test_single_write(void); -void test_all_addresses(void); - -void setup() { - pinMode(BOARD_LED_PIN, OUTPUT); - digitalWrite(BOARD_LED_PIN, HIGH); - - Serial1.begin(115200); - Serial1.println("*** Beginning RAM chip test"); - - test_single_write(); - test_all_addresses(); - - Serial1.println("Tests pass, finished."); - Serial1.println("***\n"); -} - -void loop() { -} - -void test_single_write() { - uint16 *ptr = sram_start; - uint16 tmp; - - Serial1.print("Writing 0x1234... "); - *ptr = 0x1234; - Serial1.println("Done."); - - Serial1.print("Reading... "); - tmp = *ptr; - Serial1.print("Done: 0x"); - Serial1.println(tmp, HEX); - - if (tmp != 0x1234) { - Serial1.println("Mismatch; abort."); - ASSERT(0); - } -} - -void test_all_addresses() { - uint32 start, end; - uint16 count = 0; - uint16 *ptr; - - Serial1.println("Now writing all memory addresses (unrolled loop)"); - // Turn off the USB interrupt, as it interferes most with timing - // (don't turn off SysTick, or we won't get micros()). - SerialUSB.end(); - start = micros(); - for (ptr = sram_start; ptr < sram_end;) { - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - } - end = micros(); - SerialUSB.begin(); - Serial1.print("Done. Elapsed time (us): "); - Serial1.println(end - start); - - Serial1.println("Validating writes."); - for (ptr = sram_start, count = 0; ptr < sram_end; ptr++, count++) { - uint16 value = *ptr; - if (value != count) { - Serial1.print("mismatch: 0x"); - Serial1.print((uint32)ptr); - Serial1.print(" = 0x"); - Serial1.print(value, HEX); - Serial1.print(", should be 0x"); - Serial1.print(count, HEX); - Serial1.println("."); - ASSERT(0); - } - } - Serial1.println("Done; all writes seem valid."); - - ptrdiff_t nwrites = sram_end - sram_start; - double us_per_write = double(end-start) / double(nwrites); - Serial1.print("Number of writes = "); - Serial1.print(nwrites); - Serial1.print("; avg. time per write = "); - Serial1.print(us_per_write); - Serial1.print(" us ("); - Serial1.print(1 / us_per_write); - Serial1.println(" MHz)"); -} - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - - return 0; -} +#include // for ptrdiff_t + +#include "wirish.h" +#include "fsmc.h" + +#ifndef BOARD_maple_native +#error "Sorry, this example only works on Maple Native." +#endif + +// Start of FSMC SRAM bank 1 +static uint16 *const sram_start = (uint16*)0x60000000; +// End of Maple Native SRAM chip address space (512K 16-bit words) +static uint16 *const sram_end = (uint16*)0x60100000; + +void test_single_write(void); +void test_all_addresses(void); + +void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); + digitalWrite(BOARD_LED_PIN, HIGH); + + Serial1.begin(115200); + Serial1.println("*** Beginning RAM chip test"); + + test_single_write(); + test_all_addresses(); + + Serial1.println("Tests pass, finished."); + Serial1.println("***\n"); +} + +void loop() { +} + +void test_single_write() { + uint16 *ptr = sram_start; + uint16 tmp; + + Serial1.print("Writing 0x1234... "); + *ptr = 0x1234; + Serial1.println("Done."); + + Serial1.print("Reading... "); + tmp = *ptr; + Serial1.print("Done: 0x"); + Serial1.println(tmp, HEX); + + if (tmp != 0x1234) { + Serial1.println("Mismatch; abort."); + ASSERT(0); + } +} + +void test_all_addresses() { + uint32 start, end; + uint16 count = 0; + uint16 *ptr; + + Serial1.println("Now writing all memory addresses (unrolled loop)"); + // Turn off the USB interrupt, as it interferes most with timing + // (don't turn off SysTick, or we won't get micros()). + SerialUSB.end(); + start = micros(); + for (ptr = sram_start; ptr < sram_end;) { + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + *ptr++ = count++; + } + end = micros(); + SerialUSB.begin(); + Serial1.print("Done. Elapsed time (us): "); + Serial1.println(end - start); + + Serial1.println("Validating writes."); + for (ptr = sram_start, count = 0; ptr < sram_end; ptr++, count++) { + uint16 value = *ptr; + if (value != count) { + Serial1.print("mismatch: 0x"); + Serial1.print((uint32)ptr); + Serial1.print(" = 0x"); + Serial1.print(value, HEX); + Serial1.print(", should be 0x"); + Serial1.print(count, HEX); + Serial1.println("."); + ASSERT(0); + } + } + Serial1.println("Done; all writes seem valid."); + + ptrdiff_t nwrites = sram_end - sram_start; + double us_per_write = double(end-start) / double(nwrites); + Serial1.print("Number of writes = "); + Serial1.print(nwrites); + Serial1.print("; avg. time per write = "); + Serial1.print(us_per_write); + Serial1.print(" us ("); + Serial1.print(1 / us_per_write); + Serial1.println(" MHz)"); +} + +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + + return 0; +} diff --git a/Libmaple/libmaple/examples/test-print.cpp b/Libmaple/libmaple/examples/test-print.cpp index 34250a93..5477512a 100644 --- a/Libmaple/libmaple/examples/test-print.cpp +++ b/Libmaple/libmaple/examples/test-print.cpp @@ -1,184 +1,184 @@ -/* - * print-test.cpp - * - * Tests the various Print methods. (For USBSerial; assuming that - * writing a single character works, this should generalize to - * HardwareSerial). - * - * This file is released into the public domain. - */ - -#include "wirish.h" -#undef min -#undef max - -// For snprintf() -#include -// The that comes with newlib is missing LLONG_MAX, etc. -#include - -using namespace std; - -#define BUF_SIZE 100 -char buf[BUF_SIZE]; - -void test_numbers(void); -void test_base_arithmetic(void); -void test_floating_point(void); - -void print_separator(void); - -void setup() { - while (!SerialUSB.available()) - continue; - SerialUSB.read(); -} - -void loop() { - SerialUSB.println("Testing Print methods."); - print_separator(); - - test_numbers(); - print_separator(); - - test_base_arithmetic(); - print_separator(); - - test_floating_point(); - print_separator(); - - SerialUSB.println("Test finished."); - while (true) { - continue; - } -} - -void test_numbers(void) { - SerialUSB.println("Numeric types:"); - - SerialUSB.print("unsigned char: "); - // prevent Print from treating it as an (extended) ASCII character: - SerialUSB.println((uint32)numeric_limits::max()); - - SerialUSB.print("int: "); - SerialUSB.print(numeric_limits::min()); - SerialUSB.print(" -- "); - SerialUSB.println(numeric_limits::max()); - - SerialUSB.print("unsigned int: "); - SerialUSB.print(numeric_limits::max()); - SerialUSB.println(); - - SerialUSB.print("long: "); - SerialUSB.print(numeric_limits::min()); - SerialUSB.print(" -- "); - SerialUSB.println(numeric_limits::max()); - - SerialUSB.print("long long: "); - SerialUSB.print(numeric_limits::min()); - SerialUSB.print(" -- "); - SerialUSB.println(numeric_limits::max()); - - SerialUSB.print("unsigned long long: "); - SerialUSB.println(numeric_limits::max()); -} - -void base_test(int base) { - SerialUSB.print("\tuint8: "); - SerialUSB.println(numeric_limits::max(), base); - SerialUSB.print("\tint: "); - SerialUSB.print(numeric_limits::max(), base); - SerialUSB.print(", unsigned int: "); - SerialUSB.println(numeric_limits::max(), base); - SerialUSB.print("\tlong: "); - SerialUSB.print(numeric_limits::max(), base); - SerialUSB.print(", unsigned long: "); - SerialUSB.println(numeric_limits::max(), base); - SerialUSB.print("\tlong long: "); - SerialUSB.print(numeric_limits::max(), base); - SerialUSB.print(", unsigned long long: "); - SerialUSB.println(numeric_limits::max(), base); -} - -void test_base_arithmetic(void) { - SerialUSB.println("Base arithmetic:"); - - SerialUSB.println("Binary:"); - base_test(BIN); - - SerialUSB.println("Octal:"); - base_test(OCT); - - SerialUSB.println("Decimal:"); - base_test(DEC); - - SerialUSB.println("Hexadecimal:"); - base_test(HEX); -} - -void test_floating_point(void) { - double dmax = numeric_limits::max(); - - SerialUSB.println("Floating point:"); - - SerialUSB.print("println(-5.67): "); - SerialUSB.print(-5.67); - SerialUSB.print(". println(5.67, 5): "); - SerialUSB.println(5.67, 5); - SerialUSB.print("println((double)(LLONG_MAX - 10)): "); - SerialUSB.print((double)(numeric_limits::max() - 10)); - SerialUSB.print("; from snprintf(): "); - snprintf(buf, BUF_SIZE, "%.2f", - (double)(numeric_limits::max() - 10)); - SerialUSB.println(buf); - SerialUSB.print("println((double)LLONG_MAX / 2): "); - SerialUSB.print((double)(numeric_limits::max()) / 2); - SerialUSB.print("; from snprintf(): "); - snprintf(buf, BUF_SIZE, "%.2f", - (double)(numeric_limits::max()) / 2); - SerialUSB.println(buf); - SerialUSB.print("DBL_MAX: "); - SerialUSB.print(dmax); - SerialUSB.print("; from snprintf(): "); - snprintf(buf, BUF_SIZE, "%g", dmax); - SerialUSB.println(buf); - SerialUSB.print("-DBL_MAX / 2: "); - SerialUSB.print(-dmax / 2.0); - SerialUSB.print("; from snprintf(): "); - snprintf(buf, BUF_SIZE, "%g", -dmax / 2.0); - SerialUSB.println(buf); - SerialUSB.print("Double epsilon, round error: "); - SerialUSB.print(numeric_limits::epsilon()); - SerialUSB.print(", "); - SerialUSB.println(numeric_limits::round_error()); - - SerialUSB.println(); - - float fmax = numeric_limits::max(); - - SerialUSB.print("println(-5.67f): "); - SerialUSB.println(-5.67f); - SerialUSB.print("Float max: "); - SerialUSB.println(fmax); -} - -void print_separator(void) { - SerialUSB.println(); - SerialUSB.println(" ** "); - SerialUSB.println(); -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (1) { - loop(); - } - return 0; -} +/* + * print-test.cpp + * + * Tests the various Print methods. (For USBSerial; assuming that + * writing a single character works, this should generalize to + * HardwareSerial). + * + * This file is released into the public domain. + */ + +#include "wirish.h" +#undef min +#undef max + +// For snprintf() +#include +// The that comes with newlib is missing LLONG_MAX, etc. +#include + +using namespace std; + +#define BUF_SIZE 100 +char buf[BUF_SIZE]; + +void test_numbers(void); +void test_base_arithmetic(void); +void test_floating_point(void); + +void print_separator(void); + +void setup() { + while (!SerialUSB.available()) + continue; + SerialUSB.read(); +} + +void loop() { + SerialUSB.println("Testing Print methods."); + print_separator(); + + test_numbers(); + print_separator(); + + test_base_arithmetic(); + print_separator(); + + test_floating_point(); + print_separator(); + + SerialUSB.println("Test finished."); + while (true) { + continue; + } +} + +void test_numbers(void) { + SerialUSB.println("Numeric types:"); + + SerialUSB.print("unsigned char: "); + // prevent Print from treating it as an (extended) ASCII character: + SerialUSB.println((uint32)numeric_limits::max()); + + SerialUSB.print("int: "); + SerialUSB.print(numeric_limits::min()); + SerialUSB.print(" -- "); + SerialUSB.println(numeric_limits::max()); + + SerialUSB.print("unsigned int: "); + SerialUSB.print(numeric_limits::max()); + SerialUSB.println(); + + SerialUSB.print("long: "); + SerialUSB.print(numeric_limits::min()); + SerialUSB.print(" -- "); + SerialUSB.println(numeric_limits::max()); + + SerialUSB.print("long long: "); + SerialUSB.print(numeric_limits::min()); + SerialUSB.print(" -- "); + SerialUSB.println(numeric_limits::max()); + + SerialUSB.print("unsigned long long: "); + SerialUSB.println(numeric_limits::max()); +} + +void base_test(int base) { + SerialUSB.print("\tuint8: "); + SerialUSB.println(numeric_limits::max(), base); + SerialUSB.print("\tint: "); + SerialUSB.print(numeric_limits::max(), base); + SerialUSB.print(", unsigned int: "); + SerialUSB.println(numeric_limits::max(), base); + SerialUSB.print("\tlong: "); + SerialUSB.print(numeric_limits::max(), base); + SerialUSB.print(", unsigned long: "); + SerialUSB.println(numeric_limits::max(), base); + SerialUSB.print("\tlong long: "); + SerialUSB.print(numeric_limits::max(), base); + SerialUSB.print(", unsigned long long: "); + SerialUSB.println(numeric_limits::max(), base); +} + +void test_base_arithmetic(void) { + SerialUSB.println("Base arithmetic:"); + + SerialUSB.println("Binary:"); + base_test(BIN); + + SerialUSB.println("Octal:"); + base_test(OCT); + + SerialUSB.println("Decimal:"); + base_test(DEC); + + SerialUSB.println("Hexadecimal:"); + base_test(HEX); +} + +void test_floating_point(void) { + double dmax = numeric_limits::max(); + + SerialUSB.println("Floating point:"); + + SerialUSB.print("println(-5.67): "); + SerialUSB.print(-5.67); + SerialUSB.print(". println(5.67, 5): "); + SerialUSB.println(5.67, 5); + SerialUSB.print("println((double)(LLONG_MAX - 10)): "); + SerialUSB.print((double)(numeric_limits::max() - 10)); + SerialUSB.print("; from snprintf(): "); + snprintf(buf, BUF_SIZE, "%.2f", + (double)(numeric_limits::max() - 10)); + SerialUSB.println(buf); + SerialUSB.print("println((double)LLONG_MAX / 2): "); + SerialUSB.print((double)(numeric_limits::max()) / 2); + SerialUSB.print("; from snprintf(): "); + snprintf(buf, BUF_SIZE, "%.2f", + (double)(numeric_limits::max()) / 2); + SerialUSB.println(buf); + SerialUSB.print("DBL_MAX: "); + SerialUSB.print(dmax); + SerialUSB.print("; from snprintf(): "); + snprintf(buf, BUF_SIZE, "%g", dmax); + SerialUSB.println(buf); + SerialUSB.print("-DBL_MAX / 2: "); + SerialUSB.print(-dmax / 2.0); + SerialUSB.print("; from snprintf(): "); + snprintf(buf, BUF_SIZE, "%g", -dmax / 2.0); + SerialUSB.println(buf); + SerialUSB.print("Double epsilon, round error: "); + SerialUSB.print(numeric_limits::epsilon()); + SerialUSB.print(", "); + SerialUSB.println(numeric_limits::round_error()); + + SerialUSB.println(); + + float fmax = numeric_limits::max(); + + SerialUSB.print("println(-5.67f): "); + SerialUSB.println(-5.67f); + SerialUSB.print("Float max: "); + SerialUSB.println(fmax); +} + +void print_separator(void) { + SerialUSB.println(); + SerialUSB.println(" ** "); + SerialUSB.println(); +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (1) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/test-ring-buffer-insertion.cpp b/Libmaple/libmaple/examples/test-ring-buffer-insertion.cpp index 11bbbfe3..e86372af 100644 --- a/Libmaple/libmaple/examples/test-ring-buffer-insertion.cpp +++ b/Libmaple/libmaple/examples/test-ring-buffer-insertion.cpp @@ -1,114 +1,114 @@ -/* - * Simple ring_buffer test. - * - * Does a basic test of functionality on rb_full_count(), rb_reset(), - * rb_push_insert(), and rb_safe_insert(). - * - * To test: - * - * - Connect a serial monitor to SerialUSB - * - Press any key - * - * This file is released into the public domain. - */ - -#include "wirish.h" - -#include "ring_buffer.h" - -#define BUF_SIZE 64 -ring_buffer ring_buf; -ring_buffer *rb; -uint8 rb_buffer[BUF_SIZE]; - -void test_rb_push_insert(int num_bytes_to_insert); -void test_rb_safe_insert(int num_bytes_to_insert); -void test_rb_insertion_function(int num_bytes_to_insert, - int (*insertion_fn)(ring_buffer*, uint8), - const char insertion_fn_name[]); -void print_rb_contents(void); - -void setup() { - rb = &ring_buf; - rb_init(rb, BUF_SIZE, rb_buffer); - - while (!SerialUSB.available()) - ; - - SerialUSB.println("Beginning test."); - SerialUSB.println(); -} - -void loop() { - test_rb_push_insert(63); - SerialUSB.println("------------------------------"); - test_rb_push_insert(64); - SerialUSB.println("------------------------------"); - test_rb_safe_insert(63); - SerialUSB.println("------------------------------"); - test_rb_safe_insert(64); - SerialUSB.println("------------------------------"); - - SerialUSB.println(); - SerialUSB.println("Test finished."); - while (true) - ; -} - -void test_rb_push_insert(int num_bytes_to_insert) { - test_rb_insertion_function(num_bytes_to_insert, - rb_push_insert, - "rb_push_insert()"); -} - -void test_rb_safe_insert(int num_bytes_to_insert) { - test_rb_insertion_function(num_bytes_to_insert, - rb_safe_insert, - "rb_safe_insert()"); -} - -void test_rb_insertion_function(int num_bytes_to_insert, - int (*insertion_fn)(ring_buffer *, uint8), - const char insertion_fn_name[]) { - SerialUSB.println("resetting ring buffer."); - rb_reset(rb); - print_rb_contents(); - - SerialUSB.print(insertion_fn_name); - SerialUSB.print("-ing "); - SerialUSB.print(num_bytes_to_insert); - SerialUSB.println(" bytes."); - for (uint8 i = 1; i <= num_bytes_to_insert; i++) - insertion_fn(rb, i); - - uint16 count = rb_full_count(rb); - SerialUSB.print("rb_full_count(rb) = "); - SerialUSB.println(count); - - print_rb_contents(); -} - -void print_rb_contents() { - uint16 count = rb_full_count(rb); - SerialUSB.print("ring buffer contents: "); - for (uint16 i = 0; i < count; i++) { - SerialUSB.print((int)rb_remove(rb)); - if (i < count - 1) SerialUSB.print(", "); - } - SerialUSB.println(); -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +/* + * Simple ring_buffer test. + * + * Does a basic test of functionality on rb_full_count(), rb_reset(), + * rb_push_insert(), and rb_safe_insert(). + * + * To test: + * + * - Connect a serial monitor to SerialUSB + * - Press any key + * + * This file is released into the public domain. + */ + +#include "wirish.h" + +#include "ring_buffer.h" + +#define BUF_SIZE 64 +ring_buffer ring_buf; +ring_buffer *rb; +uint8 rb_buffer[BUF_SIZE]; + +void test_rb_push_insert(int num_bytes_to_insert); +void test_rb_safe_insert(int num_bytes_to_insert); +void test_rb_insertion_function(int num_bytes_to_insert, + int (*insertion_fn)(ring_buffer*, uint8), + const char insertion_fn_name[]); +void print_rb_contents(void); + +void setup() { + rb = &ring_buf; + rb_init(rb, BUF_SIZE, rb_buffer); + + while (!SerialUSB.available()) + ; + + SerialUSB.println("Beginning test."); + SerialUSB.println(); +} + +void loop() { + test_rb_push_insert(63); + SerialUSB.println("------------------------------"); + test_rb_push_insert(64); + SerialUSB.println("------------------------------"); + test_rb_safe_insert(63); + SerialUSB.println("------------------------------"); + test_rb_safe_insert(64); + SerialUSB.println("------------------------------"); + + SerialUSB.println(); + SerialUSB.println("Test finished."); + while (true) + ; +} + +void test_rb_push_insert(int num_bytes_to_insert) { + test_rb_insertion_function(num_bytes_to_insert, + rb_push_insert, + "rb_push_insert()"); +} + +void test_rb_safe_insert(int num_bytes_to_insert) { + test_rb_insertion_function(num_bytes_to_insert, + rb_safe_insert, + "rb_safe_insert()"); +} + +void test_rb_insertion_function(int num_bytes_to_insert, + int (*insertion_fn)(ring_buffer *, uint8), + const char insertion_fn_name[]) { + SerialUSB.println("resetting ring buffer."); + rb_reset(rb); + print_rb_contents(); + + SerialUSB.print(insertion_fn_name); + SerialUSB.print("-ing "); + SerialUSB.print(num_bytes_to_insert); + SerialUSB.println(" bytes."); + for (uint8 i = 1; i <= num_bytes_to_insert; i++) + insertion_fn(rb, i); + + uint16 count = rb_full_count(rb); + SerialUSB.print("rb_full_count(rb) = "); + SerialUSB.println(count); + + print_rb_contents(); +} + +void print_rb_contents() { + uint16 count = rb_full_count(rb); + SerialUSB.print("ring buffer contents: "); + for (uint16 i = 0; i < count; i++) { + SerialUSB.print((int)rb_remove(rb)); + if (i < count - 1) SerialUSB.print(", "); + } + SerialUSB.println(); +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/test-serial-flush.cpp b/Libmaple/libmaple/examples/test-serial-flush.cpp index 65e2ccc3..adc9c3ee 100644 --- a/Libmaple/libmaple/examples/test-serial-flush.cpp +++ b/Libmaple/libmaple/examples/test-serial-flush.cpp @@ -1,38 +1,38 @@ -/* - * Tests the "flush" Serial function. - */ - -#include "wirish.h" - -void setup() { - Serial1.begin(9600); - Serial1.println("Hello world!"); -} - -void loop() { - Serial1.println("Waiting for multiple input..."); - while (Serial1.available() < 5) - ; - Serial1.println(Serial1.read()); - Serial1.println(Serial1.read()); - Serial1.flush(); - - if (Serial1.available()) { - Serial1.println("FAIL! Still had junk in the buffer..."); - } -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +/* + * Tests the "flush" Serial function. + */ + +#include "wirish.h" + +void setup() { + Serial1.begin(9600); + Serial1.println("Hello world!"); +} + +void loop() { + Serial1.println("Waiting for multiple input..."); + while (Serial1.available() < 5) + ; + Serial1.println(Serial1.read()); + Serial1.println(Serial1.read()); + Serial1.flush(); + + if (Serial1.available()) { + Serial1.println("FAIL! Still had junk in the buffer..."); + } +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/test-serialusb.cpp b/Libmaple/libmaple/examples/test-serialusb.cpp index 8b5106af..15ab9135 100644 --- a/Libmaple/libmaple/examples/test-serialusb.cpp +++ b/Libmaple/libmaple/examples/test-serialusb.cpp @@ -1,126 +1,126 @@ -// Tests SerialUSB functionality. - -#include "wirish.h" -#include "usb.h" - -#define QUICKPRINT 0 -#define BIGSTUFF 1 -#define NUMBERS 2 -#define SIMPLE 3 -#define ONOFF 4 - -uint32 state = 0; - -void setup() { - /* Set up the LED to blink */ - pinMode(BOARD_LED_PIN, OUTPUT); - - /* Set up Serial2 for use as a debug channel */ - Serial2.begin(9600); - Serial2.println("This is the debug channel. Press any key."); - while (!Serial2.available()) - ; - Serial2.read(); -} - -uint8 c1 = '-'; - -void loop() { - toggleLED(); - delay(1000); - - if (Serial2.available()) { - Serial2.read(); - state++; - } - - switch (state) { - case QUICKPRINT: - for (int i = 0; i < 30; i++) { - usbSendBytes(&c1, 1); - SerialUSB.print('.'); - SerialUSB.print('|'); - } - Serial2.println(SerialUSB.pending(), DEC); - SerialUSB.println(); - break; - case BIGSTUFF: - SerialUSB.println("0123456789012345678901234567890123456789" - "0123456789012345678901234567890123456789" - "012345678901234567890"); - SerialUSB.println((int64)123456789, DEC); - SerialUSB.println(3.1415926535); - Serial2.println(SerialUSB.pending(), DEC); - break; - case NUMBERS: - SerialUSB.println("Numbers! -----------------------------"); - Serial2.println("Numbers! -----------------------------"); - SerialUSB.println('1'); - Serial2.println('1'); - SerialUSB.println(1, DEC); - Serial2.println(1, DEC); - SerialUSB.println(-1, DEC); - Serial2.println(-1, DEC); - SerialUSB.println(3.14159265); - Serial2.println(3.14159265); - SerialUSB.println(123456789, DEC); - Serial2.println(123456789, DEC); - SerialUSB.println(-123456789, DEC); - Serial2.println(-123456789, DEC); - SerialUSB.println(65535, HEX); - Serial2.println(65535, HEX); - break; - case SIMPLE: - Serial2.println("Trying write('a')"); - SerialUSB.write('a'); - Serial2.println("Trying write(\"b\")"); - SerialUSB.write("b"); - Serial2.println("Trying print('c')"); - SerialUSB.print('c'); - Serial2.println("Trying print(\"d\")"); - SerialUSB.print("d"); - Serial2.println("Trying print(\"efg\")"); - SerialUSB.print("efg"); - Serial2.println("Trying println(\"hij\\n\\r\")"); - SerialUSB.print("hij\n\r"); - SerialUSB.write(' '); - SerialUSB.println(); - Serial2.println("Trying println(123456789, DEC)"); - SerialUSB.println(123456789, DEC); - Serial2.println("Trying println(3.141592)"); - SerialUSB.println(3.141592); - Serial2.println("Trying println(\"DONE\")"); - SerialUSB.println("DONE"); - break; - case ONOFF: - Serial2.println("Shutting down..."); - SerialUSB.println("Shutting down..."); - SerialUSB.end(); - Serial2.println("Waiting 4 seconds..."); - delay(4000); - Serial2.println("Starting up..."); - SerialUSB.begin(); - SerialUSB.println("Hello World!"); - Serial2.println("Waiting 4 seconds..."); - delay(4000); - state++; - break; - default: - state = 0; - } -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +// Tests SerialUSB functionality. + +#include "wirish.h" +#include "usb.h" + +#define QUICKPRINT 0 +#define BIGSTUFF 1 +#define NUMBERS 2 +#define SIMPLE 3 +#define ONOFF 4 + +uint32 state = 0; + +void setup() { + /* Set up the LED to blink */ + pinMode(BOARD_LED_PIN, OUTPUT); + + /* Set up Serial2 for use as a debug channel */ + Serial2.begin(9600); + Serial2.println("This is the debug channel. Press any key."); + while (!Serial2.available()) + ; + Serial2.read(); +} + +uint8 c1 = '-'; + +void loop() { + toggleLED(); + delay(1000); + + if (Serial2.available()) { + Serial2.read(); + state++; + } + + switch (state) { + case QUICKPRINT: + for (int i = 0; i < 30; i++) { + usbSendBytes(&c1, 1); + SerialUSB.print('.'); + SerialUSB.print('|'); + } + Serial2.println(SerialUSB.pending(), DEC); + SerialUSB.println(); + break; + case BIGSTUFF: + SerialUSB.println("0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "012345678901234567890"); + SerialUSB.println((int64)123456789, DEC); + SerialUSB.println(3.1415926535); + Serial2.println(SerialUSB.pending(), DEC); + break; + case NUMBERS: + SerialUSB.println("Numbers! -----------------------------"); + Serial2.println("Numbers! -----------------------------"); + SerialUSB.println('1'); + Serial2.println('1'); + SerialUSB.println(1, DEC); + Serial2.println(1, DEC); + SerialUSB.println(-1, DEC); + Serial2.println(-1, DEC); + SerialUSB.println(3.14159265); + Serial2.println(3.14159265); + SerialUSB.println(123456789, DEC); + Serial2.println(123456789, DEC); + SerialUSB.println(-123456789, DEC); + Serial2.println(-123456789, DEC); + SerialUSB.println(65535, HEX); + Serial2.println(65535, HEX); + break; + case SIMPLE: + Serial2.println("Trying write('a')"); + SerialUSB.write('a'); + Serial2.println("Trying write(\"b\")"); + SerialUSB.write("b"); + Serial2.println("Trying print('c')"); + SerialUSB.print('c'); + Serial2.println("Trying print(\"d\")"); + SerialUSB.print("d"); + Serial2.println("Trying print(\"efg\")"); + SerialUSB.print("efg"); + Serial2.println("Trying println(\"hij\\n\\r\")"); + SerialUSB.print("hij\n\r"); + SerialUSB.write(' '); + SerialUSB.println(); + Serial2.println("Trying println(123456789, DEC)"); + SerialUSB.println(123456789, DEC); + Serial2.println("Trying println(3.141592)"); + SerialUSB.println(3.141592); + Serial2.println("Trying println(\"DONE\")"); + SerialUSB.println("DONE"); + break; + case ONOFF: + Serial2.println("Shutting down..."); + SerialUSB.println("Shutting down..."); + SerialUSB.end(); + Serial2.println("Waiting 4 seconds..."); + delay(4000); + Serial2.println("Starting up..."); + SerialUSB.begin(); + SerialUSB.println("Hello World!"); + Serial2.println("Waiting 4 seconds..."); + delay(4000); + state++; + break; + default: + state = 0; + } +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/test-servo.cpp b/Libmaple/libmaple/examples/test-servo.cpp index 9b9978e7..b6b8cd5c 100644 --- a/Libmaple/libmaple/examples/test-servo.cpp +++ b/Libmaple/libmaple/examples/test-servo.cpp @@ -1,152 +1,152 @@ -/* - * Basic Servo library test program. - * - * Setup: - * - * - Connect a potentiometer to POT_PIN (default pin 15) - * - Connect an oscilloscope to SERVO_PIN1 (default pin 5) and - * SERVO_PIN2 (default pin 6). - * - Connect a serial monitor to SerialUSB - * - * The potentiometer controls the target angle for each of two Servo - * objects, one with angles in [-90, 90], and another in [0, 180]. - * Servo pulse width range is [1000, 2000]. - * - * Serial2 will tell you what inputs it's giving to each servo object, - * and some information it gets back. Pressing the button - * detaches/reattaches the Servo objects. - * - * Tests you should perform: - * - * - Check calculated pulse widths for each servo's target angle - * - Check that calculated pulse widths match actual pulse widths - * - Check that the period of the pulse train is roughly 20 ms - * - Check that the pulses stop when detached, and resume when reattached - * - Check that Servo::write() and Servo::read() round-trip properly - * - * This file is released into the public domain. - */ - -#include - -#include "wirish.h" - -#include "libraries/Servo/Servo.h" - -#define POT_PIN 15 - -#define MIN_PW 1000 -#define MAX_PW 2000 - -#define SERVO_PIN1 5 -#define MIN_ANGLE1 0 -#define MAX_ANGLE1 180 - -#define SERVO_PIN2 6 -#define MIN_ANGLE2 (-90) -#define MAX_ANGLE2 90 - -Servo servo1; -Servo servo2; - -#define BUF_SIZE 100 -char buf[BUF_SIZE]; - -#define print_buf(fmt, ...) do { \ - snprintf(buf, BUF_SIZE, fmt, __VA_ARGS__); \ - Serial2.println(buf); } while (0) - -int averageAnalogReads(int); -void attach(); -void detach(); - -void setup() { - pinMode(POT_PIN, INPUT_ANALOG); - pinMode(BOARD_BUTTON_PIN, INPUT); - pinMode(BOARD_LED_PIN, OUTPUT); - - Serial2.begin(9600); - - servo1.attach(SERVO_PIN1, MIN_PW, MAX_PW, MIN_ANGLE1, MAX_ANGLE1); - servo2.attach(SERVO_PIN2, MIN_PW, MAX_PW, MIN_ANGLE2, MAX_ANGLE2); - - ASSERT(servo1.attachedPin() == SERVO_PIN1); - ASSERT(servo2.attachedPin() == SERVO_PIN2); -} - -void loop() { - delay(250); - toggleLED(); - - if (isButtonPressed()) { - if (servo1.attached()) detach(); - else attach(); - } - - if (!servo1.attached()) return; - - int32 average = averageAnalogReads(250); - int16 angle1 = (int16)map(average, 0, 4095, MIN_ANGLE1, MAX_ANGLE1); - int16 angle2 = (int16)map(average, 0, 4095, MIN_ANGLE2, MAX_ANGLE2); - - print_buf("pot reading = %d, angle 1 = %d, angle 2 = %d.", - average, angle1, angle2); - - servo1.write(angle1); - servo2.write(angle2); - - int16 read1 = servo1.read(); - int16 read2 = servo2.read(); - - print_buf("write/read angle 1: %d/%d, angle 2: %d/%d", - angle1, read1, angle2, read2); - - ASSERT(abs(angle1 - read1) <= 1); - ASSERT(abs(angle2 - read2) <= 1); - - print_buf("pulse width 1: %d, pulse width 2: %d", - servo1.readMicroseconds(), servo2.readMicroseconds()); - - Serial2.println("\n--------------------------\n"); -} - -int32 averageAnalogReads(int n) { - uint64 total = 0; - - for (int i = 0; i < n; i++) { - total += analogRead(POT_PIN); - } - - return (int32)(total / n); -} - -void attach() { - Serial2.println("attaching"); - servo1.attach(SERVO_PIN1); - servo2.attach(SERVO_PIN2); - ASSERT(servo1.attachedPin() == SERVO_PIN1); - ASSERT(servo2.attachedPin() == SERVO_PIN2); -} - -void detach() { - Serial2.println("detaching"); - servo1.detach(); - servo2.detach(); - ASSERT(!servo1.attached()); - ASSERT(!servo2.attached()); -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +/* + * Basic Servo library test program. + * + * Setup: + * + * - Connect a potentiometer to POT_PIN (default pin 15) + * - Connect an oscilloscope to SERVO_PIN1 (default pin 5) and + * SERVO_PIN2 (default pin 6). + * - Connect a serial monitor to SerialUSB + * + * The potentiometer controls the target angle for each of two Servo + * objects, one with angles in [-90, 90], and another in [0, 180]. + * Servo pulse width range is [1000, 2000]. + * + * Serial2 will tell you what inputs it's giving to each servo object, + * and some information it gets back. Pressing the button + * detaches/reattaches the Servo objects. + * + * Tests you should perform: + * + * - Check calculated pulse widths for each servo's target angle + * - Check that calculated pulse widths match actual pulse widths + * - Check that the period of the pulse train is roughly 20 ms + * - Check that the pulses stop when detached, and resume when reattached + * - Check that Servo::write() and Servo::read() round-trip properly + * + * This file is released into the public domain. + */ + +#include + +#include "wirish.h" + +#include "libraries/Servo/Servo.h" + +#define POT_PIN 15 + +#define MIN_PW 1000 +#define MAX_PW 2000 + +#define SERVO_PIN1 5 +#define MIN_ANGLE1 0 +#define MAX_ANGLE1 180 + +#define SERVO_PIN2 6 +#define MIN_ANGLE2 (-90) +#define MAX_ANGLE2 90 + +Servo servo1; +Servo servo2; + +#define BUF_SIZE 100 +char buf[BUF_SIZE]; + +#define print_buf(fmt, ...) do { \ + snprintf(buf, BUF_SIZE, fmt, __VA_ARGS__); \ + Serial2.println(buf); } while (0) + +int averageAnalogReads(int); +void attach(); +void detach(); + +void setup() { + pinMode(POT_PIN, INPUT_ANALOG); + pinMode(BOARD_BUTTON_PIN, INPUT); + pinMode(BOARD_LED_PIN, OUTPUT); + + Serial2.begin(9600); + + servo1.attach(SERVO_PIN1, MIN_PW, MAX_PW, MIN_ANGLE1, MAX_ANGLE1); + servo2.attach(SERVO_PIN2, MIN_PW, MAX_PW, MIN_ANGLE2, MAX_ANGLE2); + + ASSERT(servo1.attachedPin() == SERVO_PIN1); + ASSERT(servo2.attachedPin() == SERVO_PIN2); +} + +void loop() { + delay(250); + toggleLED(); + + if (isButtonPressed()) { + if (servo1.attached()) detach(); + else attach(); + } + + if (!servo1.attached()) return; + + int32 average = averageAnalogReads(250); + int16 angle1 = (int16)map(average, 0, 4095, MIN_ANGLE1, MAX_ANGLE1); + int16 angle2 = (int16)map(average, 0, 4095, MIN_ANGLE2, MAX_ANGLE2); + + print_buf("pot reading = %d, angle 1 = %d, angle 2 = %d.", + average, angle1, angle2); + + servo1.write(angle1); + servo2.write(angle2); + + int16 read1 = servo1.read(); + int16 read2 = servo2.read(); + + print_buf("write/read angle 1: %d/%d, angle 2: %d/%d", + angle1, read1, angle2, read2); + + ASSERT(abs(angle1 - read1) <= 1); + ASSERT(abs(angle2 - read2) <= 1); + + print_buf("pulse width 1: %d, pulse width 2: %d", + servo1.readMicroseconds(), servo2.readMicroseconds()); + + Serial2.println("\n--------------------------\n"); +} + +int32 averageAnalogReads(int n) { + uint64 total = 0; + + for (int i = 0; i < n; i++) { + total += analogRead(POT_PIN); + } + + return (int32)(total / n); +} + +void attach() { + Serial2.println("attaching"); + servo1.attach(SERVO_PIN1); + servo2.attach(SERVO_PIN2); + ASSERT(servo1.attachedPin() == SERVO_PIN1); + ASSERT(servo2.attachedPin() == SERVO_PIN2); +} + +void detach() { + Serial2.println("detaching"); + servo1.detach(); + servo2.detach(); + ASSERT(!servo1.attached()); + ASSERT(!servo2.attached()); +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/test-session.cpp b/Libmaple/libmaple/examples/test-session.cpp index 489947da..59d8ac0f 100644 --- a/Libmaple/libmaple/examples/test-session.cpp +++ b/Libmaple/libmaple/examples/test-session.cpp @@ -1,925 +1,925 @@ -// Interactive Test Session for LeafLabs Maple -// Copyright (c) 2010 LeafLabs LLC. -// -// Useful for testing Maple features and troubleshooting. -// Communicates over SerialUSB. - -#include "wirish.h" - -// ASCII escape character -#define ESC ((uint8)27) - -// Default USART baud rate -#define BAUD 9600 - -// Number of times to sample a pin per ADC noise measurement -#define N_ADC_NOISE_MEASUREMENTS 40 - -uint8 gpio_state[BOARD_NR_GPIO_PINS]; - -const char* dummy_data = ("qwertyuiopasdfghjklzxcvbnmmmmmm,./1234567890-=" - "qwertyuiopasdfghjklzxcvbnm,./1234567890"); - -// Commands -void cmd_print_help(void); -void cmd_adc_stats(void); -void cmd_stressful_adc_stats(void); -void cmd_everything(void); -void cmd_serial1_serial3(void); -void cmd_serial1_echo(void); -void cmd_gpio_monitoring(void); -void cmd_sequential_adc_reads(void); -void cmd_gpio_qa(void); -void cmd_sequential_gpio_toggling(void); -void cmd_gpio_toggling(void); -void cmd_sequential_debug_gpio_toggling(void); -void cmd_debug_gpio_toggling(void); -void cmd_but_test(void); -void cmd_sequential_pwm_test(void); -void cmd_servo_sweep(void); -void cmd_board_info(void); - -// Helper functions -void measure_adc_noise(uint8 pin); -void fast_gpio(int pin); -void serial_baud_test(HardwareSerial **serials, int n, unsigned baud); -void serial_echo_test(HardwareSerial *serial, unsigned baud); -void init_all_timers(uint16 prescale); -void enable_usarts(void); -void disable_usarts(void); -void print_board_array(const char* msg, const uint8 arr[], int len); - -// -- setup() and loop() ------------------------------------------------------ - -void setup() { - // Set up the LED to blink - pinMode(BOARD_LED_PIN, OUTPUT); - - // Start up the serial ports - Serial1.begin(BAUD); - Serial2.begin(BAUD); - Serial3.begin(BAUD); - - // Send a message out over SerialUSB interface - SerialUSB.println(" "); - SerialUSB.println(" __ __ _ _"); - SerialUSB.println(" | \\/ | __ _ _ __ | | ___| |"); - SerialUSB.println(" | |\\/| |/ _` | '_ \\| |/ _ \\ |"); - SerialUSB.println(" | | | | (_| | |_) | | __/_|"); - SerialUSB.println(" |_| |_|\\__,_| .__/|_|\\___(_)"); - SerialUSB.println(" |_|"); - SerialUSB.println(" by leaflabs"); - SerialUSB.println(""); - SerialUSB.println(""); - SerialUSB.println("Maple interactive test program (type '?' for help)"); - SerialUSB.println("-------------------------------------------------------" - "---"); - SerialUSB.print("> "); - -} - -void loop () { - toggleLED(); - delay(250); - - while (SerialUSB.available()) { - uint8 input = SerialUSB.read(); - SerialUSB.println((char)input); - - switch(input) { - case '\r': - break; - - case ' ': - SerialUSB.println("spacebar, nice!"); - break; - - case '?': - case 'h': - cmd_print_help(); - break; - - case 'u': - SerialUSB.println("Hello World!"); - break; - - case 'w': - Serial1.println("Hello World!"); - Serial2.println("Hello World!"); - Serial3.println("Hello World!"); - break; - - case 'm': - cmd_serial1_serial3(); - break; - - case 'E': - cmd_serial1_echo(); - break; - - case '.': - while (!SerialUSB.available()) { - Serial1.print("."); - Serial2.print("."); - Serial3.print("."); - SerialUSB.print("."); - } - break; - - case 'n': - cmd_adc_stats(); - break; - - case 'N': - cmd_stressful_adc_stats(); - break; - - case 'e': - cmd_everything(); - break; - - case 'W': - while (!SerialUSB.available()) { - Serial1.print(dummy_data); - Serial2.print(dummy_data); - Serial3.print(dummy_data); - } - break; - - case 'U': - SerialUSB.println("Dumping data to USB. Press any key."); - while (!SerialUSB.available()) { - SerialUSB.print(dummy_data); - } - break; - - case 'g': - cmd_sequential_gpio_toggling(); - break; - - case 'G': - cmd_gpio_toggling(); - break; - - case 'j': - cmd_sequential_debug_gpio_toggling(); - break; - - case 'J': - cmd_debug_gpio_toggling(); - break; - - case 'B': - cmd_but_test(); - break; - - case 'f': - SerialUSB.println("Wiggling D4 as fast as possible in bursts. " - "Press any key."); - pinMode(4, OUTPUT); - while (!SerialUSB.available()) { - fast_gpio(4); - delay(1); - } - break; - - case 'p': - cmd_sequential_pwm_test(); - break; - - case '_': - SerialUSB.println("Delaying for 5 seconds..."); - delay(5000); - break; - - // Be sure to update cmd_print_help() if you implement these: - - case 't': // TODO - SerialUSB.println("Unimplemented."); - break; - - case 'T': // TODO - SerialUSB.println("Unimplemented."); - break; - - case 's': - cmd_servo_sweep(); - break; - - case 'd': - SerialUSB.println("Pulling down D4, D22. Press any key."); - pinMode(22, INPUT_PULLDOWN); - pinMode(4, INPUT_PULLDOWN); - SerialUSB.read(); - SerialUSB.println("Pulling up D4, D22. Press any key."); - pinMode(22, INPUT_PULLUP); - pinMode(4, INPUT_PULLUP); - SerialUSB.read(); - pinMode(22, OUTPUT); - pinMode(4, OUTPUT); - break; - - // Be sure to update cmd_print_help() if you implement these: - - case 'i': // TODO - SerialUSB.println("Unimplemented."); - break; - - case 'I': // TODO - SerialUSB.println("Unimplemented."); - break; - - case 'r': - cmd_gpio_monitoring(); - break; - - case 'a': - cmd_sequential_adc_reads(); - break; - - case 'b': - cmd_board_info(); - break; - - case '+': - cmd_gpio_qa(); - break; - - default: // ------------------------------- - SerialUSB.print("Unexpected byte: 0x"); - SerialUSB.print((int)input, HEX); - SerialUSB.println(", press h for help."); - } - - SerialUSB.print("> "); - } -} - -// -- Commands ---------------------------------------------------------------- - -void cmd_print_help(void) { - SerialUSB.println(""); - SerialUSB.println("Command Listing"); - SerialUSB.println("\t?: print this menu"); - SerialUSB.println("\th: print this menu"); - SerialUSB.println("\tw: print Hello World on all 3 USARTS"); - SerialUSB.println("\tn: measure noise and do statistics"); - SerialUSB.println("\tN: measure noise and do statistics with background " - "stuff"); - SerialUSB.println("\ta: show realtime ADC info"); - SerialUSB.println("\t.: echo '.' until new input"); - SerialUSB.println("\tu: print Hello World on USB"); - SerialUSB.println("\t_: do as little as possible for a couple seconds " - "(delay)"); - SerialUSB.println("\tp: test all PWM channels sequentially"); - SerialUSB.println("\tW: dump data as fast as possible on all 3 USARTS"); - SerialUSB.println("\tU: dump data as fast as possible on USB"); - SerialUSB.println("\tg: toggle GPIOs sequentially"); - SerialUSB.println("\tG: toggle GPIOs at the same time"); - SerialUSB.println("\tj: toggle debug port GPIOs sequentially"); - SerialUSB.println("\tJ: toggle debug port GPIOs simultaneously"); - SerialUSB.println("\tB: test the built-in button"); - SerialUSB.println("\tf: toggle pin 4 as fast as possible in bursts"); - SerialUSB.println("\tr: monitor and print GPIO status changes"); - SerialUSB.println("\ts: output a sweeping servo PWM on all PWM channels"); - SerialUSB.println("\tm: output data on USART1 and USART3 at various " - "baud rates"); - SerialUSB.println("\tE: echo data on USART1 at various baud rates"); - SerialUSB.println("\tb: print information about the board."); - SerialUSB.println("\t+: test shield mode (for quality assurance testing)"); - - SerialUSB.println("Unimplemented:"); - SerialUSB.println("\te: do everything all at once until new input"); - SerialUSB.println("\tt: output a 1khz squarewave on all GPIOs"); - SerialUSB.println("\tT: output a 1hz squarewave on all GPIOs"); - SerialUSB.println("\ti: print out a bunch of info about system state"); - SerialUSB.println("\tI: print out status of all headers"); -} - -void cmd_adc_stats(void) { - SerialUSB.println("Taking ADC noise stats. Press ESC to stop, " - "'R' to repeat same pin, anything else for next pin."); - - uint32 i = 0; - while (i < BOARD_NR_ADC_PINS) { - measure_adc_noise(boardADCPins[i]); - - SerialUSB.println("----------"); - uint8 c = SerialUSB.read(); - if (c == ESC) { - break; - } else if (c != 'r' && c != 'R') { - i++; - } - } -} - -void cmd_stressful_adc_stats(void) { - SerialUSB.println("Taking ADC noise stats under duress. Press ESC to " - "stop, 'R' to repeat same pin, anything else for next " - "pin."); - - uint32 i = 0; - while (i < BOARD_NR_ADC_PINS) { - // use PWM to create digital noise - for (uint32 j = 0; j < BOARD_NR_PWM_PINS; j++) { - if (boardADCPins[i] != boardPWMPins[j]) { - pinMode(boardPWMPins[j], PWM); - pwmWrite(boardPWMPins[j], 1000 + i); - } - } - - measure_adc_noise(boardADCPins[i]); - - // turn off the noise - for (uint32 j = 0; j < BOARD_NR_PWM_PINS; j++) { - if (boardADCPins[i] != boardPWMPins[j]) { - pinMode(boardPWMPins[j], OUTPUT); - digitalWrite(boardPWMPins[j], LOW); - } - } - - SerialUSB.println("----------"); - uint8 c = SerialUSB.read(); - if (c == ESC) { - break; - } else if (c != 'r' && c != 'R') { - i++; - } - } -} - -void cmd_everything(void) { // TODO - // Be sure to update cmd_print_help() if you implement this. - - // print to usart - // print to usb - // toggle gpios - // enable pwm - SerialUSB.println("Unimplemented."); -} - -void cmd_serial1_serial3(void) { - HardwareSerial *serial_1_and_3[] = {&Serial1, &Serial3}; - - SerialUSB.println("Testing 57600 baud on USART1 and USART3. " - "Press any key to stop."); - serial_baud_test(serial_1_and_3, 2, 57600); - SerialUSB.read(); - - SerialUSB.println("Testing 115200 baud on USART1 and USART3. " - "Press any key to stop."); - serial_baud_test(serial_1_and_3, 2, 115200); - SerialUSB.read(); - - SerialUSB.println("Testing 9600 baud on USART1 and USART3. " - "Press any key to stop."); - serial_baud_test(serial_1_and_3, 2, 9600); - SerialUSB.read(); - - SerialUSB.println("Resetting USART1 and USART3..."); - Serial1.begin(BAUD); - Serial3.begin(BAUD); -} - -void cmd_serial1_echo(void) { - SerialUSB.println("Testing serial echo at various baud rates. " - "Press any key for next baud rate, or ESC to quit " - "early."); - while (!SerialUSB.available()) - ; - - if (SerialUSB.read() == ESC) return; - SerialUSB.println("Testing 115200 baud on USART1."); - serial_echo_test(&Serial1, 115200); - - if (SerialUSB.read() == ESC) return; - SerialUSB.println("Testing 57600 baud on USART1."); - serial_echo_test(&Serial1, 57600); - - if (SerialUSB.read() == ESC) return; - SerialUSB.println("Testing 9600 baud on USART1."); - serial_echo_test(&Serial1, 9600); -} - -void cmd_gpio_monitoring(void) { - SerialUSB.println("Monitoring pin state changes. Press any key to stop."); - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(i, INPUT_PULLDOWN); - gpio_state[i] = (uint8)digitalRead(i); - } - - while (!SerialUSB.available()) { - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - - uint8 current_state = (uint8)digitalRead(i); - if (current_state != gpio_state[i]) { - SerialUSB.print("State change on pin "); - SerialUSB.print(i, DEC); - if (current_state) { - SerialUSB.println(":\tHIGH"); - } else { - SerialUSB.println(":\tLOW"); - } - gpio_state[i] = current_state; - } - } - } - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(i, OUTPUT); - } -} - -void cmd_sequential_adc_reads(void) { - SerialUSB.print("Sequentially reading most ADC ports."); - SerialUSB.println("Press any key for next port, or ESC to stop."); - - for (uint32 i = 0; i < BOARD_NR_ADC_PINS; i++) { - if (boardUsesPin(boardADCPins[i])) - continue; - - SerialUSB.print("Reading pin "); - SerialUSB.print(boardADCPins[i], DEC); - SerialUSB.println("..."); - pinMode(boardADCPins[i], INPUT_ANALOG); - while (!SerialUSB.available()) { - int sample = analogRead(boardADCPins[i]); - SerialUSB.print(boardADCPins[i], DEC); - SerialUSB.print("\t"); - SerialUSB.print(sample, DEC); - SerialUSB.print("\t"); - SerialUSB.print("|"); - for (int j = 0; j < 4096; j += 100) { - if (sample >= j) { - SerialUSB.print("#"); - } else { - SerialUSB.print(" "); - } - } - SerialUSB.print("| "); - for (int j = 0; j < 12; j++) { - if (sample & (1 << (11 - j))) { - SerialUSB.print("1"); - } else { - SerialUSB.print("0"); - } - } - SerialUSB.println(); - } - pinMode(boardADCPins[i], OUTPUT); - digitalWrite(boardADCPins[i], 0); - if (SerialUSB.read() == ESC) - break; - } -} - -bool test_single_pin_is_high(int high_pin, const char* err_msg) { - bool ok = true; - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) continue; - - if (digitalRead(i) == HIGH && i != high_pin) { - SerialUSB.println(); - SerialUSB.print("\t*** FAILURE! pin "); - SerialUSB.print(i, DEC); - SerialUSB.print(' '); - SerialUSB.println(err_msg); - ok = false; - } - } - return ok; -} - -bool wait_for_low_transition(uint8 pin) { - uint32 start = millis(); - while (millis() - start < 2000) { - if (digitalRead(pin) == LOW) { - return true; - } - } - return false; -} - -void cmd_gpio_qa(void) { - bool all_pins_ok = true; - const int not_a_pin = -1; - SerialUSB.println("Doing QA testing for unused GPIO pins."); - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) continue; - - pinMode(i, INPUT); - } - - SerialUSB.println("Waiting to start."); - ASSERT(!boardUsesPin(0)); - while (digitalRead(0) == LOW) continue; - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) { - SerialUSB.print("Skipping pin "); - SerialUSB.println(i, DEC); - continue; - } - bool pin_ok = true; - SerialUSB.print("Checking pin "); - SerialUSB.print(i, DEC); - while (digitalRead(i) == LOW) continue; - - pin_ok = pin_ok && test_single_pin_is_high(i, "is also HIGH"); - - if (!wait_for_low_transition(i)) { - SerialUSB.println("Transition to low timed out; something is " - "very wrong. Aborting test."); - return; - } - - pin_ok = pin_ok && test_single_pin_is_high(not_a_pin, "is still HIGH"); - - if (pin_ok) { - SerialUSB.println(": ok"); - } - - all_pins_ok = all_pins_ok && pin_ok; - } - - if (all_pins_ok) { - SerialUSB.println("Finished; test passes."); - } else { - SerialUSB.println("**** TEST FAILS *****"); - } - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) continue; - - pinMode(i, OUTPUT); - digitalWrite(i, LOW); - gpio_state[i] = 0; - } -} - -void cmd_sequential_gpio_toggling(void) { - SerialUSB.println("Sequentially toggling all unused pins. " - "Press any key for next pin, ESC to stop."); - - for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - - SerialUSB.print("Toggling pin "); - SerialUSB.print((int)i, DEC); - SerialUSB.println("..."); - - pinMode(i, OUTPUT); - do { - togglePin(i); - } while (!SerialUSB.available()); - - digitalWrite(i, LOW); - if (SerialUSB.read() == ESC) - break; - } -} - -void cmd_gpio_toggling(void) { - SerialUSB.println("Toggling all unused pins simultaneously. " - "Press any key to stop."); - - for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(i, OUTPUT); - } - - while (!SerialUSB.available()) { - for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - togglePin(i); - } - } - - for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - digitalWrite(i, LOW); - } -} - -uint8 debugGPIOPins[] = {BOARD_JTMS_SWDIO_PIN, - BOARD_JTCK_SWCLK_PIN, - BOARD_JTDI_PIN, - BOARD_JTDO_PIN, - BOARD_NJTRST_PIN}; - -#define N_DEBUG_PINS 5 - -void cmd_sequential_debug_gpio_toggling(void) { - SerialUSB.println("Toggling all debug (JTAG/SWD) pins sequentially. " - "This will permanently disable debug port " - "functionality."); - disableDebugPorts(); - - for (int i = 0; i < N_DEBUG_PINS; i++) { - pinMode(debugGPIOPins[i], OUTPUT); - } - - for (int i = 0; i < N_DEBUG_PINS; i++) { - int pin = debugGPIOPins[i]; - SerialUSB.print("Toggling pin "); - SerialUSB.print(pin, DEC); - SerialUSB.println("..."); - - pinMode(pin, OUTPUT); - do { - togglePin(pin); - } while (!SerialUSB.available()); - - digitalWrite(pin, LOW); - if (SerialUSB.read() == ESC) - break; - } - - for (int i = 0; i < N_DEBUG_PINS; i++) { - digitalWrite(debugGPIOPins[i], 0); - } -} - -void cmd_debug_gpio_toggling(void) { - SerialUSB.println("Toggling debug GPIO simultaneously. " - "This will permanently disable JTAG and Serial Wire " - "debug port functionality. " - "Press any key to stop."); - disableDebugPorts(); - - for (uint32 i = 0; i < N_DEBUG_PINS; i++) { - pinMode(debugGPIOPins[i], OUTPUT); - } - - while (!SerialUSB.available()) { - for (uint32 i = 0; i < N_DEBUG_PINS; i++) { - togglePin(debugGPIOPins[i]); - } - } - - for (uint32 i = 0; i < N_DEBUG_PINS; i++) { - digitalWrite(debugGPIOPins[i], LOW); - } -} - -void cmd_but_test(void) { - SerialUSB.println("Press the button to test. Press any key to stop."); - pinMode(BOARD_BUTTON_PIN, INPUT); - - while (!SerialUSB.available()) { - if (isButtonPressed()) { - uint32 tstamp = millis(); - SerialUSB.print("Button press detected, timestamp: "); - SerialUSB.println(tstamp); - } - } - SerialUSB.read(); -} - -void cmd_sequential_pwm_test(void) { - SerialUSB.println("Sequentially testing PWM on all unused pins. " - "Press any key for next pin, ESC to stop."); - - for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { - if (boardUsesPin(i)) - continue; - - SerialUSB.print("PWM out on header D"); - SerialUSB.print(boardPWMPins[i], DEC); - SerialUSB.println("..."); - pinMode(boardPWMPins[i], PWM); - pwmWrite(boardPWMPins[i], 16000); - - while (!SerialUSB.available()) { - delay(10); - } - - pinMode(boardPWMPins[i], OUTPUT); - digitalWrite(boardPWMPins[i], 0); - if (SerialUSB.read() == ESC) - break; - } -} - -void cmd_servo_sweep(void) { - SerialUSB.println("Testing all PWM headers with a servo sweep. " - "Press any key to stop."); - SerialUSB.println(); - - disable_usarts(); - init_all_timers(21); - - for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(boardPWMPins[i], PWM); - pwmWrite(boardPWMPins[i], 4000); - } - - // 1.25ms = 4096counts = 0deg - // 1.50ms = 4915counts = 90deg - // 1.75ms = 5734counts = 180deg - int rate = 4096; - while (!SerialUSB.available()) { - rate += 20; - if (rate > 5734) - rate = 4096; - for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { - if (boardUsesPin(i)) - continue; - pwmWrite(boardPWMPins[i], rate); - } - delay(20); - } - - for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(boardPWMPins[i], OUTPUT); - } - init_all_timers(1); - enable_usarts(); -} - -void cmd_board_info(void) { // TODO print more information - SerialUSB.println("Board information"); - SerialUSB.println("================="); - - SerialUSB.print("* Clock speed (MHz): "); - SerialUSB.println(CYCLES_PER_MICROSECOND); - - SerialUSB.print("* BOARD_LED_PIN: "); - SerialUSB.println(BOARD_LED_PIN); - - SerialUSB.print("* BOARD_BUTTON_PIN: "); - SerialUSB.println(BOARD_BUTTON_PIN); - - SerialUSB.print("* GPIO information (BOARD_NR_GPIO_PINS = "); - SerialUSB.print(BOARD_NR_GPIO_PINS); - SerialUSB.println("):"); - print_board_array("ADC pins", boardADCPins, BOARD_NR_ADC_PINS); - print_board_array("PWM pins", boardPWMPins, BOARD_NR_PWM_PINS); - print_board_array("Used pins", boardUsedPins, BOARD_NR_USED_PINS); -} - -// -- Helper functions -------------------------------------------------------- - -void measure_adc_noise(uint8 pin) { - const int N = 1000; - uint16 x; - float mean = 0; - float delta = 0; - float M2 = 0; - pinMode(pin, INPUT_ANALOG); - - // Variance algorithm from Welford, via Knuth, by way of Wikipedia: - // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm - for (int sample = 0; sample < N_ADC_NOISE_MEASUREMENTS; sample++) { - for (int i = 1; i <= N; i++) { - x = analogRead(pin); - delta = x - mean; - mean += delta / i; - M2 = M2 + delta * (x - mean); - } - SerialUSB.print("header: D"); - SerialUSB.print(pin, DEC); - SerialUSB.print("\tn: "); - SerialUSB.print(N, DEC); - SerialUSB.print("\tmean: "); - SerialUSB.print(mean); - SerialUSB.print("\tvariance: "); - SerialUSB.println(M2 / (float)(N-1)); - } - - pinMode(pin, OUTPUT); -} - -void fast_gpio(int maple_pin) { - gpio_dev *dev = PIN_MAP[maple_pin].gpio_device; - uint32 bit = PIN_MAP[maple_pin].gpio_bit; - - gpio_write_bit(dev, bit, 1); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); -} - -void serial_baud_test(HardwareSerial **serials, int n, unsigned baud) { - for (int i = 0; i < n; i++) { - serials[i]->begin(baud); - } - while (!SerialUSB.available()) { - for (int i = 0; i < n; i++) { - serials[i]->println(dummy_data); - if (serials[i]->available()) { - serials[i]->println(serials[i]->read()); - delay(1000); - } - } - } -} - -void serial_echo_test(HardwareSerial *serial, unsigned baud) { - serial->begin(baud); - while (!SerialUSB.available()) { - if (!serial->available()) - continue; - serial->print(serial->read()); - } -} - -static uint16 init_all_timers_prescale = 0; - -static void set_prescale(timer_dev *dev) { - timer_set_prescaler(dev, init_all_timers_prescale); -} - -void init_all_timers(uint16 prescale) { - init_all_timers_prescale = prescale; - timer_foreach(set_prescale); -} - -void enable_usarts(void) { - Serial1.begin(BAUD); - Serial2.begin(BAUD); - Serial3.begin(BAUD); -#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) - Serial4.begin(BAUD); - Serial5.begin(BAUD); -#endif -} - -void disable_usarts(void) { - Serial1.end(); - Serial2.end(); - Serial3.end(); -#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) - Serial4.end(); - Serial5.end(); -#endif -} - -void print_board_array(const char* msg, const uint8 arr[], int len) { - SerialUSB.print("\t"); - SerialUSB.print(msg); - SerialUSB.print(" ("); - SerialUSB.print(len); - SerialUSB.print("): "); - for (int i = 0; i < len; i++) { - SerialUSB.print(arr[i], DEC); - if (i < len - 1) SerialUSB.print(", "); - } - SerialUSB.println(); -} - -// -- premain() and main() ---------------------------------------------------- - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (1) { - loop(); - } - return 0; -} +// Interactive Test Session for LeafLabs Maple +// Copyright (c) 2010 LeafLabs LLC. +// +// Useful for testing Maple features and troubleshooting. +// Communicates over SerialUSB. + +#include "wirish.h" + +// ASCII escape character +#define ESC ((uint8)27) + +// Default USART baud rate +#define BAUD 9600 + +// Number of times to sample a pin per ADC noise measurement +#define N_ADC_NOISE_MEASUREMENTS 40 + +uint8 gpio_state[BOARD_NR_GPIO_PINS]; + +const char* dummy_data = ("qwertyuiopasdfghjklzxcvbnmmmmmm,./1234567890-=" + "qwertyuiopasdfghjklzxcvbnm,./1234567890"); + +// Commands +void cmd_print_help(void); +void cmd_adc_stats(void); +void cmd_stressful_adc_stats(void); +void cmd_everything(void); +void cmd_serial1_serial3(void); +void cmd_serial1_echo(void); +void cmd_gpio_monitoring(void); +void cmd_sequential_adc_reads(void); +void cmd_gpio_qa(void); +void cmd_sequential_gpio_toggling(void); +void cmd_gpio_toggling(void); +void cmd_sequential_debug_gpio_toggling(void); +void cmd_debug_gpio_toggling(void); +void cmd_but_test(void); +void cmd_sequential_pwm_test(void); +void cmd_servo_sweep(void); +void cmd_board_info(void); + +// Helper functions +void measure_adc_noise(uint8 pin); +void fast_gpio(int pin); +void serial_baud_test(HardwareSerial **serials, int n, unsigned baud); +void serial_echo_test(HardwareSerial *serial, unsigned baud); +void init_all_timers(uint16 prescale); +void enable_usarts(void); +void disable_usarts(void); +void print_board_array(const char* msg, const uint8 arr[], int len); + +// -- setup() and loop() ------------------------------------------------------ + +void setup() { + // Set up the LED to blink + pinMode(BOARD_LED_PIN, OUTPUT); + + // Start up the serial ports + Serial1.begin(BAUD); + Serial2.begin(BAUD); + Serial3.begin(BAUD); + + // Send a message out over SerialUSB interface + SerialUSB.println(" "); + SerialUSB.println(" __ __ _ _"); + SerialUSB.println(" | \\/ | __ _ _ __ | | ___| |"); + SerialUSB.println(" | |\\/| |/ _` | '_ \\| |/ _ \\ |"); + SerialUSB.println(" | | | | (_| | |_) | | __/_|"); + SerialUSB.println(" |_| |_|\\__,_| .__/|_|\\___(_)"); + SerialUSB.println(" |_|"); + SerialUSB.println(" by leaflabs"); + SerialUSB.println(""); + SerialUSB.println(""); + SerialUSB.println("Maple interactive test program (type '?' for help)"); + SerialUSB.println("-------------------------------------------------------" + "---"); + SerialUSB.print("> "); + +} + +void loop () { + toggleLED(); + delay(250); + + while (SerialUSB.available()) { + uint8 input = SerialUSB.read(); + SerialUSB.println((char)input); + + switch(input) { + case '\r': + break; + + case ' ': + SerialUSB.println("spacebar, nice!"); + break; + + case '?': + case 'h': + cmd_print_help(); + break; + + case 'u': + SerialUSB.println("Hello World!"); + break; + + case 'w': + Serial1.println("Hello World!"); + Serial2.println("Hello World!"); + Serial3.println("Hello World!"); + break; + + case 'm': + cmd_serial1_serial3(); + break; + + case 'E': + cmd_serial1_echo(); + break; + + case '.': + while (!SerialUSB.available()) { + Serial1.print("."); + Serial2.print("."); + Serial3.print("."); + SerialUSB.print("."); + } + break; + + case 'n': + cmd_adc_stats(); + break; + + case 'N': + cmd_stressful_adc_stats(); + break; + + case 'e': + cmd_everything(); + break; + + case 'W': + while (!SerialUSB.available()) { + Serial1.print(dummy_data); + Serial2.print(dummy_data); + Serial3.print(dummy_data); + } + break; + + case 'U': + SerialUSB.println("Dumping data to USB. Press any key."); + while (!SerialUSB.available()) { + SerialUSB.print(dummy_data); + } + break; + + case 'g': + cmd_sequential_gpio_toggling(); + break; + + case 'G': + cmd_gpio_toggling(); + break; + + case 'j': + cmd_sequential_debug_gpio_toggling(); + break; + + case 'J': + cmd_debug_gpio_toggling(); + break; + + case 'B': + cmd_but_test(); + break; + + case 'f': + SerialUSB.println("Wiggling D4 as fast as possible in bursts. " + "Press any key."); + pinMode(4, OUTPUT); + while (!SerialUSB.available()) { + fast_gpio(4); + delay(1); + } + break; + + case 'p': + cmd_sequential_pwm_test(); + break; + + case '_': + SerialUSB.println("Delaying for 5 seconds..."); + delay(5000); + break; + + // Be sure to update cmd_print_help() if you implement these: + + case 't': // TODO + SerialUSB.println("Unimplemented."); + break; + + case 'T': // TODO + SerialUSB.println("Unimplemented."); + break; + + case 's': + cmd_servo_sweep(); + break; + + case 'd': + SerialUSB.println("Pulling down D4, D22. Press any key."); + pinMode(22, INPUT_PULLDOWN); + pinMode(4, INPUT_PULLDOWN); + SerialUSB.read(); + SerialUSB.println("Pulling up D4, D22. Press any key."); + pinMode(22, INPUT_PULLUP); + pinMode(4, INPUT_PULLUP); + SerialUSB.read(); + pinMode(22, OUTPUT); + pinMode(4, OUTPUT); + break; + + // Be sure to update cmd_print_help() if you implement these: + + case 'i': // TODO + SerialUSB.println("Unimplemented."); + break; + + case 'I': // TODO + SerialUSB.println("Unimplemented."); + break; + + case 'r': + cmd_gpio_monitoring(); + break; + + case 'a': + cmd_sequential_adc_reads(); + break; + + case 'b': + cmd_board_info(); + break; + + case '+': + cmd_gpio_qa(); + break; + + default: // ------------------------------- + SerialUSB.print("Unexpected byte: 0x"); + SerialUSB.print((int)input, HEX); + SerialUSB.println(", press h for help."); + } + + SerialUSB.print("> "); + } +} + +// -- Commands ---------------------------------------------------------------- + +void cmd_print_help(void) { + SerialUSB.println(""); + SerialUSB.println("Command Listing"); + SerialUSB.println("\t?: print this menu"); + SerialUSB.println("\th: print this menu"); + SerialUSB.println("\tw: print Hello World on all 3 USARTS"); + SerialUSB.println("\tn: measure noise and do statistics"); + SerialUSB.println("\tN: measure noise and do statistics with background " + "stuff"); + SerialUSB.println("\ta: show realtime ADC info"); + SerialUSB.println("\t.: echo '.' until new input"); + SerialUSB.println("\tu: print Hello World on USB"); + SerialUSB.println("\t_: do as little as possible for a couple seconds " + "(delay)"); + SerialUSB.println("\tp: test all PWM channels sequentially"); + SerialUSB.println("\tW: dump data as fast as possible on all 3 USARTS"); + SerialUSB.println("\tU: dump data as fast as possible on USB"); + SerialUSB.println("\tg: toggle GPIOs sequentially"); + SerialUSB.println("\tG: toggle GPIOs at the same time"); + SerialUSB.println("\tj: toggle debug port GPIOs sequentially"); + SerialUSB.println("\tJ: toggle debug port GPIOs simultaneously"); + SerialUSB.println("\tB: test the built-in button"); + SerialUSB.println("\tf: toggle pin 4 as fast as possible in bursts"); + SerialUSB.println("\tr: monitor and print GPIO status changes"); + SerialUSB.println("\ts: output a sweeping servo PWM on all PWM channels"); + SerialUSB.println("\tm: output data on USART1 and USART3 at various " + "baud rates"); + SerialUSB.println("\tE: echo data on USART1 at various baud rates"); + SerialUSB.println("\tb: print information about the board."); + SerialUSB.println("\t+: test shield mode (for quality assurance testing)"); + + SerialUSB.println("Unimplemented:"); + SerialUSB.println("\te: do everything all at once until new input"); + SerialUSB.println("\tt: output a 1khz squarewave on all GPIOs"); + SerialUSB.println("\tT: output a 1hz squarewave on all GPIOs"); + SerialUSB.println("\ti: print out a bunch of info about system state"); + SerialUSB.println("\tI: print out status of all headers"); +} + +void cmd_adc_stats(void) { + SerialUSB.println("Taking ADC noise stats. Press ESC to stop, " + "'R' to repeat same pin, anything else for next pin."); + + uint32 i = 0; + while (i < BOARD_NR_ADC_PINS) { + measure_adc_noise(boardADCPins[i]); + + SerialUSB.println("----------"); + uint8 c = SerialUSB.read(); + if (c == ESC) { + break; + } else if (c != 'r' && c != 'R') { + i++; + } + } +} + +void cmd_stressful_adc_stats(void) { + SerialUSB.println("Taking ADC noise stats under duress. Press ESC to " + "stop, 'R' to repeat same pin, anything else for next " + "pin."); + + uint32 i = 0; + while (i < BOARD_NR_ADC_PINS) { + // use PWM to create digital noise + for (uint32 j = 0; j < BOARD_NR_PWM_PINS; j++) { + if (boardADCPins[i] != boardPWMPins[j]) { + pinMode(boardPWMPins[j], PWM); + pwmWrite(boardPWMPins[j], 1000 + i); + } + } + + measure_adc_noise(boardADCPins[i]); + + // turn off the noise + for (uint32 j = 0; j < BOARD_NR_PWM_PINS; j++) { + if (boardADCPins[i] != boardPWMPins[j]) { + pinMode(boardPWMPins[j], OUTPUT); + digitalWrite(boardPWMPins[j], LOW); + } + } + + SerialUSB.println("----------"); + uint8 c = SerialUSB.read(); + if (c == ESC) { + break; + } else if (c != 'r' && c != 'R') { + i++; + } + } +} + +void cmd_everything(void) { // TODO + // Be sure to update cmd_print_help() if you implement this. + + // print to usart + // print to usb + // toggle gpios + // enable pwm + SerialUSB.println("Unimplemented."); +} + +void cmd_serial1_serial3(void) { + HardwareSerial *serial_1_and_3[] = {&Serial1, &Serial3}; + + SerialUSB.println("Testing 57600 baud on USART1 and USART3. " + "Press any key to stop."); + serial_baud_test(serial_1_and_3, 2, 57600); + SerialUSB.read(); + + SerialUSB.println("Testing 115200 baud on USART1 and USART3. " + "Press any key to stop."); + serial_baud_test(serial_1_and_3, 2, 115200); + SerialUSB.read(); + + SerialUSB.println("Testing 9600 baud on USART1 and USART3. " + "Press any key to stop."); + serial_baud_test(serial_1_and_3, 2, 9600); + SerialUSB.read(); + + SerialUSB.println("Resetting USART1 and USART3..."); + Serial1.begin(BAUD); + Serial3.begin(BAUD); +} + +void cmd_serial1_echo(void) { + SerialUSB.println("Testing serial echo at various baud rates. " + "Press any key for next baud rate, or ESC to quit " + "early."); + while (!SerialUSB.available()) + ; + + if (SerialUSB.read() == ESC) return; + SerialUSB.println("Testing 115200 baud on USART1."); + serial_echo_test(&Serial1, 115200); + + if (SerialUSB.read() == ESC) return; + SerialUSB.println("Testing 57600 baud on USART1."); + serial_echo_test(&Serial1, 57600); + + if (SerialUSB.read() == ESC) return; + SerialUSB.println("Testing 9600 baud on USART1."); + serial_echo_test(&Serial1, 9600); +} + +void cmd_gpio_monitoring(void) { + SerialUSB.println("Monitoring pin state changes. Press any key to stop."); + + for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) + continue; + pinMode(i, INPUT_PULLDOWN); + gpio_state[i] = (uint8)digitalRead(i); + } + + while (!SerialUSB.available()) { + for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) + continue; + + uint8 current_state = (uint8)digitalRead(i); + if (current_state != gpio_state[i]) { + SerialUSB.print("State change on pin "); + SerialUSB.print(i, DEC); + if (current_state) { + SerialUSB.println(":\tHIGH"); + } else { + SerialUSB.println(":\tLOW"); + } + gpio_state[i] = current_state; + } + } + } + + for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) + continue; + pinMode(i, OUTPUT); + } +} + +void cmd_sequential_adc_reads(void) { + SerialUSB.print("Sequentially reading most ADC ports."); + SerialUSB.println("Press any key for next port, or ESC to stop."); + + for (uint32 i = 0; i < BOARD_NR_ADC_PINS; i++) { + if (boardUsesPin(boardADCPins[i])) + continue; + + SerialUSB.print("Reading pin "); + SerialUSB.print(boardADCPins[i], DEC); + SerialUSB.println("..."); + pinMode(boardADCPins[i], INPUT_ANALOG); + while (!SerialUSB.available()) { + int sample = analogRead(boardADCPins[i]); + SerialUSB.print(boardADCPins[i], DEC); + SerialUSB.print("\t"); + SerialUSB.print(sample, DEC); + SerialUSB.print("\t"); + SerialUSB.print("|"); + for (int j = 0; j < 4096; j += 100) { + if (sample >= j) { + SerialUSB.print("#"); + } else { + SerialUSB.print(" "); + } + } + SerialUSB.print("| "); + for (int j = 0; j < 12; j++) { + if (sample & (1 << (11 - j))) { + SerialUSB.print("1"); + } else { + SerialUSB.print("0"); + } + } + SerialUSB.println(); + } + pinMode(boardADCPins[i], OUTPUT); + digitalWrite(boardADCPins[i], 0); + if (SerialUSB.read() == ESC) + break; + } +} + +bool test_single_pin_is_high(int high_pin, const char* err_msg) { + bool ok = true; + for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) continue; + + if (digitalRead(i) == HIGH && i != high_pin) { + SerialUSB.println(); + SerialUSB.print("\t*** FAILURE! pin "); + SerialUSB.print(i, DEC); + SerialUSB.print(' '); + SerialUSB.println(err_msg); + ok = false; + } + } + return ok; +} + +bool wait_for_low_transition(uint8 pin) { + uint32 start = millis(); + while (millis() - start < 2000) { + if (digitalRead(pin) == LOW) { + return true; + } + } + return false; +} + +void cmd_gpio_qa(void) { + bool all_pins_ok = true; + const int not_a_pin = -1; + SerialUSB.println("Doing QA testing for unused GPIO pins."); + + for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) continue; + + pinMode(i, INPUT); + } + + SerialUSB.println("Waiting to start."); + ASSERT(!boardUsesPin(0)); + while (digitalRead(0) == LOW) continue; + + for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) { + SerialUSB.print("Skipping pin "); + SerialUSB.println(i, DEC); + continue; + } + bool pin_ok = true; + SerialUSB.print("Checking pin "); + SerialUSB.print(i, DEC); + while (digitalRead(i) == LOW) continue; + + pin_ok = pin_ok && test_single_pin_is_high(i, "is also HIGH"); + + if (!wait_for_low_transition(i)) { + SerialUSB.println("Transition to low timed out; something is " + "very wrong. Aborting test."); + return; + } + + pin_ok = pin_ok && test_single_pin_is_high(not_a_pin, "is still HIGH"); + + if (pin_ok) { + SerialUSB.println(": ok"); + } + + all_pins_ok = all_pins_ok && pin_ok; + } + + if (all_pins_ok) { + SerialUSB.println("Finished; test passes."); + } else { + SerialUSB.println("**** TEST FAILS *****"); + } + + for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) continue; + + pinMode(i, OUTPUT); + digitalWrite(i, LOW); + gpio_state[i] = 0; + } +} + +void cmd_sequential_gpio_toggling(void) { + SerialUSB.println("Sequentially toggling all unused pins. " + "Press any key for next pin, ESC to stop."); + + for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) + continue; + + SerialUSB.print("Toggling pin "); + SerialUSB.print((int)i, DEC); + SerialUSB.println("..."); + + pinMode(i, OUTPUT); + do { + togglePin(i); + } while (!SerialUSB.available()); + + digitalWrite(i, LOW); + if (SerialUSB.read() == ESC) + break; + } +} + +void cmd_gpio_toggling(void) { + SerialUSB.println("Toggling all unused pins simultaneously. " + "Press any key to stop."); + + for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) + continue; + pinMode(i, OUTPUT); + } + + while (!SerialUSB.available()) { + for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) + continue; + togglePin(i); + } + } + + for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { + if (boardUsesPin(i)) + continue; + digitalWrite(i, LOW); + } +} + +uint8 debugGPIOPins[] = {BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, + BOARD_JTDI_PIN, + BOARD_JTDO_PIN, + BOARD_NJTRST_PIN}; + +#define N_DEBUG_PINS 5 + +void cmd_sequential_debug_gpio_toggling(void) { + SerialUSB.println("Toggling all debug (JTAG/SWD) pins sequentially. " + "This will permanently disable debug port " + "functionality."); + disableDebugPorts(); + + for (int i = 0; i < N_DEBUG_PINS; i++) { + pinMode(debugGPIOPins[i], OUTPUT); + } + + for (int i = 0; i < N_DEBUG_PINS; i++) { + int pin = debugGPIOPins[i]; + SerialUSB.print("Toggling pin "); + SerialUSB.print(pin, DEC); + SerialUSB.println("..."); + + pinMode(pin, OUTPUT); + do { + togglePin(pin); + } while (!SerialUSB.available()); + + digitalWrite(pin, LOW); + if (SerialUSB.read() == ESC) + break; + } + + for (int i = 0; i < N_DEBUG_PINS; i++) { + digitalWrite(debugGPIOPins[i], 0); + } +} + +void cmd_debug_gpio_toggling(void) { + SerialUSB.println("Toggling debug GPIO simultaneously. " + "This will permanently disable JTAG and Serial Wire " + "debug port functionality. " + "Press any key to stop."); + disableDebugPorts(); + + for (uint32 i = 0; i < N_DEBUG_PINS; i++) { + pinMode(debugGPIOPins[i], OUTPUT); + } + + while (!SerialUSB.available()) { + for (uint32 i = 0; i < N_DEBUG_PINS; i++) { + togglePin(debugGPIOPins[i]); + } + } + + for (uint32 i = 0; i < N_DEBUG_PINS; i++) { + digitalWrite(debugGPIOPins[i], LOW); + } +} + +void cmd_but_test(void) { + SerialUSB.println("Press the button to test. Press any key to stop."); + pinMode(BOARD_BUTTON_PIN, INPUT); + + while (!SerialUSB.available()) { + if (isButtonPressed()) { + uint32 tstamp = millis(); + SerialUSB.print("Button press detected, timestamp: "); + SerialUSB.println(tstamp); + } + } + SerialUSB.read(); +} + +void cmd_sequential_pwm_test(void) { + SerialUSB.println("Sequentially testing PWM on all unused pins. " + "Press any key for next pin, ESC to stop."); + + for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { + if (boardUsesPin(i)) + continue; + + SerialUSB.print("PWM out on header D"); + SerialUSB.print(boardPWMPins[i], DEC); + SerialUSB.println("..."); + pinMode(boardPWMPins[i], PWM); + pwmWrite(boardPWMPins[i], 16000); + + while (!SerialUSB.available()) { + delay(10); + } + + pinMode(boardPWMPins[i], OUTPUT); + digitalWrite(boardPWMPins[i], 0); + if (SerialUSB.read() == ESC) + break; + } +} + +void cmd_servo_sweep(void) { + SerialUSB.println("Testing all PWM headers with a servo sweep. " + "Press any key to stop."); + SerialUSB.println(); + + disable_usarts(); + init_all_timers(21); + + for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { + if (boardUsesPin(i)) + continue; + pinMode(boardPWMPins[i], PWM); + pwmWrite(boardPWMPins[i], 4000); + } + + // 1.25ms = 4096counts = 0deg + // 1.50ms = 4915counts = 90deg + // 1.75ms = 5734counts = 180deg + int rate = 4096; + while (!SerialUSB.available()) { + rate += 20; + if (rate > 5734) + rate = 4096; + for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { + if (boardUsesPin(i)) + continue; + pwmWrite(boardPWMPins[i], rate); + } + delay(20); + } + + for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { + if (boardUsesPin(i)) + continue; + pinMode(boardPWMPins[i], OUTPUT); + } + init_all_timers(1); + enable_usarts(); +} + +void cmd_board_info(void) { // TODO print more information + SerialUSB.println("Board information"); + SerialUSB.println("================="); + + SerialUSB.print("* Clock speed (MHz): "); + SerialUSB.println(CYCLES_PER_MICROSECOND); + + SerialUSB.print("* BOARD_LED_PIN: "); + SerialUSB.println(BOARD_LED_PIN); + + SerialUSB.print("* BOARD_BUTTON_PIN: "); + SerialUSB.println(BOARD_BUTTON_PIN); + + SerialUSB.print("* GPIO information (BOARD_NR_GPIO_PINS = "); + SerialUSB.print(BOARD_NR_GPIO_PINS); + SerialUSB.println("):"); + print_board_array("ADC pins", boardADCPins, BOARD_NR_ADC_PINS); + print_board_array("PWM pins", boardPWMPins, BOARD_NR_PWM_PINS); + print_board_array("Used pins", boardUsedPins, BOARD_NR_USED_PINS); +} + +// -- Helper functions -------------------------------------------------------- + +void measure_adc_noise(uint8 pin) { + const int N = 1000; + uint16 x; + float mean = 0; + float delta = 0; + float M2 = 0; + pinMode(pin, INPUT_ANALOG); + + // Variance algorithm from Welford, via Knuth, by way of Wikipedia: + // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm + for (int sample = 0; sample < N_ADC_NOISE_MEASUREMENTS; sample++) { + for (int i = 1; i <= N; i++) { + x = analogRead(pin); + delta = x - mean; + mean += delta / i; + M2 = M2 + delta * (x - mean); + } + SerialUSB.print("header: D"); + SerialUSB.print(pin, DEC); + SerialUSB.print("\tn: "); + SerialUSB.print(N, DEC); + SerialUSB.print("\tmean: "); + SerialUSB.print(mean); + SerialUSB.print("\tvariance: "); + SerialUSB.println(M2 / (float)(N-1)); + } + + pinMode(pin, OUTPUT); +} + +void fast_gpio(int maple_pin) { + gpio_dev *dev = PIN_MAP[maple_pin].gpio_device; + uint32 bit = PIN_MAP[maple_pin].gpio_bit; + + gpio_write_bit(dev, bit, 1); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); + gpio_toggle_bit(dev, bit); +} + +void serial_baud_test(HardwareSerial **serials, int n, unsigned baud) { + for (int i = 0; i < n; i++) { + serials[i]->begin(baud); + } + while (!SerialUSB.available()) { + for (int i = 0; i < n; i++) { + serials[i]->println(dummy_data); + if (serials[i]->available()) { + serials[i]->println(serials[i]->read()); + delay(1000); + } + } + } +} + +void serial_echo_test(HardwareSerial *serial, unsigned baud) { + serial->begin(baud); + while (!SerialUSB.available()) { + if (!serial->available()) + continue; + serial->print(serial->read()); + } +} + +static uint16 init_all_timers_prescale = 0; + +static void set_prescale(timer_dev *dev) { + timer_set_prescaler(dev, init_all_timers_prescale); +} + +void init_all_timers(uint16 prescale) { + init_all_timers_prescale = prescale; + timer_foreach(set_prescale); +} + +void enable_usarts(void) { + Serial1.begin(BAUD); + Serial2.begin(BAUD); + Serial3.begin(BAUD); +#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) + Serial4.begin(BAUD); + Serial5.begin(BAUD); +#endif +} + +void disable_usarts(void) { + Serial1.end(); + Serial2.end(); + Serial3.end(); +#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) + Serial4.end(); + Serial5.end(); +#endif +} + +void print_board_array(const char* msg, const uint8 arr[], int len) { + SerialUSB.print("\t"); + SerialUSB.print(msg); + SerialUSB.print(" ("); + SerialUSB.print(len); + SerialUSB.print("): "); + for (int i = 0; i < len; i++) { + SerialUSB.print(arr[i], DEC); + if (i < len - 1) SerialUSB.print(", "); + } + SerialUSB.println(); +} + +// -- premain() and main() ---------------------------------------------------- + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (1) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/test-spi-roundtrip.cpp b/Libmaple/libmaple/examples/test-spi-roundtrip.cpp index d0dca2fd..71ae6587 100644 --- a/Libmaple/libmaple/examples/test-spi-roundtrip.cpp +++ b/Libmaple/libmaple/examples/test-spi-roundtrip.cpp @@ -1,192 +1,192 @@ -/* - * Polling SPI loopback test. - * - * Bob is nowhere to be found, so Alice decides to talk to herself. - * - * Instructions: Connect SPI2 (Alice) to herself (i.e., MISO to MOSI). - * Connect to Alice via SerialUSB. Press any key to start. - * - * Alice will talk to herself for a little while. The sketch will - * report if Alice can't hear anything she says. She'll then start - * talking forever at various frequencies, bit orders, and modes. Use - * an oscilloscope to make sure she's not trying to lie about any of - * those things. - * - * This file is released into the public domain. - * - * Author: Marti Bolivar - */ - -#include "wirish.h" - -HardwareSPI alice(2); - -#define NFREQS 8 -const SPIFrequency spi_freqs[] = { - SPI_140_625KHZ, - SPI_281_250KHZ, - SPI_562_500KHZ, - SPI_1_125MHZ, - SPI_2_25MHZ, - SPI_4_5MHZ, - SPI_9MHZ, - SPI_18MHZ, -}; - -#define TEST_BUF_SIZE 10 -uint8 test_buf[TEST_BUF_SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - -void bad_assert(const char* file, int line, const char* exp) { - SerialUSB.println(); - SerialUSB.print("ERROR: FAILED ASSERT("); - SerialUSB.print(exp); - SerialUSB.print("): "); - SerialUSB.print(file); - SerialUSB.print(": "); - SerialUSB.println(line); - throb(); -} - -#undef ASSERT -#define ASSERT(exp) \ - if (exp) { \ - } else { \ - bad_assert(__FILE__, __LINE__, #exp); \ - } - -void haveConversation(uint32 bitOrder); -void soliloquies(uint32 bitOrder); - -void setup() { - pinMode(BOARD_LED_PIN, OUTPUT); - SerialUSB.read(); -} - -void loop() { - SerialUSB.println("** Having a conversation, MSB first"); - haveConversation(MSBFIRST); - - SerialUSB.println("** Having a conversation, LSB first"); - haveConversation(LSBFIRST); - - SerialUSB.println(); - SerialUSB.println("*** All done! It looks like everything worked."); - SerialUSB.println(); - - SerialUSB.println("** Alice will now wax eloquent in various styles. " - "Press any key for the next configuration."); - soliloquies(MSBFIRST); - soliloquies(LSBFIRST); - - while (true) - ; -} - -void printFrequencyString(SPIFrequency frequency); -void chat(SPIFrequency frequency, uint32 bitOrder, uint32 mode); - -void haveConversation(uint32 bitOrder) { - for (int f = 0; f < NFREQS; f++) { - for (int mode = 0; mode < 4; mode++) { - chat(spi_freqs[f], bitOrder, mode); - delay(10); - } - } -} - -void chat(SPIFrequency frequency, uint32 bitOrder, uint32 mode) { - SerialUSB.print("Having a chat.\tFrequency: "); - printFrequencyString(frequency); - SerialUSB.print(",\tbitOrder: "); - SerialUSB.print(bitOrder == MSBFIRST ? "MSB" : "LSB"); - SerialUSB.print(",\tmode: "); - SerialUSB.print(mode); - SerialUSB.print("."); - - SerialUSB.print(" [1] "); - alice.begin(frequency, bitOrder, mode); - - SerialUSB.print(" [2] "); - uint32 txed = 0; - while (txed < TEST_BUF_SIZE) { - ASSERT(alice.transfer(test_buf[txed]) == test_buf[txed]); - txed++; - } - - SerialUSB.print(" [3] "); - alice.end(); - - SerialUSB.println(" ok."); -} - -void soliloquy(SPIFrequency freq, uint32 bitOrder, uint32 mode); - -void soliloquies(uint32 bitOrder) { - for (int f = 0; f < NFREQS; f++) { - for (int mode = 0; mode < 4; mode++) { - soliloquy(spi_freqs[f], bitOrder, mode); - } - } -} - -void soliloquy(SPIFrequency frequency, uint32 bitOrder, uint32 mode) { - const uint8 repeat = 0xAE; - SerialUSB.print("Alice is giving a soliloquy (repeating 0x"); - SerialUSB.print(repeat, HEX); - SerialUSB.print("). Frequency: "); - printFrequencyString(frequency); - SerialUSB.print(", bitOrder: "); - SerialUSB.print(bitOrder == MSBFIRST ? "big-endian" : "little-endian"); - SerialUSB.print(", SPI mode: "); - SerialUSB.println(mode); - - alice.begin(frequency, bitOrder, mode); - while (!SerialUSB.available()) { - alice.write(repeat); - delayMicroseconds(200); - } - SerialUSB.read(); -} - -void printFrequencyString(SPIFrequency frequency) { - switch (frequency) { - case SPI_18MHZ: - SerialUSB.print("18 MHz"); - break; - case SPI_9MHZ: - SerialUSB.print("9 MHz"); - break; - case SPI_4_5MHZ: - SerialUSB.print("4.5 MHz"); - break; - case SPI_2_25MHZ: - SerialUSB.print("2.25 MHZ"); - break; - case SPI_1_125MHZ: - SerialUSB.print("1.125 MHz"); - break; - case SPI_562_500KHZ: - SerialUSB.print("562.500 KHz"); - break; - case SPI_281_250KHZ: - SerialUSB.print("281.250 KHz"); - break; - case SPI_140_625KHZ: - SerialUSB.print("140.625 KHz"); - break; - } -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - while (true) { - loop(); - } - return 0; -} +/* + * Polling SPI loopback test. + * + * Bob is nowhere to be found, so Alice decides to talk to herself. + * + * Instructions: Connect SPI2 (Alice) to herself (i.e., MISO to MOSI). + * Connect to Alice via SerialUSB. Press any key to start. + * + * Alice will talk to herself for a little while. The sketch will + * report if Alice can't hear anything she says. She'll then start + * talking forever at various frequencies, bit orders, and modes. Use + * an oscilloscope to make sure she's not trying to lie about any of + * those things. + * + * This file is released into the public domain. + * + * Author: Marti Bolivar + */ + +#include "wirish.h" + +HardwareSPI alice(2); + +#define NFREQS 8 +const SPIFrequency spi_freqs[] = { + SPI_140_625KHZ, + SPI_281_250KHZ, + SPI_562_500KHZ, + SPI_1_125MHZ, + SPI_2_25MHZ, + SPI_4_5MHZ, + SPI_9MHZ, + SPI_18MHZ, +}; + +#define TEST_BUF_SIZE 10 +uint8 test_buf[TEST_BUF_SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + +void bad_assert(const char* file, int line, const char* exp) { + SerialUSB.println(); + SerialUSB.print("ERROR: FAILED ASSERT("); + SerialUSB.print(exp); + SerialUSB.print("): "); + SerialUSB.print(file); + SerialUSB.print(": "); + SerialUSB.println(line); + throb(); +} + +#undef ASSERT +#define ASSERT(exp) \ + if (exp) { \ + } else { \ + bad_assert(__FILE__, __LINE__, #exp); \ + } + +void haveConversation(uint32 bitOrder); +void soliloquies(uint32 bitOrder); + +void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); + SerialUSB.read(); +} + +void loop() { + SerialUSB.println("** Having a conversation, MSB first"); + haveConversation(MSBFIRST); + + SerialUSB.println("** Having a conversation, LSB first"); + haveConversation(LSBFIRST); + + SerialUSB.println(); + SerialUSB.println("*** All done! It looks like everything worked."); + SerialUSB.println(); + + SerialUSB.println("** Alice will now wax eloquent in various styles. " + "Press any key for the next configuration."); + soliloquies(MSBFIRST); + soliloquies(LSBFIRST); + + while (true) + ; +} + +void printFrequencyString(SPIFrequency frequency); +void chat(SPIFrequency frequency, uint32 bitOrder, uint32 mode); + +void haveConversation(uint32 bitOrder) { + for (int f = 0; f < NFREQS; f++) { + for (int mode = 0; mode < 4; mode++) { + chat(spi_freqs[f], bitOrder, mode); + delay(10); + } + } +} + +void chat(SPIFrequency frequency, uint32 bitOrder, uint32 mode) { + SerialUSB.print("Having a chat.\tFrequency: "); + printFrequencyString(frequency); + SerialUSB.print(",\tbitOrder: "); + SerialUSB.print(bitOrder == MSBFIRST ? "MSB" : "LSB"); + SerialUSB.print(",\tmode: "); + SerialUSB.print(mode); + SerialUSB.print("."); + + SerialUSB.print(" [1] "); + alice.begin(frequency, bitOrder, mode); + + SerialUSB.print(" [2] "); + uint32 txed = 0; + while (txed < TEST_BUF_SIZE) { + ASSERT(alice.transfer(test_buf[txed]) == test_buf[txed]); + txed++; + } + + SerialUSB.print(" [3] "); + alice.end(); + + SerialUSB.println(" ok."); +} + +void soliloquy(SPIFrequency freq, uint32 bitOrder, uint32 mode); + +void soliloquies(uint32 bitOrder) { + for (int f = 0; f < NFREQS; f++) { + for (int mode = 0; mode < 4; mode++) { + soliloquy(spi_freqs[f], bitOrder, mode); + } + } +} + +void soliloquy(SPIFrequency frequency, uint32 bitOrder, uint32 mode) { + const uint8 repeat = 0xAE; + SerialUSB.print("Alice is giving a soliloquy (repeating 0x"); + SerialUSB.print(repeat, HEX); + SerialUSB.print("). Frequency: "); + printFrequencyString(frequency); + SerialUSB.print(", bitOrder: "); + SerialUSB.print(bitOrder == MSBFIRST ? "big-endian" : "little-endian"); + SerialUSB.print(", SPI mode: "); + SerialUSB.println(mode); + + alice.begin(frequency, bitOrder, mode); + while (!SerialUSB.available()) { + alice.write(repeat); + delayMicroseconds(200); + } + SerialUSB.read(); +} + +void printFrequencyString(SPIFrequency frequency) { + switch (frequency) { + case SPI_18MHZ: + SerialUSB.print("18 MHz"); + break; + case SPI_9MHZ: + SerialUSB.print("9 MHz"); + break; + case SPI_4_5MHZ: + SerialUSB.print("4.5 MHz"); + break; + case SPI_2_25MHZ: + SerialUSB.print("2.25 MHZ"); + break; + case SPI_1_125MHZ: + SerialUSB.print("1.125 MHz"); + break; + case SPI_562_500KHZ: + SerialUSB.print("562.500 KHz"); + break; + case SPI_281_250KHZ: + SerialUSB.print("281.250 KHz"); + break; + case SPI_140_625KHZ: + SerialUSB.print("140.625 KHz"); + break; + } +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/test-systick.cpp b/Libmaple/libmaple/examples/test-systick.cpp index 5aab1b7b..78c7307a 100644 --- a/Libmaple/libmaple/examples/test-systick.cpp +++ b/Libmaple/libmaple/examples/test-systick.cpp @@ -1,49 +1,49 @@ -// Tests the SysTick enable/disable functions - -#include "wirish.h" -#include "systick.h" - -void setup() { - pinMode(BOARD_LED_PIN, OUTPUT); - pinMode(BOARD_BUTTON_PIN, INPUT); -} - -bool disable = true; -long time = 0; - -void loop() { - volatile int i = 0; - toggleLED(); - - // An artificial delay - for(i = 0; i < 150000; i++) - ; - - if (isButtonPressed()) { - if (disable) { - systick_disable(); - SerialUSB.println("Disabling SysTick"); - } else { - SerialUSB.println("Re-enabling SysTick"); - systick_enable(); - } - disable = !disable; - } - - SerialUSB.println(millis()); -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated object that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +// Tests the SysTick enable/disable functions + +#include "wirish.h" +#include "systick.h" + +void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); + pinMode(BOARD_BUTTON_PIN, INPUT); +} + +bool disable = true; +long time = 0; + +void loop() { + volatile int i = 0; + toggleLED(); + + // An artificial delay + for(i = 0; i < 150000; i++) + ; + + if (isButtonPressed()) { + if (disable) { + systick_disable(); + SerialUSB.println("Disabling SysTick"); + } else { + SerialUSB.println("Re-enabling SysTick"); + systick_enable(); + } + disable = !disable; + } + + SerialUSB.println(millis()); +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated object that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/test-timers.cpp b/Libmaple/libmaple/examples/test-timers.cpp index 4270c60a..247cc578 100644 --- a/Libmaple/libmaple/examples/test-timers.cpp +++ b/Libmaple/libmaple/examples/test-timers.cpp @@ -1,297 +1,297 @@ -// Program to test the timer.h implementation's essential functionality. - -#include "wirish.h" -#include "timer.h" - -void handler1(void); -void handler2(void); -void handler3(void); -void handler4(void); - -void handler3b(void); -void handler4b(void); - -int t; - -int count1 = 0; -int count2 = 0; -int count3 = 0; -int count4 = 0; -uint16 rate1 = 1000; -uint16 rate2 = 2000; -uint16 rate3 = 4000; -uint16 rate4 = 8000; -uint16 val1 = 10000; -uint16 val2 = 10000; -uint16 val3 = 10000; -uint16 val4 = 10000; - -// FIXME [0.1.0] high density timer test (especially basic timers + DAC) -timer_dev *timers[] = {TIMER1, TIMER2, TIMER3, TIMER4}; -voidFuncPtr handlers[] = {handler1, handler2, handler3, handler4}; - -void initTimer(timer_dev *dev); -void setTimerPeriod(timer_dev *dev, uint32 period_us); -void testSetTimerPeriod(uint32 period); -void testTimerChannels(timer_dev *dev); -int timerNumber(timer_dev *dev); - -void setup() { - // Set up the LED to blink - pinMode(BOARD_LED_PIN, OUTPUT); - - // Setup the button as input - pinMode(BOARD_BUTTON_PIN, INPUT); - - // Send a message out Serial2 - Serial2.begin(115200); - Serial2.println("*** Initializing timers..."); - timer_foreach(initTimer); - Serial2.println("*** Done. Beginning timer test."); -} - -void loop() { - Serial2.println("-----------------------------------------------------"); - - Serial2.println("Testing timer_get_count()/timer_set_count()"); - Serial2.print("TIMER1 count = "); - Serial2.println(timer_get_count(TIMER1)); - Serial2.println("timer_set_count(TIMER1, 1234)"); - timer_set_count(TIMER1, 1234); - Serial2.print("timer_get_count(TIMER1) = "); - Serial2.println(timer_get_count(TIMER1)); - - Serial2.println("-----------------------------------------------------"); - Serial2.println("Testing pause/resume; button roughly controls TIMER4"); - // when BUT is held down, TIMER4 is in the "pause" state and the - // timer doesn't increment, so the final counts should reflect the - // ratio of time that BUT was held down. - count3 = 0; - count4 = 0; - timer_set_mode(TIMER3, TIMER_CH1, TIMER_OUTPUT_COMPARE); - timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE); - timer_pause(TIMER3); - timer_pause(TIMER4); - timer_set_count(TIMER3, 0); - timer_set_count(TIMER4, 0); - timer_set_reload(TIMER3, 30000); - timer_set_reload(TIMER4, 30000); - timer_set_compare(TIMER3, 1, 1000); - timer_set_compare(TIMER4, 1, 1000); - timer_attach_interrupt(TIMER3, TIMER_CC1_INTERRUPT, handler3b); - timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b); - timer_resume(TIMER3); - timer_resume(TIMER4); - - Serial2.println("Testing for ~4 seconds..."); - for(int i = 0; i < 4000; i++) { - if (isButtonPressed()) { - timer_pause(TIMER4); - } else { - timer_resume(TIMER4); - } - delay(1); - } - - timer_set_mode(TIMER3, TIMER_CH1, TIMER_DISABLED); - timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED); - - Serial2.print("TIMER3 count: "); - Serial2.println(timer_get_count(TIMER3)); - Serial2.print("TIMER4 count: "); - Serial2.println(timer_get_count(TIMER4)); - - Serial2.println("-----------------------------------------------------"); - Serial2.println("Testing setTimerPeriod()"); - testSetTimerPeriod(10); - testSetTimerPeriod(30000); - testSetTimerPeriod(300000); - testSetTimerPeriod(30000); - - Serial2.println("Sanity check (with hand-coded reload and prescaler for " - "72 MHz timers):"); - timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE); - timer_set_prescaler(TIMER4, 33); - timer_set_reload(TIMER4, 65454); - timer_pause(TIMER4); - timer_set_count(TIMER4, 0); - timer_set_compare(TIMER4, TIMER_CH1, 1); - timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b); - Serial2.println("Period 30000ms, wait 2 seconds..."); - count4 = 0; - timer_resume(TIMER4); - delay(2000); - timer_pause(TIMER4); - timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED); - Serial2.print("TIMER4 count: "); - Serial2.println(count4); - Serial2.println(" (Should be around 2sec/30000ms ~ 67)"); - - // Test all the individual timer channels - timer_foreach(testTimerChannels); -} - -void initTimer(timer_dev *dev) { - switch (dev->type) { - case TIMER_ADVANCED: - case TIMER_GENERAL: - Serial2.print("Initializing timer "); - Serial2.println(timerNumber(dev)); - for (int c = 1; c <= 4; c++) { - timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE); - } - Serial2.println("Done."); - break; - case TIMER_BASIC: - break; - } -} - -void testSetTimerPeriod(uint32 period) { - timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE); - timer_set_compare(TIMER4, TIMER_CH1, 1); - setTimerPeriod(TIMER4, period); - timer_pause(TIMER4); - timer_set_count(TIMER4, 0); - timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b); - Serial2.println("Period "); - Serial2.print(period); - Serial2.print(" ms. Waiting 2 seconds..."); - count4 = 0; - timer_resume(TIMER4); - delay(2000); - timer_pause(TIMER4); - timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED); - Serial2.print("TIMER4 count: "); - Serial2.println(timer_get_count(TIMER4)); - Serial2.print(" (Should be around 2 sec / "); - Serial2.print(period); - Serial2.print(" ms = "); - Serial2.print(double(2) / period * 1000); - Serial2.println(", modulo delays due to interrupts)"); -} - -int timerNumber(timer_dev *dev) { - switch (dev->clk_id) { - case RCC_TIMER1: - return 1; - case RCC_TIMER2: - return 2; - case RCC_TIMER3: - return 3; - case RCC_TIMER4: - return 4; -#ifdef STM32_HIGH_DENSITY - case RCC_TIMER5: - return 5; - case RCC_TIMER6: - return 6; - case RCC_TIMER7: - return 7; - case RCC_TIMER8: - return 8; -#endif - default: - ASSERT(0); - return 0; - } -} - -/* This function touches every channel of a given timer. The output - * ratios should reflect the ratios of the rate variables. It - * demonstrates that, over time, the actual timing rates get blown - * away by other system interrupts. */ -void testTimerChannels(timer_dev *dev) { - t = timerNumber(dev); - toggleLED(); - delay(100); - Serial2.println("-----------------------------------------------------"); - switch (dev->type) { - case TIMER_BASIC: - Serial2.print("NOT testing channels for basic timer "); - Serial2.println(t); - break; - case TIMER_ADVANCED: - case TIMER_GENERAL: - Serial2.print("Testing channels for timer "); - Serial2.println(t); - timer_pause(dev); - count1 = count2 = count3 = count4 = 0; - timer_set_reload(dev, 0xFFFF); - timer_set_prescaler(dev, 1); - for (int c = 1; c <= 4; c++) { - timer_set_compare(dev, c, 65535); - timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE); - timer_attach_interrupt(dev, c, handlers[c - 1]); - } - timer_resume(dev); - delay(3000); - for (int c = 1; c <= 4; c++) { - timer_set_mode(dev, c, TIMER_DISABLED); - } - Serial2.print("Channel 1 count: "); Serial2.println(count1); - Serial2.print("Channel 2 count: "); Serial2.println(count2); - Serial2.print("Channel 3 count: "); Serial2.println(count3); - Serial2.print("Channel 4 count: "); Serial2.println(count4); - break; - } -} - -// FIXME [0.1.0] move some incarnation of this into timer.h -void setTimerPeriod(timer_dev *dev, uint32 period_us) { - if (!period_us) { - // FIXME handle this case - ASSERT(0); - return; - } - - uint32 cycles = period_us * CYCLES_PER_MICROSECOND; - uint16 pre = (uint16)((cycles >> 16) + 1); - timer_set_prescaler(dev, pre); - timer_set_reload(dev, cycles / pre - 1); -} - -void handler1(void) { - val1 += rate1; - timer_set_compare(timers[t], TIMER_CH1, val1); - count1++; -} - -void handler2(void) { - val2 += rate2; - timer_set_compare(timers[t], TIMER_CH2, val2); - count2++; -} - -void handler3(void) { - val3 += rate3; - timer_set_compare(timers[t], TIMER_CH3, val3); - count3++; -} - -void handler4(void) { - val4 += rate4; - timer_set_compare(timers[t], TIMER_CH4, val4); - count4++; -} - -void handler3b(void) { - count3++; -} - -void handler4b(void) { - count4++; -} - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +// Program to test the timer.h implementation's essential functionality. + +#include "wirish.h" +#include "timer.h" + +void handler1(void); +void handler2(void); +void handler3(void); +void handler4(void); + +void handler3b(void); +void handler4b(void); + +int t; + +int count1 = 0; +int count2 = 0; +int count3 = 0; +int count4 = 0; +uint16 rate1 = 1000; +uint16 rate2 = 2000; +uint16 rate3 = 4000; +uint16 rate4 = 8000; +uint16 val1 = 10000; +uint16 val2 = 10000; +uint16 val3 = 10000; +uint16 val4 = 10000; + +// FIXME [0.1.0] high density timer test (especially basic timers + DAC) +timer_dev *timers[] = {TIMER1, TIMER2, TIMER3, TIMER4}; +voidFuncPtr handlers[] = {handler1, handler2, handler3, handler4}; + +void initTimer(timer_dev *dev); +void setTimerPeriod(timer_dev *dev, uint32 period_us); +void testSetTimerPeriod(uint32 period); +void testTimerChannels(timer_dev *dev); +int timerNumber(timer_dev *dev); + +void setup() { + // Set up the LED to blink + pinMode(BOARD_LED_PIN, OUTPUT); + + // Setup the button as input + pinMode(BOARD_BUTTON_PIN, INPUT); + + // Send a message out Serial2 + Serial2.begin(115200); + Serial2.println("*** Initializing timers..."); + timer_foreach(initTimer); + Serial2.println("*** Done. Beginning timer test."); +} + +void loop() { + Serial2.println("-----------------------------------------------------"); + + Serial2.println("Testing timer_get_count()/timer_set_count()"); + Serial2.print("TIMER1 count = "); + Serial2.println(timer_get_count(TIMER1)); + Serial2.println("timer_set_count(TIMER1, 1234)"); + timer_set_count(TIMER1, 1234); + Serial2.print("timer_get_count(TIMER1) = "); + Serial2.println(timer_get_count(TIMER1)); + + Serial2.println("-----------------------------------------------------"); + Serial2.println("Testing pause/resume; button roughly controls TIMER4"); + // when BUT is held down, TIMER4 is in the "pause" state and the + // timer doesn't increment, so the final counts should reflect the + // ratio of time that BUT was held down. + count3 = 0; + count4 = 0; + timer_set_mode(TIMER3, TIMER_CH1, TIMER_OUTPUT_COMPARE); + timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE); + timer_pause(TIMER3); + timer_pause(TIMER4); + timer_set_count(TIMER3, 0); + timer_set_count(TIMER4, 0); + timer_set_reload(TIMER3, 30000); + timer_set_reload(TIMER4, 30000); + timer_set_compare(TIMER3, 1, 1000); + timer_set_compare(TIMER4, 1, 1000); + timer_attach_interrupt(TIMER3, TIMER_CC1_INTERRUPT, handler3b); + timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b); + timer_resume(TIMER3); + timer_resume(TIMER4); + + Serial2.println("Testing for ~4 seconds..."); + for(int i = 0; i < 4000; i++) { + if (isButtonPressed()) { + timer_pause(TIMER4); + } else { + timer_resume(TIMER4); + } + delay(1); + } + + timer_set_mode(TIMER3, TIMER_CH1, TIMER_DISABLED); + timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED); + + Serial2.print("TIMER3 count: "); + Serial2.println(timer_get_count(TIMER3)); + Serial2.print("TIMER4 count: "); + Serial2.println(timer_get_count(TIMER4)); + + Serial2.println("-----------------------------------------------------"); + Serial2.println("Testing setTimerPeriod()"); + testSetTimerPeriod(10); + testSetTimerPeriod(30000); + testSetTimerPeriod(300000); + testSetTimerPeriod(30000); + + Serial2.println("Sanity check (with hand-coded reload and prescaler for " + "72 MHz timers):"); + timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE); + timer_set_prescaler(TIMER4, 33); + timer_set_reload(TIMER4, 65454); + timer_pause(TIMER4); + timer_set_count(TIMER4, 0); + timer_set_compare(TIMER4, TIMER_CH1, 1); + timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b); + Serial2.println("Period 30000ms, wait 2 seconds..."); + count4 = 0; + timer_resume(TIMER4); + delay(2000); + timer_pause(TIMER4); + timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED); + Serial2.print("TIMER4 count: "); + Serial2.println(count4); + Serial2.println(" (Should be around 2sec/30000ms ~ 67)"); + + // Test all the individual timer channels + timer_foreach(testTimerChannels); +} + +void initTimer(timer_dev *dev) { + switch (dev->type) { + case TIMER_ADVANCED: + case TIMER_GENERAL: + Serial2.print("Initializing timer "); + Serial2.println(timerNumber(dev)); + for (int c = 1; c <= 4; c++) { + timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE); + } + Serial2.println("Done."); + break; + case TIMER_BASIC: + break; + } +} + +void testSetTimerPeriod(uint32 period) { + timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE); + timer_set_compare(TIMER4, TIMER_CH1, 1); + setTimerPeriod(TIMER4, period); + timer_pause(TIMER4); + timer_set_count(TIMER4, 0); + timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b); + Serial2.println("Period "); + Serial2.print(period); + Serial2.print(" ms. Waiting 2 seconds..."); + count4 = 0; + timer_resume(TIMER4); + delay(2000); + timer_pause(TIMER4); + timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED); + Serial2.print("TIMER4 count: "); + Serial2.println(timer_get_count(TIMER4)); + Serial2.print(" (Should be around 2 sec / "); + Serial2.print(period); + Serial2.print(" ms = "); + Serial2.print(double(2) / period * 1000); + Serial2.println(", modulo delays due to interrupts)"); +} + +int timerNumber(timer_dev *dev) { + switch (dev->clk_id) { + case RCC_TIMER1: + return 1; + case RCC_TIMER2: + return 2; + case RCC_TIMER3: + return 3; + case RCC_TIMER4: + return 4; +#ifdef STM32_HIGH_DENSITY + case RCC_TIMER5: + return 5; + case RCC_TIMER6: + return 6; + case RCC_TIMER7: + return 7; + case RCC_TIMER8: + return 8; +#endif + default: + ASSERT(0); + return 0; + } +} + +/* This function touches every channel of a given timer. The output + * ratios should reflect the ratios of the rate variables. It + * demonstrates that, over time, the actual timing rates get blown + * away by other system interrupts. */ +void testTimerChannels(timer_dev *dev) { + t = timerNumber(dev); + toggleLED(); + delay(100); + Serial2.println("-----------------------------------------------------"); + switch (dev->type) { + case TIMER_BASIC: + Serial2.print("NOT testing channels for basic timer "); + Serial2.println(t); + break; + case TIMER_ADVANCED: + case TIMER_GENERAL: + Serial2.print("Testing channels for timer "); + Serial2.println(t); + timer_pause(dev); + count1 = count2 = count3 = count4 = 0; + timer_set_reload(dev, 0xFFFF); + timer_set_prescaler(dev, 1); + for (int c = 1; c <= 4; c++) { + timer_set_compare(dev, c, 65535); + timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE); + timer_attach_interrupt(dev, c, handlers[c - 1]); + } + timer_resume(dev); + delay(3000); + for (int c = 1; c <= 4; c++) { + timer_set_mode(dev, c, TIMER_DISABLED); + } + Serial2.print("Channel 1 count: "); Serial2.println(count1); + Serial2.print("Channel 2 count: "); Serial2.println(count2); + Serial2.print("Channel 3 count: "); Serial2.println(count3); + Serial2.print("Channel 4 count: "); Serial2.println(count4); + break; + } +} + +// FIXME [0.1.0] move some incarnation of this into timer.h +void setTimerPeriod(timer_dev *dev, uint32 period_us) { + if (!period_us) { + // FIXME handle this case + ASSERT(0); + return; + } + + uint32 cycles = period_us * CYCLES_PER_MICROSECOND; + uint16 pre = (uint16)((cycles >> 16) + 1); + timer_set_prescaler(dev, pre); + timer_set_reload(dev, cycles / pre - 1); +} + +void handler1(void) { + val1 += rate1; + timer_set_compare(timers[t], TIMER_CH1, val1); + count1++; +} + +void handler2(void) { + val2 += rate2; + timer_set_compare(timers[t], TIMER_CH2, val2); + count2++; +} + +void handler3(void) { + val3 += rate3; + timer_set_compare(timers[t], TIMER_CH3, val3); + count3++; +} + +void handler4(void) { + val4 += rate4; + timer_set_compare(timers[t], TIMER_CH4, val4); + count4++; +} + +void handler3b(void) { + count3++; +} + +void handler4b(void) { + count4++; +} + +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/test-usart-dma.cpp b/Libmaple/libmaple/examples/test-usart-dma.cpp index ee85a1a3..5ff5b869 100644 --- a/Libmaple/libmaple/examples/test-usart-dma.cpp +++ b/Libmaple/libmaple/examples/test-usart-dma.cpp @@ -1,123 +1,123 @@ -/** - * @file test-usart-dma.cpp - * @author Marti Bolivar - * - * Simple test of DMA used with a USART receiver. - * - * Configures a USART receiver for use with DMA. Received bytes are - * placed into a buffer, with an interrupt firing when the buffer is - * full. At that point, the USART transmitter will print the contents - * of the byte buffer. The buffer is continually filled and refilled - * in this manner. - * - * This example isn't very robust; don't use it in production. In - * particular, since the buffer keeps filling (DMA_CIRC_MODE is set), - * if you keep typing after filling the buffer, you'll overwrite - * earlier bytes; this may happen before those earlier bytes are done - * printing. - * - * This code is released into the public domain. - */ - -#include "dma.h" -#include "usart.h" -#include "gpio.h" - -#include "wirish.h" - -#define BAUD 9600 - -#define USART USART2 -#define USART_HWSER Serial2 -#define USART_DMA_DEV DMA1 -#define USART_RX_DMA_CHANNEL DMA_CH6 -#define USART_TX BOARD_USART2_TX_PIN -#define USART_RX BOARD_USART2_RX_PIN - -#define BUF_SIZE 8 -uint8 rx_buf[BUF_SIZE]; - -dma_irq_cause irq_cause; - -volatile uint32 irq_fired = 0; - -void init_usart(void); -void init_dma_xfer(void); -void rx_dma_irq(void); - -void setup(void) { - pinMode(BOARD_LED_PIN, OUTPUT); - - init_dma_xfer(); - init_usart(); -} - -void loop(void) { - toggleLED(); - delay(100); - - dma_channel_reg_map *ch_regs = dma_channel_regs(USART_DMA_DEV, - USART_RX_DMA_CHANNEL); - if (irq_fired) { - USART_HWSER.println("** IRQ **"); - irq_fired = 0; - } - USART_HWSER.print("["); - USART_HWSER.print(millis()); - USART_HWSER.print("]\tISR bits: 0x"); - uint8 isr_bits = dma_get_isr_bits(USART_DMA_DEV, USART_RX_DMA_CHANNEL); - USART_HWSER.print(isr_bits, HEX); - USART_HWSER.print("\tCCR: 0x"); - USART_HWSER.print(ch_regs->CCR, HEX); - USART_HWSER.print("\tCNDTR: 0x"); - USART_HWSER.print(ch_regs->CNDTR, HEX); - USART_HWSER.print("\tBuffer contents: "); - for (int i = 0; i < BUF_SIZE; i++) { - USART_HWSER.print('\''); - USART_HWSER.print(rx_buf[i]); - USART_HWSER.print('\''); - if (i < BUF_SIZE - 1) USART_HWSER.print(", "); - } - USART_HWSER.println(); - if (isr_bits == 0x7) { - USART_HWSER.println("** Clearing ISR bits."); - dma_clear_isr_bits(USART_DMA_DEV, USART_RX_DMA_CHANNEL); - } -} - -/* Configure USART receiver for use with DMA */ -void init_usart(void) { - USART_HWSER.begin(BAUD); - USART->regs->CR3 = USART_CR3_DMAR; -} - -/* Configure DMA transmission */ -void init_dma_xfer(void) { - dma_init(USART_DMA_DEV); - dma_setup_transfer(USART_DMA_DEV, USART_RX_DMA_CHANNEL, - &USART->regs->DR, DMA_SIZE_8BITS, - rx_buf, DMA_SIZE_8BITS, - (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_TRNS_CMPLT)); - dma_set_num_transfers(USART_DMA_DEV, USART_RX_DMA_CHANNEL, BUF_SIZE); - dma_attach_interrupt(USART_DMA_DEV, USART_RX_DMA_CHANNEL, rx_dma_irq); - dma_enable(USART_DMA_DEV, USART_RX_DMA_CHANNEL); -} - -void rx_dma_irq(void) { - irq_fired = true; -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +/** + * @file test-usart-dma.cpp + * @author Marti Bolivar + * + * Simple test of DMA used with a USART receiver. + * + * Configures a USART receiver for use with DMA. Received bytes are + * placed into a buffer, with an interrupt firing when the buffer is + * full. At that point, the USART transmitter will print the contents + * of the byte buffer. The buffer is continually filled and refilled + * in this manner. + * + * This example isn't very robust; don't use it in production. In + * particular, since the buffer keeps filling (DMA_CIRC_MODE is set), + * if you keep typing after filling the buffer, you'll overwrite + * earlier bytes; this may happen before those earlier bytes are done + * printing. + * + * This code is released into the public domain. + */ + +#include "dma.h" +#include "usart.h" +#include "gpio.h" + +#include "wirish.h" + +#define BAUD 9600 + +#define USART USART2 +#define USART_HWSER Serial2 +#define USART_DMA_DEV DMA1 +#define USART_RX_DMA_CHANNEL DMA_CH6 +#define USART_TX BOARD_USART2_TX_PIN +#define USART_RX BOARD_USART2_RX_PIN + +#define BUF_SIZE 8 +uint8 rx_buf[BUF_SIZE]; + +dma_irq_cause irq_cause; + +volatile uint32 irq_fired = 0; + +void init_usart(void); +void init_dma_xfer(void); +void rx_dma_irq(void); + +void setup(void) { + pinMode(BOARD_LED_PIN, OUTPUT); + + init_dma_xfer(); + init_usart(); +} + +void loop(void) { + toggleLED(); + delay(100); + + dma_channel_reg_map *ch_regs = dma_channel_regs(USART_DMA_DEV, + USART_RX_DMA_CHANNEL); + if (irq_fired) { + USART_HWSER.println("** IRQ **"); + irq_fired = 0; + } + USART_HWSER.print("["); + USART_HWSER.print(millis()); + USART_HWSER.print("]\tISR bits: 0x"); + uint8 isr_bits = dma_get_isr_bits(USART_DMA_DEV, USART_RX_DMA_CHANNEL); + USART_HWSER.print(isr_bits, HEX); + USART_HWSER.print("\tCCR: 0x"); + USART_HWSER.print(ch_regs->CCR, HEX); + USART_HWSER.print("\tCNDTR: 0x"); + USART_HWSER.print(ch_regs->CNDTR, HEX); + USART_HWSER.print("\tBuffer contents: "); + for (int i = 0; i < BUF_SIZE; i++) { + USART_HWSER.print('\''); + USART_HWSER.print(rx_buf[i]); + USART_HWSER.print('\''); + if (i < BUF_SIZE - 1) USART_HWSER.print(", "); + } + USART_HWSER.println(); + if (isr_bits == 0x7) { + USART_HWSER.println("** Clearing ISR bits."); + dma_clear_isr_bits(USART_DMA_DEV, USART_RX_DMA_CHANNEL); + } +} + +/* Configure USART receiver for use with DMA */ +void init_usart(void) { + USART_HWSER.begin(BAUD); + USART->regs->CR3 = USART_CR3_DMAR; +} + +/* Configure DMA transmission */ +void init_dma_xfer(void) { + dma_init(USART_DMA_DEV); + dma_setup_transfer(USART_DMA_DEV, USART_RX_DMA_CHANNEL, + &USART->regs->DR, DMA_SIZE_8BITS, + rx_buf, DMA_SIZE_8BITS, + (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_TRNS_CMPLT)); + dma_set_num_transfers(USART_DMA_DEV, USART_RX_DMA_CHANNEL, BUF_SIZE); + dma_attach_interrupt(USART_DMA_DEV, USART_RX_DMA_CHANNEL, rx_dma_irq); + dma_enable(USART_DMA_DEV, USART_RX_DMA_CHANNEL); +} + +void rx_dma_irq(void) { + irq_fired = true; +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/vga-leaf.cpp b/Libmaple/libmaple/examples/vga-leaf.cpp index 0064e78b..f31dc875 100644 --- a/Libmaple/libmaple/examples/vga-leaf.cpp +++ b/Libmaple/libmaple/examples/vga-leaf.cpp @@ -1,244 +1,244 @@ -/* - VGA Output - - Outputs a red and white leaf to VGA. It should run most VGA monitors - at 640x480, though it does not follow the timing spec very - carefully. Real twisted or shielded wires, proper grounding, and not - doing this on a breadboard are recommended (but it seems to work ok - without). - - SerialUSB and SysTick are disabled to get rid of the most frequently - occurring interrupts (which mess with timing). This means that you - have to use perpetual bootloader mode or the reset button to flash - new programs. - - How to wire this to a VGA port: - D6 via ~200ohms to VGA Red (1) - D7 via ~200ohms to VGA Green (2) - D8 via ~200ohms to VGA Blue (3) - D11 to VGA VSync (14) (swapped?) - D12 to VGA HSync (13) (swapped?) - GND to VGA Ground (5) - GND to VGA Sync Ground (10) - - See also: - - http://pinouts.ru/Video/VGA15_pinout.shtml - - http://www.epanorama.net/documents/pc/vga_timing.html - - Created 20 July 2010 - By Bryan Newbold for LeafLabs - This code is released with no strings attached. - */ - -// FIXME: generalize for Native and Mini - -#include "wirish.h" - -// Pinouts -- you also must change the GPIO macros below if you change -// these -#define VGA_R 6 // STM32: A8 -#define VGA_G 7 // STM32: A9 -#define VGA_B 8 // STM32: A10 -#define VGA_V 11 // STM32: A6 -#define VGA_H 12 // STM32: A7 - -// These low level (and STM32 specific) macros make GPIO writes much -// faster -#define ABSRR ((volatile uint32*)0x40010810) -#define ABRR ((volatile uint32*)0x40010814) - -#define RBIT 8 // (see pinouts) -#define GBIT 9 -#define BBIT 10 - -#define VGA_R_HIGH *ABSRR = BIT(RBIT) -#define VGA_R_LOW *ABRR = BIT(RBIT) -#define VGA_G_HIGH *ABSRR = BIT(GBIT) -#define VGA_G_LOW *ABRR = BIT(GBIT) -#define VGA_B_HIGH *ABSRR = BIT(BBIT) -#define VGA_B_LOW *ABRR = BIT(BBIT) - -#define ON_COLOR BIT(RBIT) -#define OFF_COLOR (BIT(RBIT) | BIT(GBIT) | BIT(BBIT)) - -// set has priority, so clear every bit and set some given bits: -#define VGA_COLOR(c) (*ABSRR = c | \ - BIT(RBIT+16) | BIT(GBIT+16) | BIT(BBIT+16)) - -#define VGA_V_HIGH *ABSRR = BIT(6) -#define VGA_V_LOW *ABRR = BIT(6) -#define VGA_H_HIGH *ABSRR = BIT(7) -#define VGA_H_LOW *ABRR = BIT(7) - -void isr_porch(void); -void isr_start(void); -void isr_stop(void); -void isr_update(void); - -uint16 x = 0; // X coordinate -uint16 y = 0; // Y coordinate -uint16 logo_y = 0; // Y coordinate, mapped into valid logo index (for speed) -bool v_active = true; // Are we in the image? - -const uint8 x_max = 16; -const uint8 y_max = 18; -uint32 logo[y_max][x_max] = { - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, - {0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,}, - {0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,}, - {0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,}, - {0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,}, - {0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,}, - {0,0,1,0,0,1,0,1,0,1,0,0,1,0,0,0,}, - {0,1,0,0,0,0,1,1,1,0,0,0,0,1,0,0,}, - {0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,}, - {1,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0,}, - {1,0,0,0,0,1,0,1,0,1,0,0,0,0,1,0,}, - {1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,}, - {0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,}, - {0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,}, - {0,0,0,0,1,1,1,0,1,1,1,0,0,0,0,0,}, - {0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,}, - {0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,}, - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, }; - -HardwareTimer timer(4); - -void setup() { - // Setup our pins - pinMode(BOARD_LED_PIN, OUTPUT); - pinMode(VGA_R, OUTPUT); - pinMode(VGA_G, OUTPUT); - pinMode(VGA_B, OUTPUT); - pinMode(VGA_V, OUTPUT); - pinMode(VGA_H, OUTPUT); - digitalWrite(VGA_R, LOW); - digitalWrite(VGA_G, LOW); - digitalWrite(VGA_B, LOW); - digitalWrite(VGA_H, HIGH); - digitalWrite(VGA_V, HIGH); - - // Fill the logo array with color patterns corresponding to its - // truth value. Note that we could get more tricky here, since - // there are 3 bits of color. - for (int y = 0; y < y_max; y++) { - for (int x = 0; x < x_max; x++) { - logo[y][x] = logo[y][x] ? ON_COLOR : OFF_COLOR; - } - } - - // This gets rid of the majority of the interrupt artifacts; - // there's still a glitch for low values of y, but let's not worry - // about that. (Probably due to the hackish way vsync is done). - SerialUSB.end(); - systick_disable(); - - // Configure - timer.pause(); // while we configure - timer.setPrescaleFactor(1); // Full speed - timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE); - timer.setMode(TIMER_CH2, TIMER_OUTPUT_COMPARE); - timer.setMode(TIMER_CH3, TIMER_OUTPUT_COMPARE); - timer.setMode(TIMER_CH4, TIMER_OUTPUT_COMPARE); - timer.setOverflow(2287); // Total line time - - timer.setCompare(TIMER_CH1, 200); - timer.attachInterrupt(TIMER_CH1, isr_porch); - timer.setCompare(TIMER_CH2, 300); - timer.attachInterrupt(TIMER_CH2, isr_start); - timer.setCompare(TIMER_CH3, 2170); - timer.attachInterrupt(TIMER_CH3, isr_stop); - timer.setCompare(TIMER_CH4, 1); // Could be zero, I guess - timer.attachInterrupt(TIMER_CH4, isr_update); - - timer.setCount(0); // Ready... - timer.resume(); // Go! -} - -void loop() { - toggleLED(); - delay(100); - - // Everything happens in the interrupts! -} - -// This ISR will end horizontal sync for most of the image and -// setup the vertical sync for higher line counts -void isr_porch(void) { - VGA_H_HIGH; - y++; - logo_y = map(y, 0, 478, 0, y_max); - // Back to the top - if (y >= 523) { - y = 1; - logo_y = 0; - v_active = true; - return; - } - // Other vsync stuff below the image - if (y >= 492) { - VGA_V_HIGH; - return; - } - if (y >= 490) { - VGA_V_LOW; - return; - } - if (y >= 479) { - v_active = false; - return; - } -} - -// This is the main horizontal sweep -void isr_start(void) { - // Skip if we're not in the image at all - if (!v_active) { - return; - } - - // Start Red - VGA_R_LOW; - VGA_R_HIGH; - - // For each "pixel", go ON_COLOR or OFF_COLOR - for (x = 0; x < 16; x++) { - // setting the color several times is just an easy way to - // delay, so the image is wider. if you only do the following - // once, you'll be able to make the logo array bigger: - VGA_COLOR(logo[logo_y][x]); - VGA_COLOR(logo[logo_y][x]); - VGA_COLOR(logo[logo_y][x]); - VGA_COLOR(logo[logo_y][x]); - VGA_COLOR(logo[logo_y][x]); - VGA_COLOR(logo[logo_y][x]); - } -} - -// End of the horizontal line -void isr_stop(void) { - if (!v_active) { - return; - } - VGA_R_LOW; - VGA_G_LOW; - VGA_B_LOW; -} - -// Setup horizonal sync -void isr_update(void) { - VGA_H_LOW; -} - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +/* + VGA Output + + Outputs a red and white leaf to VGA. It should run most VGA monitors + at 640x480, though it does not follow the timing spec very + carefully. Real twisted or shielded wires, proper grounding, and not + doing this on a breadboard are recommended (but it seems to work ok + without). + + SerialUSB and SysTick are disabled to get rid of the most frequently + occurring interrupts (which mess with timing). This means that you + have to use perpetual bootloader mode or the reset button to flash + new programs. + + How to wire this to a VGA port: + D6 via ~200ohms to VGA Red (1) + D7 via ~200ohms to VGA Green (2) + D8 via ~200ohms to VGA Blue (3) + D11 to VGA VSync (14) (swapped?) + D12 to VGA HSync (13) (swapped?) + GND to VGA Ground (5) + GND to VGA Sync Ground (10) + + See also: + - http://pinouts.ru/Video/VGA15_pinout.shtml + - http://www.epanorama.net/documents/pc/vga_timing.html + + Created 20 July 2010 + By Bryan Newbold for LeafLabs + This code is released with no strings attached. + */ + +// FIXME: generalize for Native and Mini + +#include "wirish.h" + +// Pinouts -- you also must change the GPIO macros below if you change +// these +#define VGA_R 6 // STM32: A8 +#define VGA_G 7 // STM32: A9 +#define VGA_B 8 // STM32: A10 +#define VGA_V 11 // STM32: A6 +#define VGA_H 12 // STM32: A7 + +// These low level (and STM32 specific) macros make GPIO writes much +// faster +#define ABSRR ((volatile uint32*)0x40010810) +#define ABRR ((volatile uint32*)0x40010814) + +#define RBIT 8 // (see pinouts) +#define GBIT 9 +#define BBIT 10 + +#define VGA_R_HIGH *ABSRR = BIT(RBIT) +#define VGA_R_LOW *ABRR = BIT(RBIT) +#define VGA_G_HIGH *ABSRR = BIT(GBIT) +#define VGA_G_LOW *ABRR = BIT(GBIT) +#define VGA_B_HIGH *ABSRR = BIT(BBIT) +#define VGA_B_LOW *ABRR = BIT(BBIT) + +#define ON_COLOR BIT(RBIT) +#define OFF_COLOR (BIT(RBIT) | BIT(GBIT) | BIT(BBIT)) + +// set has priority, so clear every bit and set some given bits: +#define VGA_COLOR(c) (*ABSRR = c | \ + BIT(RBIT+16) | BIT(GBIT+16) | BIT(BBIT+16)) + +#define VGA_V_HIGH *ABSRR = BIT(6) +#define VGA_V_LOW *ABRR = BIT(6) +#define VGA_H_HIGH *ABSRR = BIT(7) +#define VGA_H_LOW *ABRR = BIT(7) + +void isr_porch(void); +void isr_start(void); +void isr_stop(void); +void isr_update(void); + +uint16 x = 0; // X coordinate +uint16 y = 0; // Y coordinate +uint16 logo_y = 0; // Y coordinate, mapped into valid logo index (for speed) +bool v_active = true; // Are we in the image? + +const uint8 x_max = 16; +const uint8 y_max = 18; +uint32 logo[y_max][x_max] = { + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, + {0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,}, + {0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,}, + {0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,}, + {0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,}, + {0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,}, + {0,0,1,0,0,1,0,1,0,1,0,0,1,0,0,0,}, + {0,1,0,0,0,0,1,1,1,0,0,0,0,1,0,0,}, + {0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,}, + {1,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0,}, + {1,0,0,0,0,1,0,1,0,1,0,0,0,0,1,0,}, + {1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,}, + {0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,}, + {0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,}, + {0,0,0,0,1,1,1,0,1,1,1,0,0,0,0,0,}, + {0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,}, + {0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, }; + +HardwareTimer timer(4); + +void setup() { + // Setup our pins + pinMode(BOARD_LED_PIN, OUTPUT); + pinMode(VGA_R, OUTPUT); + pinMode(VGA_G, OUTPUT); + pinMode(VGA_B, OUTPUT); + pinMode(VGA_V, OUTPUT); + pinMode(VGA_H, OUTPUT); + digitalWrite(VGA_R, LOW); + digitalWrite(VGA_G, LOW); + digitalWrite(VGA_B, LOW); + digitalWrite(VGA_H, HIGH); + digitalWrite(VGA_V, HIGH); + + // Fill the logo array with color patterns corresponding to its + // truth value. Note that we could get more tricky here, since + // there are 3 bits of color. + for (int y = 0; y < y_max; y++) { + for (int x = 0; x < x_max; x++) { + logo[y][x] = logo[y][x] ? ON_COLOR : OFF_COLOR; + } + } + + // This gets rid of the majority of the interrupt artifacts; + // there's still a glitch for low values of y, but let's not worry + // about that. (Probably due to the hackish way vsync is done). + SerialUSB.end(); + systick_disable(); + + // Configure + timer.pause(); // while we configure + timer.setPrescaleFactor(1); // Full speed + timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE); + timer.setMode(TIMER_CH2, TIMER_OUTPUT_COMPARE); + timer.setMode(TIMER_CH3, TIMER_OUTPUT_COMPARE); + timer.setMode(TIMER_CH4, TIMER_OUTPUT_COMPARE); + timer.setOverflow(2287); // Total line time + + timer.setCompare(TIMER_CH1, 200); + timer.attachInterrupt(TIMER_CH1, isr_porch); + timer.setCompare(TIMER_CH2, 300); + timer.attachInterrupt(TIMER_CH2, isr_start); + timer.setCompare(TIMER_CH3, 2170); + timer.attachInterrupt(TIMER_CH3, isr_stop); + timer.setCompare(TIMER_CH4, 1); // Could be zero, I guess + timer.attachInterrupt(TIMER_CH4, isr_update); + + timer.setCount(0); // Ready... + timer.resume(); // Go! +} + +void loop() { + toggleLED(); + delay(100); + + // Everything happens in the interrupts! +} + +// This ISR will end horizontal sync for most of the image and +// setup the vertical sync for higher line counts +void isr_porch(void) { + VGA_H_HIGH; + y++; + logo_y = map(y, 0, 478, 0, y_max); + // Back to the top + if (y >= 523) { + y = 1; + logo_y = 0; + v_active = true; + return; + } + // Other vsync stuff below the image + if (y >= 492) { + VGA_V_HIGH; + return; + } + if (y >= 490) { + VGA_V_LOW; + return; + } + if (y >= 479) { + v_active = false; + return; + } +} + +// This is the main horizontal sweep +void isr_start(void) { + // Skip if we're not in the image at all + if (!v_active) { + return; + } + + // Start Red + VGA_R_LOW; + VGA_R_HIGH; + + // For each "pixel", go ON_COLOR or OFF_COLOR + for (x = 0; x < 16; x++) { + // setting the color several times is just an easy way to + // delay, so the image is wider. if you only do the following + // once, you'll be able to make the logo array bigger: + VGA_COLOR(logo[logo_y][x]); + VGA_COLOR(logo[logo_y][x]); + VGA_COLOR(logo[logo_y][x]); + VGA_COLOR(logo[logo_y][x]); + VGA_COLOR(logo[logo_y][x]); + VGA_COLOR(logo[logo_y][x]); + } +} + +// End of the horizontal line +void isr_stop(void) { + if (!v_active) { + return; + } + VGA_R_LOW; + VGA_G_LOW; + VGA_B_LOW; +} + +// Setup horizonal sync +void isr_update(void) { + VGA_H_LOW; +} + +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/examples/vga-scope.cpp b/Libmaple/libmaple/examples/vga-scope.cpp index 14c7b0bf..b5fa8a5f 100644 --- a/Libmaple/libmaple/examples/vga-scope.cpp +++ b/Libmaple/libmaple/examples/vga-scope.cpp @@ -1,205 +1,205 @@ -/* - VGA Oscilloscope demo. - - Connect a microphone or something like it to ANALOG_PIN (0V -- 3.3V - only; 0.2V -- 3.1V will probably look nicer); an attached VGA - monitor will display the signal roughly in real-time. - - The thick blue line corresponds roughly to 0V. - - This is a fairy crude hack, but it's fun to watch/toy around with. - - SerialUSB and SysTick are disabled to get rid of the most frequently - occurring interrupts (which mess with timing). This means that you - have to use perpetual bootloader mode or the reset button to flash - new programs. - - How to wire this to a VGA port: - D6 via ~200ohms to VGA Red (1) - D7 via ~200ohms to VGA Green (2) - D8 via ~200ohms to VGA Blue (3) - D11 to VGA VSync (14) (swapped?) - D12 to VGA HSync (13) (swapped?) - GND to VGA Ground (5) - GND to VGA Sync Ground (10) - - See also: - - http://pinouts.ru/Video/VGA15_pinout.shtml - - http://www.epanorama.net/documents/pc/vga_timing.html - - This code is released into the public domain. - - Authors: - - Bryan Newbold - Marti Bolivar - */ - -#include "wirish.h" -#include "systick.h" - -// FIXME: generalize for Native and Mini - -#define ANALOG_PIN 18 - -// Pinouts -- you also must change the GPIO macros below if you change -// these -#define VGA_R 6 // STM32: A8 -#define VGA_G 7 // STM32: A9 -#define VGA_B 8 // STM32: A10 -#define VGA_V 11 // STM32: A6 -#define VGA_H 12 // STM32: A7 - -// These low level (and STM32 specific) macros make GPIO writes much -// faster -#define ABSRR ((volatile uint32*)0x40010810) -#define ABRR ((volatile uint32*)0x40010814) - -#define RBIT 8 // (see pinouts) -#define GBIT 9 -#define BBIT 10 - -#define VGA_R_HIGH *ABSRR = BIT(RBIT) -#define VGA_R_LOW *ABRR = BIT(RBIT) -#define VGA_G_HIGH *ABSRR = BIT(GBIT) -#define VGA_G_LOW *ABRR = BIT(GBIT) -#define VGA_B_HIGH *ABSRR = BIT(BBIT) -#define VGA_B_LOW *ABRR = BIT(BBIT) - -#define COLOR_WHITE (BIT(RBIT) | BIT(GBIT) | BIT(BBIT)) -#define COLOR_BLACK 0 -#define COLOR_RED BIT(RBIT) -#define COLOR_GREEN BIT(GBIT) -#define COLOR_BLUE BIT(BBIT) - -#define BORDER_COLOR COLOR_BLUE - -// set has priority, so clear every bit and set some given bits: -#define VGA_COLOR(c) (*ABSRR = c | \ - BIT(RBIT + 16) | BIT(GBIT + 16) | BIT(BBIT + 16)) - -#define VGA_V_HIGH *ABSRR = BIT(6) -#define VGA_V_LOW *ABRR = BIT(6) -#define VGA_H_HIGH *ABSRR = BIT(7) -#define VGA_H_LOW *ABRR = BIT(7) - -void isr_porch(void); -void isr_start(void); -void isr_stop(void); -void isr_update(void); - -void setup() { - pinMode(BOARD_LED_PIN, OUTPUT); - pinMode(ANALOG_PIN, INPUT_ANALOG); - digitalWrite(BOARD_LED_PIN, 1); - pinMode(VGA_R, OUTPUT); - pinMode(VGA_G, OUTPUT); - pinMode(VGA_B, OUTPUT); - pinMode(VGA_V, OUTPUT); - pinMode(VGA_H, OUTPUT); - - // Send a message out USART2 - Serial2.begin(9600); - Serial2.println("Time to kill the radio star..."); - - // This gets rid of the majority of the interrupt artifacts; - // there's still a glitch for low values of y, but let's not worry - // about that. (Probably due to the hackish way vsync is done). - SerialUSB.end(); - systick_disable(); - - digitalWrite(VGA_R, 0); - digitalWrite(VGA_G, 0); - digitalWrite(VGA_B, 0); - digitalWrite(VGA_H, 1); - digitalWrite(VGA_V, 1); - - timer_pause(TIMER4); - timer_set_prescaler(TIMER4, 0); - timer_set_mode(TIMER4, 1, TIMER_OUTPUT_COMPARE); - timer_set_mode(TIMER4, 2, TIMER_OUTPUT_COMPARE); - timer_set_mode(TIMER4, 3, TIMER_OUTPUT_COMPARE); - timer_set_mode(TIMER4, 4, TIMER_OUTPUT_COMPARE); - timer_set_reload(TIMER4, 2287); - timer_set_compare(TIMER4, 1, 200); - timer_set_compare(TIMER4, 2, 250); - timer_set_compare(TIMER4, 3, 2170); // 2219 max... - timer_set_compare(TIMER4, 4, 1); - timer_attach_interrupt(TIMER4, 1, isr_porch); - timer_attach_interrupt(TIMER4, 2, isr_start); - timer_attach_interrupt(TIMER4, 3, isr_stop); - timer_attach_interrupt(TIMER4, 4, isr_update); - - timer_set_count(TIMER4, 0); - timer_resume(TIMER4); -} - -uint16 y = 0; -uint16 val = 0; -bool v_active = true; -const uint16 x_max = 60; // empirically (and sloppily) determined - -void isr_porch(void) { - VGA_H_HIGH; - y++; - val = map(analogRead(ANALOG_PIN), 0, 4095, 0, x_max); - if (y >= 523) { - y = 1; - v_active = true; - return; - } - if (y >= 492) { - VGA_V_HIGH; - return; - } - if (y >= 490) { - VGA_V_LOW; - return; - } - if (y >= 479) { - v_active = false; - return; - } - -} - -void isr_start(void) { - if (!v_active) { - return; - } - VGA_COLOR(BORDER_COLOR); - for (int x = 0; x < val; x++) { - VGA_COLOR(COLOR_BLACK); - } - VGA_COLOR(COLOR_WHITE); - VGA_COLOR(COLOR_BLACK); -} - -void isr_stop(void) { - if (!v_active) { - return; - } - VGA_COLOR(COLOR_BLACK); -} - -void isr_update(void) { - VGA_H_LOW; -} - -void loop() { - toggleLED(); - delay(100); -} - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} +/* + VGA Oscilloscope demo. + + Connect a microphone or something like it to ANALOG_PIN (0V -- 3.3V + only; 0.2V -- 3.1V will probably look nicer); an attached VGA + monitor will display the signal roughly in real-time. + + The thick blue line corresponds roughly to 0V. + + This is a fairy crude hack, but it's fun to watch/toy around with. + + SerialUSB and SysTick are disabled to get rid of the most frequently + occurring interrupts (which mess with timing). This means that you + have to use perpetual bootloader mode or the reset button to flash + new programs. + + How to wire this to a VGA port: + D6 via ~200ohms to VGA Red (1) + D7 via ~200ohms to VGA Green (2) + D8 via ~200ohms to VGA Blue (3) + D11 to VGA VSync (14) (swapped?) + D12 to VGA HSync (13) (swapped?) + GND to VGA Ground (5) + GND to VGA Sync Ground (10) + + See also: + - http://pinouts.ru/Video/VGA15_pinout.shtml + - http://www.epanorama.net/documents/pc/vga_timing.html + + This code is released into the public domain. + + Authors: + + Bryan Newbold + Marti Bolivar + */ + +#include "wirish.h" +#include "systick.h" + +// FIXME: generalize for Native and Mini + +#define ANALOG_PIN 18 + +// Pinouts -- you also must change the GPIO macros below if you change +// these +#define VGA_R 6 // STM32: A8 +#define VGA_G 7 // STM32: A9 +#define VGA_B 8 // STM32: A10 +#define VGA_V 11 // STM32: A6 +#define VGA_H 12 // STM32: A7 + +// These low level (and STM32 specific) macros make GPIO writes much +// faster +#define ABSRR ((volatile uint32*)0x40010810) +#define ABRR ((volatile uint32*)0x40010814) + +#define RBIT 8 // (see pinouts) +#define GBIT 9 +#define BBIT 10 + +#define VGA_R_HIGH *ABSRR = BIT(RBIT) +#define VGA_R_LOW *ABRR = BIT(RBIT) +#define VGA_G_HIGH *ABSRR = BIT(GBIT) +#define VGA_G_LOW *ABRR = BIT(GBIT) +#define VGA_B_HIGH *ABSRR = BIT(BBIT) +#define VGA_B_LOW *ABRR = BIT(BBIT) + +#define COLOR_WHITE (BIT(RBIT) | BIT(GBIT) | BIT(BBIT)) +#define COLOR_BLACK 0 +#define COLOR_RED BIT(RBIT) +#define COLOR_GREEN BIT(GBIT) +#define COLOR_BLUE BIT(BBIT) + +#define BORDER_COLOR COLOR_BLUE + +// set has priority, so clear every bit and set some given bits: +#define VGA_COLOR(c) (*ABSRR = c | \ + BIT(RBIT + 16) | BIT(GBIT + 16) | BIT(BBIT + 16)) + +#define VGA_V_HIGH *ABSRR = BIT(6) +#define VGA_V_LOW *ABRR = BIT(6) +#define VGA_H_HIGH *ABSRR = BIT(7) +#define VGA_H_LOW *ABRR = BIT(7) + +void isr_porch(void); +void isr_start(void); +void isr_stop(void); +void isr_update(void); + +void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); + pinMode(ANALOG_PIN, INPUT_ANALOG); + digitalWrite(BOARD_LED_PIN, 1); + pinMode(VGA_R, OUTPUT); + pinMode(VGA_G, OUTPUT); + pinMode(VGA_B, OUTPUT); + pinMode(VGA_V, OUTPUT); + pinMode(VGA_H, OUTPUT); + + // Send a message out USART2 + Serial2.begin(9600); + Serial2.println("Time to kill the radio star..."); + + // This gets rid of the majority of the interrupt artifacts; + // there's still a glitch for low values of y, but let's not worry + // about that. (Probably due to the hackish way vsync is done). + SerialUSB.end(); + systick_disable(); + + digitalWrite(VGA_R, 0); + digitalWrite(VGA_G, 0); + digitalWrite(VGA_B, 0); + digitalWrite(VGA_H, 1); + digitalWrite(VGA_V, 1); + + timer_pause(TIMER4); + timer_set_prescaler(TIMER4, 0); + timer_set_mode(TIMER4, 1, TIMER_OUTPUT_COMPARE); + timer_set_mode(TIMER4, 2, TIMER_OUTPUT_COMPARE); + timer_set_mode(TIMER4, 3, TIMER_OUTPUT_COMPARE); + timer_set_mode(TIMER4, 4, TIMER_OUTPUT_COMPARE); + timer_set_reload(TIMER4, 2287); + timer_set_compare(TIMER4, 1, 200); + timer_set_compare(TIMER4, 2, 250); + timer_set_compare(TIMER4, 3, 2170); // 2219 max... + timer_set_compare(TIMER4, 4, 1); + timer_attach_interrupt(TIMER4, 1, isr_porch); + timer_attach_interrupt(TIMER4, 2, isr_start); + timer_attach_interrupt(TIMER4, 3, isr_stop); + timer_attach_interrupt(TIMER4, 4, isr_update); + + timer_set_count(TIMER4, 0); + timer_resume(TIMER4); +} + +uint16 y = 0; +uint16 val = 0; +bool v_active = true; +const uint16 x_max = 60; // empirically (and sloppily) determined + +void isr_porch(void) { + VGA_H_HIGH; + y++; + val = map(analogRead(ANALOG_PIN), 0, 4095, 0, x_max); + if (y >= 523) { + y = 1; + v_active = true; + return; + } + if (y >= 492) { + VGA_V_HIGH; + return; + } + if (y >= 490) { + VGA_V_LOW; + return; + } + if (y >= 479) { + v_active = false; + return; + } + +} + +void isr_start(void) { + if (!v_active) { + return; + } + VGA_COLOR(BORDER_COLOR); + for (int x = 0; x < val; x++) { + VGA_COLOR(COLOR_BLACK); + } + VGA_COLOR(COLOR_WHITE); + VGA_COLOR(COLOR_BLACK); +} + +void isr_stop(void) { + if (!v_active) { + return; + } + VGA_COLOR(COLOR_BLACK); +} + +void isr_update(void) { + VGA_H_LOW; +} + +void loop() { + toggleLED(); + delay(100); +} + +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/libmaple/adc.c b/Libmaple/libmaple/libmaple/adc.c index cc1129e3..aeeb43c0 100644 --- a/Libmaple/libmaple/libmaple/adc.c +++ b/Libmaple/libmaple/libmaple/adc.c @@ -1,200 +1,200 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file adc.c - * - * @brief Analog to digital converter routines - * - * IMPORTANT: maximum external impedance must be below 0.4kOhms for 1.5 - * sample conversion time. - * - * At 55.5 cycles/sample, the external input impedance < 50kOhms. - * - * See STM32 manual RM0008 for how to calculate this. - */ - -#include "libmaple.h" -#include "rcc.h" -#include "adc.h" - -static adc_dev adc1 = { - .regs = ADC1_BASE, - .clk_id = RCC_ADC1 -}; -/** ADC1 device. */ -const adc_dev *ADC1 = &adc1; - -static adc_dev adc2 = { - .regs = ADC2_BASE, - .clk_id = RCC_ADC2 -}; -/** ADC2 device. */ -const adc_dev *ADC2 = &adc2; - -#ifdef STM32_HIGH_DENSITY -adc_dev adc3 = { - .regs = ADC3_BASE, - .clk_id = RCC_ADC3 -}; -/** ADC3 device. */ -const adc_dev *ADC3 = &adc3; -#endif - -/** - * @brief Initialize an ADC peripheral. - * - * Initializes the RCC clock line for the given peripheral. Resets - * ADC device registers. - * - * @param dev ADC peripheral to initialize - */ -void adc_init(const adc_dev *dev) { - rcc_clk_enable(dev->clk_id); -#ifdef STM32F2 - if(dev->clk_id == RCC_ADC1) { - rcc_reset_dev(dev->clk_id); - } -#else - rcc_reset_dev(dev->clk_id); -#endif -} - -/** - * @brief Set external event select for regular group - * @param dev ADC device - * @param event Event used to trigger the start of conversion. - * @see adc_extsel_event - */ -void adc_set_extsel(const adc_dev *dev, adc_extsel_event event) { - uint32 cr2 = dev->regs->CR2; - cr2 &= ~ADC_CR2_EXTSEL; - cr2 |= event; - dev->regs->CR2 = cr2; -} - -/** - * @brief Call a function on all ADC devices. - * @param fn Function to call on each ADC device. - */ -void adc_foreach(void (*fn)(const adc_dev*)) { - fn(ADC1); - fn(ADC2); -#ifdef STM32_HIGH_DENSITY - fn(ADC3); -#endif -} - -/** - * @brief Turn the given sample rate into values for ADC_SMPRx. Don't - * call this during conversion. - * @param dev adc device - * @param smp_rate sample rate to set - * @see adc_smp_rate - */ -void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate) { - uint32 adc_smpr1_val = 0, adc_smpr2_val = 0; - int i; - - for (i = 0; i < 10; i++) { - if (i < 8) { - /* ADC_SMPR1 determines sample time for channels [10,17] */ - adc_smpr1_val |= smp_rate << (i * 3); - } - /* ADC_SMPR2 determines sample time for channels [0,9] */ - adc_smpr2_val |= smp_rate << (i * 3); - } - - dev->regs->SMPR1 = adc_smpr1_val; - dev->regs->SMPR2 = adc_smpr2_val; -} - -/** - * @brief Calibrate an ADC peripheral - * @param dev adc device - */ -void adc_calibrate(const adc_dev *dev) { -#ifndef STM32F2 - __io uint32 *rstcal_bit = bb_perip(&(dev->regs->CR2), 3); - __io uint32 *cal_bit = bb_perip(&(dev->regs->CR2), 2); - - *rstcal_bit = 1; - while (*rstcal_bit) - ; - - *cal_bit = 1; - while (*cal_bit) - ; -#endif -} - -/** - * @brief Perform a single synchronous software triggered conversion on a - * channel. - * @param dev ADC device to use for reading. - * @param channel channel to convert - * @return conversion result - */ -uint16 adc_read(const adc_dev *dev, uint8 channel) { - adc_reg_map *regs = dev->regs; - - adc_set_reg_seqlen(dev, 1); - - regs->SQR3 = channel; - regs->CR2 |= ADC_CR2_SWSTART; - while(!(regs->SR & ADC_SR_EOC)) - ; - - return (uint16)(regs->DR & ADC_DR_DATA); -} - -void setupADC_F2() { -#ifdef STM32F2 - uint32 tmpreg1 = 0; - - tmpreg1 = ADC_COMMON->CCR; - - /* Clear MULTI, DELAY, DMA and ADCPRE bits */ -#define CR_CLEAR_MASK ((uint32)0xFFFC30E0) - tmpreg1 &= CR_CLEAR_MASK; - - /* Configure ADCx: Multi mode, Delay between two sampling time, ADC prescaler, - and DMA access mode for multimode */ - /* Set MULTI bits according to ADC_Mode value */ - /* Set ADCPRE bits according to ADC_Prescaler value */ - /* Set DMA bits according to ADC_DMAAccessMode value */ - /* Set DELAY bits according to ADC_TwoSamplingDelay value */ -#define ADC_Mode_Independent 0 -#define ADC_Prescaler_Div2 0 -#define ADC_DMAAccessMode_Disabled 0 /* DMA mode disabled */ -#define ADC_TwoSamplingDelay_5Cycles 0 - - tmpreg1 |= ADC_Mode_Independent | ADC_Prescaler_Div2 | ADC_DMAAccessMode_Disabled | ADC_TwoSamplingDelay_5Cycles; - - /* Write to ADC CCR */ - ADC_COMMON->CCR = tmpreg1; -#endif -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file adc.c + * + * @brief Analog to digital converter routines + * + * IMPORTANT: maximum external impedance must be below 0.4kOhms for 1.5 + * sample conversion time. + * + * At 55.5 cycles/sample, the external input impedance < 50kOhms. + * + * See STM32 manual RM0008 for how to calculate this. + */ + +#include "libmaple.h" +#include "rcc.h" +#include "adc.h" + +static adc_dev adc1 = { + .regs = ADC1_BASE, + .clk_id = RCC_ADC1 +}; +/** ADC1 device. */ +const adc_dev *ADC1 = &adc1; + +static adc_dev adc2 = { + .regs = ADC2_BASE, + .clk_id = RCC_ADC2 +}; +/** ADC2 device. */ +const adc_dev *ADC2 = &adc2; + +#ifdef STM32_HIGH_DENSITY +adc_dev adc3 = { + .regs = ADC3_BASE, + .clk_id = RCC_ADC3 +}; +/** ADC3 device. */ +const adc_dev *ADC3 = &adc3; +#endif + +/** + * @brief Initialize an ADC peripheral. + * + * Initializes the RCC clock line for the given peripheral. Resets + * ADC device registers. + * + * @param dev ADC peripheral to initialize + */ +void adc_init(const adc_dev *dev) { + rcc_clk_enable(dev->clk_id); +#ifdef STM32F2 + if(dev->clk_id == RCC_ADC1) { + rcc_reset_dev(dev->clk_id); + } +#else + rcc_reset_dev(dev->clk_id); +#endif +} + +/** + * @brief Set external event select for regular group + * @param dev ADC device + * @param event Event used to trigger the start of conversion. + * @see adc_extsel_event + */ +void adc_set_extsel(const adc_dev *dev, adc_extsel_event event) { + uint32 cr2 = dev->regs->CR2; + cr2 &= ~ADC_CR2_EXTSEL; + cr2 |= event; + dev->regs->CR2 = cr2; +} + +/** + * @brief Call a function on all ADC devices. + * @param fn Function to call on each ADC device. + */ +void adc_foreach(void (*fn)(const adc_dev*)) { + fn(ADC1); + fn(ADC2); +#ifdef STM32_HIGH_DENSITY + fn(ADC3); +#endif +} + +/** + * @brief Turn the given sample rate into values for ADC_SMPRx. Don't + * call this during conversion. + * @param dev adc device + * @param smp_rate sample rate to set + * @see adc_smp_rate + */ +void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate) { + uint32 adc_smpr1_val = 0, adc_smpr2_val = 0; + int i; + + for (i = 0; i < 10; i++) { + if (i < 8) { + /* ADC_SMPR1 determines sample time for channels [10,17] */ + adc_smpr1_val |= smp_rate << (i * 3); + } + /* ADC_SMPR2 determines sample time for channels [0,9] */ + adc_smpr2_val |= smp_rate << (i * 3); + } + + dev->regs->SMPR1 = adc_smpr1_val; + dev->regs->SMPR2 = adc_smpr2_val; +} + +/** + * @brief Calibrate an ADC peripheral + * @param dev adc device + */ +void adc_calibrate(const adc_dev *dev) { +#ifndef STM32F2 + __io uint32 *rstcal_bit = bb_perip(&(dev->regs->CR2), 3); + __io uint32 *cal_bit = bb_perip(&(dev->regs->CR2), 2); + + *rstcal_bit = 1; + while (*rstcal_bit) + ; + + *cal_bit = 1; + while (*cal_bit) + ; +#endif +} + +/** + * @brief Perform a single synchronous software triggered conversion on a + * channel. + * @param dev ADC device to use for reading. + * @param channel channel to convert + * @return conversion result + */ +uint16 adc_read(const adc_dev *dev, uint8 channel) { + adc_reg_map *regs = dev->regs; + + adc_set_reg_seqlen(dev, 1); + + regs->SQR3 = channel; + regs->CR2 |= ADC_CR2_SWSTART; + while(!(regs->SR & ADC_SR_EOC)) + ; + + return (uint16)(regs->DR & ADC_DR_DATA); +} + +void setupADC_F2() { +#ifdef STM32F2 + uint32 tmpreg1 = 0; + + tmpreg1 = ADC_COMMON->CCR; + + /* Clear MULTI, DELAY, DMA and ADCPRE bits */ +#define CR_CLEAR_MASK ((uint32)0xFFFC30E0) + tmpreg1 &= CR_CLEAR_MASK; + + /* Configure ADCx: Multi mode, Delay between two sampling time, ADC prescaler, + and DMA access mode for multimode */ + /* Set MULTI bits according to ADC_Mode value */ + /* Set ADCPRE bits according to ADC_Prescaler value */ + /* Set DMA bits according to ADC_DMAAccessMode value */ + /* Set DELAY bits according to ADC_TwoSamplingDelay value */ +#define ADC_Mode_Independent 0 +#define ADC_Prescaler_Div2 0 +#define ADC_DMAAccessMode_Disabled 0 /* DMA mode disabled */ +#define ADC_TwoSamplingDelay_5Cycles 0 + + tmpreg1 |= ADC_Mode_Independent | ADC_Prescaler_Div2 | ADC_DMAAccessMode_Disabled | ADC_TwoSamplingDelay_5Cycles; + + /* Write to ADC CCR */ + ADC_COMMON->CCR = tmpreg1; +#endif +} diff --git a/Libmaple/libmaple/libmaple/adc.h b/Libmaple/libmaple/libmaple/adc.h index 6a2dcd5d..3a40d4c5 100644 --- a/Libmaple/libmaple/libmaple/adc.h +++ b/Libmaple/libmaple/libmaple/adc.h @@ -1,397 +1,397 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file adc.h - * - * @brief Analog-to-Digital Conversion (ADC) header. - */ - -#ifndef _ADC_H_ -#define _ADC_H_ - -#include "libmaple.h" -#include "bitband.h" -#include "rcc.h" - -#ifdef __cplusplus -extern "C"{ -#endif - - -#ifdef STM32F2 - typedef struct - { - __io uint32 CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ - __io uint32 CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ - __io uint32 CDR; /*!< ADC common regular data register for dual - AND triple modes, Address offset: ADC1 base address + 0x308 */ - } ADC_Common_TypeDef; -#define ADC_COMMON ((ADC_Common_TypeDef *) 0x40012300) - -#endif - -/** ADC register map type. */ -typedef struct adc_reg_map { - __io uint32 SR; ///< Status register - __io uint32 CR1; ///< Control register 1 - __io uint32 CR2; ///< Control register 2 - __io uint32 SMPR1; ///< Sample time register 1 - __io uint32 SMPR2; ///< Sample time register 2 - __io uint32 JOFR1; ///< Injected channel data offset register 1 - __io uint32 JOFR2; ///< Injected channel data offset register 2 - __io uint32 JOFR3; ///< Injected channel data offset register 3 - __io uint32 JOFR4; ///< Injected channel data offset register 4 - __io uint32 HTR; ///< Watchdog high threshold register - __io uint32 LTR; ///< Watchdog low threshold register - __io uint32 SQR1; ///< Regular sequence register 1 - __io uint32 SQR2; ///< Regular sequence register 2 - __io uint32 SQR3; ///< Regular sequence register 3 - __io uint32 JSQR; ///< Injected sequence register - __io uint32 JDR1; ///< Injected data register 1 - __io uint32 JDR2; ///< Injected data register 2 - __io uint32 JDR3; ///< Injected data register 3 - __io uint32 JDR4; ///< Injected data register 4 - __io uint32 DR; ///< Regular data register -} adc_reg_map; - -/** ADC device type. */ -typedef struct adc_dev { - adc_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ -} adc_dev; - -extern const adc_dev *ADC1; -extern const adc_dev *ADC2; -#ifdef STM32_HIGH_DENSITY -extern const adc_dev *ADC3; -#endif - -/* - * Register map base pointers - */ - -#ifdef STM32F2 - /** ADC1 register map base pointer. */ - #define ADC1_BASE ((struct adc_reg_map*)0x40012000) - /** ADC2 register map base pointer. */ - #define ADC2_BASE ((struct adc_reg_map*)0x40012100) - /** ADC3 register map base pointer. */ - #define ADC3_BASE ((struct adc_reg_map*)0x40012200) -#else - /** ADC1 register map base pointer. */ - #define ADC1_BASE ((struct adc_reg_map*)0x40012400) - /** ADC2 register map base pointer. */ - #define ADC2_BASE ((struct adc_reg_map*)0x40012800) - #ifdef STM32_HIGH_DENSITY - /** ADC3 register map base pointer. */ - #define ADC3_BASE ((struct adc_reg_map*)0x40013C00) - #endif -#endif - -/* - * Register bit definitions - */ - -/* Status register */ - -#define ADC_SR_AWD_BIT 0 -#define ADC_SR_EOC_BIT 1 -#define ADC_SR_JEOC_BIT 2 -#define ADC_SR_JSTRT_BIT 3 -#define ADC_SR_STRT_BIT 4 - -#define ADC_SR_AWD BIT(ADC_SR_AWD_BIT) -#define ADC_SR_EOC BIT(ADC_SR_EOC_BIT) -#define ADC_SR_JEOC BIT(ADC_SR_JEOC_BIT) -#define ADC_SR_JSTRT BIT(ADC_SR_JSTRT_BIT) -#define ADC_SR_STRT BIT(ADC_SR_STRT_BIT) - -/* Control register 1 */ - -#define ADC_CR1_EOCIE_BIT 5 -#define ADC_CR1_AWDIE_BIT 6 -#define ADC_CR1_JEOCIE_BIT 7 -#define ADC_CR1_SCAN_BIT 8 -#define ADC_CR1_AWDSGL_BIT 9 -#define ADC_CR1_JAUTO_BIT 10 -#define ADC_CR1_DISCEN_BIT 11 -#define ADC_CR1_JDISCEN_BIT 12 -#define ADC_CR1_JAWDEN_BIT 22 -#define ADC_CR1_AWDEN_BIT 23 - -#define ADC_CR1_AWDCH (0x1F) -#define ADC_CR1_EOCIE BIT(ADC_CR1_EOCIE_BIT) -#define ADC_CR1_AWDIE BIT(ADC_CR1_AWDIE_BIT) -#define ADC_CR1_JEOCIE BIT(ADC_CR1_JEOCIE_BIT) -#define ADC_CR1_SCAN BIT(ADC_CR1_SCAN_BIT) -#define ADC_CR1_AWDSGL BIT(ADC_CR1_AWDSGL_BIT) -#define ADC_CR1_JAUTO BIT(ADC_CR1_JAUTO_BIT) -#define ADC_CR1_DISCEN BIT(ADC_CR1_DISCEN_BIT) -#define ADC_CR1_JDISCEN BIT(ADC_CR1_JDISCEN_BIT) -#define ADC_CR1_DISCNUM (0xE000) -#define ADC_CR1_JAWDEN BIT(ADC_CR1_JAWDEN_BIT) -#define ADC_CR1_AWDEN BIT(ADC_CR1_AWDEN_BIT) - -/* Control register 2 */ - -#define ADC_CR2_ADON_BIT 0 -#define ADC_CR2_CONT_BIT 1 -#define ADC_CR2_CAL_BIT 2 -#define ADC_CR2_RSTCAL_BIT 3 -#define ADC_CR2_DMA_BIT 8 -#define ADC_CR2_ALIGN_BIT 11 -#define ADC_CR2_JEXTTRIG_BIT 15 -#define ADC_CR2_EXTTRIG_BIT 20 -#define ADC_CR2_TSEREFE_BIT 23 -#ifdef STM32F2 -#define ADC_CR2_JSWSTART_BIT 22 -#define ADC_CR2_SWSTART_BIT 30 -#define ADC_CR2_EXTSEL (0x0F000000) -#define ADC_CR2_JEXTSEL (0x000F0000) -#else -#define ADC_CR2_JSWSTART_BIT 21 -#define ADC_CR2_SWSTART_BIT 22 -#define ADC_CR2_EXTSEL (0x000E0000) -#define ADC_CR2_JEXTSEL (0x00007000) -#endif - - - -#define ADC_CR2_ADON BIT(ADC_CR2_ADON_BIT) -#define ADC_CR2_CONT BIT(ADC_CR2_CONT_BIT) -#define ADC_CR2_CAL BIT(ADC_CR2_CAL_BIT) -#define ADC_CR2_RSTCAL BIT(ADC_CR2_RSTCAL_BIT) -#define ADC_CR2_DMA BIT(ADC_CR2_DMA_BIT) -#define ADC_CR2_ALIGN BIT(ADC_CR2_ALIGN_BIT) -#define ADC_CR2_JEXTTRIG BIT(ADC_CR2_JEXTTRIG_BIT) -#define ADC_CR2_EXTTRIG BIT(ADC_CR2_EXTTRIG_BIT) -#define ADC_CR2_JSWSTART BIT(ADC_CR2_JSWSTART_BIT) -#define ADC_CR2_SWSTART BIT(ADC_CR2_SWSTART_BIT) -#define ADC_CR2_TSEREFE BIT(ADC_CR2_TSEREFE_BIT) - -/* Sample time register 1 */ - -#define ADC_SMPR1_SMP17 (0x7 << 21) -#define ADC_SMPR1_SMP16 (0x7 << 18) -#define ADC_SMPR1_SMP15 (0x7 << 15) -#define ADC_SMPR1_SMP14 (0x7 << 12) -#define ADC_SMPR1_SMP13 (0x7 << 9) -#define ADC_SMPR1_SMP12 (0x7 << 6) -#define ADC_SMPR1_SMP11 (0x7 << 3) -#define ADC_SMPR1_SMP10 0x7 - -/* Sample time register 2 */ - -#define ADC_SMPR2_SMP9 (0x7 << 27) -#define ADC_SMPR2_SMP8 (0x7 << 24) -#define ADC_SMPR2_SMP7 (0x7 << 21) -#define ADC_SMPR2_SMP6 (0x7 << 18) -#define ADC_SMPR2_SMP5 (0x7 << 15) -#define ADC_SMPR2_SMP4 (0x7 << 12) -#define ADC_SMPR2_SMP3 (0x7 << 9) -#define ADC_SMPR2_SMP2 (0x7 << 6) -#define ADC_SMPR2_SMP1 (0x7 << 3) -#define ADC_SMPR2_SMP0 0x7 - -/* Injected channel data offset register */ - -#define ADC_JOFR_JOFFSET 0x3FF - -/* Watchdog high threshold register */ - -#define ADC_HTR_HT 0x3FF - -/* Watchdog low threshold register */ - -#define ADC_LTR_LT 0x3FF - -/* Regular sequence register 1 */ - -#define ADC_SQR1_L (0x1F << 20) -#define ADC_SQR1_SQ16 (0x1F << 15) -#define ADC_SQR1_SQ15 (0x1F << 10) -#define ADC_SQR1_SQ14 (0x1F << 5) -#define ADC_SQR1_SQ13 0x1F - -/* Regular sequence register 2 */ - -#define ADC_SQR2_SQ12 (0x1F << 25) -#define ADC_SQR2_SQ11 (0x1F << 20) -#define ADC_SQR2_SQ10 (0x1F << 16) -#define ADC_SQR2_SQ9 (0x1F << 10) -#define ADC_SQR2_SQ8 (0x1F << 5) -#define ADC_SQR2_SQ7 0x1F - -/* Regular sequence register 3 */ - -#define ADC_SQR3_SQ6 (0x1F << 25) -#define ADC_SQR3_SQ5 (0x1F << 20) -#define ADC_SQR3_SQ4 (0x1F << 16) -#define ADC_SQR3_SQ3 (0x1F << 10) -#define ADC_SQR3_SQ2 (0x1F << 5) -#define ADC_SQR3_SQ1 0x1F - -/* Injected sequence register */ - -#define ADC_JSQR_JL (0x3 << 20) -#define ADC_JSQR_JL_1CONV (0x0 << 20) -#define ADC_JSQR_JL_2CONV (0x1 << 20) -#define ADC_JSQR_JL_3CONV (0x2 << 20) -#define ADC_JSQR_JL_4CONV (0x3 << 20) -#define ADC_JSQR_JSQ4 (0x1F << 15) -#define ADC_JSQR_JSQ3 (0x1F << 10) -#define ADC_JSQR_JSQ2 (0x1F << 5) -#define ADC_JSQR_JSQ1 0x1F - -/* Injected data registers */ - -#define ADC_JDR_JDATA 0xFFFF - -/* Regular data register */ - -#define ADC_DR_ADC2DATA (0xFFFF << 16) -#define ADC_DR_DATA 0xFFFF - -void adc_init(const adc_dev *dev); - -/** - * @brief External event selector for regular group conversion. - * @see adc_set_extsel - */ -typedef enum adc_extsel_event { - ADC_ADC12_TIM1_CC1 = (0 << 17), /**< ADC1 and ADC2: Timer 1 CC1 event */ - ADC_ADC12_TIM1_CC2 = (1 << 17), /**< ADC1 and ADC2: Timer 1 CC2 event */ - ADC_ADC12_TIM1_CC3 = (2 << 17), /**< ADC1 and ADC2: Timer 1 CC3 event */ - ADC_ADC12_TIM2_CC2 = (3 << 17), /**< ADC1 and ADC2: Timer 2 CC2 event */ - ADC_ADC12_TIM3_TRGO = (4 << 17), /**< ADC1 and ADC2: Timer 3 TRGO event */ - ADC_ADC12_TIM4_CC4 = (5 << 17), /**< ADC1 and ADC2: Timer 4 CC4 event */ - ADC_ADC12_EXTI11 = (6 << 17), /**< ADC1 and ADC2: EXTI11 event */ -#ifdef STM32_HIGH_DENSITY - ADC_ADC12_TIM8_TRGO = (6 << 17), /**< ADC1 and ADC2: Timer 8 TRGO - event (high density only) */ -#endif - ADC_ADC12_SWSTART = (7 << 17), /**< ADC1 and ADC2: Software start */ -#ifdef STM32_HIGH_DENSITY - ADC_ADC3_TIM3_CC1 = (0 << 17), /**< ADC3: Timer 3 CC1 event - (high density only) */ - ADC_ADC3_TIM2_CC3 = (1 << 17), /**< ADC3: Timer 2 CC3 event - (high density only) */ - ADC_ADC3_TIM1_CC3 = (2 << 17), /**< ADC3: Timer 1 CC3 event - (high density only) */ - ADC_ADC3_TIM8_CC1 = (3 << 17), /**< ADC3: Timer 8 CC1 event - (high density only) */ - ADC_ADC3_TIM8_TRGO = (4 << 17), /**< ADC3: Timer 8 TRGO event - (high density only) */ - ADC_ADC3_TIM5_CC1 = (5 << 17), /**< ADC3: Timer 5 CC1 event - (high density only) */ - ADC_ADC3_TIM5_CC3 = (6 << 17), /**< ADC3: Timer 5 CC3 event - (high density only) */ - ADC_ADC3_SWSTART = (7 << 17), /**< ADC3: Software start (high - density only) */ -#endif - ADC_SWSTART = (7 << 17) /**< ADC1, ADC2, ADC3: Software start */ -} adc_extsel_event; - -void adc_set_extsel(const adc_dev *dev, adc_extsel_event event); -void adc_foreach(void (*fn)(const adc_dev*)); - -/** - * @brief ADC sample times, in ADC clock cycles - * - * These control the amount of time spent sampling the input voltage. - */ -typedef enum { - ADC_SMPR_1_5, /**< 1.5 ADC cycles */ - ADC_SMPR_7_5, /**< 7.5 ADC cycles */ - ADC_SMPR_13_5, /**< 13.5 ADC cycles */ - ADC_SMPR_28_5, /**< 28.5 ADC cycles */ - ADC_SMPR_41_5, /**< 41.5 ADC cycles */ - ADC_SMPR_55_5, /**< 55.5 ADC cycles */ - ADC_SMPR_71_5, /**< 71.5 ADC cycles */ - ADC_SMPR_239_5 /**< 239.5 ADC cycles */ -} adc_smp_rate; - -void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate); -void adc_calibrate(const adc_dev *dev); -uint16 adc_read(const adc_dev *dev, uint8 channel); - -/** - * @brief Set the regular channel sequence length. - * - * Defines the total number of conversions in the regular channel - * conversion sequence. - * - * @param dev ADC device. - * @param length Regular channel sequence length, from 1 to 16. - */ -static inline void adc_set_reg_seqlen(const adc_dev *dev, uint8 length) { - uint32 tmp = dev->regs->SQR1; - tmp &= ~ADC_SQR1_L; - tmp |= (length - 1) << 20; - dev->regs->SQR1 = tmp; -} - -/** - * @brief Set external trigger conversion mode event for regular channels - * @param dev ADC device - * @param enable If 1, conversion on external events is enabled; if 0, - * disabled. - */ -static inline void adc_set_exttrig(const adc_dev *dev, uint8 enable) { - *bb_perip(&dev->regs->CR2, ADC_CR2_EXTTRIG_BIT) = !!enable; -} - -/** - * @brief Enable an adc peripheral - * @param dev ADC device to enable - */ -static inline void adc_enable(const adc_dev *dev) { - *bb_perip(&dev->regs->CR2, ADC_CR2_ADON_BIT) = 1; -} - -/** - * @brief Disable an ADC peripheral - * @param dev ADC device to disable - */ -static inline void adc_disable(const adc_dev *dev) { - *bb_perip(&dev->regs->CR2, ADC_CR2_ADON_BIT) = 0; -} - -/** - * @brief Disable all ADC peripherals. - */ -static inline void adc_disable_all(void) { - adc_foreach(adc_disable); -} - -void setupADC_F2(); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file adc.h + * + * @brief Analog-to-Digital Conversion (ADC) header. + */ + +#ifndef _ADC_H_ +#define _ADC_H_ + +#include "libmaple.h" +#include "bitband.h" +#include "rcc.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +#ifdef STM32F2 + typedef struct + { + __io uint32 CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ + __io uint32 CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ + __io uint32 CDR; /*!< ADC common regular data register for dual + AND triple modes, Address offset: ADC1 base address + 0x308 */ + } ADC_Common_TypeDef; +#define ADC_COMMON ((ADC_Common_TypeDef *) 0x40012300) + +#endif + +/** ADC register map type. */ +typedef struct adc_reg_map { + __io uint32 SR; ///< Status register + __io uint32 CR1; ///< Control register 1 + __io uint32 CR2; ///< Control register 2 + __io uint32 SMPR1; ///< Sample time register 1 + __io uint32 SMPR2; ///< Sample time register 2 + __io uint32 JOFR1; ///< Injected channel data offset register 1 + __io uint32 JOFR2; ///< Injected channel data offset register 2 + __io uint32 JOFR3; ///< Injected channel data offset register 3 + __io uint32 JOFR4; ///< Injected channel data offset register 4 + __io uint32 HTR; ///< Watchdog high threshold register + __io uint32 LTR; ///< Watchdog low threshold register + __io uint32 SQR1; ///< Regular sequence register 1 + __io uint32 SQR2; ///< Regular sequence register 2 + __io uint32 SQR3; ///< Regular sequence register 3 + __io uint32 JSQR; ///< Injected sequence register + __io uint32 JDR1; ///< Injected data register 1 + __io uint32 JDR2; ///< Injected data register 2 + __io uint32 JDR3; ///< Injected data register 3 + __io uint32 JDR4; ///< Injected data register 4 + __io uint32 DR; ///< Regular data register +} adc_reg_map; + +/** ADC device type. */ +typedef struct adc_dev { + adc_reg_map *regs; /**< Register map */ + rcc_clk_id clk_id; /**< RCC clock information */ +} adc_dev; + +extern const adc_dev *ADC1; +extern const adc_dev *ADC2; +#ifdef STM32_HIGH_DENSITY +extern const adc_dev *ADC3; +#endif + +/* + * Register map base pointers + */ + +#ifdef STM32F2 + /** ADC1 register map base pointer. */ + #define ADC1_BASE ((struct adc_reg_map*)0x40012000) + /** ADC2 register map base pointer. */ + #define ADC2_BASE ((struct adc_reg_map*)0x40012100) + /** ADC3 register map base pointer. */ + #define ADC3_BASE ((struct adc_reg_map*)0x40012200) +#else + /** ADC1 register map base pointer. */ + #define ADC1_BASE ((struct adc_reg_map*)0x40012400) + /** ADC2 register map base pointer. */ + #define ADC2_BASE ((struct adc_reg_map*)0x40012800) + #ifdef STM32_HIGH_DENSITY + /** ADC3 register map base pointer. */ + #define ADC3_BASE ((struct adc_reg_map*)0x40013C00) + #endif +#endif + +/* + * Register bit definitions + */ + +/* Status register */ + +#define ADC_SR_AWD_BIT 0 +#define ADC_SR_EOC_BIT 1 +#define ADC_SR_JEOC_BIT 2 +#define ADC_SR_JSTRT_BIT 3 +#define ADC_SR_STRT_BIT 4 + +#define ADC_SR_AWD BIT(ADC_SR_AWD_BIT) +#define ADC_SR_EOC BIT(ADC_SR_EOC_BIT) +#define ADC_SR_JEOC BIT(ADC_SR_JEOC_BIT) +#define ADC_SR_JSTRT BIT(ADC_SR_JSTRT_BIT) +#define ADC_SR_STRT BIT(ADC_SR_STRT_BIT) + +/* Control register 1 */ + +#define ADC_CR1_EOCIE_BIT 5 +#define ADC_CR1_AWDIE_BIT 6 +#define ADC_CR1_JEOCIE_BIT 7 +#define ADC_CR1_SCAN_BIT 8 +#define ADC_CR1_AWDSGL_BIT 9 +#define ADC_CR1_JAUTO_BIT 10 +#define ADC_CR1_DISCEN_BIT 11 +#define ADC_CR1_JDISCEN_BIT 12 +#define ADC_CR1_JAWDEN_BIT 22 +#define ADC_CR1_AWDEN_BIT 23 + +#define ADC_CR1_AWDCH (0x1F) +#define ADC_CR1_EOCIE BIT(ADC_CR1_EOCIE_BIT) +#define ADC_CR1_AWDIE BIT(ADC_CR1_AWDIE_BIT) +#define ADC_CR1_JEOCIE BIT(ADC_CR1_JEOCIE_BIT) +#define ADC_CR1_SCAN BIT(ADC_CR1_SCAN_BIT) +#define ADC_CR1_AWDSGL BIT(ADC_CR1_AWDSGL_BIT) +#define ADC_CR1_JAUTO BIT(ADC_CR1_JAUTO_BIT) +#define ADC_CR1_DISCEN BIT(ADC_CR1_DISCEN_BIT) +#define ADC_CR1_JDISCEN BIT(ADC_CR1_JDISCEN_BIT) +#define ADC_CR1_DISCNUM (0xE000) +#define ADC_CR1_JAWDEN BIT(ADC_CR1_JAWDEN_BIT) +#define ADC_CR1_AWDEN BIT(ADC_CR1_AWDEN_BIT) + +/* Control register 2 */ + +#define ADC_CR2_ADON_BIT 0 +#define ADC_CR2_CONT_BIT 1 +#define ADC_CR2_CAL_BIT 2 +#define ADC_CR2_RSTCAL_BIT 3 +#define ADC_CR2_DMA_BIT 8 +#define ADC_CR2_ALIGN_BIT 11 +#define ADC_CR2_JEXTTRIG_BIT 15 +#define ADC_CR2_EXTTRIG_BIT 20 +#define ADC_CR2_TSEREFE_BIT 23 +#ifdef STM32F2 +#define ADC_CR2_JSWSTART_BIT 22 +#define ADC_CR2_SWSTART_BIT 30 +#define ADC_CR2_EXTSEL (0x0F000000) +#define ADC_CR2_JEXTSEL (0x000F0000) +#else +#define ADC_CR2_JSWSTART_BIT 21 +#define ADC_CR2_SWSTART_BIT 22 +#define ADC_CR2_EXTSEL (0x000E0000) +#define ADC_CR2_JEXTSEL (0x00007000) +#endif + + + +#define ADC_CR2_ADON BIT(ADC_CR2_ADON_BIT) +#define ADC_CR2_CONT BIT(ADC_CR2_CONT_BIT) +#define ADC_CR2_CAL BIT(ADC_CR2_CAL_BIT) +#define ADC_CR2_RSTCAL BIT(ADC_CR2_RSTCAL_BIT) +#define ADC_CR2_DMA BIT(ADC_CR2_DMA_BIT) +#define ADC_CR2_ALIGN BIT(ADC_CR2_ALIGN_BIT) +#define ADC_CR2_JEXTTRIG BIT(ADC_CR2_JEXTTRIG_BIT) +#define ADC_CR2_EXTTRIG BIT(ADC_CR2_EXTTRIG_BIT) +#define ADC_CR2_JSWSTART BIT(ADC_CR2_JSWSTART_BIT) +#define ADC_CR2_SWSTART BIT(ADC_CR2_SWSTART_BIT) +#define ADC_CR2_TSEREFE BIT(ADC_CR2_TSEREFE_BIT) + +/* Sample time register 1 */ + +#define ADC_SMPR1_SMP17 (0x7 << 21) +#define ADC_SMPR1_SMP16 (0x7 << 18) +#define ADC_SMPR1_SMP15 (0x7 << 15) +#define ADC_SMPR1_SMP14 (0x7 << 12) +#define ADC_SMPR1_SMP13 (0x7 << 9) +#define ADC_SMPR1_SMP12 (0x7 << 6) +#define ADC_SMPR1_SMP11 (0x7 << 3) +#define ADC_SMPR1_SMP10 0x7 + +/* Sample time register 2 */ + +#define ADC_SMPR2_SMP9 (0x7 << 27) +#define ADC_SMPR2_SMP8 (0x7 << 24) +#define ADC_SMPR2_SMP7 (0x7 << 21) +#define ADC_SMPR2_SMP6 (0x7 << 18) +#define ADC_SMPR2_SMP5 (0x7 << 15) +#define ADC_SMPR2_SMP4 (0x7 << 12) +#define ADC_SMPR2_SMP3 (0x7 << 9) +#define ADC_SMPR2_SMP2 (0x7 << 6) +#define ADC_SMPR2_SMP1 (0x7 << 3) +#define ADC_SMPR2_SMP0 0x7 + +/* Injected channel data offset register */ + +#define ADC_JOFR_JOFFSET 0x3FF + +/* Watchdog high threshold register */ + +#define ADC_HTR_HT 0x3FF + +/* Watchdog low threshold register */ + +#define ADC_LTR_LT 0x3FF + +/* Regular sequence register 1 */ + +#define ADC_SQR1_L (0x1F << 20) +#define ADC_SQR1_SQ16 (0x1F << 15) +#define ADC_SQR1_SQ15 (0x1F << 10) +#define ADC_SQR1_SQ14 (0x1F << 5) +#define ADC_SQR1_SQ13 0x1F + +/* Regular sequence register 2 */ + +#define ADC_SQR2_SQ12 (0x1F << 25) +#define ADC_SQR2_SQ11 (0x1F << 20) +#define ADC_SQR2_SQ10 (0x1F << 16) +#define ADC_SQR2_SQ9 (0x1F << 10) +#define ADC_SQR2_SQ8 (0x1F << 5) +#define ADC_SQR2_SQ7 0x1F + +/* Regular sequence register 3 */ + +#define ADC_SQR3_SQ6 (0x1F << 25) +#define ADC_SQR3_SQ5 (0x1F << 20) +#define ADC_SQR3_SQ4 (0x1F << 16) +#define ADC_SQR3_SQ3 (0x1F << 10) +#define ADC_SQR3_SQ2 (0x1F << 5) +#define ADC_SQR3_SQ1 0x1F + +/* Injected sequence register */ + +#define ADC_JSQR_JL (0x3 << 20) +#define ADC_JSQR_JL_1CONV (0x0 << 20) +#define ADC_JSQR_JL_2CONV (0x1 << 20) +#define ADC_JSQR_JL_3CONV (0x2 << 20) +#define ADC_JSQR_JL_4CONV (0x3 << 20) +#define ADC_JSQR_JSQ4 (0x1F << 15) +#define ADC_JSQR_JSQ3 (0x1F << 10) +#define ADC_JSQR_JSQ2 (0x1F << 5) +#define ADC_JSQR_JSQ1 0x1F + +/* Injected data registers */ + +#define ADC_JDR_JDATA 0xFFFF + +/* Regular data register */ + +#define ADC_DR_ADC2DATA (0xFFFF << 16) +#define ADC_DR_DATA 0xFFFF + +void adc_init(const adc_dev *dev); + +/** + * @brief External event selector for regular group conversion. + * @see adc_set_extsel + */ +typedef enum adc_extsel_event { + ADC_ADC12_TIM1_CC1 = (0 << 17), /**< ADC1 and ADC2: Timer 1 CC1 event */ + ADC_ADC12_TIM1_CC2 = (1 << 17), /**< ADC1 and ADC2: Timer 1 CC2 event */ + ADC_ADC12_TIM1_CC3 = (2 << 17), /**< ADC1 and ADC2: Timer 1 CC3 event */ + ADC_ADC12_TIM2_CC2 = (3 << 17), /**< ADC1 and ADC2: Timer 2 CC2 event */ + ADC_ADC12_TIM3_TRGO = (4 << 17), /**< ADC1 and ADC2: Timer 3 TRGO event */ + ADC_ADC12_TIM4_CC4 = (5 << 17), /**< ADC1 and ADC2: Timer 4 CC4 event */ + ADC_ADC12_EXTI11 = (6 << 17), /**< ADC1 and ADC2: EXTI11 event */ +#ifdef STM32_HIGH_DENSITY + ADC_ADC12_TIM8_TRGO = (6 << 17), /**< ADC1 and ADC2: Timer 8 TRGO + event (high density only) */ +#endif + ADC_ADC12_SWSTART = (7 << 17), /**< ADC1 and ADC2: Software start */ +#ifdef STM32_HIGH_DENSITY + ADC_ADC3_TIM3_CC1 = (0 << 17), /**< ADC3: Timer 3 CC1 event + (high density only) */ + ADC_ADC3_TIM2_CC3 = (1 << 17), /**< ADC3: Timer 2 CC3 event + (high density only) */ + ADC_ADC3_TIM1_CC3 = (2 << 17), /**< ADC3: Timer 1 CC3 event + (high density only) */ + ADC_ADC3_TIM8_CC1 = (3 << 17), /**< ADC3: Timer 8 CC1 event + (high density only) */ + ADC_ADC3_TIM8_TRGO = (4 << 17), /**< ADC3: Timer 8 TRGO event + (high density only) */ + ADC_ADC3_TIM5_CC1 = (5 << 17), /**< ADC3: Timer 5 CC1 event + (high density only) */ + ADC_ADC3_TIM5_CC3 = (6 << 17), /**< ADC3: Timer 5 CC3 event + (high density only) */ + ADC_ADC3_SWSTART = (7 << 17), /**< ADC3: Software start (high + density only) */ +#endif + ADC_SWSTART = (7 << 17) /**< ADC1, ADC2, ADC3: Software start */ +} adc_extsel_event; + +void adc_set_extsel(const adc_dev *dev, adc_extsel_event event); +void adc_foreach(void (*fn)(const adc_dev*)); + +/** + * @brief ADC sample times, in ADC clock cycles + * + * These control the amount of time spent sampling the input voltage. + */ +typedef enum { + ADC_SMPR_1_5, /**< 1.5 ADC cycles */ + ADC_SMPR_7_5, /**< 7.5 ADC cycles */ + ADC_SMPR_13_5, /**< 13.5 ADC cycles */ + ADC_SMPR_28_5, /**< 28.5 ADC cycles */ + ADC_SMPR_41_5, /**< 41.5 ADC cycles */ + ADC_SMPR_55_5, /**< 55.5 ADC cycles */ + ADC_SMPR_71_5, /**< 71.5 ADC cycles */ + ADC_SMPR_239_5 /**< 239.5 ADC cycles */ +} adc_smp_rate; + +void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate); +void adc_calibrate(const adc_dev *dev); +uint16 adc_read(const adc_dev *dev, uint8 channel); + +/** + * @brief Set the regular channel sequence length. + * + * Defines the total number of conversions in the regular channel + * conversion sequence. + * + * @param dev ADC device. + * @param length Regular channel sequence length, from 1 to 16. + */ +static inline void adc_set_reg_seqlen(const adc_dev *dev, uint8 length) { + uint32 tmp = dev->regs->SQR1; + tmp &= ~ADC_SQR1_L; + tmp |= (length - 1) << 20; + dev->regs->SQR1 = tmp; +} + +/** + * @brief Set external trigger conversion mode event for regular channels + * @param dev ADC device + * @param enable If 1, conversion on external events is enabled; if 0, + * disabled. + */ +static inline void adc_set_exttrig(const adc_dev *dev, uint8 enable) { + *bb_perip(&dev->regs->CR2, ADC_CR2_EXTTRIG_BIT) = !!enable; +} + +/** + * @brief Enable an adc peripheral + * @param dev ADC device to enable + */ +static inline void adc_enable(const adc_dev *dev) { + *bb_perip(&dev->regs->CR2, ADC_CR2_ADON_BIT) = 1; +} + +/** + * @brief Disable an ADC peripheral + * @param dev ADC device to disable + */ +static inline void adc_disable(const adc_dev *dev) { + *bb_perip(&dev->regs->CR2, ADC_CR2_ADON_BIT) = 0; +} + +/** + * @brief Disable all ADC peripherals. + */ +static inline void adc_disable_all(void) { + adc_foreach(adc_disable); +} + +void setupADC_F2(); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/bitband.h b/Libmaple/libmaple/libmaple/bitband.h index b9994aab..73941b0b 100644 --- a/Libmaple/libmaple/libmaple/bitband.h +++ b/Libmaple/libmaple/libmaple/bitband.h @@ -1,120 +1,120 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file bitband.h - * - * @brief Bit-banding utility functions - */ - -#include "libmaple_types.h" - -#ifndef _BITBAND_H_ -#define _BITBAND_H_ - -#define BB_SRAM_REF 0x20000000 -#define BB_SRAM_BASE 0x22000000 -#define BB_PERI_REF 0x40000000 -#define BB_PERI_BASE 0x42000000 - -static inline volatile uint32* __bb_addr(volatile void*, - uint32, - uint32, - uint32); - -/** - * @brief Obtain a pointer to the bit-band address corresponding to a - * bit in a volatile SRAM address. - * @param address Address in the bit-banded SRAM region - * @param bit Bit in address to bit-band - */ -static inline volatile uint32* bb_sramp(volatile void *address, uint32 bit) { - return __bb_addr(address, bit, BB_SRAM_BASE, BB_SRAM_REF); -} - -/** - * @brief Get a bit from an address in the SRAM bit-band region. - * @param address Address in the SRAM bit-band region to read from - * @param bit Bit in address to read - * @return bit's value in address. - */ -static inline uint8 bb_sram_get_bit(volatile void *address, uint32 bit) { - return *bb_sramp(address, bit); -} - -/** - * @brief Set a bit in an address in the SRAM bit-band region. - * @param address Address in the SRAM bit-band region to write to - * @param bit Bit in address to write to - * @param val Value to write for bit, either 0 or 1. - */ -static inline void bb_sram_set_bit(volatile void *address, - uint32 bit, - uint8 val) { - *bb_sramp(address, bit) = val; -} - -/** - * @brief Obtain a pointer to the bit-band address corresponding to a - * bit in a peripheral address. - * @param address Address in the bit-banded peripheral region - * @param bit Bit in address to bit-band - */ -static inline volatile uint32* bb_perip(volatile void *address, uint32 bit) { - return __bb_addr(address, bit, BB_PERI_BASE, BB_PERI_REF); -} - -/** - * @brief Get a bit from an address in the peripheral bit-band region. - * @param address Address in the peripheral bit-band region to read from - * @param bit Bit in address to read - * @return bit's value in address. - */ -static inline uint8 bb_peri_get_bit(volatile void *address, uint32 bit) { - return *bb_perip(address, bit); -} - -/** - * @brief Set a bit in an address in the peripheral bit-band region. - * @param address Address in the peripheral bit-band region to write to - * @param bit Bit in address to write to - * @param val Value to write for bit, either 0 or 1. - */ -static inline void bb_peri_set_bit(volatile void *address, - uint32 bit, - uint8 val) { - *bb_perip(address, bit) = val; -} - -static inline volatile uint32* __bb_addr(volatile void *address, - uint32 bit, - uint32 bb_base, - uint32 bb_ref) { - return (volatile uint32*)(bb_base + ((uint32)address - bb_ref) * 32 + - bit * 4); -} - -#endif /* _BITBAND_H_ */ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file bitband.h + * + * @brief Bit-banding utility functions + */ + +#include "libmaple_types.h" + +#ifndef _BITBAND_H_ +#define _BITBAND_H_ + +#define BB_SRAM_REF 0x20000000 +#define BB_SRAM_BASE 0x22000000 +#define BB_PERI_REF 0x40000000 +#define BB_PERI_BASE 0x42000000 + +static inline volatile uint32* __bb_addr(volatile void*, + uint32, + uint32, + uint32); + +/** + * @brief Obtain a pointer to the bit-band address corresponding to a + * bit in a volatile SRAM address. + * @param address Address in the bit-banded SRAM region + * @param bit Bit in address to bit-band + */ +static inline volatile uint32* bb_sramp(volatile void *address, uint32 bit) { + return __bb_addr(address, bit, BB_SRAM_BASE, BB_SRAM_REF); +} + +/** + * @brief Get a bit from an address in the SRAM bit-band region. + * @param address Address in the SRAM bit-band region to read from + * @param bit Bit in address to read + * @return bit's value in address. + */ +static inline uint8 bb_sram_get_bit(volatile void *address, uint32 bit) { + return *bb_sramp(address, bit); +} + +/** + * @brief Set a bit in an address in the SRAM bit-band region. + * @param address Address in the SRAM bit-band region to write to + * @param bit Bit in address to write to + * @param val Value to write for bit, either 0 or 1. + */ +static inline void bb_sram_set_bit(volatile void *address, + uint32 bit, + uint8 val) { + *bb_sramp(address, bit) = val; +} + +/** + * @brief Obtain a pointer to the bit-band address corresponding to a + * bit in a peripheral address. + * @param address Address in the bit-banded peripheral region + * @param bit Bit in address to bit-band + */ +static inline volatile uint32* bb_perip(volatile void *address, uint32 bit) { + return __bb_addr(address, bit, BB_PERI_BASE, BB_PERI_REF); +} + +/** + * @brief Get a bit from an address in the peripheral bit-band region. + * @param address Address in the peripheral bit-band region to read from + * @param bit Bit in address to read + * @return bit's value in address. + */ +static inline uint8 bb_peri_get_bit(volatile void *address, uint32 bit) { + return *bb_perip(address, bit); +} + +/** + * @brief Set a bit in an address in the peripheral bit-band region. + * @param address Address in the peripheral bit-band region to write to + * @param bit Bit in address to write to + * @param val Value to write for bit, either 0 or 1. + */ +static inline void bb_peri_set_bit(volatile void *address, + uint32 bit, + uint8 val) { + *bb_perip(address, bit) = val; +} + +static inline volatile uint32* __bb_addr(volatile void *address, + uint32 bit, + uint32 bb_base, + uint32 bb_ref) { + return (volatile uint32*)(bb_base + ((uint32)address - bb_ref) * 32 + + bit * 4); +} + +#endif /* _BITBAND_H_ */ diff --git a/Libmaple/libmaple/libmaple/bkp.c b/Libmaple/libmaple/libmaple/bkp.c index 34749dd8..7d1ad7f0 100644 --- a/Libmaple/libmaple/libmaple/bkp.c +++ b/Libmaple/libmaple/libmaple/bkp.c @@ -1,129 +1,129 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file bkp.c - * @brief Backup register support. - */ - -#include "bkp.h" -#include "pwr.h" -#include "rcc.h" -#include "bitband.h" - -static inline __io uint32* data_register(uint8 reg); - -bkp_dev bkp = { - .regs = BKP_BASE, -}; -/** Backup device. */ -const bkp_dev *BKP = &bkp; - -/** - * @brief Initialize backup interface. - * - * Enables the power and backup interface clocks, and resets the - * backup device. - */ -void bkp_init(void) { - /* Don't call pwr_init(), or you'll reset the device. We just - * need the clock. */ - rcc_clk_enable(RCC_PWR); - rcc_clk_enable(RCC_BKP); - rcc_reset_dev(RCC_BKP); -} - -/** - * Enable write access to the backup registers. Backup interface must - * be initialized for subsequent register writes to work. - * @see bkp_init() - */ -void bkp_enable_writes(void) { - *bb_perip(&PWR_BASE->CR, PWR_CR_DBP) = 1; -} - -/** - * Disable write access to the backup registers. - */ -void bkp_disable_writes(void) { - *bb_perip(&PWR_BASE->CR, PWR_CR_DBP) = 0; -} - -/** - * Read a value from given backup data register. - * @param reg Data register to read, from 1 to BKP_NR_DATA_REGS (10 on - * medium-density devices, 42 on high-density devices). - */ -uint16 bkp_read(uint8 reg) { - __io uint32* dr = data_register(reg); - if (!dr) { - ASSERT(0); /* nonexistent register */ - return 0; - } - return (uint16)*dr; -} - -/** - * @brief Write a value to given data register. - * - * Write access to backup registers must be enabled. - * - * @param reg Data register to write, from 1 to BKP_NR_DATA_REGS (10 - * on medium-density devices, 42 on high-density devices). - * @param val Value to write into the register. - * @see bkp_enable_writes() - */ -void bkp_write(uint8 reg, uint16 val) { - __io uint32* dr = data_register(reg); - if (!dr) { - ASSERT(0); /* nonexistent register */ - return; - } - *dr = (uint32)val; -} - -/* - * Data register memory layout is not contiguous. It's split up from - * 1--NR_LOW_DRS, beginning at BKP_BASE->DR1, through to - * (NR_LOW_DRS+1)--BKP_NR_DATA_REGS, beginning at BKP_BASE->DR11. - */ -#define NR_LOW_DRS 10 - -static inline __io uint32* data_register(uint8 reg) { - if (reg < 1 || reg > BKP_NR_DATA_REGS) { - return 0; - } - -#if BKP_NR_DATA_REGS == NR_LOW_DRS - return (uint32*)BKP_BASE + reg; -#else - if (reg <= NR_LOW_DRS) { - return (uint32*)BKP_BASE + reg; - } else { - return (uint32*)&(BKP_BASE->DR11) + (reg - NR_LOW_DRS - 1); - } -#endif -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file bkp.c + * @brief Backup register support. + */ + +#include "bkp.h" +#include "pwr.h" +#include "rcc.h" +#include "bitband.h" + +static inline __io uint32* data_register(uint8 reg); + +bkp_dev bkp = { + .regs = BKP_BASE, +}; +/** Backup device. */ +const bkp_dev *BKP = &bkp; + +/** + * @brief Initialize backup interface. + * + * Enables the power and backup interface clocks, and resets the + * backup device. + */ +void bkp_init(void) { + /* Don't call pwr_init(), or you'll reset the device. We just + * need the clock. */ + rcc_clk_enable(RCC_PWR); + rcc_clk_enable(RCC_BKP); + rcc_reset_dev(RCC_BKP); +} + +/** + * Enable write access to the backup registers. Backup interface must + * be initialized for subsequent register writes to work. + * @see bkp_init() + */ +void bkp_enable_writes(void) { + *bb_perip(&PWR_BASE->CR, PWR_CR_DBP) = 1; +} + +/** + * Disable write access to the backup registers. + */ +void bkp_disable_writes(void) { + *bb_perip(&PWR_BASE->CR, PWR_CR_DBP) = 0; +} + +/** + * Read a value from given backup data register. + * @param reg Data register to read, from 1 to BKP_NR_DATA_REGS (10 on + * medium-density devices, 42 on high-density devices). + */ +uint16 bkp_read(uint8 reg) { + __io uint32* dr = data_register(reg); + if (!dr) { + ASSERT(0); /* nonexistent register */ + return 0; + } + return (uint16)*dr; +} + +/** + * @brief Write a value to given data register. + * + * Write access to backup registers must be enabled. + * + * @param reg Data register to write, from 1 to BKP_NR_DATA_REGS (10 + * on medium-density devices, 42 on high-density devices). + * @param val Value to write into the register. + * @see bkp_enable_writes() + */ +void bkp_write(uint8 reg, uint16 val) { + __io uint32* dr = data_register(reg); + if (!dr) { + ASSERT(0); /* nonexistent register */ + return; + } + *dr = (uint32)val; +} + +/* + * Data register memory layout is not contiguous. It's split up from + * 1--NR_LOW_DRS, beginning at BKP_BASE->DR1, through to + * (NR_LOW_DRS+1)--BKP_NR_DATA_REGS, beginning at BKP_BASE->DR11. + */ +#define NR_LOW_DRS 10 + +static inline __io uint32* data_register(uint8 reg) { + if (reg < 1 || reg > BKP_NR_DATA_REGS) { + return 0; + } + +#if BKP_NR_DATA_REGS == NR_LOW_DRS + return (uint32*)BKP_BASE + reg; +#else + if (reg <= NR_LOW_DRS) { + return (uint32*)BKP_BASE + reg; + } else { + return (uint32*)&(BKP_BASE->DR11) + (reg - NR_LOW_DRS - 1); + } +#endif +} diff --git a/Libmaple/libmaple/libmaple/bkp.h b/Libmaple/libmaple/libmaple/bkp.h index e2b185e5..a81267d1 100644 --- a/Libmaple/libmaple/libmaple/bkp.h +++ b/Libmaple/libmaple/libmaple/bkp.h @@ -1,166 +1,166 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file bkp.h - * @brief Backup register support. - */ - -#ifndef _BKP_H_ -#define _BKP_H_ - -#include "libmaple.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(STM32_MEDIUM_DENSITY) -#define BKP_NR_DATA_REGS 10 -#elif defined(STM32_HIGH_DENSITY) -#define BKP_NR_DATA_REGS 42 -#endif - -/** Backup peripheral register map type. */ -typedef struct bkp_reg_map { - const uint32 RESERVED1; ///< Reserved - __io uint32 DR1; ///< Data register 1 - __io uint32 DR2; ///< Data register 2 - __io uint32 DR3; ///< Data register 3 - __io uint32 DR4; ///< Data register 4 - __io uint32 DR5; ///< Data register 5 - __io uint32 DR6; ///< Data register 6 - __io uint32 DR7; ///< Data register 7 - __io uint32 DR8; ///< Data register 8 - __io uint32 DR9; ///< Data register 9 - __io uint32 DR10; ///< Data register 10 - __io uint32 RTCCR; ///< RTC control register - __io uint32 CR; ///< Control register - __io uint32 CSR; ///< Control and status register -#ifdef STM32_HIGH_DENSITY - const uint32 RESERVED2; ///< Reserved - const uint32 RESERVED3; ///< Reserved - __io uint32 DR11; ///< Data register 11 - __io uint32 DR12; ///< Data register 12 - __io uint32 DR13; ///< Data register 13 - __io uint32 DR14; ///< Data register 14 - __io uint32 DR15; ///< Data register 15 - __io uint32 DR16; ///< Data register 16 - __io uint32 DR17; ///< Data register 17 - __io uint32 DR18; ///< Data register 18 - __io uint32 DR19; ///< Data register 19 - __io uint32 DR20; ///< Data register 20 - __io uint32 DR21; ///< Data register 21 - __io uint32 DR22; ///< Data register 22 - __io uint32 DR23; ///< Data register 23 - __io uint32 DR24; ///< Data register 24 - __io uint32 DR25; ///< Data register 25 - __io uint32 DR26; ///< Data register 26 - __io uint32 DR27; ///< Data register 27 - __io uint32 DR28; ///< Data register 28 - __io uint32 DR29; ///< Data register 29 - __io uint32 DR30; ///< Data register 30 - __io uint32 DR31; ///< Data register 31 - __io uint32 DR32; ///< Data register 32 - __io uint32 DR33; ///< Data register 33 - __io uint32 DR34; ///< Data register 34 - __io uint32 DR35; ///< Data register 35 - __io uint32 DR36; ///< Data register 36 - __io uint32 DR37; ///< Data register 37 - __io uint32 DR38; ///< Data register 38 - __io uint32 DR39; ///< Data register 39 - __io uint32 DR40; ///< Data register 40 - __io uint32 DR41; ///< Data register 41 - __io uint32 DR42; ///< Data register 42 -#endif -} bkp_reg_map; - -/** Backup peripheral register map base pointer. */ -#define BKP_BASE ((struct bkp_reg_map*)0x40006C00) - -/** Backup peripheral device type. */ -typedef struct bkp_dev { - bkp_reg_map *regs; /**< Register map */ -} bkp_dev; - -extern const bkp_dev *BKP; - -/* - * Register bit definitions - */ - -/* Data Registers */ - -#define BKP_DR_D 0xFFFF - -/* RTC Clock Calibration Register */ - -#define BKP_RTCCR_ASOS_BIT 9 -#define BKP_RTCCR_ASOE_BIT 8 -#define BKP_RTCCR_CCO_BIT 7 - -#define BKP_RTCCR_ASOS BIT(BKP_RTCCR_ASOS_BIT) -#define BKP_RTCCR_ASOE BIT(BKP_RTCCR_ASOE_BIT) -#define BKP_RTCCR_CCO BIT(BKP_RTCCR_CCO_BIT) -#define BKP_RTCCR_CAL 0x7F - -/* Backup control register */ - -#define BKP_CR_TPAL_BIT 1 -#define BKP_CR_TPE_BIT 0 - -#define BKP_CR_TPAL BIT(BKP_CR_TPAL_BIT) -#define BKP_CR_TPE BIT(BKP_CR_TPE_BIT) - -/* Backup control/status register */ - -#define BKP_CSR_TIF_BIT 9 -#define BKP_CSR_TEF_BIT 8 -#define BKP_CSR_TPIE_BIT 2 -#define BKP_CSR_CTI_BIT 1 -#define BKP_CSR_CTE_BIT 0 - -#define BKP_CSR_TIF BIT(BKP_CSR_TIF_BIT) -#define BKP_CSR_TEF BIT(BKP_CSR_TEF_BIT) -#define BKP_CSR_TPIE BIT(BKP_CSR_TPIE_BIT) -#define BKP_CSR_CTI BIT(BKP_CSR_CTI_BIT) -#define BKP_CSR_CTE BIT(BKP_CSR_CTE_BIT) - -/* - * Convenience functions - */ - -void bkp_init(void); -void bkp_enable_writes(void); -void bkp_disable_writes(void); -uint16 bkp_read(uint8 reg); -void bkp_write(uint8 reg, uint16 val); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file bkp.h + * @brief Backup register support. + */ + +#ifndef _BKP_H_ +#define _BKP_H_ + +#include "libmaple.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(STM32_MEDIUM_DENSITY) +#define BKP_NR_DATA_REGS 10 +#elif defined(STM32_HIGH_DENSITY) +#define BKP_NR_DATA_REGS 42 +#endif + +/** Backup peripheral register map type. */ +typedef struct bkp_reg_map { + const uint32 RESERVED1; ///< Reserved + __io uint32 DR1; ///< Data register 1 + __io uint32 DR2; ///< Data register 2 + __io uint32 DR3; ///< Data register 3 + __io uint32 DR4; ///< Data register 4 + __io uint32 DR5; ///< Data register 5 + __io uint32 DR6; ///< Data register 6 + __io uint32 DR7; ///< Data register 7 + __io uint32 DR8; ///< Data register 8 + __io uint32 DR9; ///< Data register 9 + __io uint32 DR10; ///< Data register 10 + __io uint32 RTCCR; ///< RTC control register + __io uint32 CR; ///< Control register + __io uint32 CSR; ///< Control and status register +#ifdef STM32_HIGH_DENSITY + const uint32 RESERVED2; ///< Reserved + const uint32 RESERVED3; ///< Reserved + __io uint32 DR11; ///< Data register 11 + __io uint32 DR12; ///< Data register 12 + __io uint32 DR13; ///< Data register 13 + __io uint32 DR14; ///< Data register 14 + __io uint32 DR15; ///< Data register 15 + __io uint32 DR16; ///< Data register 16 + __io uint32 DR17; ///< Data register 17 + __io uint32 DR18; ///< Data register 18 + __io uint32 DR19; ///< Data register 19 + __io uint32 DR20; ///< Data register 20 + __io uint32 DR21; ///< Data register 21 + __io uint32 DR22; ///< Data register 22 + __io uint32 DR23; ///< Data register 23 + __io uint32 DR24; ///< Data register 24 + __io uint32 DR25; ///< Data register 25 + __io uint32 DR26; ///< Data register 26 + __io uint32 DR27; ///< Data register 27 + __io uint32 DR28; ///< Data register 28 + __io uint32 DR29; ///< Data register 29 + __io uint32 DR30; ///< Data register 30 + __io uint32 DR31; ///< Data register 31 + __io uint32 DR32; ///< Data register 32 + __io uint32 DR33; ///< Data register 33 + __io uint32 DR34; ///< Data register 34 + __io uint32 DR35; ///< Data register 35 + __io uint32 DR36; ///< Data register 36 + __io uint32 DR37; ///< Data register 37 + __io uint32 DR38; ///< Data register 38 + __io uint32 DR39; ///< Data register 39 + __io uint32 DR40; ///< Data register 40 + __io uint32 DR41; ///< Data register 41 + __io uint32 DR42; ///< Data register 42 +#endif +} bkp_reg_map; + +/** Backup peripheral register map base pointer. */ +#define BKP_BASE ((struct bkp_reg_map*)0x40006C00) + +/** Backup peripheral device type. */ +typedef struct bkp_dev { + bkp_reg_map *regs; /**< Register map */ +} bkp_dev; + +extern const bkp_dev *BKP; + +/* + * Register bit definitions + */ + +/* Data Registers */ + +#define BKP_DR_D 0xFFFF + +/* RTC Clock Calibration Register */ + +#define BKP_RTCCR_ASOS_BIT 9 +#define BKP_RTCCR_ASOE_BIT 8 +#define BKP_RTCCR_CCO_BIT 7 + +#define BKP_RTCCR_ASOS BIT(BKP_RTCCR_ASOS_BIT) +#define BKP_RTCCR_ASOE BIT(BKP_RTCCR_ASOE_BIT) +#define BKP_RTCCR_CCO BIT(BKP_RTCCR_CCO_BIT) +#define BKP_RTCCR_CAL 0x7F + +/* Backup control register */ + +#define BKP_CR_TPAL_BIT 1 +#define BKP_CR_TPE_BIT 0 + +#define BKP_CR_TPAL BIT(BKP_CR_TPAL_BIT) +#define BKP_CR_TPE BIT(BKP_CR_TPE_BIT) + +/* Backup control/status register */ + +#define BKP_CSR_TIF_BIT 9 +#define BKP_CSR_TEF_BIT 8 +#define BKP_CSR_TPIE_BIT 2 +#define BKP_CSR_CTI_BIT 1 +#define BKP_CSR_CTE_BIT 0 + +#define BKP_CSR_TIF BIT(BKP_CSR_TIF_BIT) +#define BKP_CSR_TEF BIT(BKP_CSR_TEF_BIT) +#define BKP_CSR_TPIE BIT(BKP_CSR_TPIE_BIT) +#define BKP_CSR_CTI BIT(BKP_CSR_CTI_BIT) +#define BKP_CSR_CTE BIT(BKP_CSR_CTE_BIT) + +/* + * Convenience functions + */ + +void bkp_init(void); +void bkp_enable_writes(void); +void bkp_disable_writes(void); +uint16 bkp_read(uint8 reg); +void bkp_write(uint8 reg, uint16 val); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/dac.c b/Libmaple/libmaple/libmaple/dac.c index 6f8ee7e0..264e4e21 100644 --- a/Libmaple/libmaple/libmaple/dac.c +++ b/Libmaple/libmaple/libmaple/dac.c @@ -1,155 +1,155 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file dac.c - * @brief Digital to analog converter support. - */ - -#include "libmaple.h" -#include "gpio.h" -#include "dac.h" - -#ifdef STM32_HIGH_DENSITY - -/** - * @brief DAC peripheral routines. - */ - -dac_dev dac = { - .regs = DAC_BASE, -}; -/** DAC device. */ -const dac_dev *DAC = &dac; - -/** - * @brief Initialize the digital to analog converter - * @param dev DAC device - * @param flags Flags: - * DAC_CH1: Enable channel 1 - * DAC_CH2: Enable channel 2 - * @sideeffect May set PA4 or PA5 to INPUT_ANALOG - */ -void dac_init(const dac_dev *dev, uint32 flags) { - /* First turn on the clock */ - rcc_clk_enable(RCC_DAC); - rcc_reset_dev(RCC_DAC); - - if (flags & DAC_CH1) { - dac_enable_channel(dev, 1); - } - - if (flags & DAC_CH2) { - dac_enable_channel(dev, 2); - } -} - -/** - * @brief Initialize the output buffer of the digital to analog converter - * @param dev DAC device - * @param flags Flags: - * DAC_CH1: Select channel 1 - * DAC_CH2: Select channel 2 - * @param status Status: - * 1: enable buffer - * 0: disable buffer - */ -void dac_enable_buffer(const dac_dev *dev, uint32 flags, int status) { - if (flags & DAC_CH1) { - if(status) { - dev->regs->CR &= ~DAC_CR_BOFF1; - } else { - dev->regs->CR |= DAC_CR_BOFF1; - } - } - - if (flags & DAC_CH2) { - if(status) { - dev->regs->CR &= ~DAC_CR_BOFF2; - } else { - dev->regs->CR |= DAC_CR_BOFF2; - } - } -} - - -/** - * @brief Write a 12-bit value to the DAC to output - * @param dev DAC device - * @param channel channel to select (1 or 2) - * @param val value to write - */ -void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val) { - switch(channel) { - case 1: - dev->regs->DHR12R1 = DAC_DHR12R1_DACC1DHR & val; - break; - case 2: - dev->regs->DHR12R2 = DAC_DHR12R2_DACC2DHR & val; - break; - } -} - -/** - * @brief Enable a DAC channel - * @param dev DAC device - * @param channel channel to enable, either 1 or 2 - * @sideeffect May change pin mode of PA4 or PA5 - */ -void dac_enable_channel(const dac_dev *dev, uint8 channel) { - /* - * Setup ANALOG mode on PA4 and PA5. This mapping is consistent across - * all STM32 chips with a DAC. See RM0008 12.2. - */ - switch (channel) { - case 1: - gpio_set_mode(GPIOA, 4, GPIO_INPUT_ANALOG); - dev->regs->CR |= DAC_CR_EN1; - break; - case 2: - gpio_set_mode(GPIOA, 5, GPIO_INPUT_ANALOG); - dev->regs->CR |= DAC_CR_EN2; - break; - } -} - -/** - * @brief Disable a DAC channel - * @param dev DAC device - * @param channel channel to disable, either 1 or 2 - */ -void dac_disable_channel(const dac_dev *dev, uint8 channel) { - switch (channel) { - case 1: - dev->regs->CR &= ~DAC_CR_EN1; - break; - case 2: - dev->regs->CR &= ~DAC_CR_EN2; - break; - } -} - -#endif /* STM32_HIGH_DENSITY */ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Bryan Newbold. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file dac.c + * @brief Digital to analog converter support. + */ + +#include "libmaple.h" +#include "gpio.h" +#include "dac.h" + +#ifdef STM32_HIGH_DENSITY + +/** + * @brief DAC peripheral routines. + */ + +dac_dev dac = { + .regs = DAC_BASE, +}; +/** DAC device. */ +const dac_dev *DAC = &dac; + +/** + * @brief Initialize the digital to analog converter + * @param dev DAC device + * @param flags Flags: + * DAC_CH1: Enable channel 1 + * DAC_CH2: Enable channel 2 + * @sideeffect May set PA4 or PA5 to INPUT_ANALOG + */ +void dac_init(const dac_dev *dev, uint32 flags) { + /* First turn on the clock */ + rcc_clk_enable(RCC_DAC); + rcc_reset_dev(RCC_DAC); + + if (flags & DAC_CH1) { + dac_enable_channel(dev, 1); + } + + if (flags & DAC_CH2) { + dac_enable_channel(dev, 2); + } +} + +/** + * @brief Initialize the output buffer of the digital to analog converter + * @param dev DAC device + * @param flags Flags: + * DAC_CH1: Select channel 1 + * DAC_CH2: Select channel 2 + * @param status Status: + * 1: enable buffer + * 0: disable buffer + */ +void dac_enable_buffer(const dac_dev *dev, uint32 flags, int status) { + if (flags & DAC_CH1) { + if(status) { + dev->regs->CR &= ~DAC_CR_BOFF1; + } else { + dev->regs->CR |= DAC_CR_BOFF1; + } + } + + if (flags & DAC_CH2) { + if(status) { + dev->regs->CR &= ~DAC_CR_BOFF2; + } else { + dev->regs->CR |= DAC_CR_BOFF2; + } + } +} + + +/** + * @brief Write a 12-bit value to the DAC to output + * @param dev DAC device + * @param channel channel to select (1 or 2) + * @param val value to write + */ +void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val) { + switch(channel) { + case 1: + dev->regs->DHR12R1 = DAC_DHR12R1_DACC1DHR & val; + break; + case 2: + dev->regs->DHR12R2 = DAC_DHR12R2_DACC2DHR & val; + break; + } +} + +/** + * @brief Enable a DAC channel + * @param dev DAC device + * @param channel channel to enable, either 1 or 2 + * @sideeffect May change pin mode of PA4 or PA5 + */ +void dac_enable_channel(const dac_dev *dev, uint8 channel) { + /* + * Setup ANALOG mode on PA4 and PA5. This mapping is consistent across + * all STM32 chips with a DAC. See RM0008 12.2. + */ + switch (channel) { + case 1: + gpio_set_mode(GPIOA, 4, GPIO_INPUT_ANALOG); + dev->regs->CR |= DAC_CR_EN1; + break; + case 2: + gpio_set_mode(GPIOA, 5, GPIO_INPUT_ANALOG); + dev->regs->CR |= DAC_CR_EN2; + break; + } +} + +/** + * @brief Disable a DAC channel + * @param dev DAC device + * @param channel channel to disable, either 1 or 2 + */ +void dac_disable_channel(const dac_dev *dev, uint8 channel) { + switch (channel) { + case 1: + dev->regs->CR &= ~DAC_CR_EN1; + break; + case 2: + dev->regs->CR &= ~DAC_CR_EN2; + break; + } +} + +#endif /* STM32_HIGH_DENSITY */ diff --git a/Libmaple/libmaple/libmaple/dac.h b/Libmaple/libmaple/libmaple/dac.h index d2497fc9..dd1b22bd 100644 --- a/Libmaple/libmaple/libmaple/dac.h +++ b/Libmaple/libmaple/libmaple/dac.h @@ -1,169 +1,169 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file dac.h - * @brief Digital to analog converter support. - */ - -/* See notes/dac.txt for more info */ - -#ifndef _DAC_H_ -#define _DAC_H_ - -#include "rcc.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - * Register maps - */ - -/** DAC register map. */ -typedef struct dac_reg_map { - __io uint32 CR; /**< Control register */ - __io uint32 SWTRIGR; /**< Software trigger register */ - __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data - holding register */ - __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data - holding register */ - __io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data - holding register */ - __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data - holding register */ - __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data - holding register */ - __io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data - holding register */ - __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data - holding register */ - __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data - holding register */ - __io uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding - register */ - __io uint32 DOR1; /**< Channel 1 data output register */ - __io uint32 DOR2; /**< Channel 2 data output register */ -} dac_reg_map; - -/** DAC register map base address */ -#define DAC_BASE ((struct dac_reg_map*)0x40007400) - -/* - * Devices - */ - -/** DAC device type. */ -typedef struct dac_dev { - dac_reg_map *regs; /**< Register map */ -} dac_dev; - -extern const dac_dev *DAC; - -/* - * Register bit definitions - */ - -/* Control register */ -/* Channel 1 control */ -#define DAC_CR_EN1 BIT(0) /* Enable */ -#define DAC_CR_BOFF1 BIT(1) /* Output buffer disable */ -#define DAC_CR_TEN1 BIT(2) /* Trigger enable */ -#define DAC_CR_TSEL1 (0x7 << 3) /* Trigger selection */ -#define DAC_CR_WAVE1 (0x3 << 6) /* Noise/triangle wave enable */ -#define DAC_CR_MAMP1 (0xF << 8) /* Mask/amplitude selector */ -#define DAC_CR_DMAEN1 BIT(12) /* DMA enable */ -/* Channel 2 control */ -#define DAC_CR_EN2 BIT(16) /* Enable */ -#define DAC_CR_BOFF2 BIT(17) /* Output buffer disable */ -#define DAC_CR_TEN2 BIT(18) /* Trigger enable */ -#define DAC_CR_TSEL2 (0x7 << 19) /* Trigger selection */ -#define DAC_CR_WAVE2 (0x3 << 22) /* Noise/triangle wave generation*/ -#define DAC_CR_MAMP2 (0xF << 24) /* Mask/amplitude selector */ -#define DAC_CR_DMAEN2 BIT(28) /* DMA enable */ - -/* Software trigger register */ -#define DAC_SWTRIGR_SWTRIG1 BIT(0) /* Channel 1 software trigger */ -#define DAC_SWTRIGR_SWTRIG2 BIT(1) /* Channel 2 software trigger */ - -/* Channel 1 12-bit right-aligned data holding register */ -#define DAC_DHR12R1_DACC1DHR 0x00000FFF - -/* Channel 1 12-bit left-aligned data holding register */ -#define DAC_DHR12L1_DACC1DHR 0x0000FFF0 - -/* Channel 1 8-bit left-aligned data holding register */ -#define DAC_DHR8R1_DACC1DHR 0x000000FF - -/* Channel 2 12-bit right-aligned data holding register */ -#define DAC_DHR12R2_DACC2DHR 0x00000FFF - -/* Channel 2 12-bit left-aligned data holding register */ -#define DAC_DHR12L2_DACC2DHR 0x0000FFF0 - -/* Channel 2 8-bit left-aligned data holding register */ -#define DAC_DHR8R2_DACC2DHR 0x000000FF - -/* Dual DAC 12-bit right-aligned data holding register */ -#define DAC_DHR12RD_DACC1DHR 0x00000FFF -#define DAC_DHR12RD_DACC2DHR 0x0FFF0000 - -/* Dual DAC 12-bit left-aligned data holding register */ -#define DAC_DHR12LD_DACC1DHR 0x0000FFF0 -#define DAC_DHR12LD_DACC2DHR 0xFFF00000 - -/* Dual DAC 8-bit left-aligned data holding register */ -#define DAC_DHR8RD_DACC1DHR 0x000000FF -#define DAC_DHR8RD_DACC2DHR 0x0000FF00 - -/* Channel 1 data output register */ -#define DAC_DOR1_DACC1DOR 0x00000FFF - -/* Channel 1 data output register */ -#define DAC_DOR2_DACC2DOR 0x00000FFF - -/* - * Convenience functions - */ - -/* We take the dev argument in these convenience functions for - * future-proofing */ - -#define DAC_CH1 0x1 -#define DAC_CH2 0x2 -void dac_init(const dac_dev *dev, uint32 flags); - -void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val); -void dac_enable_channel(const dac_dev *dev, uint8 channel); -void dac_disable_channel(const dac_dev *dev, uint8 channel); -void dac_enable_buffer(const dac_dev *dev, uint32 flags, int status); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Bryan Newbold. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file dac.h + * @brief Digital to analog converter support. + */ + +/* See notes/dac.txt for more info */ + +#ifndef _DAC_H_ +#define _DAC_H_ + +#include "rcc.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * Register maps + */ + +/** DAC register map. */ +typedef struct dac_reg_map { + __io uint32 CR; /**< Control register */ + __io uint32 SWTRIGR; /**< Software trigger register */ + __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data + holding register */ + __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data + holding register */ + __io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data + holding register */ + __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data + holding register */ + __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data + holding register */ + __io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data + holding register */ + __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data + holding register */ + __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data + holding register */ + __io uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding + register */ + __io uint32 DOR1; /**< Channel 1 data output register */ + __io uint32 DOR2; /**< Channel 2 data output register */ +} dac_reg_map; + +/** DAC register map base address */ +#define DAC_BASE ((struct dac_reg_map*)0x40007400) + +/* + * Devices + */ + +/** DAC device type. */ +typedef struct dac_dev { + dac_reg_map *regs; /**< Register map */ +} dac_dev; + +extern const dac_dev *DAC; + +/* + * Register bit definitions + */ + +/* Control register */ +/* Channel 1 control */ +#define DAC_CR_EN1 BIT(0) /* Enable */ +#define DAC_CR_BOFF1 BIT(1) /* Output buffer disable */ +#define DAC_CR_TEN1 BIT(2) /* Trigger enable */ +#define DAC_CR_TSEL1 (0x7 << 3) /* Trigger selection */ +#define DAC_CR_WAVE1 (0x3 << 6) /* Noise/triangle wave enable */ +#define DAC_CR_MAMP1 (0xF << 8) /* Mask/amplitude selector */ +#define DAC_CR_DMAEN1 BIT(12) /* DMA enable */ +/* Channel 2 control */ +#define DAC_CR_EN2 BIT(16) /* Enable */ +#define DAC_CR_BOFF2 BIT(17) /* Output buffer disable */ +#define DAC_CR_TEN2 BIT(18) /* Trigger enable */ +#define DAC_CR_TSEL2 (0x7 << 19) /* Trigger selection */ +#define DAC_CR_WAVE2 (0x3 << 22) /* Noise/triangle wave generation*/ +#define DAC_CR_MAMP2 (0xF << 24) /* Mask/amplitude selector */ +#define DAC_CR_DMAEN2 BIT(28) /* DMA enable */ + +/* Software trigger register */ +#define DAC_SWTRIGR_SWTRIG1 BIT(0) /* Channel 1 software trigger */ +#define DAC_SWTRIGR_SWTRIG2 BIT(1) /* Channel 2 software trigger */ + +/* Channel 1 12-bit right-aligned data holding register */ +#define DAC_DHR12R1_DACC1DHR 0x00000FFF + +/* Channel 1 12-bit left-aligned data holding register */ +#define DAC_DHR12L1_DACC1DHR 0x0000FFF0 + +/* Channel 1 8-bit left-aligned data holding register */ +#define DAC_DHR8R1_DACC1DHR 0x000000FF + +/* Channel 2 12-bit right-aligned data holding register */ +#define DAC_DHR12R2_DACC2DHR 0x00000FFF + +/* Channel 2 12-bit left-aligned data holding register */ +#define DAC_DHR12L2_DACC2DHR 0x0000FFF0 + +/* Channel 2 8-bit left-aligned data holding register */ +#define DAC_DHR8R2_DACC2DHR 0x000000FF + +/* Dual DAC 12-bit right-aligned data holding register */ +#define DAC_DHR12RD_DACC1DHR 0x00000FFF +#define DAC_DHR12RD_DACC2DHR 0x0FFF0000 + +/* Dual DAC 12-bit left-aligned data holding register */ +#define DAC_DHR12LD_DACC1DHR 0x0000FFF0 +#define DAC_DHR12LD_DACC2DHR 0xFFF00000 + +/* Dual DAC 8-bit left-aligned data holding register */ +#define DAC_DHR8RD_DACC1DHR 0x000000FF +#define DAC_DHR8RD_DACC2DHR 0x0000FF00 + +/* Channel 1 data output register */ +#define DAC_DOR1_DACC1DOR 0x00000FFF + +/* Channel 1 data output register */ +#define DAC_DOR2_DACC2DOR 0x00000FFF + +/* + * Convenience functions + */ + +/* We take the dev argument in these convenience functions for + * future-proofing */ + +#define DAC_CH1 0x1 +#define DAC_CH2 0x2 +void dac_init(const dac_dev *dev, uint32 flags); + +void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val); +void dac_enable_channel(const dac_dev *dev, uint8 channel); +void dac_disable_channel(const dac_dev *dev, uint8 channel); +void dac_enable_buffer(const dac_dev *dev, uint32 flags, int status); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/delay.h b/Libmaple/libmaple/libmaple/delay.h index 41383a79..84304309 100644 --- a/Libmaple/libmaple/libmaple/delay.h +++ b/Libmaple/libmaple/libmaple/delay.h @@ -1,44 +1,44 @@ -/** - * @file delay.h - * @brief Delay implementation - */ - -#include "libmaple_types.h" -#include "stm32.h" - -#ifndef _DELAY_H_ -#define _DELAY_H_ - -/** - * @brief Delay the given number of microseconds. - * - * @param us Number of microseconds to delay. - */ -static inline void delay_us(uint32 us) { - us *= STM32_DELAY_US_MULT; - - /* fudge for function call overhead */ - //us--; - asm volatile(" mov r0, %[us] \n\t" - "1: subs r0, #1 \n\t" - " bhi 1b \n\t" - : - : [us] "r" (us) - : "r0"); -} - -static inline void delay_ns100(uint32 us) { - us *= STM32_DELAY_US_MULT; - us /= 10; - - /* fudge for function call overhead */ - //us--; - asm volatile(" mov r0, %[us] \n\t" - "1: subs r0, #1 \n\t" - " bhi 1b \n\t" - : - : [us] "r" (us) - : "r0"); -} -#endif - +/** + * @file delay.h + * @brief Delay implementation + */ + +#include "libmaple_types.h" +#include "stm32.h" + +#ifndef _DELAY_H_ +#define _DELAY_H_ + +/** + * @brief Delay the given number of microseconds. + * + * @param us Number of microseconds to delay. + */ +static inline void delay_us(uint32 us) { + us *= STM32_DELAY_US_MULT; + + /* fudge for function call overhead */ + //us--; + asm volatile(" mov r0, %[us] \n\t" + "1: subs r0, #1 \n\t" + " bhi 1b \n\t" + : + : [us] "r" (us) + : "r0"); +} + +static inline void delay_ns100(uint32 us) { + us *= STM32_DELAY_US_MULT; + us /= 10; + + /* fudge for function call overhead */ + //us--; + asm volatile(" mov r0, %[us] \n\t" + "1: subs r0, #1 \n\t" + " bhi 1b \n\t" + : + : [us] "r" (us) + : "r0"); +} +#endif + diff --git a/Libmaple/libmaple/libmaple/dma.c b/Libmaple/libmaple/libmaple/dma.c index db0c46fc..8f61d0bd 100644 --- a/Libmaple/libmaple/libmaple/dma.c +++ b/Libmaple/libmaple/libmaple/dma.c @@ -1,36 +1,36 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file dma.c - * @brief DMA initialization routine - */ - -#ifdef STM32F2 -#include "dmaF2.c" -#else -#include "dmaF1.c" -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file dma.c + * @brief DMA initialization routine + */ + +#ifdef STM32F2 +#include "dmaF2.c" +#else +#include "dmaF1.c" +#endif diff --git a/Libmaple/libmaple/libmaple/dma.h b/Libmaple/libmaple/libmaple/dma.h index 6f2aa285..cce89956 100644 --- a/Libmaple/libmaple/libmaple/dma.h +++ b/Libmaple/libmaple/libmaple/dma.h @@ -1,37 +1,37 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file dma.h - * - * @brief Direct Memory Access peripheral support - */ - -#ifdef STM32F2 -#include "dmaF2.h" -#else -#include "dmaF1.h" -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*****************************************************************************/ + +/** + * @file dma.h + * + * @brief Direct Memory Access peripheral support + */ + +#ifdef STM32F2 +#include "dmaF2.h" +#else +#include "dmaF1.h" +#endif diff --git a/Libmaple/libmaple/libmaple/dmaF1.c b/Libmaple/libmaple/libmaple/dmaF1.c index 26fe9b42..60f4d473 100644 --- a/Libmaple/libmaple/libmaple/dmaF1.c +++ b/Libmaple/libmaple/libmaple/dmaF1.c @@ -1,379 +1,379 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file dma.c - * @author Marti Bolivar ; - * Original implementation by Michael Hope - * @brief Direct Memory Access peripheral support - */ - -#include "dma.h" -#include "bitband.h" -#include "util.h" - -/* - * Devices - */ - -static dma_dev dma1 = { - .regs = DMA1_BASE, - .clk_id = RCC_DMA1, - .handlers = {{ .handler = NULL, .irq_line = NVIC_DMA_CH1 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH2 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH3 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH4 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH5 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH6 }, - { .handler = NULL, .irq_line = NVIC_DMA_CH7 }} -}; -/** DMA1 device */ -dma_dev *DMA1 = &dma1; - -#ifdef STM32_HIGH_DENSITY -static dma_dev dma2 = { - .regs = DMA2_BASE, - .clk_id = RCC_DMA2, - .handlers = {{ .handler = NULL, .irq_line = NVIC_DMA2_CH1 }, - { .handler = NULL, .irq_line = NVIC_DMA2_CH2 }, - { .handler = NULL, .irq_line = NVIC_DMA2_CH3 }, - { .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 }, - { .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 }} /* !@#$ */ -}; -/** DMA2 device */ -dma_dev *DMA2 = &dma2; -#endif - -/* - * Convenience routines - */ - -/** - * @brief Initialize a DMA device. - * @param dev Device to initialize. - */ -void dma_init(dma_dev *dev) { - rcc_clk_enable(dev->clk_id); -} - -/** - * @brief Set up a DMA transfer. - * - * The channel will be disabled before being reconfigured. The - * transfer will have low priority by default. You may choose another - * priority before the transfer begins using dma_set_priority(), as - * well as performing any other configuration you desire. When the - * channel is configured to your liking, enable it using dma_enable(). - * - * @param dev DMA device. - * @param channel DMA channel. - * @param peripheral_address Base address of peripheral data register - * involved in the transfer. - * @param peripheral_size Peripheral data transfer size. - * @param memory_address Base memory address involved in the transfer. - * @param memory_size Memory data transfer size. - * @param mode Logical OR of dma_mode_flags - * @sideeffect Disables the given DMA channel. - * @see dma_xfer_size - * @see dma_mode_flags - * @see dma_set_num_transfers() - * @see dma_set_priority() - * @see dma_attach_interrupt() - * @see dma_enable() - */ -void dma_setup_transfer(dma_dev *dev, - dma_channel channel, - __io void *peripheral_address, - dma_xfer_size peripheral_size, - __io void *memory_address, - dma_xfer_size memory_size, - uint32 mode) { - dma_channel_reg_map *channel_regs = dma_channel_regs(dev, channel); - - dma_disable(dev, channel); /* can't write to CMAR/CPAR otherwise */ - channel_regs->CCR = (memory_size << 10) | (peripheral_size << 8) | mode; - channel_regs->CMAR = (uint32)memory_address; - channel_regs->CPAR = (uint32)peripheral_address; -} - -/** - * @brief Set the number of data to be transferred on a DMA channel. - * - * You may not call this function while the channel is enabled. - * - * @param dev DMA device - * @param channel Channel through which the transfer occurs. - * @param num_transfers - */ -void dma_set_num_transfers(dma_dev *dev, - dma_channel channel, - uint16 num_transfers) { - dma_channel_reg_map *channel_regs; - - ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); - - channel_regs = dma_channel_regs(dev, channel); - channel_regs->CNDTR = num_transfers; -} - -/** - * @brief Set the priority of a DMA transfer. - * - * You may not call this function while the channel is enabled. - * - * @param dev DMA device - * @param channel DMA channel - * @param priority priority to set. - */ -void dma_set_priority(dma_dev *dev, - dma_channel channel, - dma_priority priority) { - dma_channel_reg_map *channel_regs; - uint32 ccr; - - ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); - - channel_regs = dma_channel_regs(dev, channel); - ccr = channel_regs->CCR; - ccr &= ~DMA_CCR_PL; - ccr |= priority; - channel_regs->CCR = ccr; -} - -/** - * @brief Attach an interrupt to a DMA transfer. - * - * Interrupts are enabled using appropriate mode flags in - * dma_setup_transfer(). - * - * @param dev DMA device - * @param channel Channel to attach handler to - * @param handler Interrupt handler to call when channel interrupt fires. - * @see dma_setup_transfer() - * @see dma_get_irq_cause() - * @see dma_detach_interrupt() - */ -void dma_attach_interrupt(dma_dev *dev, - dma_channel channel, - void (*handler)(void)) { - dev->handlers[channel - 1].handler = handler; - nvic_irq_enable(dev->handlers[channel - 1].irq_line); -} - -/** - * @brief Detach a DMA transfer interrupt handler. - * - * After calling this function, the given channel's interrupts will be - * disabled. - * - * @param dev DMA device - * @param channel Channel whose handler to detach - * @sideeffect Clears interrupt enable bits in the channel's CCR register. - * @see dma_attach_interrupt() - */ -void dma_detach_interrupt(dma_dev *dev, dma_channel channel) { - /* Don't use nvic_irq_disable()! Think about DMA2 channels 4 and 5. */ - dma_channel_regs(dev, channel)->CCR &= ~0xF; - dev->handlers[channel - 1].handler = NULL; -} - -/** - * @brief Discover the reason why a DMA interrupt was called. - * - * You may only call this function within an attached interrupt - * handler for the given channel. - * - * This function resets the internal DMA register state which encodes - * the cause of the interrupt; consequently, it can only be called - * once per interrupt handler invocation. - * - * @param dev DMA device - * @param channel Channel whose interrupt is being handled. - * @return Reason why the interrupt fired. - * @sideeffect Clears channel status flags in dev->regs->ISR. - * @see dma_attach_interrupt() - * @see dma_irq_cause - */ -dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) { - uint8 status_bits = dma_get_isr_bits(dev, channel); - - /* If the channel global interrupt flag is cleared, then - * something's very wrong. */ - ASSERT(status_bits & BIT(0)); - - dma_clear_isr_bits(dev, channel); - - /* ISR flags get set even if the corresponding interrupt enable - * bits in the channel's configuration register are cleared, so we - * can't use a switch here. - * - * Don't change the order of these if statements. */ - if (status_bits & BIT(3)) { - return DMA_TRANSFER_ERROR; - } else if (status_bits & BIT(1)) { - return DMA_TRANSFER_COMPLETE; - } else if (status_bits & BIT(2)) { - return DMA_TRANSFER_HALF_COMPLETE; - } else if (status_bits & BIT(0)) { - /* Shouldn't happen (unless someone messed up an IFCR write). */ - throb(); - } -#if DEBUG_LEVEL < DEBUG_ALL - else { - /* We shouldn't have been called, but the debug level is too - * low for the above ASSERT() to have had any effect. In - * order to fail fast, mimic the DMA controller's behavior - * when an error occurs. */ - dma_disable(dev, channel); - } -#endif - return DMA_TRANSFER_ERROR; -} - -/** - * @brief Enable a DMA channel. - * @param dev DMA device - * @param channel Channel to enable - */ -void dma_enable(dma_dev *dev, dma_channel channel) { - dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel); - bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 1); -} - -/** - * @brief Disable a DMA channel. - * @param dev DMA device - * @param channel Channel to disable - */ -void dma_disable(dma_dev *dev, dma_channel channel) { - dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel); - bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 0); -} - -/** - * @brief Set the base memory address where data will be read from or - * written to. - * - * You must not call this function while the channel is enabled. - * - * If the DMA memory size is 16 bits, the address is automatically - * aligned to a half-word. If the DMA memory size is 32 bits, the - * address is aligned to a word. - * - * @param dev DMA Device - * @param channel Channel whose base memory address to set. - * @param addr Memory base address to use. - */ -void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *addr) { - dma_channel_reg_map *chan_regs; - - ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); - - chan_regs = dma_channel_regs(dev, channel); - chan_regs->CMAR = (uint32)addr; -} - -/** - * @brief Set the base peripheral address where data will be read from - * or written to. - * - * You must not call this function while the channel is enabled. - * - * If the DMA peripheral size is 16 bits, the address is automatically - * aligned to a half-word. If the DMA peripheral size is 32 bits, the - * address is aligned to a word. - * - * @param dev DMA Device - * @param channel Channel whose peripheral data register base address to set. - * @param addr Peripheral memory base address to use. - */ -void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *addr) { - dma_channel_reg_map *chan_regs; - - ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); - - chan_regs = dma_channel_regs(dev, channel); - chan_regs->CPAR = (uint32)addr; -} - -/* - * IRQ handlers - */ - -static inline void dispatch_handler(dma_dev *dev, dma_channel channel) { - void (*handler)(void) = dev->handlers[channel - 1].handler; - if (handler) { - handler(); - dma_clear_isr_bits(dev, channel); /* in case handler doesn't */ - } -} - -void __irq_dma1_channel1(void) { - dispatch_handler(DMA1, DMA_CH1); -} - -void __irq_dma1_channel2(void) { - dispatch_handler(DMA1, DMA_CH2); -} - -void __irq_dma1_channel3(void) { - dispatch_handler(DMA1, DMA_CH3); -} - -void __irq_dma1_channel4(void) { - dispatch_handler(DMA1, DMA_CH4); -} - -void __irq_dma1_channel5(void) { - dispatch_handler(DMA1, DMA_CH5); -} - -void __irq_dma1_channel6(void) { - dispatch_handler(DMA1, DMA_CH6); -} - -void __irq_dma1_channel7(void) { - dispatch_handler(DMA1, DMA_CH7); -} - -#ifdef STM32_HIGH_DENSITY -void __irq_dma2_channel1(void) { - dispatch_handler(DMA2, DMA_CH1); -} - -void __irq_dma2_channel2(void) { - dispatch_handler(DMA2, DMA_CH2); -} - -void __irq_dma2_channel3(void) { - dispatch_handler(DMA2, DMA_CH3); -} - -void __irq_dma2_channel4_5(void) { - dispatch_handler(DMA2, DMA_CH4); - dispatch_handler(DMA2, DMA_CH5); -} -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Michael Hope. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file dma.c + * @author Marti Bolivar ; + * Original implementation by Michael Hope + * @brief Direct Memory Access peripheral support + */ + +#include "dma.h" +#include "bitband.h" +#include "util.h" + +/* + * Devices + */ + +static dma_dev dma1 = { + .regs = DMA1_BASE, + .clk_id = RCC_DMA1, + .handlers = {{ .handler = NULL, .irq_line = NVIC_DMA_CH1 }, + { .handler = NULL, .irq_line = NVIC_DMA_CH2 }, + { .handler = NULL, .irq_line = NVIC_DMA_CH3 }, + { .handler = NULL, .irq_line = NVIC_DMA_CH4 }, + { .handler = NULL, .irq_line = NVIC_DMA_CH5 }, + { .handler = NULL, .irq_line = NVIC_DMA_CH6 }, + { .handler = NULL, .irq_line = NVIC_DMA_CH7 }} +}; +/** DMA1 device */ +dma_dev *DMA1 = &dma1; + +#ifdef STM32_HIGH_DENSITY +static dma_dev dma2 = { + .regs = DMA2_BASE, + .clk_id = RCC_DMA2, + .handlers = {{ .handler = NULL, .irq_line = NVIC_DMA2_CH1 }, + { .handler = NULL, .irq_line = NVIC_DMA2_CH2 }, + { .handler = NULL, .irq_line = NVIC_DMA2_CH3 }, + { .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 }, + { .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 }} /* !@#$ */ +}; +/** DMA2 device */ +dma_dev *DMA2 = &dma2; +#endif + +/* + * Convenience routines + */ + +/** + * @brief Initialize a DMA device. + * @param dev Device to initialize. + */ +void dma_init(dma_dev *dev) { + rcc_clk_enable(dev->clk_id); +} + +/** + * @brief Set up a DMA transfer. + * + * The channel will be disabled before being reconfigured. The + * transfer will have low priority by default. You may choose another + * priority before the transfer begins using dma_set_priority(), as + * well as performing any other configuration you desire. When the + * channel is configured to your liking, enable it using dma_enable(). + * + * @param dev DMA device. + * @param channel DMA channel. + * @param peripheral_address Base address of peripheral data register + * involved in the transfer. + * @param peripheral_size Peripheral data transfer size. + * @param memory_address Base memory address involved in the transfer. + * @param memory_size Memory data transfer size. + * @param mode Logical OR of dma_mode_flags + * @sideeffect Disables the given DMA channel. + * @see dma_xfer_size + * @see dma_mode_flags + * @see dma_set_num_transfers() + * @see dma_set_priority() + * @see dma_attach_interrupt() + * @see dma_enable() + */ +void dma_setup_transfer(dma_dev *dev, + dma_channel channel, + __io void *peripheral_address, + dma_xfer_size peripheral_size, + __io void *memory_address, + dma_xfer_size memory_size, + uint32 mode) { + dma_channel_reg_map *channel_regs = dma_channel_regs(dev, channel); + + dma_disable(dev, channel); /* can't write to CMAR/CPAR otherwise */ + channel_regs->CCR = (memory_size << 10) | (peripheral_size << 8) | mode; + channel_regs->CMAR = (uint32)memory_address; + channel_regs->CPAR = (uint32)peripheral_address; +} + +/** + * @brief Set the number of data to be transferred on a DMA channel. + * + * You may not call this function while the channel is enabled. + * + * @param dev DMA device + * @param channel Channel through which the transfer occurs. + * @param num_transfers + */ +void dma_set_num_transfers(dma_dev *dev, + dma_channel channel, + uint16 num_transfers) { + dma_channel_reg_map *channel_regs; + + ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); + + channel_regs = dma_channel_regs(dev, channel); + channel_regs->CNDTR = num_transfers; +} + +/** + * @brief Set the priority of a DMA transfer. + * + * You may not call this function while the channel is enabled. + * + * @param dev DMA device + * @param channel DMA channel + * @param priority priority to set. + */ +void dma_set_priority(dma_dev *dev, + dma_channel channel, + dma_priority priority) { + dma_channel_reg_map *channel_regs; + uint32 ccr; + + ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); + + channel_regs = dma_channel_regs(dev, channel); + ccr = channel_regs->CCR; + ccr &= ~DMA_CCR_PL; + ccr |= priority; + channel_regs->CCR = ccr; +} + +/** + * @brief Attach an interrupt to a DMA transfer. + * + * Interrupts are enabled using appropriate mode flags in + * dma_setup_transfer(). + * + * @param dev DMA device + * @param channel Channel to attach handler to + * @param handler Interrupt handler to call when channel interrupt fires. + * @see dma_setup_transfer() + * @see dma_get_irq_cause() + * @see dma_detach_interrupt() + */ +void dma_attach_interrupt(dma_dev *dev, + dma_channel channel, + void (*handler)(void)) { + dev->handlers[channel - 1].handler = handler; + nvic_irq_enable(dev->handlers[channel - 1].irq_line); +} + +/** + * @brief Detach a DMA transfer interrupt handler. + * + * After calling this function, the given channel's interrupts will be + * disabled. + * + * @param dev DMA device + * @param channel Channel whose handler to detach + * @sideeffect Clears interrupt enable bits in the channel's CCR register. + * @see dma_attach_interrupt() + */ +void dma_detach_interrupt(dma_dev *dev, dma_channel channel) { + /* Don't use nvic_irq_disable()! Think about DMA2 channels 4 and 5. */ + dma_channel_regs(dev, channel)->CCR &= ~0xF; + dev->handlers[channel - 1].handler = NULL; +} + +/** + * @brief Discover the reason why a DMA interrupt was called. + * + * You may only call this function within an attached interrupt + * handler for the given channel. + * + * This function resets the internal DMA register state which encodes + * the cause of the interrupt; consequently, it can only be called + * once per interrupt handler invocation. + * + * @param dev DMA device + * @param channel Channel whose interrupt is being handled. + * @return Reason why the interrupt fired. + * @sideeffect Clears channel status flags in dev->regs->ISR. + * @see dma_attach_interrupt() + * @see dma_irq_cause + */ +dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) { + uint8 status_bits = dma_get_isr_bits(dev, channel); + + /* If the channel global interrupt flag is cleared, then + * something's very wrong. */ + ASSERT(status_bits & BIT(0)); + + dma_clear_isr_bits(dev, channel); + + /* ISR flags get set even if the corresponding interrupt enable + * bits in the channel's configuration register are cleared, so we + * can't use a switch here. + * + * Don't change the order of these if statements. */ + if (status_bits & BIT(3)) { + return DMA_TRANSFER_ERROR; + } else if (status_bits & BIT(1)) { + return DMA_TRANSFER_COMPLETE; + } else if (status_bits & BIT(2)) { + return DMA_TRANSFER_HALF_COMPLETE; + } else if (status_bits & BIT(0)) { + /* Shouldn't happen (unless someone messed up an IFCR write). */ + throb(); + } +#if DEBUG_LEVEL < DEBUG_ALL + else { + /* We shouldn't have been called, but the debug level is too + * low for the above ASSERT() to have had any effect. In + * order to fail fast, mimic the DMA controller's behavior + * when an error occurs. */ + dma_disable(dev, channel); + } +#endif + return DMA_TRANSFER_ERROR; +} + +/** + * @brief Enable a DMA channel. + * @param dev DMA device + * @param channel Channel to enable + */ +void dma_enable(dma_dev *dev, dma_channel channel) { + dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel); + bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 1); +} + +/** + * @brief Disable a DMA channel. + * @param dev DMA device + * @param channel Channel to disable + */ +void dma_disable(dma_dev *dev, dma_channel channel) { + dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel); + bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 0); +} + +/** + * @brief Set the base memory address where data will be read from or + * written to. + * + * You must not call this function while the channel is enabled. + * + * If the DMA memory size is 16 bits, the address is automatically + * aligned to a half-word. If the DMA memory size is 32 bits, the + * address is aligned to a word. + * + * @param dev DMA Device + * @param channel Channel whose base memory address to set. + * @param addr Memory base address to use. + */ +void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *addr) { + dma_channel_reg_map *chan_regs; + + ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); + + chan_regs = dma_channel_regs(dev, channel); + chan_regs->CMAR = (uint32)addr; +} + +/** + * @brief Set the base peripheral address where data will be read from + * or written to. + * + * You must not call this function while the channel is enabled. + * + * If the DMA peripheral size is 16 bits, the address is automatically + * aligned to a half-word. If the DMA peripheral size is 32 bits, the + * address is aligned to a word. + * + * @param dev DMA Device + * @param channel Channel whose peripheral data register base address to set. + * @param addr Peripheral memory base address to use. + */ +void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *addr) { + dma_channel_reg_map *chan_regs; + + ASSERT_FAULT(!dma_is_channel_enabled(dev, channel)); + + chan_regs = dma_channel_regs(dev, channel); + chan_regs->CPAR = (uint32)addr; +} + +/* + * IRQ handlers + */ + +static inline void dispatch_handler(dma_dev *dev, dma_channel channel) { + void (*handler)(void) = dev->handlers[channel - 1].handler; + if (handler) { + handler(); + dma_clear_isr_bits(dev, channel); /* in case handler doesn't */ + } +} + +void __irq_dma1_channel1(void) { + dispatch_handler(DMA1, DMA_CH1); +} + +void __irq_dma1_channel2(void) { + dispatch_handler(DMA1, DMA_CH2); +} + +void __irq_dma1_channel3(void) { + dispatch_handler(DMA1, DMA_CH3); +} + +void __irq_dma1_channel4(void) { + dispatch_handler(DMA1, DMA_CH4); +} + +void __irq_dma1_channel5(void) { + dispatch_handler(DMA1, DMA_CH5); +} + +void __irq_dma1_channel6(void) { + dispatch_handler(DMA1, DMA_CH6); +} + +void __irq_dma1_channel7(void) { + dispatch_handler(DMA1, DMA_CH7); +} + +#ifdef STM32_HIGH_DENSITY +void __irq_dma2_channel1(void) { + dispatch_handler(DMA2, DMA_CH1); +} + +void __irq_dma2_channel2(void) { + dispatch_handler(DMA2, DMA_CH2); +} + +void __irq_dma2_channel3(void) { + dispatch_handler(DMA2, DMA_CH3); +} + +void __irq_dma2_channel4_5(void) { + dispatch_handler(DMA2, DMA_CH4); + dispatch_handler(DMA2, DMA_CH5); +} +#endif diff --git a/Libmaple/libmaple/libmaple/dmaF1.h b/Libmaple/libmaple/libmaple/dmaF1.h index 4268c71d..6e8087f4 100644 --- a/Libmaple/libmaple/libmaple/dmaF1.h +++ b/Libmaple/libmaple/libmaple/dmaF1.h @@ -1,453 +1,453 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file dma.h - * - * @author Marti Bolivar ; - * Original implementation by Michael Hope - * - * @brief Direct Memory Access peripheral support - */ - -/* - * See /notes/dma.txt for more information. - */ - -#ifndef _DMA_H_ -#define _DMA_H_ - -#include "libmaple_types.h" -#include "rcc.h" -#include "nvic.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - * Register maps - */ - -/** - * @brief DMA register map type. - * - * Note that DMA controller 2 (register map base pointer DMA2_BASE) - * only supports channels 1--5. - */ -typedef struct dma_reg_map { - __io uint32 ISR; /**< Interrupt status register */ - __io uint32 IFCR; /**< Interrupt flag clear register */ - __io uint32 CCR1; /**< Channel 1 configuration register */ - __io uint32 CNDTR1; /**< Channel 1 number of data register */ - __io uint32 CPAR1; /**< Channel 1 peripheral address register */ - __io uint32 CMAR1; /**< Channel 1 memory address register */ - const uint32 RESERVED1; /**< Reserved. */ - __io uint32 CCR2; /**< Channel 2 configuration register */ - __io uint32 CNDTR2; /**< Channel 2 number of data register */ - __io uint32 CPAR2; /**< Channel 2 peripheral address register */ - __io uint32 CMAR2; /**< Channel 2 memory address register */ - const uint32 RESERVED2; /**< Reserved. */ - __io uint32 CCR3; /**< Channel 3 configuration register */ - __io uint32 CNDTR3; /**< Channel 3 number of data register */ - __io uint32 CPAR3; /**< Channel 3 peripheral address register */ - __io uint32 CMAR3; /**< Channel 3 memory address register */ - const uint32 RESERVED3; /**< Reserved. */ - __io uint32 CCR4; /**< Channel 4 configuration register */ - __io uint32 CNDTR4; /**< Channel 4 number of data register */ - __io uint32 CPAR4; /**< Channel 4 peripheral address register */ - __io uint32 CMAR4; /**< Channel 4 memory address register */ - const uint32 RESERVED4; /**< Reserved. */ - __io uint32 CCR5; /**< Channel 5 configuration register */ - __io uint32 CNDTR5; /**< Channel 5 number of data register */ - __io uint32 CPAR5; /**< Channel 5 peripheral address register */ - __io uint32 CMAR5; /**< Channel 5 memory address register */ - const uint32 RESERVED5; /**< Reserved. */ - __io uint32 CCR6; /**< Channel 6 configuration register */ - __io uint32 CNDTR6; /**< Channel 6 number of data register */ - __io uint32 CPAR6; /**< Channel 6 peripheral address register */ - __io uint32 CMAR6; /**< Channel 6 memory address register */ - const uint32 RESERVED6; /**< Reserved. */ - __io uint32 CCR7; /**< Channel 7 configuration register */ - __io uint32 CNDTR7; /**< Channel 7 number of data register */ - __io uint32 CPAR7; /**< Channel 7 peripheral address register */ - __io uint32 CMAR7; /**< Channel 7 memory address register */ - const uint32 RESERVED7; /**< Reserved. */ -} dma_reg_map; - -/** DMA controller 1 register map base pointer */ -#define DMA1_BASE ((struct dma_reg_map*)0x40020000) - -#ifdef STM32_HIGH_DENSITY -/** DMA controller 2 register map base pointer */ -#define DMA2_BASE ((struct dma_reg_map*)0x40020400) -#endif - -/* - * Register bit definitions - */ - -/* Interrupt status register */ - -#define DMA_ISR_TEIF7_BIT 27 -#define DMA_ISR_HTIF7_BIT 26 -#define DMA_ISR_TCIF7_BIT 25 -#define DMA_ISR_GIF7_BIT 24 -#define DMA_ISR_TEIF6_BIT 23 -#define DMA_ISR_HTIF6_BIT 22 -#define DMA_ISR_TCIF6_BIT 21 -#define DMA_ISR_GIF6_BIT 20 -#define DMA_ISR_TEIF5_BIT 19 -#define DMA_ISR_HTIF5_BIT 18 -#define DMA_ISR_TCIF5_BIT 17 -#define DMA_ISR_GIF5_BIT 16 -#define DMA_ISR_TEIF4_BIT 15 -#define DMA_ISR_HTIF4_BIT 14 -#define DMA_ISR_TCIF4_BIT 13 -#define DMA_ISR_GIF4_BIT 12 -#define DMA_ISR_TEIF3_BIT 11 -#define DMA_ISR_HTIF3_BIT 10 -#define DMA_ISR_TCIF3_BIT 9 -#define DMA_ISR_GIF3_BIT 8 -#define DMA_ISR_TEIF2_BIT 7 -#define DMA_ISR_HTIF2_BIT 6 -#define DMA_ISR_TCIF2_BIT 5 -#define DMA_ISR_GIF2_BIT 4 -#define DMA_ISR_TEIF1_BIT 3 -#define DMA_ISR_HTIF1_BIT 2 -#define DMA_ISR_TCIF1_BIT 1 -#define DMA_ISR_GIF1_BIT 0 - -#define DMA_ISR_TEIF7 BIT(DMA_ISR_TEIF7_BIT) -#define DMA_ISR_HTIF7 BIT(DMA_ISR_HTIF7_BIT) -#define DMA_ISR_TCIF7 BIT(DMA_ISR_TCIF7_BIT) -#define DMA_ISR_GIF7 BIT(DMA_ISR_GIF7_BIT) -#define DMA_ISR_TEIF6 BIT(DMA_ISR_TEIF6_BIT) -#define DMA_ISR_HTIF6 BIT(DMA_ISR_HTIF6_BIT) -#define DMA_ISR_TCIF6 BIT(DMA_ISR_TCIF6_BIT) -#define DMA_ISR_GIF6 BIT(DMA_ISR_GIF6_BIT) -#define DMA_ISR_TEIF5 BIT(DMA_ISR_TEIF5_BIT) -#define DMA_ISR_HTIF5 BIT(DMA_ISR_HTIF5_BIT) -#define DMA_ISR_TCIF5 BIT(DMA_ISR_TCIF5_BIT) -#define DMA_ISR_GIF5 BIT(DMA_ISR_GIF5_BIT) -#define DMA_ISR_TEIF4 BIT(DMA_ISR_TEIF4_BIT) -#define DMA_ISR_HTIF4 BIT(DMA_ISR_HTIF4_BIT) -#define DMA_ISR_TCIF4 BIT(DMA_ISR_TCIF4_BIT) -#define DMA_ISR_GIF4 BIT(DMA_ISR_GIF4_BIT) -#define DMA_ISR_TEIF3 BIT(DMA_ISR_TEIF3_BIT) -#define DMA_ISR_HTIF3 BIT(DMA_ISR_HTIF3_BIT) -#define DMA_ISR_TCIF3 BIT(DMA_ISR_TCIF3_BIT) -#define DMA_ISR_GIF3 BIT(DMA_ISR_GIF3_BIT) -#define DMA_ISR_TEIF2 BIT(DMA_ISR_TEIF2_BIT) -#define DMA_ISR_HTIF2 BIT(DMA_ISR_HTIF2_BIT) -#define DMA_ISR_TCIF2 BIT(DMA_ISR_TCIF2_BIT) -#define DMA_ISR_GIF2 BIT(DMA_ISR_GIF2_BIT) -#define DMA_ISR_TEIF1 BIT(DMA_ISR_TEIF1_BIT) -#define DMA_ISR_HTIF1 BIT(DMA_ISR_HTIF1_BIT) -#define DMA_ISR_TCIF1 BIT(DMA_ISR_TCIF1_BIT) -#define DMA_ISR_GIF1 BIT(DMA_ISR_GIF1_BIT) - -/* Interrupt flag clear register */ - -#define DMA_IFCR_CTEIF7_BIT 27 -#define DMA_IFCR_CHTIF7_BIT 26 -#define DMA_IFCR_CTCIF7_BIT 25 -#define DMA_IFCR_CGIF7_BIT 24 -#define DMA_IFCR_CTEIF6_BIT 23 -#define DMA_IFCR_CHTIF6_BIT 22 -#define DMA_IFCR_CTCIF6_BIT 21 -#define DMA_IFCR_CGIF6_BIT 20 -#define DMA_IFCR_CTEIF5_BIT 19 -#define DMA_IFCR_CHTIF5_BIT 18 -#define DMA_IFCR_CTCIF5_BIT 17 -#define DMA_IFCR_CGIF5_BIT 16 -#define DMA_IFCR_CTEIF4_BIT 15 -#define DMA_IFCR_CHTIF4_BIT 14 -#define DMA_IFCR_CTCIF4_BIT 13 -#define DMA_IFCR_CGIF4_BIT 12 -#define DMA_IFCR_CTEIF3_BIT 11 -#define DMA_IFCR_CHTIF3_BIT 10 -#define DMA_IFCR_CTCIF3_BIT 9 -#define DMA_IFCR_CGIF3_BIT 8 -#define DMA_IFCR_CTEIF2_BIT 7 -#define DMA_IFCR_CHTIF2_BIT 6 -#define DMA_IFCR_CTCIF2_BIT 5 -#define DMA_IFCR_CGIF2_BIT 4 -#define DMA_IFCR_CTEIF1_BIT 3 -#define DMA_IFCR_CHTIF1_BIT 2 -#define DMA_IFCR_CTCIF1_BIT 1 -#define DMA_IFCR_CGIF1_BIT 0 - -#define DMA_IFCR_CTEIF7 BIT(DMA_IFCR_CTEIF7_BIT) -#define DMA_IFCR_CHTIF7 BIT(DMA_IFCR_CHTIF7_BIT) -#define DMA_IFCR_CTCIF7 BIT(DMA_IFCR_CTCIF7_BIT) -#define DMA_IFCR_CGIF7 BIT(DMA_IFCR_CGIF7_BIT) -#define DMA_IFCR_CTEIF6 BIT(DMA_IFCR_CTEIF6_BIT) -#define DMA_IFCR_CHTIF6 BIT(DMA_IFCR_CHTIF6_BIT) -#define DMA_IFCR_CTCIF6 BIT(DMA_IFCR_CTCIF6_BIT) -#define DMA_IFCR_CGIF6 BIT(DMA_IFCR_CGIF6_BIT) -#define DMA_IFCR_CTEIF5 BIT(DMA_IFCR_CTEIF5_BIT) -#define DMA_IFCR_CHTIF5 BIT(DMA_IFCR_CHTIF5_BIT) -#define DMA_IFCR_CTCIF5 BIT(DMA_IFCR_CTCIF5_BIT) -#define DMA_IFCR_CGIF5 BIT(DMA_IFCR_CGIF5_BIT) -#define DMA_IFCR_CTEIF4 BIT(DMA_IFCR_CTEIF4_BIT) -#define DMA_IFCR_CHTIF4 BIT(DMA_IFCR_CHTIF4_BIT) -#define DMA_IFCR_CTCIF4 BIT(DMA_IFCR_CTCIF4_BIT) -#define DMA_IFCR_CGIF4 BIT(DMA_IFCR_CGIF4_BIT) -#define DMA_IFCR_CTEIF3 BIT(DMA_IFCR_CTEIF3_BIT) -#define DMA_IFCR_CHTIF3 BIT(DMA_IFCR_CHTIF3_BIT) -#define DMA_IFCR_CTCIF3 BIT(DMA_IFCR_CTCIF3_BIT) -#define DMA_IFCR_CGIF3 BIT(DMA_IFCR_CGIF3_BIT) -#define DMA_IFCR_CTEIF2 BIT(DMA_IFCR_CTEIF2_BIT) -#define DMA_IFCR_CHTIF2 BIT(DMA_IFCR_CHTIF2_BIT) -#define DMA_IFCR_CTCIF2 BIT(DMA_IFCR_CTCIF2_BIT) -#define DMA_IFCR_CGIF2 BIT(DMA_IFCR_CGIF2_BIT) -#define DMA_IFCR_CTEIF1 BIT(DMA_IFCR_CTEIF1_BIT) -#define DMA_IFCR_CHTIF1 BIT(DMA_IFCR_CHTIF1_BIT) -#define DMA_IFCR_CTCIF1 BIT(DMA_IFCR_CTCIF1_BIT) -#define DMA_IFCR_CGIF1 BIT(DMA_IFCR_CGIF1_BIT) - -/* Channel configuration register */ - -#define DMA_CCR_MEM2MEM_BIT 14 -#define DMA_CCR_MINC_BIT 7 -#define DMA_CCR_PINC_BIT 6 -#define DMA_CCR_CIRC_BIT 5 -#define DMA_CCR_DIR_BIT 4 -#define DMA_CCR_TEIE_BIT 3 -#define DMA_CCR_HTIE_BIT 2 -#define DMA_CCR_TCIE_BIT 1 -#define DMA_CCR_EN_BIT 0 - -#define DMA_CCR_MEM2MEM BIT(DMA_CCR_MEM2MEM_BIT) -#define DMA_CCR_PL (0x3 << 12) -#define DMA_CCR_PL_LOW (0x0 << 12) -#define DMA_CCR_PL_MEDIUM (0x1 << 12) -#define DMA_CCR_PL_HIGH (0x2 << 12) -#define DMA_CCR_PL_VERY_HIGH (0x3 << 12) -#define DMA_CCR_MSIZE (0x3 << 10) -#define DMA_CCR_MSIZE_8BITS (0x0 << 10) -#define DMA_CCR_MSIZE_16BITS (0x1 << 10) -#define DMA_CCR_MSIZE_32BITS (0x2 << 10) -#define DMA_CCR_PSIZE (0x3 << 8) -#define DMA_CCR_PSIZE_8BITS (0x0 << 8) -#define DMA_CCR_PSIZE_16BITS (0x1 << 8) -#define DMA_CCR_PSIZE_32BITS (0x2 << 8) -#define DMA_CCR_MINC BIT(DMA_CCR_MINC_BIT) -#define DMA_CCR_PINC BIT(DMA_CCR_PINC_BIT) -#define DMA_CCR_CIRC BIT(DMA_CCR_CIRC_BIT) -#define DMA_CCR_DIR BIT(DMA_CCR_DIR_BIT) -#define DMA_CCR_TEIE BIT(DMA_CCR_TEIE_BIT) -#define DMA_CCR_HTIE BIT(DMA_CCR_HTIE_BIT) -#define DMA_CCR_TCIE BIT(DMA_CCR_TCIE_BIT) -#define DMA_CCR_EN BIT(DMA_CCR_EN_BIT) - -/* - * Devices - */ - -/** Encapsulates state related to a DMA channel interrupt. */ -typedef struct dma_handler_config { - void (*handler)(void); /**< User-specified channel interrupt - handler */ - nvic_irq_num irq_line; /**< Channel's NVIC interrupt number */ -} dma_handler_config; - -/** DMA device type */ -typedef struct dma_dev { - dma_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< Clock ID */ - dma_handler_config handlers[]; /**< - * @brief IRQ handlers and NVIC numbers. - * - * @see dma_attach_interrupt() - * @see dma_detach_interrupt() - */ -} dma_dev; - -extern dma_dev *DMA1; -#ifdef STM32_HIGH_DENSITY -extern dma_dev *DMA2; -#endif - -/* - * Convenience functions - */ - -void dma_init(dma_dev *dev); - -/** Flags for DMA transfer configuration. */ -typedef enum dma_mode_flags { - DMA_MEM_2_MEM = 1 << 14, /**< Memory to memory mode */ - DMA_MINC_MODE = 1 << 7, /**< Auto-increment memory address */ - DMA_PINC_MODE = 1 << 6, /**< Auto-increment peripheral address */ - DMA_CIRC_MODE = 1 << 5, /**< Circular mode */ - DMA_FROM_MEM = 1 << 4, /**< Read from memory to peripheral */ - DMA_TRNS_ERR = 1 << 3, /**< Interrupt on transfer error */ - DMA_HALF_TRNS = 1 << 2, /**< Interrupt on half-transfer */ - DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */ -} dma_mode_flags; - -/** Source and destination transfer sizes. */ -typedef enum dma_xfer_size { - DMA_SIZE_8BITS = 0, /**< 8-bit transfers */ - DMA_SIZE_16BITS = 1, /**< 16-bit transfers */ - DMA_SIZE_32BITS = 2 /**< 32-bit transfers */ -} dma_xfer_size; - -/** DMA channel */ -typedef enum dma_channel { - DMA_CH1 = 1, /**< Channel 1 */ - DMA_CH2 = 2, /**< Channel 2 */ - DMA_CH3 = 3, /**< Channel 3 */ - DMA_CH4 = 4, /**< Channel 4 */ - DMA_CH5 = 5, /**< Channel 5 */ - DMA_CH6 = 6, /**< Channel 6 */ - DMA_CH7 = 7, /**< Channel 7 */ -} dma_channel; - -void dma_setup_transfer(dma_dev *dev, - dma_channel channel, - __io void *peripheral_address, - dma_xfer_size peripheral_size, - __io void *memory_address, - dma_xfer_size memory_size, - uint32 mode); - -void dma_set_num_transfers(dma_dev *dev, - dma_channel channel, - uint16 num_transfers); - -/** DMA transfer priority. */ -typedef enum dma_priority { - DMA_PRIORITY_LOW = DMA_CCR_PL_LOW, /**< Low priority */ - DMA_PRIORITY_MEDIUM = DMA_CCR_PL_MEDIUM, /**< Medium priority */ - DMA_PRIORITY_HIGH = DMA_CCR_PL_HIGH, /**< High priority */ - DMA_PRIORITY_VERY_HIGH = DMA_CCR_PL_VERY_HIGH /**< Very high priority */ -} dma_priority; - -void dma_set_priority(dma_dev *dev, - dma_channel channel, - dma_priority priority); - -void dma_attach_interrupt(dma_dev *dev, - dma_channel channel, - void (*handler)(void)); -void dma_detach_interrupt(dma_dev *dev, dma_channel channel); - -/** - * Encodes the reason why a DMA interrupt was called. - * @see dma_get_irq_cause() - */ -typedef enum dma_irq_cause { - DMA_TRANSFER_COMPLETE, /**< Transfer is complete. */ - DMA_TRANSFER_HALF_COMPLETE, /**< Transfer is half complete. */ - DMA_TRANSFER_ERROR, /**< Error occurred during transfer. */ -} dma_irq_cause; - -dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel); - -void dma_enable(dma_dev *dev, dma_channel channel); -void dma_disable(dma_dev *dev, dma_channel channel); - -void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *address); -void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *address); - -/** - * @brief DMA channel register map type. - * - * Provides access to an individual channel's registers. - */ -typedef struct dma_channel_reg_map { - __io uint32 CCR; /**< Channel configuration register */ - __io uint32 CNDTR; /**< Channel number of data register */ - __io uint32 CPAR; /**< Channel peripheral address register */ - __io uint32 CMAR; /**< Channel memory address register */ -} dma_channel_reg_map; - -#define DMA_CHANNEL_NREGS 5 - -/** - * @brief Obtain a pointer to an individual DMA channel's registers. - * - * For example, dma_channel_regs(DMA1, DMA_CH1)->CCR is DMA1_BASE->CCR1. - * - * @param dev DMA device - * @param channel DMA channel whose channel register map to obtain. - */ -static inline dma_channel_reg_map* dma_channel_regs(dma_dev *dev, - dma_channel channel) { - __io uint32 *ccr1 = &dev->regs->CCR1; - return (dma_channel_reg_map*)(ccr1 + DMA_CHANNEL_NREGS * (channel - 1)); -} - -/** - * @brief Check if a DMA channel is enabled - * @param dev DMA device - * @param channel Channel whose enabled bit to check. - */ -static inline uint8 dma_is_channel_enabled(dma_dev *dev, dma_channel channel) { - return (uint8)(dma_channel_regs(dev, channel)->CCR & DMA_CCR_EN); -} - -/** - * @brief Get the ISR status bits for a DMA channel. - * - * The bits are returned right-aligned, in the following order: - * transfer error flag, half-transfer flag, transfer complete flag, - * global interrupt flag. - * - * If you're attempting to figure out why a DMA interrupt fired; you - * may find dma_get_irq_cause() more convenient. - * - * @param dev DMA device - * @param channel Channel whose ISR bits to return. - * @see dma_get_irq_cause(). - */ -static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_channel channel) { - uint8 shift = (channel - 1) * 4; - return (dev->regs->ISR >> shift) & 0xF; -} - -/** - * @brief Clear the ISR status bits for a given DMA channel. - * - * If you're attempting to clean up after yourself in a DMA interrupt, - * you may find dma_get_irq_cause() more convenient. - * - * @param dev DMA device - * @param channel Channel whose ISR bits to clear. - * @see dma_get_irq_cause() - */ -static inline void dma_clear_isr_bits(dma_dev *dev, dma_channel channel) { - dev->regs->IFCR = BIT(4 * (channel - 1)); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Michael Hope. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file dma.h + * + * @author Marti Bolivar ; + * Original implementation by Michael Hope + * + * @brief Direct Memory Access peripheral support + */ + +/* + * See /notes/dma.txt for more information. + */ + +#ifndef _DMA_H_ +#define _DMA_H_ + +#include "libmaple_types.h" +#include "rcc.h" +#include "nvic.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * Register maps + */ + +/** + * @brief DMA register map type. + * + * Note that DMA controller 2 (register map base pointer DMA2_BASE) + * only supports channels 1--5. + */ +typedef struct dma_reg_map { + __io uint32 ISR; /**< Interrupt status register */ + __io uint32 IFCR; /**< Interrupt flag clear register */ + __io uint32 CCR1; /**< Channel 1 configuration register */ + __io uint32 CNDTR1; /**< Channel 1 number of data register */ + __io uint32 CPAR1; /**< Channel 1 peripheral address register */ + __io uint32 CMAR1; /**< Channel 1 memory address register */ + const uint32 RESERVED1; /**< Reserved. */ + __io uint32 CCR2; /**< Channel 2 configuration register */ + __io uint32 CNDTR2; /**< Channel 2 number of data register */ + __io uint32 CPAR2; /**< Channel 2 peripheral address register */ + __io uint32 CMAR2; /**< Channel 2 memory address register */ + const uint32 RESERVED2; /**< Reserved. */ + __io uint32 CCR3; /**< Channel 3 configuration register */ + __io uint32 CNDTR3; /**< Channel 3 number of data register */ + __io uint32 CPAR3; /**< Channel 3 peripheral address register */ + __io uint32 CMAR3; /**< Channel 3 memory address register */ + const uint32 RESERVED3; /**< Reserved. */ + __io uint32 CCR4; /**< Channel 4 configuration register */ + __io uint32 CNDTR4; /**< Channel 4 number of data register */ + __io uint32 CPAR4; /**< Channel 4 peripheral address register */ + __io uint32 CMAR4; /**< Channel 4 memory address register */ + const uint32 RESERVED4; /**< Reserved. */ + __io uint32 CCR5; /**< Channel 5 configuration register */ + __io uint32 CNDTR5; /**< Channel 5 number of data register */ + __io uint32 CPAR5; /**< Channel 5 peripheral address register */ + __io uint32 CMAR5; /**< Channel 5 memory address register */ + const uint32 RESERVED5; /**< Reserved. */ + __io uint32 CCR6; /**< Channel 6 configuration register */ + __io uint32 CNDTR6; /**< Channel 6 number of data register */ + __io uint32 CPAR6; /**< Channel 6 peripheral address register */ + __io uint32 CMAR6; /**< Channel 6 memory address register */ + const uint32 RESERVED6; /**< Reserved. */ + __io uint32 CCR7; /**< Channel 7 configuration register */ + __io uint32 CNDTR7; /**< Channel 7 number of data register */ + __io uint32 CPAR7; /**< Channel 7 peripheral address register */ + __io uint32 CMAR7; /**< Channel 7 memory address register */ + const uint32 RESERVED7; /**< Reserved. */ +} dma_reg_map; + +/** DMA controller 1 register map base pointer */ +#define DMA1_BASE ((struct dma_reg_map*)0x40020000) + +#ifdef STM32_HIGH_DENSITY +/** DMA controller 2 register map base pointer */ +#define DMA2_BASE ((struct dma_reg_map*)0x40020400) +#endif + +/* + * Register bit definitions + */ + +/* Interrupt status register */ + +#define DMA_ISR_TEIF7_BIT 27 +#define DMA_ISR_HTIF7_BIT 26 +#define DMA_ISR_TCIF7_BIT 25 +#define DMA_ISR_GIF7_BIT 24 +#define DMA_ISR_TEIF6_BIT 23 +#define DMA_ISR_HTIF6_BIT 22 +#define DMA_ISR_TCIF6_BIT 21 +#define DMA_ISR_GIF6_BIT 20 +#define DMA_ISR_TEIF5_BIT 19 +#define DMA_ISR_HTIF5_BIT 18 +#define DMA_ISR_TCIF5_BIT 17 +#define DMA_ISR_GIF5_BIT 16 +#define DMA_ISR_TEIF4_BIT 15 +#define DMA_ISR_HTIF4_BIT 14 +#define DMA_ISR_TCIF4_BIT 13 +#define DMA_ISR_GIF4_BIT 12 +#define DMA_ISR_TEIF3_BIT 11 +#define DMA_ISR_HTIF3_BIT 10 +#define DMA_ISR_TCIF3_BIT 9 +#define DMA_ISR_GIF3_BIT 8 +#define DMA_ISR_TEIF2_BIT 7 +#define DMA_ISR_HTIF2_BIT 6 +#define DMA_ISR_TCIF2_BIT 5 +#define DMA_ISR_GIF2_BIT 4 +#define DMA_ISR_TEIF1_BIT 3 +#define DMA_ISR_HTIF1_BIT 2 +#define DMA_ISR_TCIF1_BIT 1 +#define DMA_ISR_GIF1_BIT 0 + +#define DMA_ISR_TEIF7 BIT(DMA_ISR_TEIF7_BIT) +#define DMA_ISR_HTIF7 BIT(DMA_ISR_HTIF7_BIT) +#define DMA_ISR_TCIF7 BIT(DMA_ISR_TCIF7_BIT) +#define DMA_ISR_GIF7 BIT(DMA_ISR_GIF7_BIT) +#define DMA_ISR_TEIF6 BIT(DMA_ISR_TEIF6_BIT) +#define DMA_ISR_HTIF6 BIT(DMA_ISR_HTIF6_BIT) +#define DMA_ISR_TCIF6 BIT(DMA_ISR_TCIF6_BIT) +#define DMA_ISR_GIF6 BIT(DMA_ISR_GIF6_BIT) +#define DMA_ISR_TEIF5 BIT(DMA_ISR_TEIF5_BIT) +#define DMA_ISR_HTIF5 BIT(DMA_ISR_HTIF5_BIT) +#define DMA_ISR_TCIF5 BIT(DMA_ISR_TCIF5_BIT) +#define DMA_ISR_GIF5 BIT(DMA_ISR_GIF5_BIT) +#define DMA_ISR_TEIF4 BIT(DMA_ISR_TEIF4_BIT) +#define DMA_ISR_HTIF4 BIT(DMA_ISR_HTIF4_BIT) +#define DMA_ISR_TCIF4 BIT(DMA_ISR_TCIF4_BIT) +#define DMA_ISR_GIF4 BIT(DMA_ISR_GIF4_BIT) +#define DMA_ISR_TEIF3 BIT(DMA_ISR_TEIF3_BIT) +#define DMA_ISR_HTIF3 BIT(DMA_ISR_HTIF3_BIT) +#define DMA_ISR_TCIF3 BIT(DMA_ISR_TCIF3_BIT) +#define DMA_ISR_GIF3 BIT(DMA_ISR_GIF3_BIT) +#define DMA_ISR_TEIF2 BIT(DMA_ISR_TEIF2_BIT) +#define DMA_ISR_HTIF2 BIT(DMA_ISR_HTIF2_BIT) +#define DMA_ISR_TCIF2 BIT(DMA_ISR_TCIF2_BIT) +#define DMA_ISR_GIF2 BIT(DMA_ISR_GIF2_BIT) +#define DMA_ISR_TEIF1 BIT(DMA_ISR_TEIF1_BIT) +#define DMA_ISR_HTIF1 BIT(DMA_ISR_HTIF1_BIT) +#define DMA_ISR_TCIF1 BIT(DMA_ISR_TCIF1_BIT) +#define DMA_ISR_GIF1 BIT(DMA_ISR_GIF1_BIT) + +/* Interrupt flag clear register */ + +#define DMA_IFCR_CTEIF7_BIT 27 +#define DMA_IFCR_CHTIF7_BIT 26 +#define DMA_IFCR_CTCIF7_BIT 25 +#define DMA_IFCR_CGIF7_BIT 24 +#define DMA_IFCR_CTEIF6_BIT 23 +#define DMA_IFCR_CHTIF6_BIT 22 +#define DMA_IFCR_CTCIF6_BIT 21 +#define DMA_IFCR_CGIF6_BIT 20 +#define DMA_IFCR_CTEIF5_BIT 19 +#define DMA_IFCR_CHTIF5_BIT 18 +#define DMA_IFCR_CTCIF5_BIT 17 +#define DMA_IFCR_CGIF5_BIT 16 +#define DMA_IFCR_CTEIF4_BIT 15 +#define DMA_IFCR_CHTIF4_BIT 14 +#define DMA_IFCR_CTCIF4_BIT 13 +#define DMA_IFCR_CGIF4_BIT 12 +#define DMA_IFCR_CTEIF3_BIT 11 +#define DMA_IFCR_CHTIF3_BIT 10 +#define DMA_IFCR_CTCIF3_BIT 9 +#define DMA_IFCR_CGIF3_BIT 8 +#define DMA_IFCR_CTEIF2_BIT 7 +#define DMA_IFCR_CHTIF2_BIT 6 +#define DMA_IFCR_CTCIF2_BIT 5 +#define DMA_IFCR_CGIF2_BIT 4 +#define DMA_IFCR_CTEIF1_BIT 3 +#define DMA_IFCR_CHTIF1_BIT 2 +#define DMA_IFCR_CTCIF1_BIT 1 +#define DMA_IFCR_CGIF1_BIT 0 + +#define DMA_IFCR_CTEIF7 BIT(DMA_IFCR_CTEIF7_BIT) +#define DMA_IFCR_CHTIF7 BIT(DMA_IFCR_CHTIF7_BIT) +#define DMA_IFCR_CTCIF7 BIT(DMA_IFCR_CTCIF7_BIT) +#define DMA_IFCR_CGIF7 BIT(DMA_IFCR_CGIF7_BIT) +#define DMA_IFCR_CTEIF6 BIT(DMA_IFCR_CTEIF6_BIT) +#define DMA_IFCR_CHTIF6 BIT(DMA_IFCR_CHTIF6_BIT) +#define DMA_IFCR_CTCIF6 BIT(DMA_IFCR_CTCIF6_BIT) +#define DMA_IFCR_CGIF6 BIT(DMA_IFCR_CGIF6_BIT) +#define DMA_IFCR_CTEIF5 BIT(DMA_IFCR_CTEIF5_BIT) +#define DMA_IFCR_CHTIF5 BIT(DMA_IFCR_CHTIF5_BIT) +#define DMA_IFCR_CTCIF5 BIT(DMA_IFCR_CTCIF5_BIT) +#define DMA_IFCR_CGIF5 BIT(DMA_IFCR_CGIF5_BIT) +#define DMA_IFCR_CTEIF4 BIT(DMA_IFCR_CTEIF4_BIT) +#define DMA_IFCR_CHTIF4 BIT(DMA_IFCR_CHTIF4_BIT) +#define DMA_IFCR_CTCIF4 BIT(DMA_IFCR_CTCIF4_BIT) +#define DMA_IFCR_CGIF4 BIT(DMA_IFCR_CGIF4_BIT) +#define DMA_IFCR_CTEIF3 BIT(DMA_IFCR_CTEIF3_BIT) +#define DMA_IFCR_CHTIF3 BIT(DMA_IFCR_CHTIF3_BIT) +#define DMA_IFCR_CTCIF3 BIT(DMA_IFCR_CTCIF3_BIT) +#define DMA_IFCR_CGIF3 BIT(DMA_IFCR_CGIF3_BIT) +#define DMA_IFCR_CTEIF2 BIT(DMA_IFCR_CTEIF2_BIT) +#define DMA_IFCR_CHTIF2 BIT(DMA_IFCR_CHTIF2_BIT) +#define DMA_IFCR_CTCIF2 BIT(DMA_IFCR_CTCIF2_BIT) +#define DMA_IFCR_CGIF2 BIT(DMA_IFCR_CGIF2_BIT) +#define DMA_IFCR_CTEIF1 BIT(DMA_IFCR_CTEIF1_BIT) +#define DMA_IFCR_CHTIF1 BIT(DMA_IFCR_CHTIF1_BIT) +#define DMA_IFCR_CTCIF1 BIT(DMA_IFCR_CTCIF1_BIT) +#define DMA_IFCR_CGIF1 BIT(DMA_IFCR_CGIF1_BIT) + +/* Channel configuration register */ + +#define DMA_CCR_MEM2MEM_BIT 14 +#define DMA_CCR_MINC_BIT 7 +#define DMA_CCR_PINC_BIT 6 +#define DMA_CCR_CIRC_BIT 5 +#define DMA_CCR_DIR_BIT 4 +#define DMA_CCR_TEIE_BIT 3 +#define DMA_CCR_HTIE_BIT 2 +#define DMA_CCR_TCIE_BIT 1 +#define DMA_CCR_EN_BIT 0 + +#define DMA_CCR_MEM2MEM BIT(DMA_CCR_MEM2MEM_BIT) +#define DMA_CCR_PL (0x3 << 12) +#define DMA_CCR_PL_LOW (0x0 << 12) +#define DMA_CCR_PL_MEDIUM (0x1 << 12) +#define DMA_CCR_PL_HIGH (0x2 << 12) +#define DMA_CCR_PL_VERY_HIGH (0x3 << 12) +#define DMA_CCR_MSIZE (0x3 << 10) +#define DMA_CCR_MSIZE_8BITS (0x0 << 10) +#define DMA_CCR_MSIZE_16BITS (0x1 << 10) +#define DMA_CCR_MSIZE_32BITS (0x2 << 10) +#define DMA_CCR_PSIZE (0x3 << 8) +#define DMA_CCR_PSIZE_8BITS (0x0 << 8) +#define DMA_CCR_PSIZE_16BITS (0x1 << 8) +#define DMA_CCR_PSIZE_32BITS (0x2 << 8) +#define DMA_CCR_MINC BIT(DMA_CCR_MINC_BIT) +#define DMA_CCR_PINC BIT(DMA_CCR_PINC_BIT) +#define DMA_CCR_CIRC BIT(DMA_CCR_CIRC_BIT) +#define DMA_CCR_DIR BIT(DMA_CCR_DIR_BIT) +#define DMA_CCR_TEIE BIT(DMA_CCR_TEIE_BIT) +#define DMA_CCR_HTIE BIT(DMA_CCR_HTIE_BIT) +#define DMA_CCR_TCIE BIT(DMA_CCR_TCIE_BIT) +#define DMA_CCR_EN BIT(DMA_CCR_EN_BIT) + +/* + * Devices + */ + +/** Encapsulates state related to a DMA channel interrupt. */ +typedef struct dma_handler_config { + void (*handler)(void); /**< User-specified channel interrupt + handler */ + nvic_irq_num irq_line; /**< Channel's NVIC interrupt number */ +} dma_handler_config; + +/** DMA device type */ +typedef struct dma_dev { + dma_reg_map *regs; /**< Register map */ + rcc_clk_id clk_id; /**< Clock ID */ + dma_handler_config handlers[]; /**< + * @brief IRQ handlers and NVIC numbers. + * + * @see dma_attach_interrupt() + * @see dma_detach_interrupt() + */ +} dma_dev; + +extern dma_dev *DMA1; +#ifdef STM32_HIGH_DENSITY +extern dma_dev *DMA2; +#endif + +/* + * Convenience functions + */ + +void dma_init(dma_dev *dev); + +/** Flags for DMA transfer configuration. */ +typedef enum dma_mode_flags { + DMA_MEM_2_MEM = 1 << 14, /**< Memory to memory mode */ + DMA_MINC_MODE = 1 << 7, /**< Auto-increment memory address */ + DMA_PINC_MODE = 1 << 6, /**< Auto-increment peripheral address */ + DMA_CIRC_MODE = 1 << 5, /**< Circular mode */ + DMA_FROM_MEM = 1 << 4, /**< Read from memory to peripheral */ + DMA_TRNS_ERR = 1 << 3, /**< Interrupt on transfer error */ + DMA_HALF_TRNS = 1 << 2, /**< Interrupt on half-transfer */ + DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */ +} dma_mode_flags; + +/** Source and destination transfer sizes. */ +typedef enum dma_xfer_size { + DMA_SIZE_8BITS = 0, /**< 8-bit transfers */ + DMA_SIZE_16BITS = 1, /**< 16-bit transfers */ + DMA_SIZE_32BITS = 2 /**< 32-bit transfers */ +} dma_xfer_size; + +/** DMA channel */ +typedef enum dma_channel { + DMA_CH1 = 1, /**< Channel 1 */ + DMA_CH2 = 2, /**< Channel 2 */ + DMA_CH3 = 3, /**< Channel 3 */ + DMA_CH4 = 4, /**< Channel 4 */ + DMA_CH5 = 5, /**< Channel 5 */ + DMA_CH6 = 6, /**< Channel 6 */ + DMA_CH7 = 7, /**< Channel 7 */ +} dma_channel; + +void dma_setup_transfer(dma_dev *dev, + dma_channel channel, + __io void *peripheral_address, + dma_xfer_size peripheral_size, + __io void *memory_address, + dma_xfer_size memory_size, + uint32 mode); + +void dma_set_num_transfers(dma_dev *dev, + dma_channel channel, + uint16 num_transfers); + +/** DMA transfer priority. */ +typedef enum dma_priority { + DMA_PRIORITY_LOW = DMA_CCR_PL_LOW, /**< Low priority */ + DMA_PRIORITY_MEDIUM = DMA_CCR_PL_MEDIUM, /**< Medium priority */ + DMA_PRIORITY_HIGH = DMA_CCR_PL_HIGH, /**< High priority */ + DMA_PRIORITY_VERY_HIGH = DMA_CCR_PL_VERY_HIGH /**< Very high priority */ +} dma_priority; + +void dma_set_priority(dma_dev *dev, + dma_channel channel, + dma_priority priority); + +void dma_attach_interrupt(dma_dev *dev, + dma_channel channel, + void (*handler)(void)); +void dma_detach_interrupt(dma_dev *dev, dma_channel channel); + +/** + * Encodes the reason why a DMA interrupt was called. + * @see dma_get_irq_cause() + */ +typedef enum dma_irq_cause { + DMA_TRANSFER_COMPLETE, /**< Transfer is complete. */ + DMA_TRANSFER_HALF_COMPLETE, /**< Transfer is half complete. */ + DMA_TRANSFER_ERROR, /**< Error occurred during transfer. */ +} dma_irq_cause; + +dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel); + +void dma_enable(dma_dev *dev, dma_channel channel); +void dma_disable(dma_dev *dev, dma_channel channel); + +void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *address); +void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *address); + +/** + * @brief DMA channel register map type. + * + * Provides access to an individual channel's registers. + */ +typedef struct dma_channel_reg_map { + __io uint32 CCR; /**< Channel configuration register */ + __io uint32 CNDTR; /**< Channel number of data register */ + __io uint32 CPAR; /**< Channel peripheral address register */ + __io uint32 CMAR; /**< Channel memory address register */ +} dma_channel_reg_map; + +#define DMA_CHANNEL_NREGS 5 + +/** + * @brief Obtain a pointer to an individual DMA channel's registers. + * + * For example, dma_channel_regs(DMA1, DMA_CH1)->CCR is DMA1_BASE->CCR1. + * + * @param dev DMA device + * @param channel DMA channel whose channel register map to obtain. + */ +static inline dma_channel_reg_map* dma_channel_regs(dma_dev *dev, + dma_channel channel) { + __io uint32 *ccr1 = &dev->regs->CCR1; + return (dma_channel_reg_map*)(ccr1 + DMA_CHANNEL_NREGS * (channel - 1)); +} + +/** + * @brief Check if a DMA channel is enabled + * @param dev DMA device + * @param channel Channel whose enabled bit to check. + */ +static inline uint8 dma_is_channel_enabled(dma_dev *dev, dma_channel channel) { + return (uint8)(dma_channel_regs(dev, channel)->CCR & DMA_CCR_EN); +} + +/** + * @brief Get the ISR status bits for a DMA channel. + * + * The bits are returned right-aligned, in the following order: + * transfer error flag, half-transfer flag, transfer complete flag, + * global interrupt flag. + * + * If you're attempting to figure out why a DMA interrupt fired; you + * may find dma_get_irq_cause() more convenient. + * + * @param dev DMA device + * @param channel Channel whose ISR bits to return. + * @see dma_get_irq_cause(). + */ +static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_channel channel) { + uint8 shift = (channel - 1) * 4; + return (dev->regs->ISR >> shift) & 0xF; +} + +/** + * @brief Clear the ISR status bits for a given DMA channel. + * + * If you're attempting to clean up after yourself in a DMA interrupt, + * you may find dma_get_irq_cause() more convenient. + * + * @param dev DMA device + * @param channel Channel whose ISR bits to clear. + * @see dma_get_irq_cause() + */ +static inline void dma_clear_isr_bits(dma_dev *dev, dma_channel channel) { + dev->regs->IFCR = BIT(4 * (channel - 1)); +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/dmaF2.c b/Libmaple/libmaple/libmaple/dmaF2.c index 9ae17bb0..e70bafec 100644 --- a/Libmaple/libmaple/libmaple/dmaF2.c +++ b/Libmaple/libmaple/libmaple/dmaF2.c @@ -1,238 +1,238 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file dmaF2.c - * @brief Direct Memory Access peripheral support - */ - -#include "dma.h" -#include "bitband.h" -#include "util.h" - -/* - * Devices - */ - -static dma_dev dma1 = { - .regs = DMA1_BASE, - .clk_id = RCC_DMA1, - .handlers = {{ .handler = NULL, .irq_line = 11 }, - { .handler = NULL, .irq_line = 12 }, - { .handler = NULL, .irq_line = 13 }, - { .handler = NULL, .irq_line = 14 }, - { .handler = NULL, .irq_line = 15 }, - { .handler = NULL, .irq_line = 16 }, - { .handler = NULL, .irq_line = 17 }, - { .handler = NULL, .irq_line = 47 }} -}; -/** DMA1 device */ -dma_dev *DMA1 = &dma1; - -static dma_dev dma2 = { - .regs = DMA2_BASE, - .clk_id = RCC_DMA2, - .handlers = {{ .handler = NULL, .irq_line = 56 }, - { .handler = NULL, .irq_line = 57 }, - { .handler = NULL, .irq_line = 58 }, - { .handler = NULL, .irq_line = 59 }, - { .handler = NULL, .irq_line = 60 }, - { .handler = NULL, .irq_line = 68 }, - { .handler = NULL, .irq_line = 69 }, - { .handler = NULL, .irq_line = 70 }} /* !@#$ */ -}; -/** DMA2 device */ -dma_dev *DMA2 = &dma2; - - -/* - * Convenience routines - */ - -/** - * @brief Initialize a DMA device. - * @param dev Device to initialize. - */ -void dma_init(dma_dev *dev) { - rcc_clk_enable(dev->clk_id); -} - -/** - * @brief Attach an interrupt to a DMA transfer. - * - * Interrupts are enabled using appropriate mode flags in - * dma_setup_transfer(). - * - * @param dev DMA device - * @param stream Stream to attach handler to - * @param handler Interrupt handler to call when channel interrupt fires. - * @see dma_setup_transfer() - * @see dma_detach_interrupt() - */ -void dma_attach_interrupt(dma_dev *dev, - dma_stream stream, - void (*handler)(void)) { - dev->handlers[stream].handler = handler; - nvic_irq_enable(dev->handlers[stream].irq_line); -} - -/** - * @brief Detach a DMA transfer interrupt handler. - * - * After calling this function, the given channel's interrupts will be - * disabled. - * - * @param dev DMA device - * @param stream Stream whose handler to detach - * @sideeffect Clears interrupt enable bits in the channel's CCR register. - * @see dma_attach_interrupt() - */ -void dma_detach_interrupt(dma_dev *dev, dma_stream stream) { - nvic_irq_disable(dev->handlers[stream].irq_line); - dev->handlers[stream].handler = NULL; -} - -void dma_clear_isr_bits(dma_dev *dev, dma_stream stream) { - switch (stream) { - case 0: - dev->regs->LIFCR|=0x0000003d; - break; - case 1: - dev->regs->LIFCR|=0x00000f40; - break; - case 2: - dev->regs->LIFCR|=0x003d0000; - break; - case 3: - dev->regs->LIFCR|=0x0f400000; - break; - case 4: - dev->regs->HIFCR|=0x0000003d; - break; - case 5: - dev->regs->HIFCR|=0x00000f40; - break; - case 6: - dev->regs->HIFCR|=0x003d0000; - break; - case 7: - dev->regs->HIFCR|=0x0f400000; - break; - } -} - -/* - * IRQ handlers - */ - -static inline void dispatch_handler(dma_dev *dev, dma_stream stream) { - void (*handler)(void) = dev->handlers[stream].handler; - if (handler) { - handler(); - dma_clear_isr_bits(dev, stream); /* in case handler doesn't */ - } -} - -//void __irq_dma1_stream0(void) { -void __irq_dma1_channel1(void) { - dispatch_handler(DMA1, DMA_STREAM0); -} - -//void __irq_dma1_stream1(void) { -void __irq_dma1_channel2(void) { - dispatch_handler(DMA1, DMA_STREAM1); -} - -//void __irq_dma1_stream2(void) { -void __irq_dma1_channel3(void) { - dispatch_handler(DMA1, DMA_STREAM2); -} - -//void __irq_dma1_stream3(void) { -void __irq_dma1_channel4(void) { - dispatch_handler(DMA1, DMA_STREAM3); -} - -//void __irq_dma1_stream4(void) { -void __irq_dma1_channel5(void) { - dispatch_handler(DMA1, DMA_STREAM4); -} - -//void __irq_dma1_stream5(void) { -void __irq_dma1_channel6(void) { - dispatch_handler(DMA1, DMA_STREAM5); -} - -//void __irq_dma1_stream6(void) { -void __irq_dma1_channel7(void) { - dispatch_handler(DMA1, DMA_STREAM6); -} - -//void __irq_dma1_stream7(void) { -void __irq_adc3(void) { - dispatch_handler(DMA1, DMA_STREAM7); -} - -//void __irq_dma2_stream0(void) { -void __irq_dma2_channel1(void) { - dispatch_handler(DMA2, DMA_STREAM0); -} - -//void __irq_dma2_stream1(void) { -void __irq_dma2_channel2(void) { - dispatch_handler(DMA2, DMA_STREAM1); -} - -//void __irq_dma2_stream2(void) { -void __irq_dma2_channel3(void) { - dispatch_handler(DMA2, DMA_STREAM2); -} - -//void __irq_dma2_stream3(void) { -void __irq_dma2_channel4_5(void) { - dispatch_handler(DMA2, DMA_STREAM3); -} - -//void __irq_dma2_stream4(void) { -void __irq_DMA2_Stream4_IRQHandler(void) { - dispatch_handler(DMA2, DMA_STREAM4); -} - -//void __irq_dma2_stream5(void) { -void __irq_DMA2_Stream5_IRQHandler(void) { - dispatch_handler(DMA2, DMA_STREAM5); -} - -//void __irq_dma2_stream6(void) { -void __irq_DMA2_Stream6_IRQHandler(void) { - dispatch_handler(DMA2, DMA_STREAM6); -} - -//void __irq_dma2_stream7(void) { -void __irq_DMA2_Stream7_IRQHandler(void) { - dispatch_handler(DMA2, DMA_STREAM7); -} - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Michael Hope. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file dmaF2.c + * @brief Direct Memory Access peripheral support + */ + +#include "dma.h" +#include "bitband.h" +#include "util.h" + +/* + * Devices + */ + +static dma_dev dma1 = { + .regs = DMA1_BASE, + .clk_id = RCC_DMA1, + .handlers = {{ .handler = NULL, .irq_line = 11 }, + { .handler = NULL, .irq_line = 12 }, + { .handler = NULL, .irq_line = 13 }, + { .handler = NULL, .irq_line = 14 }, + { .handler = NULL, .irq_line = 15 }, + { .handler = NULL, .irq_line = 16 }, + { .handler = NULL, .irq_line = 17 }, + { .handler = NULL, .irq_line = 47 }} +}; +/** DMA1 device */ +dma_dev *DMA1 = &dma1; + +static dma_dev dma2 = { + .regs = DMA2_BASE, + .clk_id = RCC_DMA2, + .handlers = {{ .handler = NULL, .irq_line = 56 }, + { .handler = NULL, .irq_line = 57 }, + { .handler = NULL, .irq_line = 58 }, + { .handler = NULL, .irq_line = 59 }, + { .handler = NULL, .irq_line = 60 }, + { .handler = NULL, .irq_line = 68 }, + { .handler = NULL, .irq_line = 69 }, + { .handler = NULL, .irq_line = 70 }} /* !@#$ */ +}; +/** DMA2 device */ +dma_dev *DMA2 = &dma2; + + +/* + * Convenience routines + */ + +/** + * @brief Initialize a DMA device. + * @param dev Device to initialize. + */ +void dma_init(dma_dev *dev) { + rcc_clk_enable(dev->clk_id); +} + +/** + * @brief Attach an interrupt to a DMA transfer. + * + * Interrupts are enabled using appropriate mode flags in + * dma_setup_transfer(). + * + * @param dev DMA device + * @param stream Stream to attach handler to + * @param handler Interrupt handler to call when channel interrupt fires. + * @see dma_setup_transfer() + * @see dma_detach_interrupt() + */ +void dma_attach_interrupt(dma_dev *dev, + dma_stream stream, + void (*handler)(void)) { + dev->handlers[stream].handler = handler; + nvic_irq_enable(dev->handlers[stream].irq_line); +} + +/** + * @brief Detach a DMA transfer interrupt handler. + * + * After calling this function, the given channel's interrupts will be + * disabled. + * + * @param dev DMA device + * @param stream Stream whose handler to detach + * @sideeffect Clears interrupt enable bits in the channel's CCR register. + * @see dma_attach_interrupt() + */ +void dma_detach_interrupt(dma_dev *dev, dma_stream stream) { + nvic_irq_disable(dev->handlers[stream].irq_line); + dev->handlers[stream].handler = NULL; +} + +void dma_clear_isr_bits(dma_dev *dev, dma_stream stream) { + switch (stream) { + case 0: + dev->regs->LIFCR|=0x0000003d; + break; + case 1: + dev->regs->LIFCR|=0x00000f40; + break; + case 2: + dev->regs->LIFCR|=0x003d0000; + break; + case 3: + dev->regs->LIFCR|=0x0f400000; + break; + case 4: + dev->regs->HIFCR|=0x0000003d; + break; + case 5: + dev->regs->HIFCR|=0x00000f40; + break; + case 6: + dev->regs->HIFCR|=0x003d0000; + break; + case 7: + dev->regs->HIFCR|=0x0f400000; + break; + } +} + +/* + * IRQ handlers + */ + +static inline void dispatch_handler(dma_dev *dev, dma_stream stream) { + void (*handler)(void) = dev->handlers[stream].handler; + if (handler) { + handler(); + dma_clear_isr_bits(dev, stream); /* in case handler doesn't */ + } +} + +//void __irq_dma1_stream0(void) { +void __irq_dma1_channel1(void) { + dispatch_handler(DMA1, DMA_STREAM0); +} + +//void __irq_dma1_stream1(void) { +void __irq_dma1_channel2(void) { + dispatch_handler(DMA1, DMA_STREAM1); +} + +//void __irq_dma1_stream2(void) { +void __irq_dma1_channel3(void) { + dispatch_handler(DMA1, DMA_STREAM2); +} + +//void __irq_dma1_stream3(void) { +void __irq_dma1_channel4(void) { + dispatch_handler(DMA1, DMA_STREAM3); +} + +//void __irq_dma1_stream4(void) { +void __irq_dma1_channel5(void) { + dispatch_handler(DMA1, DMA_STREAM4); +} + +//void __irq_dma1_stream5(void) { +void __irq_dma1_channel6(void) { + dispatch_handler(DMA1, DMA_STREAM5); +} + +//void __irq_dma1_stream6(void) { +void __irq_dma1_channel7(void) { + dispatch_handler(DMA1, DMA_STREAM6); +} + +//void __irq_dma1_stream7(void) { +void __irq_adc3(void) { + dispatch_handler(DMA1, DMA_STREAM7); +} + +//void __irq_dma2_stream0(void) { +void __irq_dma2_channel1(void) { + dispatch_handler(DMA2, DMA_STREAM0); +} + +//void __irq_dma2_stream1(void) { +void __irq_dma2_channel2(void) { + dispatch_handler(DMA2, DMA_STREAM1); +} + +//void __irq_dma2_stream2(void) { +void __irq_dma2_channel3(void) { + dispatch_handler(DMA2, DMA_STREAM2); +} + +//void __irq_dma2_stream3(void) { +void __irq_dma2_channel4_5(void) { + dispatch_handler(DMA2, DMA_STREAM3); +} + +//void __irq_dma2_stream4(void) { +void __irq_DMA2_Stream4_IRQHandler(void) { + dispatch_handler(DMA2, DMA_STREAM4); +} + +//void __irq_dma2_stream5(void) { +void __irq_DMA2_Stream5_IRQHandler(void) { + dispatch_handler(DMA2, DMA_STREAM5); +} + +//void __irq_dma2_stream6(void) { +void __irq_DMA2_Stream6_IRQHandler(void) { + dispatch_handler(DMA2, DMA_STREAM6); +} + +//void __irq_dma2_stream7(void) { +void __irq_DMA2_Stream7_IRQHandler(void) { + dispatch_handler(DMA2, DMA_STREAM7); +} + diff --git a/Libmaple/libmaple/libmaple/dmaF2.h b/Libmaple/libmaple/libmaple/dmaF2.h index 5bbd011b..6f7086f3 100644 --- a/Libmaple/libmaple/libmaple/dmaF2.h +++ b/Libmaple/libmaple/libmaple/dmaF2.h @@ -1,270 +1,270 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file dma.h - * - * @author Marti Bolivar ; - * Original implementation by Michael Hope - * - * @brief Direct Memory Access peripheral support - */ - -/* - * See /notes/dma.txt for more information. - */ - -#ifndef _DMA_H_ -#define _DMA_H_ - -#include "libmaple_types.h" -#include "rcc.h" -#include "nvic.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - * Register maps - */ - -/** - * @brief DMA stream type. - * - */ -typedef struct dma_stream_t { - __io uint32 CR; /**< Stream configuration register */ - __io uint32 NDTR; /**< Stream number of data register */ - __io uint32 PAR; /**< Stream peripheral address register */ - __io uint32 M0AR; /**< Stream memory address register 0 */ - __io uint32 M1AR; /**< Stream memory address register 1 */ - __io uint32 FCR; /**< Stream FIFO configuration register */ -} dma_stream_t; -/** - * @brief DMA register map type. - * - */ -typedef struct dma_reg_map { - __io uint32 LISR; /**< Low interrupt status register */ - __io uint32 HISR; /**< High interrupt status register */ - __io uint32 LIFCR; /**< Low interrupt flag clear register */ - __io uint32 HIFCR; /**< High interrupt flag clear register */ - dma_stream_t STREAM[8]; -} dma_reg_map; - -/** DMA controller register map base pointers */ -#define DMA1_BASE ((struct dma_reg_map*)0x40026000) -#define DMA2_BASE ((struct dma_reg_map*)0x40026400) - -/* - * Register bit definitions - */ - -/* Channel configuration register */ - -#define DMA_CR_CH0 (0x0 << 25) -#define DMA_CR_CH1 (0x1 << 25) -#define DMA_CR_CH2 (0x2 << 25) -#define DMA_CR_CH3 (0x3 << 25) -#define DMA_CR_CH4 (0x4 << 25) -#define DMA_CR_CH5 (0x5 << 25) -#define DMA_CR_CH6 (0x6 << 25) -#define DMA_CR_CH7 (0x7 << 25) -#define DMA_CR_MBURST0 (0x0 << 23) -#define DMA_CR_MBURST4 (0x1 << 23) -#define DMA_CR_MBURST8 (0x2 << 23) -#define DMA_CR_MBURST16 (0x3 << 23) -#define DMA_CR_PBURST0 (0x0 << 21) -#define DMA_CR_PBURST4 (0x1 << 21) -#define DMA_CR_PBURST8 (0x2 << 21) -#define DMA_CR_PBURST16 (0x3 << 21) -#define DMA_CR_CT0 (0x0 << 19) -#define DMA_CR_CT1 (0x1 << 19) -#define DMA_CR_DBM (0x1 << 18) - -#define DMA_CR_PL_LOW (0x0 << 16) -#define DMA_CR_PL_MEDIUM (0x1 << 16) -#define DMA_CR_PL_HIGH (0x2 << 16) -#define DMA_CR_PL_VERY_HIGH (0x3 << 16) -#define DMA_CR_PL_MASK (0x3 << 16) - -#define DMA_CR_PINCOS (0x1 << 15) - -#define DMA_CR_MSIZE_8BITS (0x0 << 13) -#define DMA_CR_MSIZE_16BITS (0x1 << 13) -#define DMA_CR_MSIZE_32BITS (0x2 << 13) - -#define DMA_CR_PSIZE_8BITS (0x0 << 11) -#define DMA_CR_PSIZE_16BITS (0x1 << 11) -#define DMA_CR_PSIZE_32BITS (0x2 << 11) - -#define DMA_CR_MINC (0x1 << 10) -#define DMA_CR_PINC (0x1 << 9) -#define DMA_CR_CIRC (0x1 << 8) -#define DMA_CR_DIR_P2M (0x0 << 6) -#define DMA_CR_DIR_M2P (0x1 << 6) -#define DMA_CR_DIR_M2M (0x2 << 6) - -#define DMA_CR_PFCTRL (0x1 << 5) -#define DMA_CR_TCIE (0x1 << 4) -#define DMA_CR_HTIE (0x1 << 3) -#define DMA_CR_TEIE (0x1 << 2) -#define DMA_CR_DMEIE (0x1 << 1) -#define DMA_CR_EN (0x1) - -/* - * Devices - */ - -/** Encapsulates state related to a DMA channel interrupt. */ -typedef struct dma_handler_config { - void (*handler)(void); /**< User-specified channel interrupt - handler */ - nvic_irq_num irq_line; /**< Channel's NVIC interrupt number */ -} dma_handler_config; - -/** DMA device type */ -typedef struct dma_dev { - dma_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< Clock ID */ - dma_handler_config handlers[]; /**< - * @brief IRQ handlers and NVIC numbers. - * - * @see dma_attach_interrupt() - * @see dma_detach_interrupt() - */ -} dma_dev; - -extern dma_dev *DMA1; -extern dma_dev *DMA2; - -/* - * Convenience functions - */ - -void dma_init(dma_dev *dev); - -/** Flags for DMA transfer configuration. */ -typedef enum dma_mode_flags { - DMA_MEM_2_MEM = 1 << 14, /**< Memory to memory mode */ - DMA_MINC_MODE = 1 << 7, /**< Auto-increment memory address */ - DMA_PINC_MODE = 1 << 6, /**< Auto-increment peripheral address */ - DMA_CIRC_MODE = 1 << 5, /**< Circular mode */ - DMA_FROM_MEM = 1 << 4, /**< Read from memory to peripheral */ - DMA_TRNS_ERR = 1 << 3, /**< Interrupt on transfer error */ - DMA_HALF_TRNS = 1 << 2, /**< Interrupt on half-transfer */ - DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */ -} dma_mode_flags; - -/** Source and destination transfer sizes. */ -typedef enum dma_xfer_size { - DMA_SIZE_8BITS = 0, /**< 8-bit transfers */ - DMA_SIZE_16BITS = 1, /**< 16-bit transfers */ - DMA_SIZE_32BITS = 2 /**< 32-bit transfers */ -} dma_xfer_size; - -/** DMA channel */ -typedef enum dma_stream { - DMA_STREAM0 = 0, /**< Stream 0 */ - DMA_STREAM1 = 1, /**< Stream 1 */ - DMA_STREAM2 = 2, /**< Stream 2 */ - DMA_STREAM3 = 3, /**< Stream 3 */ - DMA_STREAM4 = 4, /**< Stream 4 */ - DMA_STREAM5 = 5, /**< Stream 5 */ - DMA_STREAM6 = 6, /**< Stream 6 */ - DMA_STREAM7 = 7, /**< Stream 7 */ -} dma_stream; - -static inline void dma_setup_transfer(dma_dev *dev, - dma_stream stream, - __io void *peripheral_address, - __io void *memory_address0, - __io void *memory_address1, - uint32 flags, - uint32 fifo_flags) { - dev->regs->STREAM[stream].CR &= ~DMA_CR_EN; // disable - dev->regs->STREAM[stream].PAR = (uint32)peripheral_address; - dev->regs->STREAM[stream].M0AR = (uint32)memory_address0; - dev->regs->STREAM[stream].M1AR = (uint32)memory_address1; - dev->regs->STREAM[stream].FCR = fifo_flags & 0x87; // mask out reserved bits - dev->regs->STREAM[stream].CR = flags & 0x0feffffe; // mask out reserved and enable -} - -static inline void dma_set_num_transfers(dma_dev *dev, - dma_stream stream, - uint16 num_transfers) { - dev->regs->STREAM[stream].NDTR = num_transfers; -} - -void dma_attach_interrupt(dma_dev *dev, - dma_stream stream, - void (*handler)(void)); - -void dma_detach_interrupt(dma_dev *dev, dma_stream stream); - -static inline void dma_enable(dma_dev *dev, dma_stream stream) { - dev->regs->STREAM[stream].CR |= DMA_CR_EN; -} - -static inline void dma_disable(dma_dev *dev, dma_stream stream) { - dev->regs->STREAM[stream].CR &= ~DMA_CR_EN; -} - -/** - * @brief Check if a DMA stream is enabled - * @param dev DMA device - * @param stream Stream whose enabled bit to check. - */ -static inline uint8 dma_is_stream_enabled(dma_dev *dev, dma_stream stream) { - return (uint8)(dev->regs->STREAM[stream].CR & DMA_CR_EN); -} - -/** - * @brief Get the ISR status bits for a DMA stream. - * - * The bits are returned right-aligned, in the following order: - * transfer error flag, half-transfer flag, transfer complete flag, - * global interrupt flag. - * - * @param dev DMA device - * @param stream Stream whose ISR bits to return. - */ -uint8 dma_get_isr_bits(dma_dev *dev, dma_stream stream); - -/** - * @brief Clear the ISR status bits for a given DMA stream. - * - * @param dev DMA device - * @param stream Stream whose ISR bits to clear. - */ -void dma_clear_isr_bits(dma_dev *dev, dma_stream stream); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Michael Hope. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file dma.h + * + * @author Marti Bolivar ; + * Original implementation by Michael Hope + * + * @brief Direct Memory Access peripheral support + */ + +/* + * See /notes/dma.txt for more information. + */ + +#ifndef _DMA_H_ +#define _DMA_H_ + +#include "libmaple_types.h" +#include "rcc.h" +#include "nvic.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * Register maps + */ + +/** + * @brief DMA stream type. + * + */ +typedef struct dma_stream_t { + __io uint32 CR; /**< Stream configuration register */ + __io uint32 NDTR; /**< Stream number of data register */ + __io uint32 PAR; /**< Stream peripheral address register */ + __io uint32 M0AR; /**< Stream memory address register 0 */ + __io uint32 M1AR; /**< Stream memory address register 1 */ + __io uint32 FCR; /**< Stream FIFO configuration register */ +} dma_stream_t; +/** + * @brief DMA register map type. + * + */ +typedef struct dma_reg_map { + __io uint32 LISR; /**< Low interrupt status register */ + __io uint32 HISR; /**< High interrupt status register */ + __io uint32 LIFCR; /**< Low interrupt flag clear register */ + __io uint32 HIFCR; /**< High interrupt flag clear register */ + dma_stream_t STREAM[8]; +} dma_reg_map; + +/** DMA controller register map base pointers */ +#define DMA1_BASE ((struct dma_reg_map*)0x40026000) +#define DMA2_BASE ((struct dma_reg_map*)0x40026400) + +/* + * Register bit definitions + */ + +/* Channel configuration register */ + +#define DMA_CR_CH0 (0x0 << 25) +#define DMA_CR_CH1 (0x1 << 25) +#define DMA_CR_CH2 (0x2 << 25) +#define DMA_CR_CH3 (0x3 << 25) +#define DMA_CR_CH4 (0x4 << 25) +#define DMA_CR_CH5 (0x5 << 25) +#define DMA_CR_CH6 (0x6 << 25) +#define DMA_CR_CH7 (0x7 << 25) +#define DMA_CR_MBURST0 (0x0 << 23) +#define DMA_CR_MBURST4 (0x1 << 23) +#define DMA_CR_MBURST8 (0x2 << 23) +#define DMA_CR_MBURST16 (0x3 << 23) +#define DMA_CR_PBURST0 (0x0 << 21) +#define DMA_CR_PBURST4 (0x1 << 21) +#define DMA_CR_PBURST8 (0x2 << 21) +#define DMA_CR_PBURST16 (0x3 << 21) +#define DMA_CR_CT0 (0x0 << 19) +#define DMA_CR_CT1 (0x1 << 19) +#define DMA_CR_DBM (0x1 << 18) + +#define DMA_CR_PL_LOW (0x0 << 16) +#define DMA_CR_PL_MEDIUM (0x1 << 16) +#define DMA_CR_PL_HIGH (0x2 << 16) +#define DMA_CR_PL_VERY_HIGH (0x3 << 16) +#define DMA_CR_PL_MASK (0x3 << 16) + +#define DMA_CR_PINCOS (0x1 << 15) + +#define DMA_CR_MSIZE_8BITS (0x0 << 13) +#define DMA_CR_MSIZE_16BITS (0x1 << 13) +#define DMA_CR_MSIZE_32BITS (0x2 << 13) + +#define DMA_CR_PSIZE_8BITS (0x0 << 11) +#define DMA_CR_PSIZE_16BITS (0x1 << 11) +#define DMA_CR_PSIZE_32BITS (0x2 << 11) + +#define DMA_CR_MINC (0x1 << 10) +#define DMA_CR_PINC (0x1 << 9) +#define DMA_CR_CIRC (0x1 << 8) +#define DMA_CR_DIR_P2M (0x0 << 6) +#define DMA_CR_DIR_M2P (0x1 << 6) +#define DMA_CR_DIR_M2M (0x2 << 6) + +#define DMA_CR_PFCTRL (0x1 << 5) +#define DMA_CR_TCIE (0x1 << 4) +#define DMA_CR_HTIE (0x1 << 3) +#define DMA_CR_TEIE (0x1 << 2) +#define DMA_CR_DMEIE (0x1 << 1) +#define DMA_CR_EN (0x1) + +/* + * Devices + */ + +/** Encapsulates state related to a DMA channel interrupt. */ +typedef struct dma_handler_config { + void (*handler)(void); /**< User-specified channel interrupt + handler */ + nvic_irq_num irq_line; /**< Channel's NVIC interrupt number */ +} dma_handler_config; + +/** DMA device type */ +typedef struct dma_dev { + dma_reg_map *regs; /**< Register map */ + rcc_clk_id clk_id; /**< Clock ID */ + dma_handler_config handlers[]; /**< + * @brief IRQ handlers and NVIC numbers. + * + * @see dma_attach_interrupt() + * @see dma_detach_interrupt() + */ +} dma_dev; + +extern dma_dev *DMA1; +extern dma_dev *DMA2; + +/* + * Convenience functions + */ + +void dma_init(dma_dev *dev); + +/** Flags for DMA transfer configuration. */ +typedef enum dma_mode_flags { + DMA_MEM_2_MEM = 1 << 14, /**< Memory to memory mode */ + DMA_MINC_MODE = 1 << 7, /**< Auto-increment memory address */ + DMA_PINC_MODE = 1 << 6, /**< Auto-increment peripheral address */ + DMA_CIRC_MODE = 1 << 5, /**< Circular mode */ + DMA_FROM_MEM = 1 << 4, /**< Read from memory to peripheral */ + DMA_TRNS_ERR = 1 << 3, /**< Interrupt on transfer error */ + DMA_HALF_TRNS = 1 << 2, /**< Interrupt on half-transfer */ + DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */ +} dma_mode_flags; + +/** Source and destination transfer sizes. */ +typedef enum dma_xfer_size { + DMA_SIZE_8BITS = 0, /**< 8-bit transfers */ + DMA_SIZE_16BITS = 1, /**< 16-bit transfers */ + DMA_SIZE_32BITS = 2 /**< 32-bit transfers */ +} dma_xfer_size; + +/** DMA channel */ +typedef enum dma_stream { + DMA_STREAM0 = 0, /**< Stream 0 */ + DMA_STREAM1 = 1, /**< Stream 1 */ + DMA_STREAM2 = 2, /**< Stream 2 */ + DMA_STREAM3 = 3, /**< Stream 3 */ + DMA_STREAM4 = 4, /**< Stream 4 */ + DMA_STREAM5 = 5, /**< Stream 5 */ + DMA_STREAM6 = 6, /**< Stream 6 */ + DMA_STREAM7 = 7, /**< Stream 7 */ +} dma_stream; + +static inline void dma_setup_transfer(dma_dev *dev, + dma_stream stream, + __io void *peripheral_address, + __io void *memory_address0, + __io void *memory_address1, + uint32 flags, + uint32 fifo_flags) { + dev->regs->STREAM[stream].CR &= ~DMA_CR_EN; // disable + dev->regs->STREAM[stream].PAR = (uint32)peripheral_address; + dev->regs->STREAM[stream].M0AR = (uint32)memory_address0; + dev->regs->STREAM[stream].M1AR = (uint32)memory_address1; + dev->regs->STREAM[stream].FCR = fifo_flags & 0x87; // mask out reserved bits + dev->regs->STREAM[stream].CR = flags & 0x0feffffe; // mask out reserved and enable +} + +static inline void dma_set_num_transfers(dma_dev *dev, + dma_stream stream, + uint16 num_transfers) { + dev->regs->STREAM[stream].NDTR = num_transfers; +} + +void dma_attach_interrupt(dma_dev *dev, + dma_stream stream, + void (*handler)(void)); + +void dma_detach_interrupt(dma_dev *dev, dma_stream stream); + +static inline void dma_enable(dma_dev *dev, dma_stream stream) { + dev->regs->STREAM[stream].CR |= DMA_CR_EN; +} + +static inline void dma_disable(dma_dev *dev, dma_stream stream) { + dev->regs->STREAM[stream].CR &= ~DMA_CR_EN; +} + +/** + * @brief Check if a DMA stream is enabled + * @param dev DMA device + * @param stream Stream whose enabled bit to check. + */ +static inline uint8 dma_is_stream_enabled(dma_dev *dev, dma_stream stream) { + return (uint8)(dev->regs->STREAM[stream].CR & DMA_CR_EN); +} + +/** + * @brief Get the ISR status bits for a DMA stream. + * + * The bits are returned right-aligned, in the following order: + * transfer error flag, half-transfer flag, transfer complete flag, + * global interrupt flag. + * + * @param dev DMA device + * @param stream Stream whose ISR bits to return. + */ +uint8 dma_get_isr_bits(dma_dev *dev, dma_stream stream); + +/** + * @brief Clear the ISR status bits for a given DMA stream. + * + * @param dev DMA device + * @param stream Stream whose ISR bits to clear. + */ +void dma_clear_isr_bits(dma_dev *dev, dma_stream stream); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/exc.S b/Libmaple/libmaple/libmaple/exc.S index e92634af..1b573e4b 100644 --- a/Libmaple/libmaple/libmaple/exc.S +++ b/Libmaple/libmaple/libmaple/exc.S @@ -1,104 +1,104 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -# On an exception, push a fake stack thread mode stack frame and redirect -# thread execution to a thread mode error handler - -# From RM008: -# The SP is decremented by eight words by the completion of the stack push. -# Figure 5-1 shows the contents of the stack after an exception pre-empts the -# current program flow. -# -# Old SP--> -# xPSR -# PC -# LR -# r12 -# r3 -# r2 -# r1 -# SP--> r0 - -.text -.globl __exc_hardfault -.globl __exc_nmi -.globl __exc_hardfault -.globl __exc_memmanage -.globl __exc_busfault -.globl __exc_usagefault - -.code 16 -.thumb_func -__exc_nmi: - mov r0, #1 - b __default_exc - -.thumb_func -__exc_hardfault: - mov r0, #2 - b __default_exc - -.thumb_func -__exc_memmanage: - mov r0, #3 - b __default_exc - -.thumb_func -__exc_busfault: - mov r0, #4 - b __default_exc - -.thumb_func -__exc_usagefault: - mov r0, #5 - b __default_exc - -.thumb_func -__default_exc: - b __default_exc - - - ldr r2, NVIC_CCR @ Enable returning to thread mode even if there are - mov r1 ,#1 @ pending exceptions. See flag NONEBASETHRDENA. - str r1, [r2] - cpsid i @ Disable global interrupts - ldr r2, SYSTICK_CSR @ Disable systick handler - mov r1, #0 - str r1, [r2] - ldr r1, CPSR_MASK @ Set default CPSR - push {r1} - ldr r1, TARGET_PC @ Set target pc - push {r1} - sub sp, sp, #24 @ Don't care - ldr r1, EXC_RETURN @ Return to thread mode - mov lr, r1 - bx lr @ Exception exit - -.align 4 -CPSR_MASK: .word 0x61000000 -EXC_RETURN: .word 0xFFFFFFF9 -TARGET_PC: .word __error -NVIC_CCR: .word 0xE000ED14 @ NVIC configuration control register -SYSTICK_CSR: .word 0xE000E010 @ Systick control register - +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +# On an exception, push a fake stack thread mode stack frame and redirect +# thread execution to a thread mode error handler + +# From RM008: +# The SP is decremented by eight words by the completion of the stack push. +# Figure 5-1 shows the contents of the stack after an exception pre-empts the +# current program flow. +# +# Old SP--> +# xPSR +# PC +# LR +# r12 +# r3 +# r2 +# r1 +# SP--> r0 + +.text +.globl __exc_hardfault +.globl __exc_nmi +.globl __exc_hardfault +.globl __exc_memmanage +.globl __exc_busfault +.globl __exc_usagefault + +.code 16 +.thumb_func +__exc_nmi: + mov r0, #1 + b __default_exc + +.thumb_func +__exc_hardfault: + mov r0, #2 + b __default_exc + +.thumb_func +__exc_memmanage: + mov r0, #3 + b __default_exc + +.thumb_func +__exc_busfault: + mov r0, #4 + b __default_exc + +.thumb_func +__exc_usagefault: + mov r0, #5 + b __default_exc + +.thumb_func +__default_exc: + b __default_exc + + + ldr r2, NVIC_CCR @ Enable returning to thread mode even if there are + mov r1 ,#1 @ pending exceptions. See flag NONEBASETHRDENA. + str r1, [r2] + cpsid i @ Disable global interrupts + ldr r2, SYSTICK_CSR @ Disable systick handler + mov r1, #0 + str r1, [r2] + ldr r1, CPSR_MASK @ Set default CPSR + push {r1} + ldr r1, TARGET_PC @ Set target pc + push {r1} + sub sp, sp, #24 @ Don't care + ldr r1, EXC_RETURN @ Return to thread mode + mov lr, r1 + bx lr @ Exception exit + +.align 4 +CPSR_MASK: .word 0x61000000 +EXC_RETURN: .word 0xFFFFFFF9 +TARGET_PC: .word __error +NVIC_CCR: .word 0xE000ED14 @ NVIC configuration control register +SYSTICK_CSR: .word 0xE000E010 @ Systick control register + diff --git a/Libmaple/libmaple/libmaple/exti.c b/Libmaple/libmaple/libmaple/exti.c index ae54d6f6..1fcc35ba 100644 --- a/Libmaple/libmaple/libmaple/exti.c +++ b/Libmaple/libmaple/libmaple/exti.c @@ -1,219 +1,219 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file exti.c - * @brief External interrupt control routines - */ - -#include "exti.h" -#include "libmaple.h" -#include "nvic.h" -#include "bitband.h" - -static inline void dispatch_single_exti(uint32 exti_num); -static inline void dispatch_extis(uint32 start, uint32 stop); - -/* - * Internal state - */ - -typedef struct exti_channel { - void (*handler)(void); - uint32 irq_line; -} exti_channel; - -static exti_channel exti_channels[] = { - { .handler = NULL, .irq_line = NVIC_EXTI0 }, // EXTI0 - { .handler = NULL, .irq_line = NVIC_EXTI1 }, // EXTI1 - { .handler = NULL, .irq_line = NVIC_EXTI2 }, // EXTI2 - { .handler = NULL, .irq_line = NVIC_EXTI3 }, // EXTI3 - { .handler = NULL, .irq_line = NVIC_EXTI4 }, // EXTI4 - { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI5 - { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI6 - { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI7 - { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI8 - { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI9 - { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI10 - { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI11 - { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI12 - { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI13 - { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI14 - { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI15 -}; - -/* - * Convenience routines - */ - -/** - * @brief Register a handler to run upon external interrupt. - * - * This function assumes that the interrupt request corresponding to - * the given external interrupt is masked. - * - * @param num External interrupt line number. - * @param port Port to use as source input for external interrupt. - * @param handler Function handler to execute when interrupt is triggered. - * @param mode Type of transition to trigger on, one of: - * EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING. - * @see afio_exti_num - * @see afio_exti_port - * @see voidFuncPtr - * @see exti_trigger_mode - */ -void exti_attach_interrupt(afio_exti_num num, - afio_exti_port port, - voidFuncPtr handler, - exti_trigger_mode mode) { - ASSERT(handler); - - /* Register the handler */ - exti_channels[num].handler = handler; - - /* Set trigger mode */ - switch (mode) { - case EXTI_RISING: - bb_peri_set_bit(&EXTI_BASE->RTSR, num, 1); - break; - case EXTI_FALLING: - bb_peri_set_bit(&EXTI_BASE->FTSR, num, 1); - break; - case EXTI_RISING_FALLING: - bb_peri_set_bit(&EXTI_BASE->RTSR, num, 1); - bb_peri_set_bit(&EXTI_BASE->FTSR, num, 1); - break; - } - - /* Map num to port */ - afio_exti_select(num, port); - - /* Unmask external interrupt request */ - bb_peri_set_bit(&EXTI_BASE->IMR, num, 1); - - /* Enable the interrupt line */ - nvic_irq_enable(exti_channels[num].irq_line); -} - -/** - * @brief Unregister an external interrupt handler - * @param num Number of the external interrupt line to disable. - * @see afio_exti_num - */ -void exti_detach_interrupt(afio_exti_num num) { - /* First, mask the interrupt request */ - bb_peri_set_bit(&EXTI_BASE->IMR, num, 0); - - /* Then, clear the trigger selection registers */ - bb_peri_set_bit(&EXTI_BASE->FTSR, num, 0); - bb_peri_set_bit(&EXTI_BASE->RTSR, num, 0); - - /* Finally, unregister the user's handler */ - exti_channels[num].handler = NULL; -} - -/* - * Interrupt handlers - */ - -void __irq_exti0(void) { - dispatch_single_exti(AFIO_EXTI_0); -} - -void __irq_exti1(void) { - dispatch_single_exti(AFIO_EXTI_1); -} - -void __irq_exti2(void) { - dispatch_single_exti(AFIO_EXTI_2); -} - -void __irq_exti3(void) { - dispatch_single_exti(AFIO_EXTI_3); -} - -void __irq_exti4(void) { - dispatch_single_exti(AFIO_EXTI_4); -} - -void __irq_exti9_5(void) { - dispatch_extis(5, 9); -} - -void __irq_exti15_10(void) { - dispatch_extis(10, 15); -} - -/* - * Auxiliary functions - */ - -/* Clear the pending bits for EXTIs whose bits are set in exti_msk. - * - * If a pending bit is cleared as the last instruction in an ISR, it - * won't actually be cleared in time and the ISR will fire again. To - * compensate, this function NOPs for 2 cycles after clearing the - * pending bits to ensure it takes effect. */ -static inline void clear_pending_msk(uint32 exti_msk) { - EXTI_BASE->PR = exti_msk; - asm volatile("nop"); - asm volatile("nop"); -} - -/* This dispatch routine is for non-multiplexed EXTI lines only; i.e., - * it doesn't check EXTI_PR. */ -static inline void dispatch_single_exti(uint32 exti) { - voidFuncPtr handler = exti_channels[exti].handler; - - if (!handler) { - return; - } - - handler(); - clear_pending_msk(BIT(exti)); -} - -/* Dispatch routine for EXTIs which share an IRQ. */ -static inline void dispatch_extis(uint32 start, uint32 stop) { - uint32 pr = EXTI_BASE->PR; - uint32 handled_msk = 0; - uint32 exti; - - /* Dispatch user handlers for pending EXTIs. */ - for (exti = start; exti <= stop; exti++) { - uint32 eb = BIT(exti); - if (pr & eb) { - voidFuncPtr handler = exti_channels[exti].handler; - if (handler) { - handler(); - handled_msk |= eb; - } - } - } - - /* Clear the pending bits for handled EXTIs. */ - clear_pending_msk(handled_msk); -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file exti.c + * @brief External interrupt control routines + */ + +#include "exti.h" +#include "libmaple.h" +#include "nvic.h" +#include "bitband.h" + +static inline void dispatch_single_exti(uint32 exti_num); +static inline void dispatch_extis(uint32 start, uint32 stop); + +/* + * Internal state + */ + +typedef struct exti_channel { + void (*handler)(void); + uint32 irq_line; +} exti_channel; + +static exti_channel exti_channels[] = { + { .handler = NULL, .irq_line = NVIC_EXTI0 }, // EXTI0 + { .handler = NULL, .irq_line = NVIC_EXTI1 }, // EXTI1 + { .handler = NULL, .irq_line = NVIC_EXTI2 }, // EXTI2 + { .handler = NULL, .irq_line = NVIC_EXTI3 }, // EXTI3 + { .handler = NULL, .irq_line = NVIC_EXTI4 }, // EXTI4 + { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI5 + { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI6 + { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI7 + { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI8 + { .handler = NULL, .irq_line = NVIC_EXTI_9_5 }, // EXTI9 + { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI10 + { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI11 + { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI12 + { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI13 + { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI14 + { .handler = NULL, .irq_line = NVIC_EXTI_15_10 }, // EXTI15 +}; + +/* + * Convenience routines + */ + +/** + * @brief Register a handler to run upon external interrupt. + * + * This function assumes that the interrupt request corresponding to + * the given external interrupt is masked. + * + * @param num External interrupt line number. + * @param port Port to use as source input for external interrupt. + * @param handler Function handler to execute when interrupt is triggered. + * @param mode Type of transition to trigger on, one of: + * EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING. + * @see afio_exti_num + * @see afio_exti_port + * @see voidFuncPtr + * @see exti_trigger_mode + */ +void exti_attach_interrupt(afio_exti_num num, + afio_exti_port port, + voidFuncPtr handler, + exti_trigger_mode mode) { + ASSERT(handler); + + /* Register the handler */ + exti_channels[num].handler = handler; + + /* Set trigger mode */ + switch (mode) { + case EXTI_RISING: + bb_peri_set_bit(&EXTI_BASE->RTSR, num, 1); + break; + case EXTI_FALLING: + bb_peri_set_bit(&EXTI_BASE->FTSR, num, 1); + break; + case EXTI_RISING_FALLING: + bb_peri_set_bit(&EXTI_BASE->RTSR, num, 1); + bb_peri_set_bit(&EXTI_BASE->FTSR, num, 1); + break; + } + + /* Map num to port */ + afio_exti_select(num, port); + + /* Unmask external interrupt request */ + bb_peri_set_bit(&EXTI_BASE->IMR, num, 1); + + /* Enable the interrupt line */ + nvic_irq_enable(exti_channels[num].irq_line); +} + +/** + * @brief Unregister an external interrupt handler + * @param num Number of the external interrupt line to disable. + * @see afio_exti_num + */ +void exti_detach_interrupt(afio_exti_num num) { + /* First, mask the interrupt request */ + bb_peri_set_bit(&EXTI_BASE->IMR, num, 0); + + /* Then, clear the trigger selection registers */ + bb_peri_set_bit(&EXTI_BASE->FTSR, num, 0); + bb_peri_set_bit(&EXTI_BASE->RTSR, num, 0); + + /* Finally, unregister the user's handler */ + exti_channels[num].handler = NULL; +} + +/* + * Interrupt handlers + */ + +void __irq_exti0(void) { + dispatch_single_exti(AFIO_EXTI_0); +} + +void __irq_exti1(void) { + dispatch_single_exti(AFIO_EXTI_1); +} + +void __irq_exti2(void) { + dispatch_single_exti(AFIO_EXTI_2); +} + +void __irq_exti3(void) { + dispatch_single_exti(AFIO_EXTI_3); +} + +void __irq_exti4(void) { + dispatch_single_exti(AFIO_EXTI_4); +} + +void __irq_exti9_5(void) { + dispatch_extis(5, 9); +} + +void __irq_exti15_10(void) { + dispatch_extis(10, 15); +} + +/* + * Auxiliary functions + */ + +/* Clear the pending bits for EXTIs whose bits are set in exti_msk. + * + * If a pending bit is cleared as the last instruction in an ISR, it + * won't actually be cleared in time and the ISR will fire again. To + * compensate, this function NOPs for 2 cycles after clearing the + * pending bits to ensure it takes effect. */ +static inline void clear_pending_msk(uint32 exti_msk) { + EXTI_BASE->PR = exti_msk; + asm volatile("nop"); + asm volatile("nop"); +} + +/* This dispatch routine is for non-multiplexed EXTI lines only; i.e., + * it doesn't check EXTI_PR. */ +static inline void dispatch_single_exti(uint32 exti) { + voidFuncPtr handler = exti_channels[exti].handler; + + if (!handler) { + return; + } + + handler(); + clear_pending_msk(BIT(exti)); +} + +/* Dispatch routine for EXTIs which share an IRQ. */ +static inline void dispatch_extis(uint32 start, uint32 stop) { + uint32 pr = EXTI_BASE->PR; + uint32 handled_msk = 0; + uint32 exti; + + /* Dispatch user handlers for pending EXTIs. */ + for (exti = start; exti <= stop; exti++) { + uint32 eb = BIT(exti); + if (pr & eb) { + voidFuncPtr handler = exti_channels[exti].handler; + if (handler) { + handler(); + handled_msk |= eb; + } + } + } + + /* Clear the pending bits for handled EXTIs. */ + clear_pending_msk(handled_msk); +} diff --git a/Libmaple/libmaple/libmaple/exti.h b/Libmaple/libmaple/libmaple/exti.h index 5f28c9cb..bac8adcf 100644 --- a/Libmaple/libmaple/libmaple/exti.h +++ b/Libmaple/libmaple/libmaple/exti.h @@ -1,78 +1,78 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file exti.h - * @brief External interrupt control prototypes and defines - */ - -/* See notes/exti.txt for more info */ - -#include "libmaple.h" -#include "gpio.h" - -#ifndef _EXTI_H_ -#define _EXTI_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -/** EXTI register map type */ -typedef struct exti_reg_map { - __io uint32 IMR; /**< Interrupt mask register */ - __io uint32 EMR; /**< Event mask register */ - __io uint32 RTSR; /**< Rising trigger selection register */ - __io uint32 FTSR; /**< Falling trigger selection register */ - __io uint32 SWIER; /**< Software interrupt event register */ - __io uint32 PR; /**< Pending register */ -} exti_reg_map; - -/** EXTI register map base pointer */ -#ifdef STM32F2 -#define EXTI_BASE ((struct exti_reg_map*)0x40013C00) -#else -#define EXTI_BASE ((struct exti_reg_map*)0x40010400) -#endif - -/** External interrupt trigger mode */ -typedef enum exti_trigger_mode { - EXTI_RISING, /**< Trigger on the rising edge */ - EXTI_FALLING, /**< Trigger on the falling edge */ - EXTI_RISING_FALLING /**< Trigger on both the rising and falling edges */ -} exti_trigger_mode; - -void exti_attach_interrupt(afio_exti_num num, - afio_exti_port port, - voidFuncPtr handler, - exti_trigger_mode mode); -void exti_detach_interrupt(afio_exti_num num); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file exti.h + * @brief External interrupt control prototypes and defines + */ + +/* See notes/exti.txt for more info */ + +#include "libmaple.h" +#include "gpio.h" + +#ifndef _EXTI_H_ +#define _EXTI_H_ + +#ifdef __cplusplus +extern "C"{ +#endif + +/** EXTI register map type */ +typedef struct exti_reg_map { + __io uint32 IMR; /**< Interrupt mask register */ + __io uint32 EMR; /**< Event mask register */ + __io uint32 RTSR; /**< Rising trigger selection register */ + __io uint32 FTSR; /**< Falling trigger selection register */ + __io uint32 SWIER; /**< Software interrupt event register */ + __io uint32 PR; /**< Pending register */ +} exti_reg_map; + +/** EXTI register map base pointer */ +#ifdef STM32F2 +#define EXTI_BASE ((struct exti_reg_map*)0x40013C00) +#else +#define EXTI_BASE ((struct exti_reg_map*)0x40010400) +#endif + +/** External interrupt trigger mode */ +typedef enum exti_trigger_mode { + EXTI_RISING, /**< Trigger on the rising edge */ + EXTI_FALLING, /**< Trigger on the falling edge */ + EXTI_RISING_FALLING /**< Trigger on both the rising and falling edges */ +} exti_trigger_mode; + +void exti_attach_interrupt(afio_exti_num num, + afio_exti_port port, + voidFuncPtr handler, + exti_trigger_mode mode); +void exti_detach_interrupt(afio_exti_num num); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/flash.c b/Libmaple/libmaple/libmaple/flash.c index d8369000..a22fbd3f 100644 --- a/Libmaple/libmaple/libmaple/flash.c +++ b/Libmaple/libmaple/libmaple/flash.c @@ -1,60 +1,60 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file flash.c - * @brief Flash management functions - */ - -#include "libmaple.h" -#include "flash.h" -#include "bitband.h" - -/** - * @brief Turn on the hardware prefetcher. - */ -void flash_enable_prefetch(void) { - *bb_perip(&FLASH_BASE->ACR, FLASH_ACR_PRFTBE_BIT) = 1; -} - -/** - * @brief Set flash wait states - * - * See ST PM0042, section 3.1 for restrictions on the acceptable value - * of wait_states for a given SYSCLK configuration. - * - * @param wait_states number of wait states (one of - * FLASH_WAIT_STATE_0, FLASH_WAIT_STATE_1, - * FLASH_WAIT_STATE_2). - */ -void flash_set_latency(uint32 wait_states) { - uint32 val = FLASH_BASE->ACR; - - val &= ~FLASH_ACR_LATENCY; - val |= wait_states; - - FLASH_BASE->ACR = val; -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file flash.c + * @brief Flash management functions + */ + +#include "libmaple.h" +#include "flash.h" +#include "bitband.h" + +/** + * @brief Turn on the hardware prefetcher. + */ +void flash_enable_prefetch(void) { + *bb_perip(&FLASH_BASE->ACR, FLASH_ACR_PRFTBE_BIT) = 1; +} + +/** + * @brief Set flash wait states + * + * See ST PM0042, section 3.1 for restrictions on the acceptable value + * of wait_states for a given SYSCLK configuration. + * + * @param wait_states number of wait states (one of + * FLASH_WAIT_STATE_0, FLASH_WAIT_STATE_1, + * FLASH_WAIT_STATE_2). + */ +void flash_set_latency(uint32 wait_states) { + uint32 val = FLASH_BASE->ACR; + + val &= ~FLASH_ACR_LATENCY; + val |= wait_states; + + FLASH_BASE->ACR = val; +} diff --git a/Libmaple/libmaple/libmaple/flash.h b/Libmaple/libmaple/libmaple/flash.h index f8b18671..0b4e49b6 100644 --- a/Libmaple/libmaple/libmaple/flash.h +++ b/Libmaple/libmaple/libmaple/flash.h @@ -1,142 +1,142 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file flash.h - * @brief STM32 Medium and high density Flash register map and setup - * routines - */ - -#include "libmaple_types.h" - -#ifndef _FLASH_H_ -#define _FLASH_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -/** Flash register map type */ -typedef struct flash_reg_map { - __io uint32 ACR; /**< Access control register */ - __io uint32 KEYR; /**< Key register */ - __io uint32 OPTKEYR; /**< OPTKEY register */ - __io uint32 SR; /**< Status register */ - __io uint32 CR; /**< Control register */ - __io uint32 AR; /**< Address register */ - __io uint32 OBR; /**< Option byte register */ - __io uint32 WRPR; /**< Write protection register */ -} flash_reg_map; - -/** Flash register map base pointer */ -#define FLASH_BASE ((struct flash_reg_map*)0x40022000) - -/* - * Register bit definitions - */ - -/* Access control register */ - -#define FLASH_ACR_PRFTBS_BIT 5 -#define FLASH_ACR_PRFTBE_BIT 4 -#define FLASH_ACR_HLFCYA_BIT 3 - -#define FLASH_ACR_PRFTBS BIT(FLASH_ACR_PRFTBS_BIT) -#define FLASH_ACR_PRFTBE BIT(FLASH_ACR_PRFTBE_BIT) -#define FLASH_ACR_HLFCYA BIT(FLASH_ACR_HLFCYA_BIT) -#define FLASH_ACR_LATENCY 0x7 - -/* Status register */ - -#define FLASH_SR_EOP_BIT 5 -#define FLASH_SR_WRPRTERR_BIT 4 -#define FLASH_SR_PGERR_BIT 2 -#define FLASH_SR_BSY_BIT 0 - -#define FLASH_SR_EOP BIT(FLASH_SR_EOP_BIT) -#define FLASH_SR_WRPRTERR BIT(FLASH_SR_WRPRTERR_BIT) -#define FLASH_SR_PGERR BIT(FLASH_SR_PGERR_BIT) -#define FLASH_SR_BSY BIT(FLASH_SR_BSY_BIT) - -/* Control register */ - -#define FLASH_CR_EOPIE_BIT 12 -#define FLASH_CR_ERRIE_BIT 10 -#define FLASH_CR_OPTWRE_BIT 9 -#define FLASH_CR_LOCK_BIT 7 -#define FLASH_CR_STRT_BIT 6 -#define FLASH_CR_OPTER_BIT 5 -#define FLASH_CR_OPTPG_BIT 4 -#define FLASH_CR_MER_BIT 2 -#define FLASH_CR_PER_BIT 1 -#define FLASH_CR_PG_BIT 0 - -#define FLASH_CR_EOPIE BIT(FLASH_CR_EOPIE_BIT) -#define FLASH_CR_ERRIE BIT(FLASH_CR_ERRIE_BIT) -#define FLASH_CR_OPTWRE BIT(FLASH_CR_OPTWRE_BIT) -#define FLASH_CR_LOCK BIT(FLASH_CR_LOCK_BIT) -#define FLASH_CR_STRT BIT(FLASH_CR_STRT_BIT) -#define FLASH_CR_OPTER BIT(FLASH_CR_OPTER_BIT) -#define FLASH_CR_OPTPG BIT(FLASH_CR_OPTPG_BIT) -#define FLASH_CR_MER BIT(FLASH_CR_MER_BIT) -#define FLASH_CR_PER BIT(FLASH_CR_PER_BIT) -#define FLASH_CR_PG BIT(FLASH_CR_PG_BIT) - -/* Option byte register */ - -#define FLASH_OBR_nRST_STDBY_BIT 4 -#define FLASH_OBR_nRST_STOP_BIT 3 -#define FLASH_OBR_WDG_SW_BIT 2 -#define FLASH_OBR_RDPRT_BIT 1 -#define FLASH_OBR_OPTERR_BIT 0 - -#define FLASH_OBR_DATA1 (0xFF << 18) -#define FLASH_OBR_DATA0 (0xFF << 10) -#define FLASH_OBR_USER 0x3FF -#define FLASH_OBR_nRST_STDBY BIT(FLASH_OBR_nRST_STDBY_BIT) -#define FLASH_OBR_nRST_STOP BIT(FLASH_OBR_nRST_STOP_BIT) -#define FLASH_OBR_WDG_SW BIT(FLASH_OBR_WDG_SW_BIT) -#define FLASH_OBR_RDPRT BIT(FLASH_OBR_RDPRT_BIT) -#define FLASH_OBR_OPTERR BIT(FLASH_OBR_OPTERR_BIT) - -/* - * Setup routines - */ - -#define FLASH_WAIT_STATE_0 0x0 -#define FLASH_WAIT_STATE_1 0x1 -#define FLASH_WAIT_STATE_2 0x2 - -void flash_enable_prefetch(void); -void flash_set_latency(uint32 wait_states); - -#ifdef __cplusplus -} -#endif - -#endif - - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file flash.h + * @brief STM32 Medium and high density Flash register map and setup + * routines + */ + +#include "libmaple_types.h" + +#ifndef _FLASH_H_ +#define _FLASH_H_ + +#ifdef __cplusplus +extern "C"{ +#endif + +/** Flash register map type */ +typedef struct flash_reg_map { + __io uint32 ACR; /**< Access control register */ + __io uint32 KEYR; /**< Key register */ + __io uint32 OPTKEYR; /**< OPTKEY register */ + __io uint32 SR; /**< Status register */ + __io uint32 CR; /**< Control register */ + __io uint32 AR; /**< Address register */ + __io uint32 OBR; /**< Option byte register */ + __io uint32 WRPR; /**< Write protection register */ +} flash_reg_map; + +/** Flash register map base pointer */ +#define FLASH_BASE ((struct flash_reg_map*)0x40022000) + +/* + * Register bit definitions + */ + +/* Access control register */ + +#define FLASH_ACR_PRFTBS_BIT 5 +#define FLASH_ACR_PRFTBE_BIT 4 +#define FLASH_ACR_HLFCYA_BIT 3 + +#define FLASH_ACR_PRFTBS BIT(FLASH_ACR_PRFTBS_BIT) +#define FLASH_ACR_PRFTBE BIT(FLASH_ACR_PRFTBE_BIT) +#define FLASH_ACR_HLFCYA BIT(FLASH_ACR_HLFCYA_BIT) +#define FLASH_ACR_LATENCY 0x7 + +/* Status register */ + +#define FLASH_SR_EOP_BIT 5 +#define FLASH_SR_WRPRTERR_BIT 4 +#define FLASH_SR_PGERR_BIT 2 +#define FLASH_SR_BSY_BIT 0 + +#define FLASH_SR_EOP BIT(FLASH_SR_EOP_BIT) +#define FLASH_SR_WRPRTERR BIT(FLASH_SR_WRPRTERR_BIT) +#define FLASH_SR_PGERR BIT(FLASH_SR_PGERR_BIT) +#define FLASH_SR_BSY BIT(FLASH_SR_BSY_BIT) + +/* Control register */ + +#define FLASH_CR_EOPIE_BIT 12 +#define FLASH_CR_ERRIE_BIT 10 +#define FLASH_CR_OPTWRE_BIT 9 +#define FLASH_CR_LOCK_BIT 7 +#define FLASH_CR_STRT_BIT 6 +#define FLASH_CR_OPTER_BIT 5 +#define FLASH_CR_OPTPG_BIT 4 +#define FLASH_CR_MER_BIT 2 +#define FLASH_CR_PER_BIT 1 +#define FLASH_CR_PG_BIT 0 + +#define FLASH_CR_EOPIE BIT(FLASH_CR_EOPIE_BIT) +#define FLASH_CR_ERRIE BIT(FLASH_CR_ERRIE_BIT) +#define FLASH_CR_OPTWRE BIT(FLASH_CR_OPTWRE_BIT) +#define FLASH_CR_LOCK BIT(FLASH_CR_LOCK_BIT) +#define FLASH_CR_STRT BIT(FLASH_CR_STRT_BIT) +#define FLASH_CR_OPTER BIT(FLASH_CR_OPTER_BIT) +#define FLASH_CR_OPTPG BIT(FLASH_CR_OPTPG_BIT) +#define FLASH_CR_MER BIT(FLASH_CR_MER_BIT) +#define FLASH_CR_PER BIT(FLASH_CR_PER_BIT) +#define FLASH_CR_PG BIT(FLASH_CR_PG_BIT) + +/* Option byte register */ + +#define FLASH_OBR_nRST_STDBY_BIT 4 +#define FLASH_OBR_nRST_STOP_BIT 3 +#define FLASH_OBR_WDG_SW_BIT 2 +#define FLASH_OBR_RDPRT_BIT 1 +#define FLASH_OBR_OPTERR_BIT 0 + +#define FLASH_OBR_DATA1 (0xFF << 18) +#define FLASH_OBR_DATA0 (0xFF << 10) +#define FLASH_OBR_USER 0x3FF +#define FLASH_OBR_nRST_STDBY BIT(FLASH_OBR_nRST_STDBY_BIT) +#define FLASH_OBR_nRST_STOP BIT(FLASH_OBR_nRST_STOP_BIT) +#define FLASH_OBR_WDG_SW BIT(FLASH_OBR_WDG_SW_BIT) +#define FLASH_OBR_RDPRT BIT(FLASH_OBR_RDPRT_BIT) +#define FLASH_OBR_OPTERR BIT(FLASH_OBR_OPTERR_BIT) + +/* + * Setup routines + */ + +#define FLASH_WAIT_STATE_0 0x0 +#define FLASH_WAIT_STATE_1 0x1 +#define FLASH_WAIT_STATE_2 0x2 + +void flash_enable_prefetch(void); +void flash_set_latency(uint32 wait_states); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/Libmaple/libmaple/libmaple/fsmc.c b/Libmaple/libmaple/libmaple/fsmc.c index bfeba93e..06ca7df6 100644 --- a/Libmaple/libmaple/libmaple/fsmc.c +++ b/Libmaple/libmaple/libmaple/fsmc.c @@ -1,93 +1,93 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file fsmc.c - * @brief Flexible static memory controller support. - */ - -#include "fsmc.h" -#include "gpio.h" - -#ifdef STM32_HIGH_DENSITY - -/** - * Configure FSMC GPIOs for use with SRAM. - */ -void fsmc_sram_init_gpios(void) { - /* Data lines... */ - gpio_set_mode(GPIOD, 0, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOD, 1, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOD, 8, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOD, 9, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOD, 10, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOD, 14, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOD, 15, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOE, 7, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOE, 8, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOE, 9, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOE, 10, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOE, 11, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOE, 12, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOE, 13, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOE, 14, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOE, 15, GPIO_AF_OUTPUT_PP); - - /* Address lines... */ - gpio_set_mode(GPIOD, 11, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOD, 12, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOD, 13, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOF, 0, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOF, 1, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOF, 2, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOF, 3, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOF, 4, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOF, 5, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOF, 12, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOF, 13, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOF, 14, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOF, 15, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOG, 0, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOG, 1, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOG, 2, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOG, 3, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOG, 4, GPIO_AF_OUTPUT_PP); - gpio_set_mode(GPIOG, 5, GPIO_AF_OUTPUT_PP); - - /* And control lines... */ - gpio_set_mode(GPIOD, 4, GPIO_AF_OUTPUT_PP); // NOE - gpio_set_mode(GPIOD, 5, GPIO_AF_OUTPUT_PP); // NWE - - gpio_set_mode(GPIOD, 7, GPIO_AF_OUTPUT_PP); // NE1 - gpio_set_mode(GPIOG, 9, GPIO_AF_OUTPUT_PP); // NE2 - gpio_set_mode(GPIOG, 10, GPIO_AF_OUTPUT_PP); // NE3 - gpio_set_mode(GPIOG, 12, GPIO_AF_OUTPUT_PP); // NE4 - - gpio_set_mode(GPIOE, 0, GPIO_AF_OUTPUT_PP); // NBL0 - gpio_set_mode(GPIOE, 1, GPIO_AF_OUTPUT_PP); // NBL1 -} - -#endif /* STM32_HIGH_DENSITY */ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Bryan Newbold. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file fsmc.c + * @brief Flexible static memory controller support. + */ + +#include "fsmc.h" +#include "gpio.h" + +#ifdef STM32_HIGH_DENSITY + +/** + * Configure FSMC GPIOs for use with SRAM. + */ +void fsmc_sram_init_gpios(void) { + /* Data lines... */ + gpio_set_mode(GPIOD, 0, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 1, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 8, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 9, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 10, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 14, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 15, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 7, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 8, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 9, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 10, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 11, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 12, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 13, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 14, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 15, GPIO_AF_OUTPUT_PP); + + /* Address lines... */ + gpio_set_mode(GPIOD, 11, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 12, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 13, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 0, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 1, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 2, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 3, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 4, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 5, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 12, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 13, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 14, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 15, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 0, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 1, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 2, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 3, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 4, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 5, GPIO_AF_OUTPUT_PP); + + /* And control lines... */ + gpio_set_mode(GPIOD, 4, GPIO_AF_OUTPUT_PP); // NOE + gpio_set_mode(GPIOD, 5, GPIO_AF_OUTPUT_PP); // NWE + + gpio_set_mode(GPIOD, 7, GPIO_AF_OUTPUT_PP); // NE1 + gpio_set_mode(GPIOG, 9, GPIO_AF_OUTPUT_PP); // NE2 + gpio_set_mode(GPIOG, 10, GPIO_AF_OUTPUT_PP); // NE3 + gpio_set_mode(GPIOG, 12, GPIO_AF_OUTPUT_PP); // NE4 + + gpio_set_mode(GPIOE, 0, GPIO_AF_OUTPUT_PP); // NBL0 + gpio_set_mode(GPIOE, 1, GPIO_AF_OUTPUT_PP); // NBL1 +} + +#endif /* STM32_HIGH_DENSITY */ diff --git a/Libmaple/libmaple/libmaple/fsmc.h b/Libmaple/libmaple/libmaple/fsmc.h index f21cf109..ef82b08a 100644 --- a/Libmaple/libmaple/libmaple/fsmc.h +++ b/Libmaple/libmaple/libmaple/fsmc.h @@ -1,320 +1,320 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file fsmc.h - * @brief Flexible static memory controller support. - */ - -/* - * See ../notes/fsmc.txt for more info - */ - -#include "libmaple_types.h" - -/** - * @file fsmc.h - */ - -#ifndef _FSMC_H_ -#define _FSMC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#ifdef STM32_HIGH_DENSITY - -/* - * Register maps and devices - */ - -/** FSMC register map type */ -typedef struct fsmc_reg_map { - __io uint32 BCR1; /**< SRAM/NOR-Flash chip-select control register 1 */ - __io uint32 BTR1; /**< SRAM/NOR-Flash chip-select timing register 1 */ - __io uint32 BCR2; /**< SRAM/NOR-Flash chip-select control register 2 */ - __io uint32 BTR2; /**< SRAM/NOR-Flash chip-select timing register 2 */ - __io uint32 BCR3; /**< SRAM/NOR-Flash chip-select control register 3 */ - __io uint32 BTR3; /**< SRAM/NOR-Flash chip-select timing register 3 */ - __io uint32 BCR4; /**< SRAM/NOR-Flash chip-select control register 4 */ - __io uint32 BTR4; /**< SRAM/NOR-Flash chip-select timing register 4 */ - const uint8 RESERVED1[64]; /**< Reserved */ - __io uint32 PCR2; /**< PC Card/NAND Flash control register 2 */ - __io uint32 SR2; /**< FIFO status and interrupt register 2 */ - __io uint32 PMEM2; /**< Common memory space timing register 2 */ - __io uint32 PATT2; /**< Attribute memory space timing register 2 */ - const uint8 RESERVED2[4]; /**< Reserved */ - __io uint32 ECCR2; /**< ECC result register 2 */ - const uint8 RESERVED3[2]; - __io uint32 PCR3; /**< PC Card/NAND Flash control register 3 */ - __io uint32 SR3; /**< FIFO status and interrupt register 3 */ - __io uint32 PMEM3; /**< Common memory space timing register 3 */ - __io uint32 PATT3; /**< Attribute memory space timing register 3 */ - const uint32 RESERVED4; /**< Reserved */ - __io uint32 ECCR3; /**< ECC result register 3 */ - const uint8 RESERVED5[8]; /**< Reserved */ - __io uint32 PCR4; /**< PC Card/NAND Flash control register 4 */ - __io uint32 SR4; /**< FIFO status and interrupt register 4 */ - __io uint32 PMEM4; /**< Common memory space timing register 4 */ - __io uint32 PATT4; /**< Attribute memory space timing register 4 */ - __io uint32 PIO4; /**< I/O space timing register 4 */ - const uint8 RESERVED6[80]; /**< Reserved */ - __io uint32 BWTR1; /**< SRAM/NOR-Flash write timing register 1 */ - const uint32 RESERVED7; /**< Reserved */ - __io uint32 BWTR2; /**< SRAM/NOR-Flash write timing register 2 */ - const uint32 RESERVED8; /**< Reserved */ - __io uint32 BWTR3; /**< SRAM/NOR-Flash write timing register 3 */ - const uint32 RESERVED9; /**< Reserved */ - __io uint32 BWTR4; /**< SRAM/NOR-Flash write timing register 4 */ -} __attribute__((packed)) fsmc_reg_map; - -#define __FSMCB 0xA0000000 - -/** FSMC register map base pointer */ -#define FSMC_BASE ((struct fsmc_reg_map*)__FSMCB) - -/** FSMC NOR/PSRAM register map type */ -typedef struct fsmc_nor_psram_reg_map { - __io uint32 BCR; /**< Chip-select control register */ - __io uint32 BTR; /**< Chip-select timing register */ - const uint8 RESERVED[252]; /**< Reserved */ - __io uint32 BWTR; /**< Write timing register */ -} fsmc_nor_psram_reg_map; - -/** FSMC NOR/PSRAM base pointer 1 */ -#define FSMC_NOR_PSRAM1_BASE ((struct fsmc_nor_psram_reg_map*)__FSMCB) - -/** FSMC NOR/PSRAM base pointer 2 */ -#define FSMC_NOR_PSRAM2_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x8)) - -/** FSMC NOR/PSRAM base pointer 3 */ -#define FSMC_NOR_PSRAM3_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x10)) - -/** FSMC NOR/PSRAM base pointer 4 */ -#define FSMC_NOR_PSRAM4_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x18)) - -/* - * Register bit definitions - */ - -/* NOR/PSRAM chip-select control registers */ - -#define FSMC_BCR_CBURSTRW_BIT 19 -#define FSMC_BCR_ASYNCWAIT_BIT 15 -#define FSMC_BCR_EXTMOD_BIT 14 -#define FSMC_BCR_WAITEN_BIT 13 -#define FSMC_BCR_WREN_BIT 12 -#define FSMC_BCR_WAITCFG_BIT 11 -#define FSMC_BCR_WRAPMOD_BIT 10 -#define FSMC_BCR_WAITPOL_BIT 9 -#define FSMC_BCR_BURSTEN_BIT 8 -#define FSMC_BCR_FACCEN_BIT 6 -#define FSMC_BCR_MUXEN_BIT 1 -#define FSMC_BCR_MBKEN_BIT 0 - -#define FSMC_BCR_CBURSTRW BIT(FSMC_BCR_CBURSTRW_BIT) -#define FSMC_BCR_ASYNCWAIT BIT(FSMC_BCR_ASYNCWAIT_BIT) -#define FSMC_BCR_EXTMOD BIT(FSMC_BCR_EXTMOD_BIT) -#define FSMC_BCR_WAITEN BIT(FSMC_BCR_WAITEN_BIT) -#define FSMC_BCR_WREN BIT(FSMC_BCR_WREN_BIT) -#define FSMC_BCR_WAITCFG BIT(FSMC_BCR_WAITCFG_BIT) -#define FSMC_BCR_WRAPMOD BIT(FSMC_BCR_WRAPMOD_BIT) -#define FSMC_BCR_WAITPOL BIT(FSMC_BCR_WAITPOL_BIT) -#define FSMC_BCR_BURSTEN BIT(FSMC_BCR_BURSTEN_BIT) -#define FSMC_BCR_FACCEN BIT(FSMC_BCR_FACCEN_BIT) -#define FSMC_BCR_MWID (0x3 << 4) -#define FSMC_BCR_MWID_8BITS (0x0 << 4) -#define FSMC_BCR_MWID_16BITS (0x1 << 4) -#define FSMC_BCR_MTYP (0x3 << 2) -#define FSMC_BCR_MTYP_SRAM (0x0 << 2) -#define FSMC_BCR_MTYP_PSRAM (0x1 << 2) -#define FSMC_BCR_MTYP_NOR_FLASH (0x2 << 2) -#define FSMC_BCR_MUXEN BIT(FSMC_BCR_MUXEN_BIT) -#define FSMC_BCR_MBKEN BIT(FSMC_BCR_MBKEN_BIT) - -/* SRAM/NOR-Flash chip-select timing registers */ - -#define FSMC_BTR_ACCMOD (0x3 << 28) -#define FSMC_BTR_ACCMOD_A (0x0 << 28) -#define FSMC_BTR_ACCMOD_B (0x1 << 28) -#define FSMC_BTR_ACCMOD_C (0x2 << 28) -#define FSMC_BTR_ACCMOD_D (0x3 << 28) -#define FSMC_BTR_DATLAT (0xF << 24) -#define FSMC_BTR_CLKDIV (0xF << 20) -#define FSMC_BTR_BUSTURN (0xF << 16) -#define FSMC_BTR_DATAST (0xFF << 8) -#define FSMC_BTR_ADDHLD (0xF << 4) -#define FSMC_BTR_ADDSET 0xF - -/* SRAM/NOR-Flash write timing registers */ - -#define FSMC_BWTR_ACCMOD (0x3 << 28) -#define FSMC_BWTR_ACCMOD_A (0x0 << 28) -#define FSMC_BWTR_ACCMOD_B (0x1 << 28) -#define FSMC_BWTR_ACCMOD_C (0x2 << 28) -#define FSMC_BWTR_ACCMOD_D (0x3 << 28) -#define FSMC_BWTR_DATLAT (0xF << 24) -#define FSMC_BWTR_CLKDIV (0xF << 20) -#define FSMC_BWTR_DATAST (0xFF << 8) -#define FSMC_BWTR_ADDHLD (0xF << 4) -#define FSMC_BWTR_ADDSET 0xF - -/* NAND Flash/PC Card controller registers */ - -#define FSMC_PCR_ECCEN_BIT 6 -#define FSMC_PCR_PTYP_BIT 3 -#define FSMC_PCR_PBKEN_BIT 2 -#define FSMC_PCR_PWAITEN_BIT 1 - -#define FSMC_PCR_ECCPS (0x7 << 17) -#define FSMC_PCR_ECCPS_256B (0x0 << 17) -#define FSMC_PCR_ECCPS_512B (0x1 << 17) -#define FSMC_PCR_ECCPS_1024B (0x2 << 17) -#define FSMC_PCR_ECCPS_2048B (0x3 << 17) -#define FSMC_PCR_ECCPS_4096B (0x4 << 17) -#define FSMC_PCR_ECCPS_8192B (0x5 << 17) -#define FSMC_PCR_TAR (0xF << 13) -#define FSMC_PCR_TCLR (0xF << 9) -#define FSMC_PCR_ECCEN BIT(FSMC_PCR_ECCEN_BIT) -#define FSMC_PCR_PWID (0x3 << 4) -#define FSMC_PCR_PWID_8BITS (0x0 << 4) -#define FSMC_PCR_PWID_16BITS (0x1 << 4) -#define FSMC_PCR_PTYP BIT(FSMC_PCR_PTYP_BIT) -#define FSMC_PCR_PTYP_PC_CF_PCMCIA (0x0 << FSMC_PCR_PTYP_BIT) -#define FSMC_PCR_PTYP_NAND (0x1 << FSMC_PCR_PTYP_BIT) -#define FSMC_PCR_PBKEN BIT(FSMC_PCR_PBKEN_BIT) -#define FSMC_PCR_PWAITEN BIT(FSMC_PCR_PWAITEN_BIT) - -/* FIFO status and interrupt registers */ - -#define FSMC_SR_FEMPT_BIT 6 -#define FSMC_SR_IFEN_BIT 5 -#define FSMC_SR_ILEN_BIT 4 -#define FSMC_SR_IREN_BIT 3 -#define FSMC_SR_IFS_BIT 2 -#define FSMC_SR_ILS_BIT 1 -#define FSMC_SR_IRS_BIT 0 - -#define FSMC_SR_FEMPT BIT(FSMC_SR_FEMPT_BIT) -#define FSMC_SR_IFEN BIT(FSMC_SR_IFEN_BIT) -#define FSMC_SR_ILEN BIT(FSMC_SR_ILEN_BIT) -#define FSMC_SR_IREN BIT(FSMC_SR_IREN_BIT) -#define FSMC_SR_IFS BIT(FSMC_SR_IFS_BIT) -#define FSMC_SR_ILS BIT(FSMC_SR_ILS_BIT) -#define FSMC_SR_IRS BIT(FSMC_SR_IRS_BIT) - -/* Common memory space timing registers */ - -#define FSMC_PMEM_MEMHIZ (0xFF << 24) -#define FSMC_PMEM_MEMHOLD (0xFF << 16) -#define FSMC_PMEM_MEMWAIT (0xFF << 8) -#define FSMC_PMEM_MEMSET 0xFF - -/* Attribute memory space timing registers */ - -#define FSMC_PATT_ATTHIZ (0xFF << 24) -#define FSMC_PATT_ATTHOLD (0xFF << 16) -#define FSMC_PATT_ATTWAIT (0xFF << 8) -#define FSMC_PATT_ATTSET 0xFF - -/* I/O space timing register 4 */ - -#define FSMC_PIO_IOHIZ (0xFF << 24) -#define FSMC_PIO_IOHOLD (0xFF << 16) -#define FSMC_PIO_IOWAIT (0xFF << 8) -#define FSMC_PIO_IOSET 0xFF - -/* - * Memory bank boundary addresses - */ - -/** Pointer to base address of FSMC memory bank 1 (split into 4 - * regions, each supporting 1 NOR Flash, SRAM, or PSRAM chip) */ -#define FSMC_BANK1 ((void*)0x60000000) - -/** Pointer to base address of FSMC memory bank 1, region 1 (for NOR/PSRAM) */ -#define FSMC_NOR_PSRAM_REGION1 FSMC_BANK1 - -/** Pointer to base address of FSMC memory bank 1, region 2 (for NOR/PSRAM) */ -#define FSMC_NOR_PSRAM_REGION2 ((void*)0x64000000) - -/** Pointer to base address of FSMC memory bank 1, region 3 (for NOR/PSRAM) */ -#define FSMC_NOR_PSRAM_REGION3 ((void*)0x68000000) - -/** Pointer to base address of FSMC memory bank 1, region 4 (for NOR/PSRAM) */ -#define FSMC_NOR_PSRAM_REGION4 ((void*)0x6C000000) - -/** Pointer to base address of FSMC memory bank 2 (for NAND Flash) */ -#define FSMC_BANK2 ((void*)0x70000000) - -/** Pointer to base address of FSMC memory bank 3 (for NAND Flash) */ -#define FSMC_BANK3 ((void*)0x80000000) - -/** Pointer to base address of FSMC memory bank 4 (for PC card devices */ -#define FSMC_BANK4 ((void*)0x90000000) - -/* - * SRAM/NOR Flash routines - */ - -void fsmc_sram_init_gpios(void); - -/** - * Set the DATAST bits in the given NOR/PSRAM register map's - * chip-select timing register (FSMC_BTR). - * - * @param regs NOR Flash/PSRAM register map whose chip-select timing - * register to set. - * @param datast Value to use for DATAST bits. - */ -static inline void fsmc_nor_psram_set_datast(fsmc_nor_psram_reg_map *regs, - uint8 datast) { - regs->BTR &= ~FSMC_BTR_DATAST; - regs->BTR |= datast << 8; -} - -/** - * Set the ADDHLD bits in the given NOR/PSRAM register map's chip - * select timing register (FSMC_BTRx). - * - * @param regs NOR Flash/PSRAM register map whose chip-select timing - * register to set. - * @param addset Value to use for ADDSET bits. - */ -static inline void fsmc_nor_psram_set_addset(fsmc_nor_psram_reg_map *regs, - uint8 addset) { - regs->BTR &= ~FSMC_BTR_ADDSET; - regs->BTR |= addset & 0xF; -} - -#endif /* STM32_HIGH_DENSITY */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Bryan Newbold. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file fsmc.h + * @brief Flexible static memory controller support. + */ + +/* + * See ../notes/fsmc.txt for more info + */ + +#include "libmaple_types.h" + +/** + * @file fsmc.h + */ + +#ifndef _FSMC_H_ +#define _FSMC_H_ + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifdef STM32_HIGH_DENSITY + +/* + * Register maps and devices + */ + +/** FSMC register map type */ +typedef struct fsmc_reg_map { + __io uint32 BCR1; /**< SRAM/NOR-Flash chip-select control register 1 */ + __io uint32 BTR1; /**< SRAM/NOR-Flash chip-select timing register 1 */ + __io uint32 BCR2; /**< SRAM/NOR-Flash chip-select control register 2 */ + __io uint32 BTR2; /**< SRAM/NOR-Flash chip-select timing register 2 */ + __io uint32 BCR3; /**< SRAM/NOR-Flash chip-select control register 3 */ + __io uint32 BTR3; /**< SRAM/NOR-Flash chip-select timing register 3 */ + __io uint32 BCR4; /**< SRAM/NOR-Flash chip-select control register 4 */ + __io uint32 BTR4; /**< SRAM/NOR-Flash chip-select timing register 4 */ + const uint8 RESERVED1[64]; /**< Reserved */ + __io uint32 PCR2; /**< PC Card/NAND Flash control register 2 */ + __io uint32 SR2; /**< FIFO status and interrupt register 2 */ + __io uint32 PMEM2; /**< Common memory space timing register 2 */ + __io uint32 PATT2; /**< Attribute memory space timing register 2 */ + const uint8 RESERVED2[4]; /**< Reserved */ + __io uint32 ECCR2; /**< ECC result register 2 */ + const uint8 RESERVED3[2]; + __io uint32 PCR3; /**< PC Card/NAND Flash control register 3 */ + __io uint32 SR3; /**< FIFO status and interrupt register 3 */ + __io uint32 PMEM3; /**< Common memory space timing register 3 */ + __io uint32 PATT3; /**< Attribute memory space timing register 3 */ + const uint32 RESERVED4; /**< Reserved */ + __io uint32 ECCR3; /**< ECC result register 3 */ + const uint8 RESERVED5[8]; /**< Reserved */ + __io uint32 PCR4; /**< PC Card/NAND Flash control register 4 */ + __io uint32 SR4; /**< FIFO status and interrupt register 4 */ + __io uint32 PMEM4; /**< Common memory space timing register 4 */ + __io uint32 PATT4; /**< Attribute memory space timing register 4 */ + __io uint32 PIO4; /**< I/O space timing register 4 */ + const uint8 RESERVED6[80]; /**< Reserved */ + __io uint32 BWTR1; /**< SRAM/NOR-Flash write timing register 1 */ + const uint32 RESERVED7; /**< Reserved */ + __io uint32 BWTR2; /**< SRAM/NOR-Flash write timing register 2 */ + const uint32 RESERVED8; /**< Reserved */ + __io uint32 BWTR3; /**< SRAM/NOR-Flash write timing register 3 */ + const uint32 RESERVED9; /**< Reserved */ + __io uint32 BWTR4; /**< SRAM/NOR-Flash write timing register 4 */ +} __attribute__((packed)) fsmc_reg_map; + +#define __FSMCB 0xA0000000 + +/** FSMC register map base pointer */ +#define FSMC_BASE ((struct fsmc_reg_map*)__FSMCB) + +/** FSMC NOR/PSRAM register map type */ +typedef struct fsmc_nor_psram_reg_map { + __io uint32 BCR; /**< Chip-select control register */ + __io uint32 BTR; /**< Chip-select timing register */ + const uint8 RESERVED[252]; /**< Reserved */ + __io uint32 BWTR; /**< Write timing register */ +} fsmc_nor_psram_reg_map; + +/** FSMC NOR/PSRAM base pointer 1 */ +#define FSMC_NOR_PSRAM1_BASE ((struct fsmc_nor_psram_reg_map*)__FSMCB) + +/** FSMC NOR/PSRAM base pointer 2 */ +#define FSMC_NOR_PSRAM2_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x8)) + +/** FSMC NOR/PSRAM base pointer 3 */ +#define FSMC_NOR_PSRAM3_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x10)) + +/** FSMC NOR/PSRAM base pointer 4 */ +#define FSMC_NOR_PSRAM4_BASE ((struct fsmc_nor_psram_reg_map*)(__FSMCB + 0x18)) + +/* + * Register bit definitions + */ + +/* NOR/PSRAM chip-select control registers */ + +#define FSMC_BCR_CBURSTRW_BIT 19 +#define FSMC_BCR_ASYNCWAIT_BIT 15 +#define FSMC_BCR_EXTMOD_BIT 14 +#define FSMC_BCR_WAITEN_BIT 13 +#define FSMC_BCR_WREN_BIT 12 +#define FSMC_BCR_WAITCFG_BIT 11 +#define FSMC_BCR_WRAPMOD_BIT 10 +#define FSMC_BCR_WAITPOL_BIT 9 +#define FSMC_BCR_BURSTEN_BIT 8 +#define FSMC_BCR_FACCEN_BIT 6 +#define FSMC_BCR_MUXEN_BIT 1 +#define FSMC_BCR_MBKEN_BIT 0 + +#define FSMC_BCR_CBURSTRW BIT(FSMC_BCR_CBURSTRW_BIT) +#define FSMC_BCR_ASYNCWAIT BIT(FSMC_BCR_ASYNCWAIT_BIT) +#define FSMC_BCR_EXTMOD BIT(FSMC_BCR_EXTMOD_BIT) +#define FSMC_BCR_WAITEN BIT(FSMC_BCR_WAITEN_BIT) +#define FSMC_BCR_WREN BIT(FSMC_BCR_WREN_BIT) +#define FSMC_BCR_WAITCFG BIT(FSMC_BCR_WAITCFG_BIT) +#define FSMC_BCR_WRAPMOD BIT(FSMC_BCR_WRAPMOD_BIT) +#define FSMC_BCR_WAITPOL BIT(FSMC_BCR_WAITPOL_BIT) +#define FSMC_BCR_BURSTEN BIT(FSMC_BCR_BURSTEN_BIT) +#define FSMC_BCR_FACCEN BIT(FSMC_BCR_FACCEN_BIT) +#define FSMC_BCR_MWID (0x3 << 4) +#define FSMC_BCR_MWID_8BITS (0x0 << 4) +#define FSMC_BCR_MWID_16BITS (0x1 << 4) +#define FSMC_BCR_MTYP (0x3 << 2) +#define FSMC_BCR_MTYP_SRAM (0x0 << 2) +#define FSMC_BCR_MTYP_PSRAM (0x1 << 2) +#define FSMC_BCR_MTYP_NOR_FLASH (0x2 << 2) +#define FSMC_BCR_MUXEN BIT(FSMC_BCR_MUXEN_BIT) +#define FSMC_BCR_MBKEN BIT(FSMC_BCR_MBKEN_BIT) + +/* SRAM/NOR-Flash chip-select timing registers */ + +#define FSMC_BTR_ACCMOD (0x3 << 28) +#define FSMC_BTR_ACCMOD_A (0x0 << 28) +#define FSMC_BTR_ACCMOD_B (0x1 << 28) +#define FSMC_BTR_ACCMOD_C (0x2 << 28) +#define FSMC_BTR_ACCMOD_D (0x3 << 28) +#define FSMC_BTR_DATLAT (0xF << 24) +#define FSMC_BTR_CLKDIV (0xF << 20) +#define FSMC_BTR_BUSTURN (0xF << 16) +#define FSMC_BTR_DATAST (0xFF << 8) +#define FSMC_BTR_ADDHLD (0xF << 4) +#define FSMC_BTR_ADDSET 0xF + +/* SRAM/NOR-Flash write timing registers */ + +#define FSMC_BWTR_ACCMOD (0x3 << 28) +#define FSMC_BWTR_ACCMOD_A (0x0 << 28) +#define FSMC_BWTR_ACCMOD_B (0x1 << 28) +#define FSMC_BWTR_ACCMOD_C (0x2 << 28) +#define FSMC_BWTR_ACCMOD_D (0x3 << 28) +#define FSMC_BWTR_DATLAT (0xF << 24) +#define FSMC_BWTR_CLKDIV (0xF << 20) +#define FSMC_BWTR_DATAST (0xFF << 8) +#define FSMC_BWTR_ADDHLD (0xF << 4) +#define FSMC_BWTR_ADDSET 0xF + +/* NAND Flash/PC Card controller registers */ + +#define FSMC_PCR_ECCEN_BIT 6 +#define FSMC_PCR_PTYP_BIT 3 +#define FSMC_PCR_PBKEN_BIT 2 +#define FSMC_PCR_PWAITEN_BIT 1 + +#define FSMC_PCR_ECCPS (0x7 << 17) +#define FSMC_PCR_ECCPS_256B (0x0 << 17) +#define FSMC_PCR_ECCPS_512B (0x1 << 17) +#define FSMC_PCR_ECCPS_1024B (0x2 << 17) +#define FSMC_PCR_ECCPS_2048B (0x3 << 17) +#define FSMC_PCR_ECCPS_4096B (0x4 << 17) +#define FSMC_PCR_ECCPS_8192B (0x5 << 17) +#define FSMC_PCR_TAR (0xF << 13) +#define FSMC_PCR_TCLR (0xF << 9) +#define FSMC_PCR_ECCEN BIT(FSMC_PCR_ECCEN_BIT) +#define FSMC_PCR_PWID (0x3 << 4) +#define FSMC_PCR_PWID_8BITS (0x0 << 4) +#define FSMC_PCR_PWID_16BITS (0x1 << 4) +#define FSMC_PCR_PTYP BIT(FSMC_PCR_PTYP_BIT) +#define FSMC_PCR_PTYP_PC_CF_PCMCIA (0x0 << FSMC_PCR_PTYP_BIT) +#define FSMC_PCR_PTYP_NAND (0x1 << FSMC_PCR_PTYP_BIT) +#define FSMC_PCR_PBKEN BIT(FSMC_PCR_PBKEN_BIT) +#define FSMC_PCR_PWAITEN BIT(FSMC_PCR_PWAITEN_BIT) + +/* FIFO status and interrupt registers */ + +#define FSMC_SR_FEMPT_BIT 6 +#define FSMC_SR_IFEN_BIT 5 +#define FSMC_SR_ILEN_BIT 4 +#define FSMC_SR_IREN_BIT 3 +#define FSMC_SR_IFS_BIT 2 +#define FSMC_SR_ILS_BIT 1 +#define FSMC_SR_IRS_BIT 0 + +#define FSMC_SR_FEMPT BIT(FSMC_SR_FEMPT_BIT) +#define FSMC_SR_IFEN BIT(FSMC_SR_IFEN_BIT) +#define FSMC_SR_ILEN BIT(FSMC_SR_ILEN_BIT) +#define FSMC_SR_IREN BIT(FSMC_SR_IREN_BIT) +#define FSMC_SR_IFS BIT(FSMC_SR_IFS_BIT) +#define FSMC_SR_ILS BIT(FSMC_SR_ILS_BIT) +#define FSMC_SR_IRS BIT(FSMC_SR_IRS_BIT) + +/* Common memory space timing registers */ + +#define FSMC_PMEM_MEMHIZ (0xFF << 24) +#define FSMC_PMEM_MEMHOLD (0xFF << 16) +#define FSMC_PMEM_MEMWAIT (0xFF << 8) +#define FSMC_PMEM_MEMSET 0xFF + +/* Attribute memory space timing registers */ + +#define FSMC_PATT_ATTHIZ (0xFF << 24) +#define FSMC_PATT_ATTHOLD (0xFF << 16) +#define FSMC_PATT_ATTWAIT (0xFF << 8) +#define FSMC_PATT_ATTSET 0xFF + +/* I/O space timing register 4 */ + +#define FSMC_PIO_IOHIZ (0xFF << 24) +#define FSMC_PIO_IOHOLD (0xFF << 16) +#define FSMC_PIO_IOWAIT (0xFF << 8) +#define FSMC_PIO_IOSET 0xFF + +/* + * Memory bank boundary addresses + */ + +/** Pointer to base address of FSMC memory bank 1 (split into 4 + * regions, each supporting 1 NOR Flash, SRAM, or PSRAM chip) */ +#define FSMC_BANK1 ((void*)0x60000000) + +/** Pointer to base address of FSMC memory bank 1, region 1 (for NOR/PSRAM) */ +#define FSMC_NOR_PSRAM_REGION1 FSMC_BANK1 + +/** Pointer to base address of FSMC memory bank 1, region 2 (for NOR/PSRAM) */ +#define FSMC_NOR_PSRAM_REGION2 ((void*)0x64000000) + +/** Pointer to base address of FSMC memory bank 1, region 3 (for NOR/PSRAM) */ +#define FSMC_NOR_PSRAM_REGION3 ((void*)0x68000000) + +/** Pointer to base address of FSMC memory bank 1, region 4 (for NOR/PSRAM) */ +#define FSMC_NOR_PSRAM_REGION4 ((void*)0x6C000000) + +/** Pointer to base address of FSMC memory bank 2 (for NAND Flash) */ +#define FSMC_BANK2 ((void*)0x70000000) + +/** Pointer to base address of FSMC memory bank 3 (for NAND Flash) */ +#define FSMC_BANK3 ((void*)0x80000000) + +/** Pointer to base address of FSMC memory bank 4 (for PC card devices */ +#define FSMC_BANK4 ((void*)0x90000000) + +/* + * SRAM/NOR Flash routines + */ + +void fsmc_sram_init_gpios(void); + +/** + * Set the DATAST bits in the given NOR/PSRAM register map's + * chip-select timing register (FSMC_BTR). + * + * @param regs NOR Flash/PSRAM register map whose chip-select timing + * register to set. + * @param datast Value to use for DATAST bits. + */ +static inline void fsmc_nor_psram_set_datast(fsmc_nor_psram_reg_map *regs, + uint8 datast) { + regs->BTR &= ~FSMC_BTR_DATAST; + regs->BTR |= datast << 8; +} + +/** + * Set the ADDHLD bits in the given NOR/PSRAM register map's chip + * select timing register (FSMC_BTRx). + * + * @param regs NOR Flash/PSRAM register map whose chip-select timing + * register to set. + * @param addset Value to use for ADDSET bits. + */ +static inline void fsmc_nor_psram_set_addset(fsmc_nor_psram_reg_map *regs, + uint8 addset) { + regs->BTR &= ~FSMC_BTR_ADDSET; + regs->BTR |= addset & 0xF; +} + +#endif /* STM32_HIGH_DENSITY */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/gpio.c b/Libmaple/libmaple/libmaple/gpio.c index d57f6e4f..cca4218f 100644 --- a/Libmaple/libmaple/libmaple/gpio.c +++ b/Libmaple/libmaple/libmaple/gpio.c @@ -1,36 +1,36 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file gpio.c - * @brief GPIO initialization routine - */ - -#ifdef STM32F2 -#include "gpioF2.c" -#else -#include "gpioF1.c" -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file gpio.c + * @brief GPIO initialization routine + */ + +#ifdef STM32F2 +#include "gpioF2.c" +#else +#include "gpioF1.c" +#endif diff --git a/Libmaple/libmaple/libmaple/gpio.h b/Libmaple/libmaple/libmaple/gpio.h index 5ce1bea1..4d42386c 100644 --- a/Libmaple/libmaple/libmaple/gpio.h +++ b/Libmaple/libmaple/libmaple/gpio.h @@ -1,38 +1,38 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file gpio.h - * - * @brief General purpose I/O (GPIO) and Alternate Function I/O - * (AFIO) prototypes, defines, and inlined access functions. - */ - -#ifdef STM32F2 -#include "gpioF2.h" -#else -#include "gpioF1.h" -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*****************************************************************************/ + +/** + * @file gpio.h + * + * @brief General purpose I/O (GPIO) and Alternate Function I/O + * (AFIO) prototypes, defines, and inlined access functions. + */ + +#ifdef STM32F2 +#include "gpioF2.h" +#else +#include "gpioF1.h" +#endif diff --git a/Libmaple/libmaple/libmaple/gpioF1.c b/Libmaple/libmaple/libmaple/gpioF1.c index f1b5c70b..e6438731 100644 --- a/Libmaple/libmaple/libmaple/gpioF1.c +++ b/Libmaple/libmaple/libmaple/gpioF1.c @@ -1,196 +1,196 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file gpio.c - * @brief GPIO initialization routine - */ - -#include "gpio.h" -#include "rcc.h" - -/* - * GPIO devices - */ - -gpio_dev gpioa = { - .regs = GPIOA_BASE, - .clk_id = RCC_GPIOA, - .exti_port = AFIO_EXTI_PA, -}; -/** GPIO port A device. */ -gpio_dev* const GPIOA = &gpioa; - -gpio_dev gpiob = { - .regs = GPIOB_BASE, - .clk_id = RCC_GPIOB, - .exti_port = AFIO_EXTI_PB, -}; -/** GPIO port B device. */ -gpio_dev* const GPIOB = &gpiob; - -gpio_dev gpioc = { - .regs = GPIOC_BASE, - .clk_id = RCC_GPIOC, - .exti_port = AFIO_EXTI_PC, -}; -/** GPIO port C device. */ -gpio_dev* const GPIOC = &gpioc; - -gpio_dev gpiod = { - .regs = GPIOD_BASE, - .clk_id = RCC_GPIOD, - .exti_port = AFIO_EXTI_PD, -}; -/** GPIO port D device. */ -gpio_dev* const GPIOD = &gpiod; - -#ifdef STM32_HIGH_DENSITY -gpio_dev gpioe = { - .regs = GPIOE_BASE, - .clk_id = RCC_GPIOE, - .exti_port = AFIO_EXTI_PE, -}; -/** GPIO port E device. */ -gpio_dev* const GPIOE = &gpioe; - -gpio_dev gpiof = { - .regs = GPIOF_BASE, - .clk_id = RCC_GPIOF, - .exti_port = AFIO_EXTI_PF, -}; -/** GPIO port F device. */ -gpio_dev* const GPIOF = &gpiof; - -gpio_dev gpiog = { - .regs = GPIOG_BASE, - .clk_id = RCC_GPIOG, - .exti_port = AFIO_EXTI_PG, -}; -/** GPIO port G device. */ -gpio_dev* const GPIOG = &gpiog; -#endif - -/* - * GPIO convenience routines - */ - -/** - * Initialize a GPIO device. - * - * Enables the clock for and resets the given device. - * - * @param dev GPIO device to initialize. - */ -void gpio_init(gpio_dev *dev) { - rcc_clk_enable(dev->clk_id); - rcc_reset_dev(dev->clk_id); -} - -/** - * Initialize and reset all available GPIO devices. - */ -void gpio_init_all(void) { - gpio_init(GPIOA); - gpio_init(GPIOB); - gpio_init(GPIOC); - gpio_init(GPIOD); -#ifdef STM32_HIGH_DENSITY - gpio_init(GPIOE); - gpio_init(GPIOF); - gpio_init(GPIOG); -#endif -} - -/** - * Set the mode of a GPIO pin. - * - * @param dev GPIO device. - * @param pin Pin on the device whose mode to set, 0--15. - * @param mode General purpose or alternate function mode to set the pin to. - * @see gpio_pin_mode - */ -void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) { - gpio_reg_map *regs = dev->regs; - __io uint32 *cr = ®s->CRL + (pin >> 3); - uint32 shift = (pin & 0x7) * 4; - uint32 tmp = *cr; - - tmp &= ~(0xF << shift); - tmp |= (mode == GPIO_INPUT_PU ? GPIO_INPUT_PD : mode) << shift; - *cr = tmp; - - if (mode == GPIO_INPUT_PD) { - regs->ODR &= ~BIT(pin); - } else if (mode == GPIO_INPUT_PU) { - regs->ODR |= BIT(pin); - } -} - -/* - * AFIO - */ - -/** - * @brief Initialize the AFIO clock, and reset the AFIO registers. - */ -void afio_init(void) { - rcc_clk_enable(RCC_AFIO); - rcc_reset_dev(RCC_AFIO); -} - -#define AFIO_EXTI_SEL_MASK 0xF - -/** - * @brief Select a source input for an external interrupt. - * - * @param exti External interrupt. - * @param gpio_port Port which contains pin to use as source input. - * @see afio_exti_num - * @see afio_exti_port - */ -void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) { - __io uint32 *exti_cr = &AFIO_BASE->EXTICR1 + exti / 4; - uint32 shift = 4 * (exti % 4); - uint32 cr = *exti_cr; - - cr &= ~(AFIO_EXTI_SEL_MASK << shift); - cr |= gpio_port << shift; - *exti_cr = cr; -} - -/** - * @brief Perform an alternate function remap. - * @param remapping Remapping to perform. - */ -void afio_remap(afio_remap_peripheral remapping) { - if (remapping & AFIO_REMAP_USE_MAPR2) { - remapping &= ~AFIO_REMAP_USE_MAPR2; - AFIO_BASE->MAPR2 |= remapping; - } else { - AFIO_BASE->MAPR |= remapping; - } -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file gpio.c + * @brief GPIO initialization routine + */ + +#include "gpio.h" +#include "rcc.h" + +/* + * GPIO devices + */ + +gpio_dev gpioa = { + .regs = GPIOA_BASE, + .clk_id = RCC_GPIOA, + .exti_port = AFIO_EXTI_PA, +}; +/** GPIO port A device. */ +gpio_dev* const GPIOA = &gpioa; + +gpio_dev gpiob = { + .regs = GPIOB_BASE, + .clk_id = RCC_GPIOB, + .exti_port = AFIO_EXTI_PB, +}; +/** GPIO port B device. */ +gpio_dev* const GPIOB = &gpiob; + +gpio_dev gpioc = { + .regs = GPIOC_BASE, + .clk_id = RCC_GPIOC, + .exti_port = AFIO_EXTI_PC, +}; +/** GPIO port C device. */ +gpio_dev* const GPIOC = &gpioc; + +gpio_dev gpiod = { + .regs = GPIOD_BASE, + .clk_id = RCC_GPIOD, + .exti_port = AFIO_EXTI_PD, +}; +/** GPIO port D device. */ +gpio_dev* const GPIOD = &gpiod; + +#ifdef STM32_HIGH_DENSITY +gpio_dev gpioe = { + .regs = GPIOE_BASE, + .clk_id = RCC_GPIOE, + .exti_port = AFIO_EXTI_PE, +}; +/** GPIO port E device. */ +gpio_dev* const GPIOE = &gpioe; + +gpio_dev gpiof = { + .regs = GPIOF_BASE, + .clk_id = RCC_GPIOF, + .exti_port = AFIO_EXTI_PF, +}; +/** GPIO port F device. */ +gpio_dev* const GPIOF = &gpiof; + +gpio_dev gpiog = { + .regs = GPIOG_BASE, + .clk_id = RCC_GPIOG, + .exti_port = AFIO_EXTI_PG, +}; +/** GPIO port G device. */ +gpio_dev* const GPIOG = &gpiog; +#endif + +/* + * GPIO convenience routines + */ + +/** + * Initialize a GPIO device. + * + * Enables the clock for and resets the given device. + * + * @param dev GPIO device to initialize. + */ +void gpio_init(gpio_dev *dev) { + rcc_clk_enable(dev->clk_id); + rcc_reset_dev(dev->clk_id); +} + +/** + * Initialize and reset all available GPIO devices. + */ +void gpio_init_all(void) { + gpio_init(GPIOA); + gpio_init(GPIOB); + gpio_init(GPIOC); + gpio_init(GPIOD); +#ifdef STM32_HIGH_DENSITY + gpio_init(GPIOE); + gpio_init(GPIOF); + gpio_init(GPIOG); +#endif +} + +/** + * Set the mode of a GPIO pin. + * + * @param dev GPIO device. + * @param pin Pin on the device whose mode to set, 0--15. + * @param mode General purpose or alternate function mode to set the pin to. + * @see gpio_pin_mode + */ +void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) { + gpio_reg_map *regs = dev->regs; + __io uint32 *cr = ®s->CRL + (pin >> 3); + uint32 shift = (pin & 0x7) * 4; + uint32 tmp = *cr; + + tmp &= ~(0xF << shift); + tmp |= (mode == GPIO_INPUT_PU ? GPIO_INPUT_PD : mode) << shift; + *cr = tmp; + + if (mode == GPIO_INPUT_PD) { + regs->ODR &= ~BIT(pin); + } else if (mode == GPIO_INPUT_PU) { + regs->ODR |= BIT(pin); + } +} + +/* + * AFIO + */ + +/** + * @brief Initialize the AFIO clock, and reset the AFIO registers. + */ +void afio_init(void) { + rcc_clk_enable(RCC_AFIO); + rcc_reset_dev(RCC_AFIO); +} + +#define AFIO_EXTI_SEL_MASK 0xF + +/** + * @brief Select a source input for an external interrupt. + * + * @param exti External interrupt. + * @param gpio_port Port which contains pin to use as source input. + * @see afio_exti_num + * @see afio_exti_port + */ +void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) { + __io uint32 *exti_cr = &AFIO_BASE->EXTICR1 + exti / 4; + uint32 shift = 4 * (exti % 4); + uint32 cr = *exti_cr; + + cr &= ~(AFIO_EXTI_SEL_MASK << shift); + cr |= gpio_port << shift; + *exti_cr = cr; +} + +/** + * @brief Perform an alternate function remap. + * @param remapping Remapping to perform. + */ +void afio_remap(afio_remap_peripheral remapping) { + if (remapping & AFIO_REMAP_USE_MAPR2) { + remapping &= ~AFIO_REMAP_USE_MAPR2; + AFIO_BASE->MAPR2 |= remapping; + } else { + AFIO_BASE->MAPR |= remapping; + } +} diff --git a/Libmaple/libmaple/libmaple/gpioF1.h b/Libmaple/libmaple/libmaple/gpioF1.h index 6bf3f08c..c69efb41 100644 --- a/Libmaple/libmaple/libmaple/gpioF1.h +++ b/Libmaple/libmaple/libmaple/gpioF1.h @@ -1,530 +1,530 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file gpio.h - * - * @brief General purpose I/O (GPIO) and Alternate Function I/O - * (AFIO) prototypes, defines, and inlined access functions. - */ - -#ifndef _GPIO_H_ -#define _GPIO_H_ - -#include "libmaple.h" -#include "rcc.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - * GPIO register maps and devices - */ - -/** GPIO register map type */ -typedef struct gpio_reg_map { - __io uint32 CRL; /**< Port configuration register low */ - __io uint32 CRH; /**< Port configuration register high */ - __io uint32 IDR; /**< Port input data register */ - __io uint32 ODR; /**< Port output data register */ - __io uint32 BSRR; /**< Port bit set/reset register */ - __io uint32 BRR; /**< Port bit reset register */ - __io uint32 LCKR; /**< Port configuration lock register */ -} gpio_reg_map; - -/** - * @brief External interrupt line port selector. - * - * Used to determine which GPIO port to map an external interrupt line - * onto. */ -/* (See AFIO sections, below) */ -typedef enum afio_exti_port { - AFIO_EXTI_PA, /**< Use port A (PAx) pin. */ - AFIO_EXTI_PB, /**< Use port B (PBx) pin. */ - AFIO_EXTI_PC, /**< Use port C (PCx) pin. */ - AFIO_EXTI_PD, /**< Use port D (PDx) pin. */ -#ifdef STM32_HIGH_DENSITY - AFIO_EXTI_PE, /**< Use port E (PEx) pin. */ - AFIO_EXTI_PF, /**< Use port F (PFx) pin. */ - AFIO_EXTI_PG, /**< Use port G (PGx) pin. */ -#endif -} afio_exti_port; - -/** GPIO device type */ -typedef struct gpio_dev { - gpio_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ - afio_exti_port exti_port; /**< AFIO external interrupt port value */ -} gpio_dev; - -extern gpio_dev gpioa; -extern gpio_dev* const GPIOA; -extern gpio_dev gpiob; -extern gpio_dev* const GPIOB; -extern gpio_dev gpioc; -extern gpio_dev* const GPIOC; -extern gpio_dev gpiod; -extern gpio_dev* const GPIOD; -#ifdef STM32_HIGH_DENSITY -extern gpio_dev gpioe; -extern gpio_dev* const GPIOE; -extern gpio_dev gpiof; -extern gpio_dev* const GPIOF; -extern gpio_dev gpiog; -extern gpio_dev* const GPIOG; -#endif - -/** GPIO port A register map base pointer */ -#define GPIOA_BASE ((struct gpio_reg_map*)0x40010800) -/** GPIO port B register map base pointer */ -#define GPIOB_BASE ((struct gpio_reg_map*)0x40010C00) -/** GPIO port C register map base pointer */ -#define GPIOC_BASE ((struct gpio_reg_map*)0x40011000) -/** GPIO port D register map base pointer */ -#define GPIOD_BASE ((struct gpio_reg_map*)0x40011400) -#ifdef STM32_HIGH_DENSITY -/** GPIO port E register map base pointer */ -#define GPIOE_BASE ((struct gpio_reg_map*)0x40011800) -/** GPIO port F register map base pointer */ -#define GPIOF_BASE ((struct gpio_reg_map*)0x40011C00) -/** GPIO port G register map base pointer */ -#define GPIOG_BASE ((struct gpio_reg_map*)0x40012000) -#endif - -/* - * GPIO register bit definitions - */ - -/* Control registers, low and high */ - -#define GPIO_CR_CNF (0x3 << 2) -#define GPIO_CR_CNF_INPUT_ANALOG (0x0 << 2) -#define GPIO_CR_CNF_INPUT_FLOATING (0x1 << 2) -#define GPIO_CR_CNF_INPUT_PU_PD (0x2 << 2) -#define GPIO_CR_CNF_OUTPUT_PP (0x0 << 2) -#define GPIO_CR_CNF_OUTPUT_OD (0x1 << 2) -#define GPIO_CR_CNF_AF_OUTPUT_PP (0x2 << 2) -#define GPIO_CR_CNF_AF_OUTPUT_OD (0x3 << 2) -#define GPIO_CR_MODE 0x3 -#define GPIO_CR_MODE_INPUT 0x0 -#define GPIO_CR_MODE_OUTPUT_10MHZ 0x1 -#define GPIO_CR_MODE_OUTPUT_2MHZ 0x2 -#define GPIO_CR_MODE_OUTPUT_50MHZ 0x3 - -/** - * @brief GPIO Pin modes. - * - * These only allow for 50MHZ max output speeds; if you want slower, - * use direct register access. - */ -typedef enum gpio_pin_mode { - GPIO_OUTPUT_PP = (GPIO_CR_CNF_OUTPUT_PP | - GPIO_CR_MODE_OUTPUT_50MHZ), /**< Output push-pull. */ - GPIO_OUTPUT_OD = (GPIO_CR_CNF_OUTPUT_OD | - GPIO_CR_MODE_OUTPUT_50MHZ), /**< Output open-drain. */ - GPIO_AF_OUTPUT_PP = (GPIO_CR_CNF_AF_OUTPUT_PP | - GPIO_CR_MODE_OUTPUT_50MHZ), /**< Alternate function - output push-pull. */ - GPIO_AF_OUTPUT_OD = (GPIO_CR_CNF_AF_OUTPUT_OD | - GPIO_CR_MODE_OUTPUT_50MHZ), /**< Alternate function - output open drain. */ - GPIO_INPUT_ANALOG = (GPIO_CR_CNF_INPUT_ANALOG | - GPIO_CR_MODE_INPUT), /**< Analog input. */ - GPIO_INPUT_FLOATING = (GPIO_CR_CNF_INPUT_FLOATING | - GPIO_CR_MODE_INPUT), /**< Input floating. */ - GPIO_INPUT_PD = (GPIO_CR_CNF_INPUT_PU_PD | - GPIO_CR_MODE_INPUT), /**< Input pull-down. */ - GPIO_AF_INPUT_PD = (GPIO_INPUT_PD), /**< Input pull-down. */ - GPIO_INPUT_PU /**< Input pull-up. */ - - - /* GPIO_INPUT_PU treated as a special case, for ODR twiddling */ -} gpio_pin_mode; - -/* - * GPIO Convenience routines - */ - -void gpio_init(gpio_dev *dev); -void gpio_init_all(void); -void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode); - -/** - * @brief Get a GPIO port's corresponding afio_exti_port. - * @param dev GPIO device whose afio_exti_port to return. - */ -static inline afio_exti_port gpio_exti_port(gpio_dev *dev) { - return dev->exti_port; -} - -/** - * Set or reset a GPIO pin. - * - * Pin must have previously been configured to output mode. - * - * @param dev GPIO device whose pin to set. - * @param pin Pin on to set or reset - * @param val If true, set the pin. If false, reset the pin. - */ -static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) { - if (val) { - dev->regs->BSRR = BIT(pin); - } else { - dev->regs->BRR = BIT(pin); - } -} - -/** - * Determine whether or not a GPIO pin is set. - * - * Pin must have previously been configured to input mode. - * - * @param dev GPIO device whose pin to test. - * @param pin Pin on dev to test. - * @return True if the pin is set, false otherwise. - */ -static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) { - return dev->regs->IDR & BIT(pin); -} - -/** - * Toggle a pin configured as output push-pull. - * @param dev GPIO device. - * @param pin Pin on dev to toggle. - */ -static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) { - dev->regs->ODR = dev->regs->ODR ^ BIT(pin); -} - -/* - * AFIO register map - */ - -/** AFIO register map */ -typedef struct afio_reg_map { - __io uint32 EVCR; /**< Event control register. */ - __io uint32 MAPR; /**< AF remap and debug I/O configuration - register. */ - __io uint32 EXTICR1; /**< External interrupt configuration - register 1. */ - __io uint32 EXTICR2; /**< External interrupt configuration - register 2. */ - __io uint32 EXTICR3; /**< External interrupt configuration - register 3. */ - __io uint32 EXTICR4; /**< External interrupt configuration - register 4. */ - __io uint32 MAPR2; /**< AF remap and debug I/O configuration - register 2. */ -} afio_reg_map; - -/** AFIO register map base pointer. */ -#define AFIO_BASE ((struct afio_reg_map *)0x40010000) - -/* - * AFIO register bit definitions - */ - -/* Event control register */ - -#define AFIO_EVCR_EVOE (0x1 << 7) -#define AFIO_EVCR_PORT_PA (0x0 << 4) -#define AFIO_EVCR_PORT_PB (0x1 << 4) -#define AFIO_EVCR_PORT_PC (0x2 << 4) -#define AFIO_EVCR_PORT_PD (0x3 << 4) -#define AFIO_EVCR_PORT_PE (0x4 << 4) -#define AFIO_EVCR_PIN_0 0x0 -#define AFIO_EVCR_PIN_1 0x1 -#define AFIO_EVCR_PIN_2 0x2 -#define AFIO_EVCR_PIN_3 0x3 -#define AFIO_EVCR_PIN_4 0x4 -#define AFIO_EVCR_PIN_5 0x5 -#define AFIO_EVCR_PIN_6 0x6 -#define AFIO_EVCR_PIN_7 0x7 -#define AFIO_EVCR_PIN_8 0x8 -#define AFIO_EVCR_PIN_9 0x9 -#define AFIO_EVCR_PIN_10 0xA -#define AFIO_EVCR_PIN_11 0xB -#define AFIO_EVCR_PIN_12 0xC -#define AFIO_EVCR_PIN_13 0xD -#define AFIO_EVCR_PIN_14 0xE -#define AFIO_EVCR_PIN_15 0xF - -/* AF remap and debug I/O configuration register */ - -#define AFIO_MAPR_SWJ_CFG (0x7 << 24) -#define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24) -#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24) -#define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW (0x2 << 24) -#define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW (0x4 << 24) -#define AFIO_MAPR_ADC2_ETRGREG_REMAP BIT(20) -#define AFIO_MAPR_ADC2_ETRGINJ_REMAP BIT(19) -#define AFIO_MAPR_ADC1_ETRGREG_REMAP BIT(18) -#define AFIO_MAPR_ADC1_ETRGINJ_REMAP BIT(17) -#define AFIO_MAPR_TIM5CH4_IREMAP BIT(16) -#define AFIO_MAPR_PD01_REMAP BIT(15) -#define AFIO_MAPR_CAN_REMAP (0x3 << 13) -#define AFIO_MAPR_CAN_REMAP_NONE (0x0 << 13) -#define AFIO_MAPR_CAN_REMAP_PB8_PB9 (0x2 << 13) -#define AFIO_MAPR_CAN_REMAP_PD0_PD1 (0x3 << 13) -#define AFIO_MAPR_TIM4_REMAP BIT(12) -#define AFIO_MAPR_TIM3_REMAP (0x3 << 10) -#define AFIO_MAPR_TIM3_REMAP_NONE (0x0 << 10) -#define AFIO_MAPR_TIM3_REMAP_PARTIAL (0x2 << 10) -#define AFIO_MAPR_TIM3_REMAP_FULL (0x3 << 10) -#define AFIO_MAPR_TIM2_REMAP (0x3 << 8) -#define AFIO_MAPR_TIM2_REMAP_NONE (0x0 << 8) -#define AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 (0x1 << 8) -#define AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11 (0x2 << 8) -#define AFIO_MAPR_TIM2_REMAP_FULL (0x3 << 8) -#define AFIO_MAPR_TIM1_REMAP (0x3 << 6) -#define AFIO_MAPR_TIM1_REMAP_NONE (0x0 << 6) -#define AFIO_MAPR_TIM1_REMAP_PARTIAL (0x1 << 6) -#define AFIO_MAPR_TIM1_REMAP_FULL (0x3 << 6) -#define AFIO_MAPR_USART3_REMAP (0x3 << 4) -#define AFIO_MAPR_USART3_REMAP_NONE (0x0 << 4) -#define AFIO_MAPR_USART3_REMAP_PARTIAL (0x1 << 4) -#define AFIO_MAPR_USART3_REMAP_FULL (0x3 << 4) -#define AFIO_MAPR_USART2_REMAP BIT(3) -#define AFIO_MAPR_USART1_REMAP BIT(2) -#define AFIO_MAPR_I2C1_REMAP BIT(1) -#define AFIO_MAPR_SPI1_REMAP BIT(0) - -/* External interrupt configuration register 1 */ - -#define AFIO_EXTICR1_EXTI3 (0xF << 12) -#define AFIO_EXTICR1_EXTI3_PA (0x0 << 12) -#define AFIO_EXTICR1_EXTI3_PB (0x1 << 12) -#define AFIO_EXTICR1_EXTI3_PC (0x2 << 12) -#define AFIO_EXTICR1_EXTI3_PD (0x3 << 12) -#define AFIO_EXTICR1_EXTI3_PE (0x4 << 12) -#define AFIO_EXTICR1_EXTI3_PF (0x5 << 12) -#define AFIO_EXTICR1_EXTI3_PG (0x6 << 12) -#define AFIO_EXTICR1_EXTI2 (0xF << 8) -#define AFIO_EXTICR1_EXTI2_PA (0x0 << 8) -#define AFIO_EXTICR1_EXTI2_PB (0x1 << 8) -#define AFIO_EXTICR1_EXTI2_PC (0x2 << 8) -#define AFIO_EXTICR1_EXTI2_PD (0x3 << 8) -#define AFIO_EXTICR1_EXTI2_PE (0x4 << 8) -#define AFIO_EXTICR1_EXTI2_PF (0x5 << 8) -#define AFIO_EXTICR1_EXTI2_PG (0x6 << 8) -#define AFIO_EXTICR1_EXTI1 (0xF << 4) -#define AFIO_EXTICR1_EXTI1_PA (0x0 << 4) -#define AFIO_EXTICR1_EXTI1_PB (0x1 << 4) -#define AFIO_EXTICR1_EXTI1_PC (0x2 << 4) -#define AFIO_EXTICR1_EXTI1_PD (0x3 << 4) -#define AFIO_EXTICR1_EXTI1_PE (0x4 << 4) -#define AFIO_EXTICR1_EXTI1_PF (0x5 << 4) -#define AFIO_EXTICR1_EXTI1_PG (0x6 << 4) -#define AFIO_EXTICR1_EXTI0 0xF -#define AFIO_EXTICR1_EXTI0_PA 0x0 -#define AFIO_EXTICR1_EXTI0_PB 0x1 -#define AFIO_EXTICR1_EXTI0_PC 0x2 -#define AFIO_EXTICR1_EXTI0_PD 0x3 -#define AFIO_EXTICR1_EXTI0_PE 0x4 -#define AFIO_EXTICR1_EXTI0_PF 0x5 -#define AFIO_EXTICR1_EXTI0_PG 0x6 - -/* External interrupt configuration register 2 */ - -#define AFIO_EXTICR2_EXTI7 (0xF << 12) -#define AFIO_EXTICR2_EXTI7_PA (0x0 << 12) -#define AFIO_EXTICR2_EXTI7_PB (0x1 << 12) -#define AFIO_EXTICR2_EXTI7_PC (0x2 << 12) -#define AFIO_EXTICR2_EXTI7_PD (0x3 << 12) -#define AFIO_EXTICR2_EXTI7_PE (0x4 << 12) -#define AFIO_EXTICR2_EXTI7_PF (0x5 << 12) -#define AFIO_EXTICR2_EXTI7_PG (0x6 << 12) -#define AFIO_EXTICR2_EXTI6 (0xF << 8) -#define AFIO_EXTICR2_EXTI6_PA (0x0 << 8) -#define AFIO_EXTICR2_EXTI6_PB (0x1 << 8) -#define AFIO_EXTICR2_EXTI6_PC (0x2 << 8) -#define AFIO_EXTICR2_EXTI6_PD (0x3 << 8) -#define AFIO_EXTICR2_EXTI6_PE (0x4 << 8) -#define AFIO_EXTICR2_EXTI6_PF (0x5 << 8) -#define AFIO_EXTICR2_EXTI6_PG (0x6 << 8) -#define AFIO_EXTICR2_EXTI5 (0xF << 4) -#define AFIO_EXTICR2_EXTI5_PA (0x0 << 4) -#define AFIO_EXTICR2_EXTI5_PB (0x1 << 4) -#define AFIO_EXTICR2_EXTI5_PC (0x2 << 4) -#define AFIO_EXTICR2_EXTI5_PD (0x3 << 4) -#define AFIO_EXTICR2_EXTI5_PE (0x4 << 4) -#define AFIO_EXTICR2_EXTI5_PF (0x5 << 4) -#define AFIO_EXTICR2_EXTI5_PG (0x6 << 4) -#define AFIO_EXTICR2_EXTI4 0xF -#define AFIO_EXTICR2_EXTI4_PA 0x0 -#define AFIO_EXTICR2_EXTI4_PB 0x1 -#define AFIO_EXTICR2_EXTI4_PC 0x2 -#define AFIO_EXTICR2_EXTI4_PD 0x3 -#define AFIO_EXTICR2_EXTI4_PE 0x4 -#define AFIO_EXTICR2_EXTI4_PF 0x5 -#define AFIO_EXTICR2_EXTI4_PG 0x6 - -/* AF remap and debug I/O configuration register 2 */ - -#define AFIO_MAPR2_FSMC_NADV BIT(10) -#define AFIO_MAPR2_TIM14_REMAP BIT(9) -#define AFIO_MAPR2_TIM13_REMAP BIT(8) -#define AFIO_MAPR2_TIM11_REMAP BIT(7) -#define AFIO_MAPR2_TIM10_REMAP BIT(6) -#define AFIO_MAPR2_TIM9_REMAP BIT(5) - -/* - * AFIO convenience routines - */ - -void afio_init(void); - -/** - * External interrupt line numbers. - */ -typedef enum afio_exti_num { - AFIO_EXTI_0, /**< External interrupt line 0. */ - AFIO_EXTI_1, /**< External interrupt line 1. */ - AFIO_EXTI_2, /**< External interrupt line 2. */ - AFIO_EXTI_3, /**< External interrupt line 3. */ - AFIO_EXTI_4, /**< External interrupt line 4. */ - AFIO_EXTI_5, /**< External interrupt line 5. */ - AFIO_EXTI_6, /**< External interrupt line 6. */ - AFIO_EXTI_7, /**< External interrupt line 7. */ - AFIO_EXTI_8, /**< External interrupt line 8. */ - AFIO_EXTI_9, /**< External interrupt line 9. */ - AFIO_EXTI_10, /**< External interrupt line 10. */ - AFIO_EXTI_11, /**< External interrupt line 11. */ - AFIO_EXTI_12, /**< External interrupt line 12. */ - AFIO_EXTI_13, /**< External interrupt line 13. */ - AFIO_EXTI_14, /**< External interrupt line 14. */ - AFIO_EXTI_15, /**< External interrupt line 15. */ -} afio_exti_num; - -void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port); - -/* HACK: Use upper bit to denote MAPR2, Bit 31 is reserved and - * not used in either MAPR or MAPR2 */ -#define AFIO_REMAP_USE_MAPR2 (1 << 31) - -/** - * @brief Available peripheral remaps. - * @see afio_remap() - */ -typedef enum afio_remap_peripheral { - AFIO_REMAP_ADC2_ETRGREG = AFIO_MAPR_ADC2_ETRGREG_REMAP, /**< - ADC 2 external trigger regular conversion remapping */ - AFIO_REMAP_ADC2_ETRGINJ = AFIO_MAPR_ADC2_ETRGINJ_REMAP, /**< - ADC 2 external trigger injected conversion remapping */ - AFIO_REMAP_ADC1_ETRGREG = AFIO_MAPR_ADC1_ETRGREG_REMAP, /**< - ADC 1 external trigger regular conversion remapping */ - AFIO_REMAP_ADC1_ETRGINJ = AFIO_MAPR_ADC1_ETRGINJ_REMAP, /**< - ADC 1 external trigger injected conversion remapping */ - AFIO_REMAP_TIM5CH4_I = AFIO_MAPR_TIM5CH4_IREMAP, /**< - Timer 5 channel 4 internal remapping */ - AFIO_REMAP_PD01 = AFIO_MAPR_PD01_REMAP, /**< - Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ - AFIO_REMAP_CAN_1 = AFIO_MAPR_CAN_REMAP_PB8_PB9, /**< - CAN alternate function remapping 1 (RX on PB8, TX on PB9) */ - AFIO_REMAP_CAN_2 = AFIO_MAPR_CAN_REMAP_PD0_PD1, /**< - CAN alternate function remapping 2 (RX on PD0, TX on PD1) */ - AFIO_REMAP_TIM4 = AFIO_MAPR_TIM4_REMAP, /**< - Timer 4 remapping */ - AFIO_REMAP_TIM3_PARTIAL = AFIO_MAPR_TIM3_REMAP_PARTIAL, /**< - Timer 3 partial remapping */ - AFIO_REMAP_TIM3_FULL = AFIO_MAPR_TIM3_REMAP_FULL, /**< - Timer 3 full remapping */ - AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3, /**< - Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3, CH3 - on PA2, CH4 on PA3) */ - AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11, /**< - Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1, CH3 - on PB10, CH4 on PB11) */ - AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL, /**< - Timer 2 full remapping */ - AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP, /**< - USART 2 remapping */ - AFIO_REMAP_USART1 = AFIO_MAPR_USART1_REMAP, /**< - USART 1 remapping */ - AFIO_REMAP_I2C1 = AFIO_MAPR_I2C1_REMAP, /**< - I2C 1 remapping */ - AFIO_REMAP_SPI1 = AFIO_MAPR_SPI1_REMAP, /**< - SPI 1 remapping */ - AFIO_REMAP_FSMC_NADV = (AFIO_MAPR2_FSMC_NADV | - AFIO_REMAP_USE_MAPR2), /**< - NADV signal not connected */ - AFIO_REMAP_TIM14 = (AFIO_MAPR2_TIM14_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 14 remapping */ - AFIO_REMAP_TIM13 = (AFIO_MAPR2_TIM13_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 13 remapping */ - AFIO_REMAP_TIM11 = (AFIO_MAPR2_TIM11_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 11 remapping */ - AFIO_REMAP_TIM10 = (AFIO_MAPR2_TIM10_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 10 remapping */ - AFIO_REMAP_TIM9 = (AFIO_MAPR2_TIM9_REMAP | - AFIO_REMAP_USE_MAPR2) /**< - Timer 9 */ -} afio_remap_peripheral; - -void afio_remap(afio_remap_peripheral p); - -/** - * @brief Debug port configuration - * - * Used to configure the behavior of JTAG and Serial Wire (SW) debug - * ports and their associated GPIO pins. - * - * @see afio_cfg_debug_ports() - */ -typedef enum afio_debug_cfg { - AFIO_DEBUG_FULL_SWJ = AFIO_MAPR_SWJ_CFG_FULL_SWJ, /**< - Full Serial Wire and JTAG debug */ - AFIO_DEBUG_FULL_SWJ_NO_NJRST = AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST, /**< - Full Serial Wire and JTAG, but no NJTRST. */ - AFIO_DEBUG_SW_ONLY = AFIO_MAPR_SWJ_CFG_NO_JTAG_SW, /**< - Serial Wire debug only (JTAG-DP disabled, - SW-DP enabled) */ - AFIO_DEBUG_NONE = AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW /**< - No debug; all JTAG and SW pins are free - for use as GPIOs. */ -} afio_debug_cfg; - -/** - * @brief Enable or disable the JTAG and SW debug ports. - * @param config Desired debug port configuration - * @see afio_debug_cfg - */ -static inline void afio_cfg_debug_ports(afio_debug_cfg config) { - __io uint32 *mapr = &AFIO_BASE->MAPR; - *mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config; -} - -#ifdef __cplusplus -} -#endif - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*****************************************************************************/ + +/** + * @file gpio.h + * + * @brief General purpose I/O (GPIO) and Alternate Function I/O + * (AFIO) prototypes, defines, and inlined access functions. + */ + +#ifndef _GPIO_H_ +#define _GPIO_H_ + +#include "libmaple.h" +#include "rcc.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * GPIO register maps and devices + */ + +/** GPIO register map type */ +typedef struct gpio_reg_map { + __io uint32 CRL; /**< Port configuration register low */ + __io uint32 CRH; /**< Port configuration register high */ + __io uint32 IDR; /**< Port input data register */ + __io uint32 ODR; /**< Port output data register */ + __io uint32 BSRR; /**< Port bit set/reset register */ + __io uint32 BRR; /**< Port bit reset register */ + __io uint32 LCKR; /**< Port configuration lock register */ +} gpio_reg_map; + +/** + * @brief External interrupt line port selector. + * + * Used to determine which GPIO port to map an external interrupt line + * onto. */ +/* (See AFIO sections, below) */ +typedef enum afio_exti_port { + AFIO_EXTI_PA, /**< Use port A (PAx) pin. */ + AFIO_EXTI_PB, /**< Use port B (PBx) pin. */ + AFIO_EXTI_PC, /**< Use port C (PCx) pin. */ + AFIO_EXTI_PD, /**< Use port D (PDx) pin. */ +#ifdef STM32_HIGH_DENSITY + AFIO_EXTI_PE, /**< Use port E (PEx) pin. */ + AFIO_EXTI_PF, /**< Use port F (PFx) pin. */ + AFIO_EXTI_PG, /**< Use port G (PGx) pin. */ +#endif +} afio_exti_port; + +/** GPIO device type */ +typedef struct gpio_dev { + gpio_reg_map *regs; /**< Register map */ + rcc_clk_id clk_id; /**< RCC clock information */ + afio_exti_port exti_port; /**< AFIO external interrupt port value */ +} gpio_dev; + +extern gpio_dev gpioa; +extern gpio_dev* const GPIOA; +extern gpio_dev gpiob; +extern gpio_dev* const GPIOB; +extern gpio_dev gpioc; +extern gpio_dev* const GPIOC; +extern gpio_dev gpiod; +extern gpio_dev* const GPIOD; +#ifdef STM32_HIGH_DENSITY +extern gpio_dev gpioe; +extern gpio_dev* const GPIOE; +extern gpio_dev gpiof; +extern gpio_dev* const GPIOF; +extern gpio_dev gpiog; +extern gpio_dev* const GPIOG; +#endif + +/** GPIO port A register map base pointer */ +#define GPIOA_BASE ((struct gpio_reg_map*)0x40010800) +/** GPIO port B register map base pointer */ +#define GPIOB_BASE ((struct gpio_reg_map*)0x40010C00) +/** GPIO port C register map base pointer */ +#define GPIOC_BASE ((struct gpio_reg_map*)0x40011000) +/** GPIO port D register map base pointer */ +#define GPIOD_BASE ((struct gpio_reg_map*)0x40011400) +#ifdef STM32_HIGH_DENSITY +/** GPIO port E register map base pointer */ +#define GPIOE_BASE ((struct gpio_reg_map*)0x40011800) +/** GPIO port F register map base pointer */ +#define GPIOF_BASE ((struct gpio_reg_map*)0x40011C00) +/** GPIO port G register map base pointer */ +#define GPIOG_BASE ((struct gpio_reg_map*)0x40012000) +#endif + +/* + * GPIO register bit definitions + */ + +/* Control registers, low and high */ + +#define GPIO_CR_CNF (0x3 << 2) +#define GPIO_CR_CNF_INPUT_ANALOG (0x0 << 2) +#define GPIO_CR_CNF_INPUT_FLOATING (0x1 << 2) +#define GPIO_CR_CNF_INPUT_PU_PD (0x2 << 2) +#define GPIO_CR_CNF_OUTPUT_PP (0x0 << 2) +#define GPIO_CR_CNF_OUTPUT_OD (0x1 << 2) +#define GPIO_CR_CNF_AF_OUTPUT_PP (0x2 << 2) +#define GPIO_CR_CNF_AF_OUTPUT_OD (0x3 << 2) +#define GPIO_CR_MODE 0x3 +#define GPIO_CR_MODE_INPUT 0x0 +#define GPIO_CR_MODE_OUTPUT_10MHZ 0x1 +#define GPIO_CR_MODE_OUTPUT_2MHZ 0x2 +#define GPIO_CR_MODE_OUTPUT_50MHZ 0x3 + +/** + * @brief GPIO Pin modes. + * + * These only allow for 50MHZ max output speeds; if you want slower, + * use direct register access. + */ +typedef enum gpio_pin_mode { + GPIO_OUTPUT_PP = (GPIO_CR_CNF_OUTPUT_PP | + GPIO_CR_MODE_OUTPUT_50MHZ), /**< Output push-pull. */ + GPIO_OUTPUT_OD = (GPIO_CR_CNF_OUTPUT_OD | + GPIO_CR_MODE_OUTPUT_50MHZ), /**< Output open-drain. */ + GPIO_AF_OUTPUT_PP = (GPIO_CR_CNF_AF_OUTPUT_PP | + GPIO_CR_MODE_OUTPUT_50MHZ), /**< Alternate function + output push-pull. */ + GPIO_AF_OUTPUT_OD = (GPIO_CR_CNF_AF_OUTPUT_OD | + GPIO_CR_MODE_OUTPUT_50MHZ), /**< Alternate function + output open drain. */ + GPIO_INPUT_ANALOG = (GPIO_CR_CNF_INPUT_ANALOG | + GPIO_CR_MODE_INPUT), /**< Analog input. */ + GPIO_INPUT_FLOATING = (GPIO_CR_CNF_INPUT_FLOATING | + GPIO_CR_MODE_INPUT), /**< Input floating. */ + GPIO_INPUT_PD = (GPIO_CR_CNF_INPUT_PU_PD | + GPIO_CR_MODE_INPUT), /**< Input pull-down. */ + GPIO_AF_INPUT_PD = (GPIO_INPUT_PD), /**< Input pull-down. */ + GPIO_INPUT_PU /**< Input pull-up. */ + + + /* GPIO_INPUT_PU treated as a special case, for ODR twiddling */ +} gpio_pin_mode; + +/* + * GPIO Convenience routines + */ + +void gpio_init(gpio_dev *dev); +void gpio_init_all(void); +void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode); + +/** + * @brief Get a GPIO port's corresponding afio_exti_port. + * @param dev GPIO device whose afio_exti_port to return. + */ +static inline afio_exti_port gpio_exti_port(gpio_dev *dev) { + return dev->exti_port; +} + +/** + * Set or reset a GPIO pin. + * + * Pin must have previously been configured to output mode. + * + * @param dev GPIO device whose pin to set. + * @param pin Pin on to set or reset + * @param val If true, set the pin. If false, reset the pin. + */ +static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) { + if (val) { + dev->regs->BSRR = BIT(pin); + } else { + dev->regs->BRR = BIT(pin); + } +} + +/** + * Determine whether or not a GPIO pin is set. + * + * Pin must have previously been configured to input mode. + * + * @param dev GPIO device whose pin to test. + * @param pin Pin on dev to test. + * @return True if the pin is set, false otherwise. + */ +static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) { + return dev->regs->IDR & BIT(pin); +} + +/** + * Toggle a pin configured as output push-pull. + * @param dev GPIO device. + * @param pin Pin on dev to toggle. + */ +static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) { + dev->regs->ODR = dev->regs->ODR ^ BIT(pin); +} + +/* + * AFIO register map + */ + +/** AFIO register map */ +typedef struct afio_reg_map { + __io uint32 EVCR; /**< Event control register. */ + __io uint32 MAPR; /**< AF remap and debug I/O configuration + register. */ + __io uint32 EXTICR1; /**< External interrupt configuration + register 1. */ + __io uint32 EXTICR2; /**< External interrupt configuration + register 2. */ + __io uint32 EXTICR3; /**< External interrupt configuration + register 3. */ + __io uint32 EXTICR4; /**< External interrupt configuration + register 4. */ + __io uint32 MAPR2; /**< AF remap and debug I/O configuration + register 2. */ +} afio_reg_map; + +/** AFIO register map base pointer. */ +#define AFIO_BASE ((struct afio_reg_map *)0x40010000) + +/* + * AFIO register bit definitions + */ + +/* Event control register */ + +#define AFIO_EVCR_EVOE (0x1 << 7) +#define AFIO_EVCR_PORT_PA (0x0 << 4) +#define AFIO_EVCR_PORT_PB (0x1 << 4) +#define AFIO_EVCR_PORT_PC (0x2 << 4) +#define AFIO_EVCR_PORT_PD (0x3 << 4) +#define AFIO_EVCR_PORT_PE (0x4 << 4) +#define AFIO_EVCR_PIN_0 0x0 +#define AFIO_EVCR_PIN_1 0x1 +#define AFIO_EVCR_PIN_2 0x2 +#define AFIO_EVCR_PIN_3 0x3 +#define AFIO_EVCR_PIN_4 0x4 +#define AFIO_EVCR_PIN_5 0x5 +#define AFIO_EVCR_PIN_6 0x6 +#define AFIO_EVCR_PIN_7 0x7 +#define AFIO_EVCR_PIN_8 0x8 +#define AFIO_EVCR_PIN_9 0x9 +#define AFIO_EVCR_PIN_10 0xA +#define AFIO_EVCR_PIN_11 0xB +#define AFIO_EVCR_PIN_12 0xC +#define AFIO_EVCR_PIN_13 0xD +#define AFIO_EVCR_PIN_14 0xE +#define AFIO_EVCR_PIN_15 0xF + +/* AF remap and debug I/O configuration register */ + +#define AFIO_MAPR_SWJ_CFG (0x7 << 24) +#define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24) +#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24) +#define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW (0x2 << 24) +#define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW (0x4 << 24) +#define AFIO_MAPR_ADC2_ETRGREG_REMAP BIT(20) +#define AFIO_MAPR_ADC2_ETRGINJ_REMAP BIT(19) +#define AFIO_MAPR_ADC1_ETRGREG_REMAP BIT(18) +#define AFIO_MAPR_ADC1_ETRGINJ_REMAP BIT(17) +#define AFIO_MAPR_TIM5CH4_IREMAP BIT(16) +#define AFIO_MAPR_PD01_REMAP BIT(15) +#define AFIO_MAPR_CAN_REMAP (0x3 << 13) +#define AFIO_MAPR_CAN_REMAP_NONE (0x0 << 13) +#define AFIO_MAPR_CAN_REMAP_PB8_PB9 (0x2 << 13) +#define AFIO_MAPR_CAN_REMAP_PD0_PD1 (0x3 << 13) +#define AFIO_MAPR_TIM4_REMAP BIT(12) +#define AFIO_MAPR_TIM3_REMAP (0x3 << 10) +#define AFIO_MAPR_TIM3_REMAP_NONE (0x0 << 10) +#define AFIO_MAPR_TIM3_REMAP_PARTIAL (0x2 << 10) +#define AFIO_MAPR_TIM3_REMAP_FULL (0x3 << 10) +#define AFIO_MAPR_TIM2_REMAP (0x3 << 8) +#define AFIO_MAPR_TIM2_REMAP_NONE (0x0 << 8) +#define AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 (0x1 << 8) +#define AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11 (0x2 << 8) +#define AFIO_MAPR_TIM2_REMAP_FULL (0x3 << 8) +#define AFIO_MAPR_TIM1_REMAP (0x3 << 6) +#define AFIO_MAPR_TIM1_REMAP_NONE (0x0 << 6) +#define AFIO_MAPR_TIM1_REMAP_PARTIAL (0x1 << 6) +#define AFIO_MAPR_TIM1_REMAP_FULL (0x3 << 6) +#define AFIO_MAPR_USART3_REMAP (0x3 << 4) +#define AFIO_MAPR_USART3_REMAP_NONE (0x0 << 4) +#define AFIO_MAPR_USART3_REMAP_PARTIAL (0x1 << 4) +#define AFIO_MAPR_USART3_REMAP_FULL (0x3 << 4) +#define AFIO_MAPR_USART2_REMAP BIT(3) +#define AFIO_MAPR_USART1_REMAP BIT(2) +#define AFIO_MAPR_I2C1_REMAP BIT(1) +#define AFIO_MAPR_SPI1_REMAP BIT(0) + +/* External interrupt configuration register 1 */ + +#define AFIO_EXTICR1_EXTI3 (0xF << 12) +#define AFIO_EXTICR1_EXTI3_PA (0x0 << 12) +#define AFIO_EXTICR1_EXTI3_PB (0x1 << 12) +#define AFIO_EXTICR1_EXTI3_PC (0x2 << 12) +#define AFIO_EXTICR1_EXTI3_PD (0x3 << 12) +#define AFIO_EXTICR1_EXTI3_PE (0x4 << 12) +#define AFIO_EXTICR1_EXTI3_PF (0x5 << 12) +#define AFIO_EXTICR1_EXTI3_PG (0x6 << 12) +#define AFIO_EXTICR1_EXTI2 (0xF << 8) +#define AFIO_EXTICR1_EXTI2_PA (0x0 << 8) +#define AFIO_EXTICR1_EXTI2_PB (0x1 << 8) +#define AFIO_EXTICR1_EXTI2_PC (0x2 << 8) +#define AFIO_EXTICR1_EXTI2_PD (0x3 << 8) +#define AFIO_EXTICR1_EXTI2_PE (0x4 << 8) +#define AFIO_EXTICR1_EXTI2_PF (0x5 << 8) +#define AFIO_EXTICR1_EXTI2_PG (0x6 << 8) +#define AFIO_EXTICR1_EXTI1 (0xF << 4) +#define AFIO_EXTICR1_EXTI1_PA (0x0 << 4) +#define AFIO_EXTICR1_EXTI1_PB (0x1 << 4) +#define AFIO_EXTICR1_EXTI1_PC (0x2 << 4) +#define AFIO_EXTICR1_EXTI1_PD (0x3 << 4) +#define AFIO_EXTICR1_EXTI1_PE (0x4 << 4) +#define AFIO_EXTICR1_EXTI1_PF (0x5 << 4) +#define AFIO_EXTICR1_EXTI1_PG (0x6 << 4) +#define AFIO_EXTICR1_EXTI0 0xF +#define AFIO_EXTICR1_EXTI0_PA 0x0 +#define AFIO_EXTICR1_EXTI0_PB 0x1 +#define AFIO_EXTICR1_EXTI0_PC 0x2 +#define AFIO_EXTICR1_EXTI0_PD 0x3 +#define AFIO_EXTICR1_EXTI0_PE 0x4 +#define AFIO_EXTICR1_EXTI0_PF 0x5 +#define AFIO_EXTICR1_EXTI0_PG 0x6 + +/* External interrupt configuration register 2 */ + +#define AFIO_EXTICR2_EXTI7 (0xF << 12) +#define AFIO_EXTICR2_EXTI7_PA (0x0 << 12) +#define AFIO_EXTICR2_EXTI7_PB (0x1 << 12) +#define AFIO_EXTICR2_EXTI7_PC (0x2 << 12) +#define AFIO_EXTICR2_EXTI7_PD (0x3 << 12) +#define AFIO_EXTICR2_EXTI7_PE (0x4 << 12) +#define AFIO_EXTICR2_EXTI7_PF (0x5 << 12) +#define AFIO_EXTICR2_EXTI7_PG (0x6 << 12) +#define AFIO_EXTICR2_EXTI6 (0xF << 8) +#define AFIO_EXTICR2_EXTI6_PA (0x0 << 8) +#define AFIO_EXTICR2_EXTI6_PB (0x1 << 8) +#define AFIO_EXTICR2_EXTI6_PC (0x2 << 8) +#define AFIO_EXTICR2_EXTI6_PD (0x3 << 8) +#define AFIO_EXTICR2_EXTI6_PE (0x4 << 8) +#define AFIO_EXTICR2_EXTI6_PF (0x5 << 8) +#define AFIO_EXTICR2_EXTI6_PG (0x6 << 8) +#define AFIO_EXTICR2_EXTI5 (0xF << 4) +#define AFIO_EXTICR2_EXTI5_PA (0x0 << 4) +#define AFIO_EXTICR2_EXTI5_PB (0x1 << 4) +#define AFIO_EXTICR2_EXTI5_PC (0x2 << 4) +#define AFIO_EXTICR2_EXTI5_PD (0x3 << 4) +#define AFIO_EXTICR2_EXTI5_PE (0x4 << 4) +#define AFIO_EXTICR2_EXTI5_PF (0x5 << 4) +#define AFIO_EXTICR2_EXTI5_PG (0x6 << 4) +#define AFIO_EXTICR2_EXTI4 0xF +#define AFIO_EXTICR2_EXTI4_PA 0x0 +#define AFIO_EXTICR2_EXTI4_PB 0x1 +#define AFIO_EXTICR2_EXTI4_PC 0x2 +#define AFIO_EXTICR2_EXTI4_PD 0x3 +#define AFIO_EXTICR2_EXTI4_PE 0x4 +#define AFIO_EXTICR2_EXTI4_PF 0x5 +#define AFIO_EXTICR2_EXTI4_PG 0x6 + +/* AF remap and debug I/O configuration register 2 */ + +#define AFIO_MAPR2_FSMC_NADV BIT(10) +#define AFIO_MAPR2_TIM14_REMAP BIT(9) +#define AFIO_MAPR2_TIM13_REMAP BIT(8) +#define AFIO_MAPR2_TIM11_REMAP BIT(7) +#define AFIO_MAPR2_TIM10_REMAP BIT(6) +#define AFIO_MAPR2_TIM9_REMAP BIT(5) + +/* + * AFIO convenience routines + */ + +void afio_init(void); + +/** + * External interrupt line numbers. + */ +typedef enum afio_exti_num { + AFIO_EXTI_0, /**< External interrupt line 0. */ + AFIO_EXTI_1, /**< External interrupt line 1. */ + AFIO_EXTI_2, /**< External interrupt line 2. */ + AFIO_EXTI_3, /**< External interrupt line 3. */ + AFIO_EXTI_4, /**< External interrupt line 4. */ + AFIO_EXTI_5, /**< External interrupt line 5. */ + AFIO_EXTI_6, /**< External interrupt line 6. */ + AFIO_EXTI_7, /**< External interrupt line 7. */ + AFIO_EXTI_8, /**< External interrupt line 8. */ + AFIO_EXTI_9, /**< External interrupt line 9. */ + AFIO_EXTI_10, /**< External interrupt line 10. */ + AFIO_EXTI_11, /**< External interrupt line 11. */ + AFIO_EXTI_12, /**< External interrupt line 12. */ + AFIO_EXTI_13, /**< External interrupt line 13. */ + AFIO_EXTI_14, /**< External interrupt line 14. */ + AFIO_EXTI_15, /**< External interrupt line 15. */ +} afio_exti_num; + +void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port); + +/* HACK: Use upper bit to denote MAPR2, Bit 31 is reserved and + * not used in either MAPR or MAPR2 */ +#define AFIO_REMAP_USE_MAPR2 (1 << 31) + +/** + * @brief Available peripheral remaps. + * @see afio_remap() + */ +typedef enum afio_remap_peripheral { + AFIO_REMAP_ADC2_ETRGREG = AFIO_MAPR_ADC2_ETRGREG_REMAP, /**< + ADC 2 external trigger regular conversion remapping */ + AFIO_REMAP_ADC2_ETRGINJ = AFIO_MAPR_ADC2_ETRGINJ_REMAP, /**< + ADC 2 external trigger injected conversion remapping */ + AFIO_REMAP_ADC1_ETRGREG = AFIO_MAPR_ADC1_ETRGREG_REMAP, /**< + ADC 1 external trigger regular conversion remapping */ + AFIO_REMAP_ADC1_ETRGINJ = AFIO_MAPR_ADC1_ETRGINJ_REMAP, /**< + ADC 1 external trigger injected conversion remapping */ + AFIO_REMAP_TIM5CH4_I = AFIO_MAPR_TIM5CH4_IREMAP, /**< + Timer 5 channel 4 internal remapping */ + AFIO_REMAP_PD01 = AFIO_MAPR_PD01_REMAP, /**< + Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ + AFIO_REMAP_CAN_1 = AFIO_MAPR_CAN_REMAP_PB8_PB9, /**< + CAN alternate function remapping 1 (RX on PB8, TX on PB9) */ + AFIO_REMAP_CAN_2 = AFIO_MAPR_CAN_REMAP_PD0_PD1, /**< + CAN alternate function remapping 2 (RX on PD0, TX on PD1) */ + AFIO_REMAP_TIM4 = AFIO_MAPR_TIM4_REMAP, /**< + Timer 4 remapping */ + AFIO_REMAP_TIM3_PARTIAL = AFIO_MAPR_TIM3_REMAP_PARTIAL, /**< + Timer 3 partial remapping */ + AFIO_REMAP_TIM3_FULL = AFIO_MAPR_TIM3_REMAP_FULL, /**< + Timer 3 full remapping */ + AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3, /**< + Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3, CH3 + on PA2, CH4 on PA3) */ + AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11, /**< + Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1, CH3 + on PB10, CH4 on PB11) */ + AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL, /**< + Timer 2 full remapping */ + AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP, /**< + USART 2 remapping */ + AFIO_REMAP_USART1 = AFIO_MAPR_USART1_REMAP, /**< + USART 1 remapping */ + AFIO_REMAP_I2C1 = AFIO_MAPR_I2C1_REMAP, /**< + I2C 1 remapping */ + AFIO_REMAP_SPI1 = AFIO_MAPR_SPI1_REMAP, /**< + SPI 1 remapping */ + AFIO_REMAP_FSMC_NADV = (AFIO_MAPR2_FSMC_NADV | + AFIO_REMAP_USE_MAPR2), /**< + NADV signal not connected */ + AFIO_REMAP_TIM14 = (AFIO_MAPR2_TIM14_REMAP | + AFIO_REMAP_USE_MAPR2), /**< + Timer 14 remapping */ + AFIO_REMAP_TIM13 = (AFIO_MAPR2_TIM13_REMAP | + AFIO_REMAP_USE_MAPR2), /**< + Timer 13 remapping */ + AFIO_REMAP_TIM11 = (AFIO_MAPR2_TIM11_REMAP | + AFIO_REMAP_USE_MAPR2), /**< + Timer 11 remapping */ + AFIO_REMAP_TIM10 = (AFIO_MAPR2_TIM10_REMAP | + AFIO_REMAP_USE_MAPR2), /**< + Timer 10 remapping */ + AFIO_REMAP_TIM9 = (AFIO_MAPR2_TIM9_REMAP | + AFIO_REMAP_USE_MAPR2) /**< + Timer 9 */ +} afio_remap_peripheral; + +void afio_remap(afio_remap_peripheral p); + +/** + * @brief Debug port configuration + * + * Used to configure the behavior of JTAG and Serial Wire (SW) debug + * ports and their associated GPIO pins. + * + * @see afio_cfg_debug_ports() + */ +typedef enum afio_debug_cfg { + AFIO_DEBUG_FULL_SWJ = AFIO_MAPR_SWJ_CFG_FULL_SWJ, /**< + Full Serial Wire and JTAG debug */ + AFIO_DEBUG_FULL_SWJ_NO_NJRST = AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST, /**< + Full Serial Wire and JTAG, but no NJTRST. */ + AFIO_DEBUG_SW_ONLY = AFIO_MAPR_SWJ_CFG_NO_JTAG_SW, /**< + Serial Wire debug only (JTAG-DP disabled, + SW-DP enabled) */ + AFIO_DEBUG_NONE = AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW /**< + No debug; all JTAG and SW pins are free + for use as GPIOs. */ +} afio_debug_cfg; + +/** + * @brief Enable or disable the JTAG and SW debug ports. + * @param config Desired debug port configuration + * @see afio_debug_cfg + */ +static inline void afio_cfg_debug_ports(afio_debug_cfg config) { + __io uint32 *mapr = &AFIO_BASE->MAPR; + *mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config; +} + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Libmaple/libmaple/libmaple/gpioF2.c b/Libmaple/libmaple/libmaple/gpioF2.c index fcd8c332..3a18217e 100644 --- a/Libmaple/libmaple/libmaple/gpioF2.c +++ b/Libmaple/libmaple/libmaple/gpioF2.c @@ -1,208 +1,208 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file gpio.c - * @brief GPIO initialization routine - */ - -#include "gpio.h" -#include "rcc.h" - -/* - * GPIO devices - */ - -gpio_dev gpioa = { - .regs = GPIOA_BASE, - .clk_id = RCC_GPIOA, - .exti_port = AFIO_EXTI_PA, -}; -/** GPIO port A device. */ -gpio_dev* const GPIOA = &gpioa; - -gpio_dev gpiob = { - .regs = GPIOB_BASE, - .clk_id = RCC_GPIOB, - .exti_port = AFIO_EXTI_PB, -}; -/** GPIO port B device. */ -gpio_dev* const GPIOB = &gpiob; - -gpio_dev gpioc = { - .regs = GPIOC_BASE, - .clk_id = RCC_GPIOC, - .exti_port = AFIO_EXTI_PC, -}; -/** GPIO port C device. */ -gpio_dev* const GPIOC = &gpioc; - -gpio_dev gpiod = { - .regs = GPIOD_BASE, - .clk_id = RCC_GPIOD, - .exti_port = AFIO_EXTI_PD, -}; -/** GPIO port D device. */ -gpio_dev* const GPIOD = &gpiod; - -#ifdef STM32_HIGH_DENSITY -gpio_dev gpioe = { - .regs = GPIOE_BASE, - .clk_id = RCC_GPIOE, - .exti_port = AFIO_EXTI_PE, -}; -/** GPIO port E device. */ -gpio_dev* const GPIOE = &gpioe; - -gpio_dev gpiof = { - .regs = GPIOF_BASE, - .clk_id = RCC_GPIOF, - .exti_port = AFIO_EXTI_PF, -}; -/** GPIO port F device. */ -gpio_dev* const GPIOF = &gpiof; - -gpio_dev gpiog = { - .regs = GPIOG_BASE, - .clk_id = RCC_GPIOG, - .exti_port = AFIO_EXTI_PG, -}; -/** GPIO port G device. */ -gpio_dev* const GPIOG = &gpiog; -#endif - -/* - * GPIO convenience routines - */ - -/** - * Initialize a GPIO device. - * - * Enables the clock for and resets the given device. - * - * @param dev GPIO device to initialize. - */ -void gpio_init(gpio_dev *dev) { - rcc_clk_enable(dev->clk_id); - rcc_reset_dev(dev->clk_id); -} - -/** - * Initialize and reset all available GPIO devices. - */ -void gpio_init_all(void) { - gpio_init(GPIOA); - gpio_init(GPIOB); - gpio_init(GPIOC); - gpio_init(GPIOD); - -#ifdef STM32_HIGH_DENSITY - gpio_init(GPIOE); - gpio_init(GPIOF); - gpio_init(GPIOG); -#endif -} - -/** - * Set the mode of a GPIO pin. - * - * @param dev GPIO device. - * @param pin Pin on the device whose mode to set, 0--15. - * @param mode General purpose or alternate function mode to set the pin to. - * @see gpio_pin_mode - */ -void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) { - gpio_reg_map *regs = dev->regs; - - //regs->AFR[pin/8] = (regs->AFR[pin/8] & ~(15 << (4*(pin&7)))) | (((mode >> 8) & 15) << (4*(pin&7))); - //gpio_set_af_mode(dev, pin, mode>>8); - - regs->MODER = (regs->MODER & ~( 3 << (2*pin))) | (((mode >> 0) & 3) << (2*pin)); - regs->PUPDR = (regs->PUPDR & ~( 3 << (2*pin))) | (((mode >> 2) & 3) << (2*pin)); - regs->OSPEEDR = (regs->OSPEEDR & ~( 3 << (2*pin))) | (((mode >> 4) & 3) << (2*pin)); - regs->OTYPER = (regs->OTYPER & ~( 1 << (1*pin))) | (((mode >> 6) & 1) << (1*pin)); -} - -/** - * Set the alternate function mode of a GPIO pin. - * - * @param dev GPIO device. - * @param pin Pin on the device whose mode to set, 0--15. - * @param mode alternate function mode to set the pin to. - * @see gpio_pin_mode - */ -void gpio_set_af_mode(gpio_dev *dev, uint8 pin, int mode) { - gpio_reg_map *regs = dev->regs; - - regs->AFR[pin/8] = (regs->AFR[pin/8] & ~(15 << (4*(pin&7)))) | (((mode >> 0) & 15) << (4*(pin&7))); -} - -/* - * AFIO - */ - -/** - * @brief Initialize the AFIO clock, and reset the AFIO registers. - */ -void afio_init(void) { - //rcc_clk_enable(RCC_AFIO); - //rcc_reset_dev(RCC_AFIO); -} - -#define AFIO_EXTI_SEL_MASK 0xF - -/** - * @brief Select a source input for an external interrupt. - * - * @param exti External interrupt. - * @param gpio_port Port which contains pin to use as source input. - * @see afio_exti_num - * @see afio_exti_port - */ -void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) { - __io uint32 *exti_cr = &SYSCFG_BASE->EXTICR1 + exti / 4; - uint32 shift = 4 * (exti % 4); - uint32 cr = *exti_cr; - - cr &= ~(AFIO_EXTI_SEL_MASK << shift); - cr |= gpio_port << shift; - *exti_cr = cr; -} - -/** - * @brief Perform an alternate function remap. - * @param remapping Remapping to perform. - */ -#if 0 -void afio_remap(afio_remap_peripheral remapping) { - if (remapping & AFIO_REMAP_USE_MAPR2) { - remapping &= ~AFIO_REMAP_USE_MAPR2; - AFIO_BASE->MAPR2 |= remapping; - } else { - AFIO_BASE->MAPR |= remapping; - } -} -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file gpio.c + * @brief GPIO initialization routine + */ + +#include "gpio.h" +#include "rcc.h" + +/* + * GPIO devices + */ + +gpio_dev gpioa = { + .regs = GPIOA_BASE, + .clk_id = RCC_GPIOA, + .exti_port = AFIO_EXTI_PA, +}; +/** GPIO port A device. */ +gpio_dev* const GPIOA = &gpioa; + +gpio_dev gpiob = { + .regs = GPIOB_BASE, + .clk_id = RCC_GPIOB, + .exti_port = AFIO_EXTI_PB, +}; +/** GPIO port B device. */ +gpio_dev* const GPIOB = &gpiob; + +gpio_dev gpioc = { + .regs = GPIOC_BASE, + .clk_id = RCC_GPIOC, + .exti_port = AFIO_EXTI_PC, +}; +/** GPIO port C device. */ +gpio_dev* const GPIOC = &gpioc; + +gpio_dev gpiod = { + .regs = GPIOD_BASE, + .clk_id = RCC_GPIOD, + .exti_port = AFIO_EXTI_PD, +}; +/** GPIO port D device. */ +gpio_dev* const GPIOD = &gpiod; + +#ifdef STM32_HIGH_DENSITY +gpio_dev gpioe = { + .regs = GPIOE_BASE, + .clk_id = RCC_GPIOE, + .exti_port = AFIO_EXTI_PE, +}; +/** GPIO port E device. */ +gpio_dev* const GPIOE = &gpioe; + +gpio_dev gpiof = { + .regs = GPIOF_BASE, + .clk_id = RCC_GPIOF, + .exti_port = AFIO_EXTI_PF, +}; +/** GPIO port F device. */ +gpio_dev* const GPIOF = &gpiof; + +gpio_dev gpiog = { + .regs = GPIOG_BASE, + .clk_id = RCC_GPIOG, + .exti_port = AFIO_EXTI_PG, +}; +/** GPIO port G device. */ +gpio_dev* const GPIOG = &gpiog; +#endif + +/* + * GPIO convenience routines + */ + +/** + * Initialize a GPIO device. + * + * Enables the clock for and resets the given device. + * + * @param dev GPIO device to initialize. + */ +void gpio_init(gpio_dev *dev) { + rcc_clk_enable(dev->clk_id); + rcc_reset_dev(dev->clk_id); +} + +/** + * Initialize and reset all available GPIO devices. + */ +void gpio_init_all(void) { + gpio_init(GPIOA); + gpio_init(GPIOB); + gpio_init(GPIOC); + gpio_init(GPIOD); + +#ifdef STM32_HIGH_DENSITY + gpio_init(GPIOE); + gpio_init(GPIOF); + gpio_init(GPIOG); +#endif +} + +/** + * Set the mode of a GPIO pin. + * + * @param dev GPIO device. + * @param pin Pin on the device whose mode to set, 0--15. + * @param mode General purpose or alternate function mode to set the pin to. + * @see gpio_pin_mode + */ +void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) { + gpio_reg_map *regs = dev->regs; + + //regs->AFR[pin/8] = (regs->AFR[pin/8] & ~(15 << (4*(pin&7)))) | (((mode >> 8) & 15) << (4*(pin&7))); + //gpio_set_af_mode(dev, pin, mode>>8); + + regs->MODER = (regs->MODER & ~( 3 << (2*pin))) | (((mode >> 0) & 3) << (2*pin)); + regs->PUPDR = (regs->PUPDR & ~( 3 << (2*pin))) | (((mode >> 2) & 3) << (2*pin)); + regs->OSPEEDR = (regs->OSPEEDR & ~( 3 << (2*pin))) | (((mode >> 4) & 3) << (2*pin)); + regs->OTYPER = (regs->OTYPER & ~( 1 << (1*pin))) | (((mode >> 6) & 1) << (1*pin)); +} + +/** + * Set the alternate function mode of a GPIO pin. + * + * @param dev GPIO device. + * @param pin Pin on the device whose mode to set, 0--15. + * @param mode alternate function mode to set the pin to. + * @see gpio_pin_mode + */ +void gpio_set_af_mode(gpio_dev *dev, uint8 pin, int mode) { + gpio_reg_map *regs = dev->regs; + + regs->AFR[pin/8] = (regs->AFR[pin/8] & ~(15 << (4*(pin&7)))) | (((mode >> 0) & 15) << (4*(pin&7))); +} + +/* + * AFIO + */ + +/** + * @brief Initialize the AFIO clock, and reset the AFIO registers. + */ +void afio_init(void) { + //rcc_clk_enable(RCC_AFIO); + //rcc_reset_dev(RCC_AFIO); +} + +#define AFIO_EXTI_SEL_MASK 0xF + +/** + * @brief Select a source input for an external interrupt. + * + * @param exti External interrupt. + * @param gpio_port Port which contains pin to use as source input. + * @see afio_exti_num + * @see afio_exti_port + */ +void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) { + __io uint32 *exti_cr = &SYSCFG_BASE->EXTICR1 + exti / 4; + uint32 shift = 4 * (exti % 4); + uint32 cr = *exti_cr; + + cr &= ~(AFIO_EXTI_SEL_MASK << shift); + cr |= gpio_port << shift; + *exti_cr = cr; +} + +/** + * @brief Perform an alternate function remap. + * @param remapping Remapping to perform. + */ +#if 0 +void afio_remap(afio_remap_peripheral remapping) { + if (remapping & AFIO_REMAP_USE_MAPR2) { + remapping &= ~AFIO_REMAP_USE_MAPR2; + AFIO_BASE->MAPR2 |= remapping; + } else { + AFIO_BASE->MAPR |= remapping; + } +} +#endif diff --git a/Libmaple/libmaple/libmaple/gpioF2.h b/Libmaple/libmaple/libmaple/gpioF2.h index 6f2a6841..91bd67be 100644 --- a/Libmaple/libmaple/libmaple/gpioF2.h +++ b/Libmaple/libmaple/libmaple/gpioF2.h @@ -1,550 +1,550 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*****************************************************************************/ - -/** - * @file gpio.h - * - * @brief General purpose I/O (GPIO) and Alternate Function I/O - * (AFIO) prototypes, defines, and inlined access functions. - */ - -#ifndef _GPIO_H_ -#define _GPIO_H_ - -#include "libmaple.h" -#include "rcc.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - * GPIO register maps and devices - */ - -/** GPIO register map type */ -typedef struct gpio_reg_map { - __io uint32 MODER; /*!< GPIO port mode register, Address offset: 0x00 */ - __io uint32 OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ - __io uint32 OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ - __io uint32 PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ - __io uint32 IDR; /*!< GPIO port input data register, Address offset: 0x10 */ - __io uint32 ODR; /*!< GPIO port output data register, Address offset: 0x14 */ - __io uint16 BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ - __io uint16 BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ - __io uint32 LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ - __io uint32 AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x24-0x28 */ -} gpio_reg_map; - - - -/** - * @brief External interrupt line port selector. - * - * Used to determine which GPIO port to map an external interrupt line - * onto. */ -/* (See AFIO sections, below) */ -typedef enum afio_exti_port { - AFIO_EXTI_PA, /**< Use port A (PAx) pin. */ - AFIO_EXTI_PB, /**< Use port B (PBx) pin. */ - AFIO_EXTI_PC, /**< Use port C (PCx) pin. */ - AFIO_EXTI_PD, /**< Use port D (PDx) pin. */ -#ifdef STM32_HIGH_DENSITY - AFIO_EXTI_PE, /**< Use port E (PEx) pin. */ - AFIO_EXTI_PF, /**< Use port F (PFx) pin. */ - AFIO_EXTI_PG, /**< Use port G (PGx) pin. */ -#endif -} afio_exti_port; - -/** GPIO device type */ -typedef struct gpio_dev { - gpio_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ - afio_exti_port exti_port; /**< AFIO external interrupt port value */ -} gpio_dev; - -extern gpio_dev gpioa; -extern gpio_dev* const GPIOA; -extern gpio_dev gpiob; -extern gpio_dev* const GPIOB; -extern gpio_dev gpioc; -extern gpio_dev* const GPIOC; -extern gpio_dev gpiod; -extern gpio_dev* const GPIOD; -#ifdef STM32_HIGH_DENSITY -extern gpio_dev gpioe; -extern gpio_dev* const GPIOE; -extern gpio_dev gpiof; -extern gpio_dev* const GPIOF; -extern gpio_dev gpiog; -extern gpio_dev* const GPIOG; -#endif - -/** GPIO port register map base pointer */ -#define GPIOA_BASE ((struct gpio_reg_map*)0x40020000) -#define GPIOB_BASE ((struct gpio_reg_map*)0x40020400) -#define GPIOC_BASE ((struct gpio_reg_map*)0x40020800) -#define GPIOD_BASE ((struct gpio_reg_map*)0x40020C00) -#ifdef STM32_HIGH_DENSITY -#define GPIOE_BASE ((struct gpio_reg_map*)0x40021000) -#define GPIOF_BASE ((struct gpio_reg_map*)0x40021400) -#define GPIOG_BASE ((struct gpio_reg_map*)0x40021800) -#endif - -/* - * GPIO register bit definitions - */ - -#define GPIO_MODE_INPUT 0 -#define GPIO_MODE_OUTPUT 1 -#define GPIO_MODE_AF 2 -#define GPIO_MODE_ANALOG 3 - -#define GPIO_PUPD_INPUT_FLOATING (0 << 2) -#define GPIO_PUPD_INPUT_PU (1 << 2) -#define GPIO_PUPD_INPUT_PD (2 << 2) - -#define GPIO_OSPEED_2MHZ (0 << 4) -#define GPIO_OSPEED_25MHZ (1 << 4) -#define GPIO_OSPEED_50MHZ (2 << 4) -#define GPIO_OSPEED_100MHZ (3 << 4) - -#define GPIO_OTYPE_PP (0 << 6) -#define GPIO_OTYPE_OD (1 << 6) - -/* -MODER -00: Input (reset state) -01: General purpose output mode -10: Alternate function mode -11: Analog mode - -OTYPER -0: Output push-pull (reset state) -1: Output open-drain - -OSPEEDR -00: 2 MHz Low speed -01: 25 MHz Medium speed -10: 50 MHz Fast speed -11: 100 MHz High speed on 30 pF (80 MHz Output max speed on 15 pF) - -PUPDR -00: No pull-up, pull-down -01: Pull-up -10: Pull-down - -AFRL 4 bit AF00-AF15 -AFRH 4 bit AF00-AF15 -*/ - -/** - * @brief GPIO Pin modes. - * - * These only allow for 50MHZ max output speeds; if you want slower, - * use direct register access. - */ -typedef enum gpio_pin_mode { - GPIO_OUTPUT_PP = (GPIO_MODE_OUTPUT | GPIO_OTYPE_PP | - GPIO_OSPEED_50MHZ), /**< Output push-pull. */ - GPIO_OUTPUT_OD = (GPIO_MODE_OUTPUT | GPIO_OTYPE_OD | - GPIO_OSPEED_50MHZ), /**< Output open-drain. */ - GPIO_AF_OUTPUT_PP = (GPIO_MODE_AF | GPIO_OTYPE_PP | - GPIO_OSPEED_50MHZ), /**< Alternate function - output push-pull. */ - GPIO_AF_OUTPUT_OD = (GPIO_MODE_AF | GPIO_OTYPE_OD | - GPIO_OSPEED_50MHZ), /**< Alternate function - output open drain. */ - GPIO_INPUT_ANALOG = (GPIO_MODE_ANALOG), /**< Analog input. */ - GPIO_INPUT_FLOATING = (GPIO_MODE_INPUT | - GPIO_PUPD_INPUT_FLOATING), /**< Input floating. */ - GPIO_INPUT_PD = (GPIO_MODE_INPUT | - GPIO_PUPD_INPUT_PD), /**< Input pull-down. */ - GPIO_INPUT_PU = (GPIO_MODE_INPUT | - GPIO_PUPD_INPUT_PU), /**< Input pull-up. */ - GPIO_AF_INPUT_PD = (GPIO_MODE_AF | - GPIO_PUPD_INPUT_PD), /**< Input pull-down. */ - GPIO_BIGNUMBER = 0xfff -} gpio_pin_mode; - -/* - * GPIO Convenience routines - */ - -void gpio_init(gpio_dev *dev); -void gpio_init_all(void); -void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode); -void gpio_set_af_mode(gpio_dev *dev, uint8 pin, int mode); - -/** - * @brief Get a GPIO port's corresponding afio_exti_port. - * @param dev GPIO device whose afio_exti_port to return. - */ -static inline afio_exti_port gpio_exti_port(gpio_dev *dev) { - return dev->exti_port; -} - -/** - * Set or reset a GPIO pin. - * - * Pin must have previously been configured to output mode. - * - * @param dev GPIO device whose pin to set. - * @param pin Pin on to set or reset - * @param val If true, set the pin. If false, reset the pin. - */ -static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) { - if (val) { - dev->regs->BSRRL = BIT(pin); - } else { - dev->regs->BSRRH = BIT(pin); - } -} - -/** - * Determine whether or not a GPIO pin is set. - * - * Pin must have previously been configured to input mode. - * - * @param dev GPIO device whose pin to test. - * @param pin Pin on dev to test. - * @return True if the pin is set, false otherwise. - */ -static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) { - return dev->regs->IDR & BIT(pin); -} - -/** - * Toggle a pin configured as output push-pull. - * @param dev GPIO device. - * @param pin Pin on dev to toggle. - */ -static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) { - dev->regs->ODR = dev->regs->ODR ^ BIT(pin); -} - -/* - * AFIO register map - */ - -/** AFIO register map */ -typedef struct syscfg_reg_map { - __io uint32 MEMRM; /**< memory remap register */ - __io uint32 PMC; /**< peripheral mode configuration register */ - __io uint32 EXTICR1; /**< External interrupt configuration register 1. */ - __io uint32 EXTICR2; /**< External interrupt configuration register 2. */ - __io uint32 EXTICR3; /**< External interrupt configuration register 3. */ - __io uint32 EXTICR4; /**< External interrupt configuration register 4. */ - __io uint32 CMPCR; /**< Compensation cell control register */ -} syscfg_reg_map; - -/** AFIO register map base pointer. */ -#define SYSCFG_BASE ((struct syscfg_reg_map *)0x40013800) - -/* - * AFIO register bit definitions - */ - -/* Event control register */ - -#define AFIO_EVCR_EVOE (0x1 << 7) -#define AFIO_EVCR_PORT_PA (0x0 << 4) -#define AFIO_EVCR_PORT_PB (0x1 << 4) -#define AFIO_EVCR_PORT_PC (0x2 << 4) -#define AFIO_EVCR_PORT_PD (0x3 << 4) -#define AFIO_EVCR_PORT_PE (0x4 << 4) -#define AFIO_EVCR_PIN_0 0x0 -#define AFIO_EVCR_PIN_1 0x1 -#define AFIO_EVCR_PIN_2 0x2 -#define AFIO_EVCR_PIN_3 0x3 -#define AFIO_EVCR_PIN_4 0x4 -#define AFIO_EVCR_PIN_5 0x5 -#define AFIO_EVCR_PIN_6 0x6 -#define AFIO_EVCR_PIN_7 0x7 -#define AFIO_EVCR_PIN_8 0x8 -#define AFIO_EVCR_PIN_9 0x9 -#define AFIO_EVCR_PIN_10 0xA -#define AFIO_EVCR_PIN_11 0xB -#define AFIO_EVCR_PIN_12 0xC -#define AFIO_EVCR_PIN_13 0xD -#define AFIO_EVCR_PIN_14 0xE -#define AFIO_EVCR_PIN_15 0xF - -/* AF remap and debug I/O configuration register */ - -#define AFIO_MAPR_SWJ_CFG (0x7 << 24) -#define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24) -#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24) -#define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW (0x2 << 24) -#define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW (0x4 << 24) -#define AFIO_MAPR_ADC2_ETRGREG_REMAP BIT(20) -#define AFIO_MAPR_ADC2_ETRGINJ_REMAP BIT(19) -#define AFIO_MAPR_ADC1_ETRGREG_REMAP BIT(18) -#define AFIO_MAPR_ADC1_ETRGINJ_REMAP BIT(17) -#define AFIO_MAPR_TIM5CH4_IREMAP BIT(16) -#define AFIO_MAPR_PD01_REMAP BIT(15) -#define AFIO_MAPR_CAN_REMAP (0x3 << 13) -#define AFIO_MAPR_CAN_REMAP_NONE (0x0 << 13) -#define AFIO_MAPR_CAN_REMAP_PB8_PB9 (0x2 << 13) -#define AFIO_MAPR_CAN_REMAP_PD0_PD1 (0x3 << 13) -#define AFIO_MAPR_TIM4_REMAP BIT(12) -#define AFIO_MAPR_TIM3_REMAP (0x3 << 10) -#define AFIO_MAPR_TIM3_REMAP_NONE (0x0 << 10) -#define AFIO_MAPR_TIM3_REMAP_PARTIAL (0x2 << 10) -#define AFIO_MAPR_TIM3_REMAP_FULL (0x3 << 10) -#define AFIO_MAPR_TIM2_REMAP (0x3 << 8) -#define AFIO_MAPR_TIM2_REMAP_NONE (0x0 << 8) -#define AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 (0x1 << 8) -#define AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11 (0x2 << 8) -#define AFIO_MAPR_TIM2_REMAP_FULL (0x3 << 8) -#define AFIO_MAPR_TIM1_REMAP (0x3 << 6) -#define AFIO_MAPR_TIM1_REMAP_NONE (0x0 << 6) -#define AFIO_MAPR_TIM1_REMAP_PARTIAL (0x1 << 6) -#define AFIO_MAPR_TIM1_REMAP_FULL (0x3 << 6) -#define AFIO_MAPR_USART3_REMAP (0x3 << 4) -#define AFIO_MAPR_USART3_REMAP_NONE (0x0 << 4) -#define AFIO_MAPR_USART3_REMAP_PARTIAL (0x1 << 4) -#define AFIO_MAPR_USART3_REMAP_FULL (0x3 << 4) -#define AFIO_MAPR_USART2_REMAP BIT(3) -#define AFIO_MAPR_USART1_REMAP BIT(2) -#define AFIO_MAPR_I2C1_REMAP BIT(1) -#define AFIO_MAPR_SPI1_REMAP BIT(0) - -/* External interrupt configuration register 1 */ - -#define AFIO_EXTICR1_EXTI3 (0xF << 12) -#define AFIO_EXTICR1_EXTI3_PA (0x0 << 12) -#define AFIO_EXTICR1_EXTI3_PB (0x1 << 12) -#define AFIO_EXTICR1_EXTI3_PC (0x2 << 12) -#define AFIO_EXTICR1_EXTI3_PD (0x3 << 12) -#define AFIO_EXTICR1_EXTI3_PE (0x4 << 12) -#define AFIO_EXTICR1_EXTI3_PF (0x5 << 12) -#define AFIO_EXTICR1_EXTI3_PG (0x6 << 12) -#define AFIO_EXTICR1_EXTI2 (0xF << 8) -#define AFIO_EXTICR1_EXTI2_PA (0x0 << 8) -#define AFIO_EXTICR1_EXTI2_PB (0x1 << 8) -#define AFIO_EXTICR1_EXTI2_PC (0x2 << 8) -#define AFIO_EXTICR1_EXTI2_PD (0x3 << 8) -#define AFIO_EXTICR1_EXTI2_PE (0x4 << 8) -#define AFIO_EXTICR1_EXTI2_PF (0x5 << 8) -#define AFIO_EXTICR1_EXTI2_PG (0x6 << 8) -#define AFIO_EXTICR1_EXTI1 (0xF << 4) -#define AFIO_EXTICR1_EXTI1_PA (0x0 << 4) -#define AFIO_EXTICR1_EXTI1_PB (0x1 << 4) -#define AFIO_EXTICR1_EXTI1_PC (0x2 << 4) -#define AFIO_EXTICR1_EXTI1_PD (0x3 << 4) -#define AFIO_EXTICR1_EXTI1_PE (0x4 << 4) -#define AFIO_EXTICR1_EXTI1_PF (0x5 << 4) -#define AFIO_EXTICR1_EXTI1_PG (0x6 << 4) -#define AFIO_EXTICR1_EXTI0 0xF -#define AFIO_EXTICR1_EXTI0_PA 0x0 -#define AFIO_EXTICR1_EXTI0_PB 0x1 -#define AFIO_EXTICR1_EXTI0_PC 0x2 -#define AFIO_EXTICR1_EXTI0_PD 0x3 -#define AFIO_EXTICR1_EXTI0_PE 0x4 -#define AFIO_EXTICR1_EXTI0_PF 0x5 -#define AFIO_EXTICR1_EXTI0_PG 0x6 - -/* External interrupt configuration register 2 */ - -#define AFIO_EXTICR2_EXTI7 (0xF << 12) -#define AFIO_EXTICR2_EXTI7_PA (0x0 << 12) -#define AFIO_EXTICR2_EXTI7_PB (0x1 << 12) -#define AFIO_EXTICR2_EXTI7_PC (0x2 << 12) -#define AFIO_EXTICR2_EXTI7_PD (0x3 << 12) -#define AFIO_EXTICR2_EXTI7_PE (0x4 << 12) -#define AFIO_EXTICR2_EXTI7_PF (0x5 << 12) -#define AFIO_EXTICR2_EXTI7_PG (0x6 << 12) -#define AFIO_EXTICR2_EXTI6 (0xF << 8) -#define AFIO_EXTICR2_EXTI6_PA (0x0 << 8) -#define AFIO_EXTICR2_EXTI6_PB (0x1 << 8) -#define AFIO_EXTICR2_EXTI6_PC (0x2 << 8) -#define AFIO_EXTICR2_EXTI6_PD (0x3 << 8) -#define AFIO_EXTICR2_EXTI6_PE (0x4 << 8) -#define AFIO_EXTICR2_EXTI6_PF (0x5 << 8) -#define AFIO_EXTICR2_EXTI6_PG (0x6 << 8) -#define AFIO_EXTICR2_EXTI5 (0xF << 4) -#define AFIO_EXTICR2_EXTI5_PA (0x0 << 4) -#define AFIO_EXTICR2_EXTI5_PB (0x1 << 4) -#define AFIO_EXTICR2_EXTI5_PC (0x2 << 4) -#define AFIO_EXTICR2_EXTI5_PD (0x3 << 4) -#define AFIO_EXTICR2_EXTI5_PE (0x4 << 4) -#define AFIO_EXTICR2_EXTI5_PF (0x5 << 4) -#define AFIO_EXTICR2_EXTI5_PG (0x6 << 4) -#define AFIO_EXTICR2_EXTI4 0xF -#define AFIO_EXTICR2_EXTI4_PA 0x0 -#define AFIO_EXTICR2_EXTI4_PB 0x1 -#define AFIO_EXTICR2_EXTI4_PC 0x2 -#define AFIO_EXTICR2_EXTI4_PD 0x3 -#define AFIO_EXTICR2_EXTI4_PE 0x4 -#define AFIO_EXTICR2_EXTI4_PF 0x5 -#define AFIO_EXTICR2_EXTI4_PG 0x6 - -/* AF remap and debug I/O configuration register 2 */ - -#define AFIO_MAPR2_FSMC_NADV BIT(10) -#define AFIO_MAPR2_TIM14_REMAP BIT(9) -#define AFIO_MAPR2_TIM13_REMAP BIT(8) -#define AFIO_MAPR2_TIM11_REMAP BIT(7) -#define AFIO_MAPR2_TIM10_REMAP BIT(6) -#define AFIO_MAPR2_TIM9_REMAP BIT(5) - -/* - * AFIO convenience routines - */ - -void afio_init(void); - -/** - * External interrupt line numbers. - */ -typedef enum afio_exti_num { - AFIO_EXTI_0, /**< External interrupt line 0. */ - AFIO_EXTI_1, /**< External interrupt line 1. */ - AFIO_EXTI_2, /**< External interrupt line 2. */ - AFIO_EXTI_3, /**< External interrupt line 3. */ - AFIO_EXTI_4, /**< External interrupt line 4. */ - AFIO_EXTI_5, /**< External interrupt line 5. */ - AFIO_EXTI_6, /**< External interrupt line 6. */ - AFIO_EXTI_7, /**< External interrupt line 7. */ - AFIO_EXTI_8, /**< External interrupt line 8. */ - AFIO_EXTI_9, /**< External interrupt line 9. */ - AFIO_EXTI_10, /**< External interrupt line 10. */ - AFIO_EXTI_11, /**< External interrupt line 11. */ - AFIO_EXTI_12, /**< External interrupt line 12. */ - AFIO_EXTI_13, /**< External interrupt line 13. */ - AFIO_EXTI_14, /**< External interrupt line 14. */ - AFIO_EXTI_15, /**< External interrupt line 15. */ -} afio_exti_num; - -void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port); - -/* HACK: Use upper bit to denote MAPR2, Bit 31 is reserved and - * not used in either MAPR or MAPR2 */ -#define AFIO_REMAP_USE_MAPR2 (1 << 31) - -/** - * @brief Available peripheral remaps. - * @see afio_remap() - */ -typedef enum afio_remap_peripheral { - AFIO_REMAP_ADC2_ETRGREG = AFIO_MAPR_ADC2_ETRGREG_REMAP, /**< - ADC 2 external trigger regular conversion remapping */ - AFIO_REMAP_ADC2_ETRGINJ = AFIO_MAPR_ADC2_ETRGINJ_REMAP, /**< - ADC 2 external trigger injected conversion remapping */ - AFIO_REMAP_ADC1_ETRGREG = AFIO_MAPR_ADC1_ETRGREG_REMAP, /**< - ADC 1 external trigger regular conversion remapping */ - AFIO_REMAP_ADC1_ETRGINJ = AFIO_MAPR_ADC1_ETRGINJ_REMAP, /**< - ADC 1 external trigger injected conversion remapping */ - AFIO_REMAP_TIM5CH4_I = AFIO_MAPR_TIM5CH4_IREMAP, /**< - Timer 5 channel 4 internal remapping */ - AFIO_REMAP_PD01 = AFIO_MAPR_PD01_REMAP, /**< - Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ - AFIO_REMAP_CAN_1 = AFIO_MAPR_CAN_REMAP_PB8_PB9, /**< - CAN alternate function remapping 1 (RX on PB8, TX on PB9) */ - AFIO_REMAP_CAN_2 = AFIO_MAPR_CAN_REMAP_PD0_PD1, /**< - CAN alternate function remapping 2 (RX on PD0, TX on PD1) */ - AFIO_REMAP_TIM4 = AFIO_MAPR_TIM4_REMAP, /**< - Timer 4 remapping */ - AFIO_REMAP_TIM3_PARTIAL = AFIO_MAPR_TIM3_REMAP_PARTIAL, /**< - Timer 3 partial remapping */ - AFIO_REMAP_TIM3_FULL = AFIO_MAPR_TIM3_REMAP_FULL, /**< - Timer 3 full remapping */ - AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3, /**< - Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3, CH3 - on PA2, CH4 on PA3) */ - AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11, /**< - Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1, CH3 - on PB10, CH4 on PB11) */ - AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL, /**< - Timer 2 full remapping */ - AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP, /**< - USART 2 remapping */ - AFIO_REMAP_USART1 = AFIO_MAPR_USART1_REMAP, /**< - USART 1 remapping */ - AFIO_REMAP_I2C1 = AFIO_MAPR_I2C1_REMAP, /**< - I2C 1 remapping */ - AFIO_REMAP_SPI1 = AFIO_MAPR_SPI1_REMAP, /**< - SPI 1 remapping */ - AFIO_REMAP_FSMC_NADV = (AFIO_MAPR2_FSMC_NADV | - AFIO_REMAP_USE_MAPR2), /**< - NADV signal not connected */ - AFIO_REMAP_TIM14 = (AFIO_MAPR2_TIM14_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 14 remapping */ - AFIO_REMAP_TIM13 = (AFIO_MAPR2_TIM13_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 13 remapping */ - AFIO_REMAP_TIM11 = (AFIO_MAPR2_TIM11_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 11 remapping */ - AFIO_REMAP_TIM10 = (AFIO_MAPR2_TIM10_REMAP | - AFIO_REMAP_USE_MAPR2), /**< - Timer 10 remapping */ - AFIO_REMAP_TIM9 = (AFIO_MAPR2_TIM9_REMAP | - AFIO_REMAP_USE_MAPR2) /**< - Timer 9 */ -} afio_remap_peripheral; - -void afio_remap(afio_remap_peripheral p); - -/** - * @brief Debug port configuration - * - * Used to configure the behavior of JTAG and Serial Wire (SW) debug - * ports and their associated GPIO pins. - * - * @see afio_cfg_debug_ports() - */ -typedef enum afio_debug_cfg { - AFIO_DEBUG_FULL_SWJ = AFIO_MAPR_SWJ_CFG_FULL_SWJ, /**< - Full Serial Wire and JTAG debug */ - AFIO_DEBUG_FULL_SWJ_NO_NJRST = AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST, /**< - Full Serial Wire and JTAG, but no NJTRST. */ - AFIO_DEBUG_SW_ONLY = AFIO_MAPR_SWJ_CFG_NO_JTAG_SW, /**< - Serial Wire debug only (JTAG-DP disabled, - SW-DP enabled) */ - AFIO_DEBUG_NONE = AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW /**< - No debug; all JTAG and SW pins are free - for use as GPIOs. */ -} afio_debug_cfg; - -/** - * @brief Enable or disable the JTAG and SW debug ports. - * @param config Desired debug port configuration - * @see afio_debug_cfg - */ -static inline void afio_cfg_debug_ports(afio_debug_cfg config) { - //__io uint32 *mapr = &AFIO_BASE->MAPR; - //*mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config; -} - -#ifdef __cplusplus -} -#endif - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*****************************************************************************/ + +/** + * @file gpio.h + * + * @brief General purpose I/O (GPIO) and Alternate Function I/O + * (AFIO) prototypes, defines, and inlined access functions. + */ + +#ifndef _GPIO_H_ +#define _GPIO_H_ + +#include "libmaple.h" +#include "rcc.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * GPIO register maps and devices + */ + +/** GPIO register map type */ +typedef struct gpio_reg_map { + __io uint32 MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __io uint32 OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __io uint32 OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __io uint32 PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __io uint32 IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __io uint32 ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __io uint16 BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ + __io uint16 BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ + __io uint32 LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __io uint32 AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x24-0x28 */ +} gpio_reg_map; + + + +/** + * @brief External interrupt line port selector. + * + * Used to determine which GPIO port to map an external interrupt line + * onto. */ +/* (See AFIO sections, below) */ +typedef enum afio_exti_port { + AFIO_EXTI_PA, /**< Use port A (PAx) pin. */ + AFIO_EXTI_PB, /**< Use port B (PBx) pin. */ + AFIO_EXTI_PC, /**< Use port C (PCx) pin. */ + AFIO_EXTI_PD, /**< Use port D (PDx) pin. */ +#ifdef STM32_HIGH_DENSITY + AFIO_EXTI_PE, /**< Use port E (PEx) pin. */ + AFIO_EXTI_PF, /**< Use port F (PFx) pin. */ + AFIO_EXTI_PG, /**< Use port G (PGx) pin. */ +#endif +} afio_exti_port; + +/** GPIO device type */ +typedef struct gpio_dev { + gpio_reg_map *regs; /**< Register map */ + rcc_clk_id clk_id; /**< RCC clock information */ + afio_exti_port exti_port; /**< AFIO external interrupt port value */ +} gpio_dev; + +extern gpio_dev gpioa; +extern gpio_dev* const GPIOA; +extern gpio_dev gpiob; +extern gpio_dev* const GPIOB; +extern gpio_dev gpioc; +extern gpio_dev* const GPIOC; +extern gpio_dev gpiod; +extern gpio_dev* const GPIOD; +#ifdef STM32_HIGH_DENSITY +extern gpio_dev gpioe; +extern gpio_dev* const GPIOE; +extern gpio_dev gpiof; +extern gpio_dev* const GPIOF; +extern gpio_dev gpiog; +extern gpio_dev* const GPIOG; +#endif + +/** GPIO port register map base pointer */ +#define GPIOA_BASE ((struct gpio_reg_map*)0x40020000) +#define GPIOB_BASE ((struct gpio_reg_map*)0x40020400) +#define GPIOC_BASE ((struct gpio_reg_map*)0x40020800) +#define GPIOD_BASE ((struct gpio_reg_map*)0x40020C00) +#ifdef STM32_HIGH_DENSITY +#define GPIOE_BASE ((struct gpio_reg_map*)0x40021000) +#define GPIOF_BASE ((struct gpio_reg_map*)0x40021400) +#define GPIOG_BASE ((struct gpio_reg_map*)0x40021800) +#endif + +/* + * GPIO register bit definitions + */ + +#define GPIO_MODE_INPUT 0 +#define GPIO_MODE_OUTPUT 1 +#define GPIO_MODE_AF 2 +#define GPIO_MODE_ANALOG 3 + +#define GPIO_PUPD_INPUT_FLOATING (0 << 2) +#define GPIO_PUPD_INPUT_PU (1 << 2) +#define GPIO_PUPD_INPUT_PD (2 << 2) + +#define GPIO_OSPEED_2MHZ (0 << 4) +#define GPIO_OSPEED_25MHZ (1 << 4) +#define GPIO_OSPEED_50MHZ (2 << 4) +#define GPIO_OSPEED_100MHZ (3 << 4) + +#define GPIO_OTYPE_PP (0 << 6) +#define GPIO_OTYPE_OD (1 << 6) + +/* +MODER +00: Input (reset state) +01: General purpose output mode +10: Alternate function mode +11: Analog mode + +OTYPER +0: Output push-pull (reset state) +1: Output open-drain + +OSPEEDR +00: 2 MHz Low speed +01: 25 MHz Medium speed +10: 50 MHz Fast speed +11: 100 MHz High speed on 30 pF (80 MHz Output max speed on 15 pF) + +PUPDR +00: No pull-up, pull-down +01: Pull-up +10: Pull-down + +AFRL 4 bit AF00-AF15 +AFRH 4 bit AF00-AF15 +*/ + +/** + * @brief GPIO Pin modes. + * + * These only allow for 50MHZ max output speeds; if you want slower, + * use direct register access. + */ +typedef enum gpio_pin_mode { + GPIO_OUTPUT_PP = (GPIO_MODE_OUTPUT | GPIO_OTYPE_PP | + GPIO_OSPEED_50MHZ), /**< Output push-pull. */ + GPIO_OUTPUT_OD = (GPIO_MODE_OUTPUT | GPIO_OTYPE_OD | + GPIO_OSPEED_50MHZ), /**< Output open-drain. */ + GPIO_AF_OUTPUT_PP = (GPIO_MODE_AF | GPIO_OTYPE_PP | + GPIO_OSPEED_50MHZ), /**< Alternate function + output push-pull. */ + GPIO_AF_OUTPUT_OD = (GPIO_MODE_AF | GPIO_OTYPE_OD | + GPIO_OSPEED_50MHZ), /**< Alternate function + output open drain. */ + GPIO_INPUT_ANALOG = (GPIO_MODE_ANALOG), /**< Analog input. */ + GPIO_INPUT_FLOATING = (GPIO_MODE_INPUT | + GPIO_PUPD_INPUT_FLOATING), /**< Input floating. */ + GPIO_INPUT_PD = (GPIO_MODE_INPUT | + GPIO_PUPD_INPUT_PD), /**< Input pull-down. */ + GPIO_INPUT_PU = (GPIO_MODE_INPUT | + GPIO_PUPD_INPUT_PU), /**< Input pull-up. */ + GPIO_AF_INPUT_PD = (GPIO_MODE_AF | + GPIO_PUPD_INPUT_PD), /**< Input pull-down. */ + GPIO_BIGNUMBER = 0xfff +} gpio_pin_mode; + +/* + * GPIO Convenience routines + */ + +void gpio_init(gpio_dev *dev); +void gpio_init_all(void); +void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode); +void gpio_set_af_mode(gpio_dev *dev, uint8 pin, int mode); + +/** + * @brief Get a GPIO port's corresponding afio_exti_port. + * @param dev GPIO device whose afio_exti_port to return. + */ +static inline afio_exti_port gpio_exti_port(gpio_dev *dev) { + return dev->exti_port; +} + +/** + * Set or reset a GPIO pin. + * + * Pin must have previously been configured to output mode. + * + * @param dev GPIO device whose pin to set. + * @param pin Pin on to set or reset + * @param val If true, set the pin. If false, reset the pin. + */ +static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) { + if (val) { + dev->regs->BSRRL = BIT(pin); + } else { + dev->regs->BSRRH = BIT(pin); + } +} + +/** + * Determine whether or not a GPIO pin is set. + * + * Pin must have previously been configured to input mode. + * + * @param dev GPIO device whose pin to test. + * @param pin Pin on dev to test. + * @return True if the pin is set, false otherwise. + */ +static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) { + return dev->regs->IDR & BIT(pin); +} + +/** + * Toggle a pin configured as output push-pull. + * @param dev GPIO device. + * @param pin Pin on dev to toggle. + */ +static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) { + dev->regs->ODR = dev->regs->ODR ^ BIT(pin); +} + +/* + * AFIO register map + */ + +/** AFIO register map */ +typedef struct syscfg_reg_map { + __io uint32 MEMRM; /**< memory remap register */ + __io uint32 PMC; /**< peripheral mode configuration register */ + __io uint32 EXTICR1; /**< External interrupt configuration register 1. */ + __io uint32 EXTICR2; /**< External interrupt configuration register 2. */ + __io uint32 EXTICR3; /**< External interrupt configuration register 3. */ + __io uint32 EXTICR4; /**< External interrupt configuration register 4. */ + __io uint32 CMPCR; /**< Compensation cell control register */ +} syscfg_reg_map; + +/** AFIO register map base pointer. */ +#define SYSCFG_BASE ((struct syscfg_reg_map *)0x40013800) + +/* + * AFIO register bit definitions + */ + +/* Event control register */ + +#define AFIO_EVCR_EVOE (0x1 << 7) +#define AFIO_EVCR_PORT_PA (0x0 << 4) +#define AFIO_EVCR_PORT_PB (0x1 << 4) +#define AFIO_EVCR_PORT_PC (0x2 << 4) +#define AFIO_EVCR_PORT_PD (0x3 << 4) +#define AFIO_EVCR_PORT_PE (0x4 << 4) +#define AFIO_EVCR_PIN_0 0x0 +#define AFIO_EVCR_PIN_1 0x1 +#define AFIO_EVCR_PIN_2 0x2 +#define AFIO_EVCR_PIN_3 0x3 +#define AFIO_EVCR_PIN_4 0x4 +#define AFIO_EVCR_PIN_5 0x5 +#define AFIO_EVCR_PIN_6 0x6 +#define AFIO_EVCR_PIN_7 0x7 +#define AFIO_EVCR_PIN_8 0x8 +#define AFIO_EVCR_PIN_9 0x9 +#define AFIO_EVCR_PIN_10 0xA +#define AFIO_EVCR_PIN_11 0xB +#define AFIO_EVCR_PIN_12 0xC +#define AFIO_EVCR_PIN_13 0xD +#define AFIO_EVCR_PIN_14 0xE +#define AFIO_EVCR_PIN_15 0xF + +/* AF remap and debug I/O configuration register */ + +#define AFIO_MAPR_SWJ_CFG (0x7 << 24) +#define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24) +#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24) +#define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW (0x2 << 24) +#define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW (0x4 << 24) +#define AFIO_MAPR_ADC2_ETRGREG_REMAP BIT(20) +#define AFIO_MAPR_ADC2_ETRGINJ_REMAP BIT(19) +#define AFIO_MAPR_ADC1_ETRGREG_REMAP BIT(18) +#define AFIO_MAPR_ADC1_ETRGINJ_REMAP BIT(17) +#define AFIO_MAPR_TIM5CH4_IREMAP BIT(16) +#define AFIO_MAPR_PD01_REMAP BIT(15) +#define AFIO_MAPR_CAN_REMAP (0x3 << 13) +#define AFIO_MAPR_CAN_REMAP_NONE (0x0 << 13) +#define AFIO_MAPR_CAN_REMAP_PB8_PB9 (0x2 << 13) +#define AFIO_MAPR_CAN_REMAP_PD0_PD1 (0x3 << 13) +#define AFIO_MAPR_TIM4_REMAP BIT(12) +#define AFIO_MAPR_TIM3_REMAP (0x3 << 10) +#define AFIO_MAPR_TIM3_REMAP_NONE (0x0 << 10) +#define AFIO_MAPR_TIM3_REMAP_PARTIAL (0x2 << 10) +#define AFIO_MAPR_TIM3_REMAP_FULL (0x3 << 10) +#define AFIO_MAPR_TIM2_REMAP (0x3 << 8) +#define AFIO_MAPR_TIM2_REMAP_NONE (0x0 << 8) +#define AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 (0x1 << 8) +#define AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11 (0x2 << 8) +#define AFIO_MAPR_TIM2_REMAP_FULL (0x3 << 8) +#define AFIO_MAPR_TIM1_REMAP (0x3 << 6) +#define AFIO_MAPR_TIM1_REMAP_NONE (0x0 << 6) +#define AFIO_MAPR_TIM1_REMAP_PARTIAL (0x1 << 6) +#define AFIO_MAPR_TIM1_REMAP_FULL (0x3 << 6) +#define AFIO_MAPR_USART3_REMAP (0x3 << 4) +#define AFIO_MAPR_USART3_REMAP_NONE (0x0 << 4) +#define AFIO_MAPR_USART3_REMAP_PARTIAL (0x1 << 4) +#define AFIO_MAPR_USART3_REMAP_FULL (0x3 << 4) +#define AFIO_MAPR_USART2_REMAP BIT(3) +#define AFIO_MAPR_USART1_REMAP BIT(2) +#define AFIO_MAPR_I2C1_REMAP BIT(1) +#define AFIO_MAPR_SPI1_REMAP BIT(0) + +/* External interrupt configuration register 1 */ + +#define AFIO_EXTICR1_EXTI3 (0xF << 12) +#define AFIO_EXTICR1_EXTI3_PA (0x0 << 12) +#define AFIO_EXTICR1_EXTI3_PB (0x1 << 12) +#define AFIO_EXTICR1_EXTI3_PC (0x2 << 12) +#define AFIO_EXTICR1_EXTI3_PD (0x3 << 12) +#define AFIO_EXTICR1_EXTI3_PE (0x4 << 12) +#define AFIO_EXTICR1_EXTI3_PF (0x5 << 12) +#define AFIO_EXTICR1_EXTI3_PG (0x6 << 12) +#define AFIO_EXTICR1_EXTI2 (0xF << 8) +#define AFIO_EXTICR1_EXTI2_PA (0x0 << 8) +#define AFIO_EXTICR1_EXTI2_PB (0x1 << 8) +#define AFIO_EXTICR1_EXTI2_PC (0x2 << 8) +#define AFIO_EXTICR1_EXTI2_PD (0x3 << 8) +#define AFIO_EXTICR1_EXTI2_PE (0x4 << 8) +#define AFIO_EXTICR1_EXTI2_PF (0x5 << 8) +#define AFIO_EXTICR1_EXTI2_PG (0x6 << 8) +#define AFIO_EXTICR1_EXTI1 (0xF << 4) +#define AFIO_EXTICR1_EXTI1_PA (0x0 << 4) +#define AFIO_EXTICR1_EXTI1_PB (0x1 << 4) +#define AFIO_EXTICR1_EXTI1_PC (0x2 << 4) +#define AFIO_EXTICR1_EXTI1_PD (0x3 << 4) +#define AFIO_EXTICR1_EXTI1_PE (0x4 << 4) +#define AFIO_EXTICR1_EXTI1_PF (0x5 << 4) +#define AFIO_EXTICR1_EXTI1_PG (0x6 << 4) +#define AFIO_EXTICR1_EXTI0 0xF +#define AFIO_EXTICR1_EXTI0_PA 0x0 +#define AFIO_EXTICR1_EXTI0_PB 0x1 +#define AFIO_EXTICR1_EXTI0_PC 0x2 +#define AFIO_EXTICR1_EXTI0_PD 0x3 +#define AFIO_EXTICR1_EXTI0_PE 0x4 +#define AFIO_EXTICR1_EXTI0_PF 0x5 +#define AFIO_EXTICR1_EXTI0_PG 0x6 + +/* External interrupt configuration register 2 */ + +#define AFIO_EXTICR2_EXTI7 (0xF << 12) +#define AFIO_EXTICR2_EXTI7_PA (0x0 << 12) +#define AFIO_EXTICR2_EXTI7_PB (0x1 << 12) +#define AFIO_EXTICR2_EXTI7_PC (0x2 << 12) +#define AFIO_EXTICR2_EXTI7_PD (0x3 << 12) +#define AFIO_EXTICR2_EXTI7_PE (0x4 << 12) +#define AFIO_EXTICR2_EXTI7_PF (0x5 << 12) +#define AFIO_EXTICR2_EXTI7_PG (0x6 << 12) +#define AFIO_EXTICR2_EXTI6 (0xF << 8) +#define AFIO_EXTICR2_EXTI6_PA (0x0 << 8) +#define AFIO_EXTICR2_EXTI6_PB (0x1 << 8) +#define AFIO_EXTICR2_EXTI6_PC (0x2 << 8) +#define AFIO_EXTICR2_EXTI6_PD (0x3 << 8) +#define AFIO_EXTICR2_EXTI6_PE (0x4 << 8) +#define AFIO_EXTICR2_EXTI6_PF (0x5 << 8) +#define AFIO_EXTICR2_EXTI6_PG (0x6 << 8) +#define AFIO_EXTICR2_EXTI5 (0xF << 4) +#define AFIO_EXTICR2_EXTI5_PA (0x0 << 4) +#define AFIO_EXTICR2_EXTI5_PB (0x1 << 4) +#define AFIO_EXTICR2_EXTI5_PC (0x2 << 4) +#define AFIO_EXTICR2_EXTI5_PD (0x3 << 4) +#define AFIO_EXTICR2_EXTI5_PE (0x4 << 4) +#define AFIO_EXTICR2_EXTI5_PF (0x5 << 4) +#define AFIO_EXTICR2_EXTI5_PG (0x6 << 4) +#define AFIO_EXTICR2_EXTI4 0xF +#define AFIO_EXTICR2_EXTI4_PA 0x0 +#define AFIO_EXTICR2_EXTI4_PB 0x1 +#define AFIO_EXTICR2_EXTI4_PC 0x2 +#define AFIO_EXTICR2_EXTI4_PD 0x3 +#define AFIO_EXTICR2_EXTI4_PE 0x4 +#define AFIO_EXTICR2_EXTI4_PF 0x5 +#define AFIO_EXTICR2_EXTI4_PG 0x6 + +/* AF remap and debug I/O configuration register 2 */ + +#define AFIO_MAPR2_FSMC_NADV BIT(10) +#define AFIO_MAPR2_TIM14_REMAP BIT(9) +#define AFIO_MAPR2_TIM13_REMAP BIT(8) +#define AFIO_MAPR2_TIM11_REMAP BIT(7) +#define AFIO_MAPR2_TIM10_REMAP BIT(6) +#define AFIO_MAPR2_TIM9_REMAP BIT(5) + +/* + * AFIO convenience routines + */ + +void afio_init(void); + +/** + * External interrupt line numbers. + */ +typedef enum afio_exti_num { + AFIO_EXTI_0, /**< External interrupt line 0. */ + AFIO_EXTI_1, /**< External interrupt line 1. */ + AFIO_EXTI_2, /**< External interrupt line 2. */ + AFIO_EXTI_3, /**< External interrupt line 3. */ + AFIO_EXTI_4, /**< External interrupt line 4. */ + AFIO_EXTI_5, /**< External interrupt line 5. */ + AFIO_EXTI_6, /**< External interrupt line 6. */ + AFIO_EXTI_7, /**< External interrupt line 7. */ + AFIO_EXTI_8, /**< External interrupt line 8. */ + AFIO_EXTI_9, /**< External interrupt line 9. */ + AFIO_EXTI_10, /**< External interrupt line 10. */ + AFIO_EXTI_11, /**< External interrupt line 11. */ + AFIO_EXTI_12, /**< External interrupt line 12. */ + AFIO_EXTI_13, /**< External interrupt line 13. */ + AFIO_EXTI_14, /**< External interrupt line 14. */ + AFIO_EXTI_15, /**< External interrupt line 15. */ +} afio_exti_num; + +void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port); + +/* HACK: Use upper bit to denote MAPR2, Bit 31 is reserved and + * not used in either MAPR or MAPR2 */ +#define AFIO_REMAP_USE_MAPR2 (1 << 31) + +/** + * @brief Available peripheral remaps. + * @see afio_remap() + */ +typedef enum afio_remap_peripheral { + AFIO_REMAP_ADC2_ETRGREG = AFIO_MAPR_ADC2_ETRGREG_REMAP, /**< + ADC 2 external trigger regular conversion remapping */ + AFIO_REMAP_ADC2_ETRGINJ = AFIO_MAPR_ADC2_ETRGINJ_REMAP, /**< + ADC 2 external trigger injected conversion remapping */ + AFIO_REMAP_ADC1_ETRGREG = AFIO_MAPR_ADC1_ETRGREG_REMAP, /**< + ADC 1 external trigger regular conversion remapping */ + AFIO_REMAP_ADC1_ETRGINJ = AFIO_MAPR_ADC1_ETRGINJ_REMAP, /**< + ADC 1 external trigger injected conversion remapping */ + AFIO_REMAP_TIM5CH4_I = AFIO_MAPR_TIM5CH4_IREMAP, /**< + Timer 5 channel 4 internal remapping */ + AFIO_REMAP_PD01 = AFIO_MAPR_PD01_REMAP, /**< + Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ + AFIO_REMAP_CAN_1 = AFIO_MAPR_CAN_REMAP_PB8_PB9, /**< + CAN alternate function remapping 1 (RX on PB8, TX on PB9) */ + AFIO_REMAP_CAN_2 = AFIO_MAPR_CAN_REMAP_PD0_PD1, /**< + CAN alternate function remapping 2 (RX on PD0, TX on PD1) */ + AFIO_REMAP_TIM4 = AFIO_MAPR_TIM4_REMAP, /**< + Timer 4 remapping */ + AFIO_REMAP_TIM3_PARTIAL = AFIO_MAPR_TIM3_REMAP_PARTIAL, /**< + Timer 3 partial remapping */ + AFIO_REMAP_TIM3_FULL = AFIO_MAPR_TIM3_REMAP_FULL, /**< + Timer 3 full remapping */ + AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3, /**< + Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3, CH3 + on PA2, CH4 on PA3) */ + AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11, /**< + Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1, CH3 + on PB10, CH4 on PB11) */ + AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL, /**< + Timer 2 full remapping */ + AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP, /**< + USART 2 remapping */ + AFIO_REMAP_USART1 = AFIO_MAPR_USART1_REMAP, /**< + USART 1 remapping */ + AFIO_REMAP_I2C1 = AFIO_MAPR_I2C1_REMAP, /**< + I2C 1 remapping */ + AFIO_REMAP_SPI1 = AFIO_MAPR_SPI1_REMAP, /**< + SPI 1 remapping */ + AFIO_REMAP_FSMC_NADV = (AFIO_MAPR2_FSMC_NADV | + AFIO_REMAP_USE_MAPR2), /**< + NADV signal not connected */ + AFIO_REMAP_TIM14 = (AFIO_MAPR2_TIM14_REMAP | + AFIO_REMAP_USE_MAPR2), /**< + Timer 14 remapping */ + AFIO_REMAP_TIM13 = (AFIO_MAPR2_TIM13_REMAP | + AFIO_REMAP_USE_MAPR2), /**< + Timer 13 remapping */ + AFIO_REMAP_TIM11 = (AFIO_MAPR2_TIM11_REMAP | + AFIO_REMAP_USE_MAPR2), /**< + Timer 11 remapping */ + AFIO_REMAP_TIM10 = (AFIO_MAPR2_TIM10_REMAP | + AFIO_REMAP_USE_MAPR2), /**< + Timer 10 remapping */ + AFIO_REMAP_TIM9 = (AFIO_MAPR2_TIM9_REMAP | + AFIO_REMAP_USE_MAPR2) /**< + Timer 9 */ +} afio_remap_peripheral; + +void afio_remap(afio_remap_peripheral p); + +/** + * @brief Debug port configuration + * + * Used to configure the behavior of JTAG and Serial Wire (SW) debug + * ports and their associated GPIO pins. + * + * @see afio_cfg_debug_ports() + */ +typedef enum afio_debug_cfg { + AFIO_DEBUG_FULL_SWJ = AFIO_MAPR_SWJ_CFG_FULL_SWJ, /**< + Full Serial Wire and JTAG debug */ + AFIO_DEBUG_FULL_SWJ_NO_NJRST = AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST, /**< + Full Serial Wire and JTAG, but no NJTRST. */ + AFIO_DEBUG_SW_ONLY = AFIO_MAPR_SWJ_CFG_NO_JTAG_SW, /**< + Serial Wire debug only (JTAG-DP disabled, + SW-DP enabled) */ + AFIO_DEBUG_NONE = AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW /**< + No debug; all JTAG and SW pins are free + for use as GPIOs. */ +} afio_debug_cfg; + +/** + * @brief Enable or disable the JTAG and SW debug ports. + * @param config Desired debug port configuration + * @see afio_debug_cfg + */ +static inline void afio_cfg_debug_ports(afio_debug_cfg config) { + //__io uint32 *mapr = &AFIO_BASE->MAPR; + //*mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config; +} + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Libmaple/libmaple/libmaple/i2c.c b/Libmaple/libmaple/libmaple/i2c.c index 336c9e3e..e3f3199b 100644 --- a/Libmaple/libmaple/libmaple/i2c.c +++ b/Libmaple/libmaple/libmaple/i2c.c @@ -1,565 +1,565 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file i2c.c - * @brief Inter-Integrated Circuit (I2C) support. - * - * Currently, only master mode is supported. - */ - -#include "libmaple.h" -#include "rcc.h" -#include "gpio.h" -#include "nvic.h" -#include "i2c.h" -#include "string.h" -#include "systick.h" - -static i2c_dev i2c_dev1 = { - .regs = I2C1_BASE, - .gpio_port = &gpiob, - .sda_pin = 7, - .scl_pin = 6, - .clk_id = RCC_I2C1, - .ev_nvic_line = NVIC_I2C1_EV, - .er_nvic_line = NVIC_I2C1_ER, - .state = I2C_STATE_DISABLED -}; -/** I2C1 device */ -i2c_dev* const I2C1 = &i2c_dev1; - -static i2c_dev i2c_dev2 = { - .regs = I2C2_BASE, - .gpio_port = &gpiob, - .sda_pin = 11, - .scl_pin = 10, - .clk_id = RCC_I2C2, - .ev_nvic_line = NVIC_I2C2_EV, - .er_nvic_line = NVIC_I2C2_ER, - .state = I2C_STATE_DISABLED -}; -/** I2C2 device */ -i2c_dev* const I2C2 = &i2c_dev2; - -static inline int32 wait_for_state_change(i2c_dev *dev, - i2c_state state, - uint32 timeout); - -/** - * @brief Fill data register with slave address - * @param dev I2C device - * @param addr Slave address - * @param rw Read/write bit - */ -static inline void i2c_send_slave_addr(i2c_dev *dev, uint32 addr, uint32 rw) { - dev->regs->DR = (addr << 1) | rw; -} - -/* - * Simple debugging trail. Define I2C_DEBUG to turn on. - */ -#ifdef I2C_DEBUG - -#define NR_CRUMBS 128 -static struct crumb crumbs[NR_CRUMBS]; -static uint32 cur_crumb = 0; - -static inline void i2c_drop_crumb(uint32 event, uint32 arg0, uint32 arg1) { - if (cur_crumb < NR_CRUMBS) { - struct crumb *crumb = &crumbs[cur_crumb++]; - crumb->event = event; - crumb->arg0 = arg0; - crumb->arg1 = arg1; - } -} -#define I2C_CRUMB(event, arg0, arg1) i2c_drop_crumb(event, arg0, arg1) - -#else -#define I2C_CRUMB(event, arg0, arg1) -#endif - -struct crumb { - uint32 event; - uint32 arg0; - uint32 arg1; -}; - -enum { - IRQ_ENTRY = 1, - TXE_ONLY = 2, - TXE_BTF = 3, - STOP_SENT = 4, - TEST = 5, - RX_ADDR_START = 6, - RX_ADDR_STOP = 7, - RXNE_ONLY = 8, - RXNE_SENDING = 9, - RXNE_START_SENT = 10, - RXNE_STOP_SENT = 11, - RXNE_DONE = 12, - ERROR_ENTRY = 13, -}; - -/** - * @brief IRQ handler for I2C master. Handles transmission/reception. - * @param dev I2C device - */ -static void i2c_irq_handler(i2c_dev *dev) { - i2c_msg *msg = dev->msg; - - uint8 read = msg->flags & I2C_MSG_READ; - - uint32 sr1 = dev->regs->SR1; - uint32 sr2 = dev->regs->SR2; - I2C_CRUMB(IRQ_ENTRY, sr1, sr2); - - /* - * Reset timeout counter - */ - dev->timestamp = systick_uptime(); - - /* - * EV5: Start condition sent - */ - if (sr1 & I2C_SR1_SB) { - msg->xferred = 0; - i2c_enable_irq(dev, I2C_IRQ_BUFFER); - - /* - * Master receiver - */ - if (read) { - i2c_enable_ack(dev); - } - - i2c_send_slave_addr(dev, msg->addr, read); - sr1 = sr2 = 0; - } - - /* - * EV6: Slave address sent - */ - if (sr1 & I2C_SR1_ADDR) { - /* - * Special case event EV6_1 for master receiver. - * Generate NACK and restart/stop condition after ADDR - * is cleared. - */ - if (read) { - if (msg->length == 1) { - i2c_disable_ack(dev); - if (dev->msgs_left > 1) { - i2c_start_condition(dev); - I2C_CRUMB(RX_ADDR_START, 0, 0); - } else { - i2c_stop_condition(dev); - I2C_CRUMB(RX_ADDR_STOP, 0, 0); - } - } - } else { - /* - * Master transmitter: write first byte to fill shift - * register. We should get another TXE interrupt - * immediately to fill DR again. - */ - if (msg->length != 1) { - i2c_write(dev, msg->data[msg->xferred++]); - } - } - sr1 = sr2 = 0; - } - - /* - * EV8: Master transmitter - * Transmit buffer empty, but we haven't finished transmitting the last - * byte written. - */ - if ((sr1 & I2C_SR1_TXE) && !(sr1 & I2C_SR1_BTF)) { - I2C_CRUMB(TXE_ONLY, 0, 0); - if (dev->msgs_left) { - i2c_write(dev, msg->data[msg->xferred++]); - if (msg->xferred == msg->length) { - /* - * End of this message. Turn off TXE/RXNE and wait for - * BTF to send repeated start or stop condition. - */ - i2c_disable_irq(dev, I2C_IRQ_BUFFER); - dev->msgs_left--; - } - } else { - /* - * This should be impossible... - */ - throb(); - } - sr1 = sr2 = 0; - } - - /* - * EV8_2: Master transmitter - * Last byte sent, program repeated start/stop - */ - if ((sr1 & I2C_SR1_TXE) && (sr1 & I2C_SR1_BTF)) { - I2C_CRUMB(TXE_BTF, 0, 0); - if (dev->msgs_left) { - I2C_CRUMB(TEST, 0, 0); - /* - * Repeated start insanity: We can't disable ITEVTEN or else SB - * won't interrupt, but if we don't disable ITEVTEN, BTF will - * continually interrupt us. What the fuck ST? - */ - i2c_start_condition(dev); - while (!(dev->regs->SR1 & I2C_SR1_SB)) - ; - dev->msg++; - } else { - i2c_stop_condition(dev); - - /* - * Turn off event interrupts to keep BTF from firing until - * the end of the stop condition. Why on earth they didn't - * have a start/stop condition request clear BTF is beyond - * me. - */ - i2c_disable_irq(dev, I2C_IRQ_EVENT); - I2C_CRUMB(STOP_SENT, 0, 0); - dev->state = I2C_STATE_XFER_DONE; - } - sr1 = sr2 = 0; - } - - /* - * EV7: Master Receiver - */ - if (sr1 & I2C_SR1_RXNE) { - I2C_CRUMB(RXNE_ONLY, 0, 0); - msg->data[msg->xferred++] = dev->regs->DR; - - /* - * EV7_1: Second to last byte in the reception? Set NACK and generate - * stop/restart condition in time for the last byte. We'll get one more - * RXNE interrupt before shutting things down. - */ - if (msg->xferred == (msg->length - 1)) { - i2c_disable_ack(dev); - if (dev->msgs_left > 2) { - i2c_start_condition(dev); - I2C_CRUMB(RXNE_START_SENT, 0, 0); - } else { - i2c_stop_condition(dev); - I2C_CRUMB(RXNE_STOP_SENT, 0, 0); - } - } else if (msg->xferred == msg->length) { - dev->msgs_left--; - if (dev->msgs_left == 0) { - /* - * We're done. - */ - I2C_CRUMB(RXNE_DONE, 0, 0); - dev->state = I2C_STATE_XFER_DONE; - } else { - dev->msg++; - } - } - } -} - -void __irq_i2c1_ev(void) { - i2c_irq_handler(&i2c_dev1); -} - -void __irq_i2c2_ev(void) { - i2c_irq_handler(&i2c_dev2); -} - -/** - * @brief Interrupt handler for I2C error conditions - * @param dev I2C device - * @sideeffect Aborts any pending I2C transactions - */ -static void i2c_irq_error_handler(i2c_dev *dev) { - I2C_CRUMB(ERROR_ENTRY, dev->regs->SR1, dev->regs->SR2); - - dev->error_flags = dev->regs->SR2 & (I2C_SR1_BERR | - I2C_SR1_ARLO | - I2C_SR1_AF | - I2C_SR1_OVR); - /* Clear flags */ - dev->regs->SR1 = 0; - dev->regs->SR2 = 0; - - i2c_stop_condition(dev); - i2c_disable_irq(dev, I2C_IRQ_BUFFER | I2C_IRQ_EVENT | I2C_IRQ_ERROR); - dev->state = I2C_STATE_ERROR; -} - -void __irq_i2c1_er(void) { - i2c_irq_error_handler(&i2c_dev1); -} - -void __irq_i2c2_er(void) { - i2c_irq_error_handler(&i2c_dev2); -} - -/** - * @brief Reset an I2C bus. - * - * Reset is accomplished by clocking out pulses until any hung slaves - * release SDA and SCL, then generating a START condition, then a STOP - * condition. - * - * @param dev I2C device - */ -void i2c_bus_reset(const i2c_dev *dev) { - /* Release both lines */ - gpio_write_bit(dev->gpio_port, dev->scl_pin, 1); - gpio_write_bit(dev->gpio_port, dev->sda_pin, 1); - gpio_set_mode(dev->gpio_port, dev->scl_pin, GPIO_OUTPUT_OD); - gpio_set_mode(dev->gpio_port, dev->sda_pin, GPIO_OUTPUT_OD); - - /* - * Make sure the bus is free by clocking it until any slaves release the - * bus. - */ - while (!gpio_read_bit(dev->gpio_port, dev->sda_pin)) { - /* Wait for any clock stretching to finish */ - while (!gpio_read_bit(dev->gpio_port, dev->scl_pin)) - ; - delay_us(10); - - /* Pull low */ - gpio_write_bit(dev->gpio_port, dev->scl_pin, 0); - delay_us(10); - - /* Release high again */ - gpio_write_bit(dev->gpio_port, dev->scl_pin, 1); - delay_us(10); - } - - /* Generate start then stop condition */ - gpio_write_bit(dev->gpio_port, dev->sda_pin, 0); - delay_us(10); - gpio_write_bit(dev->gpio_port, dev->scl_pin, 0); - delay_us(10); - gpio_write_bit(dev->gpio_port, dev->scl_pin, 1); - delay_us(10); - gpio_write_bit(dev->gpio_port, dev->sda_pin, 1); -} - -/** - * @brief Initialize an I2C device and reset its registers to their - * default values. - * @param dev Device to initialize. - */ -void i2c_init(i2c_dev *dev) { - rcc_reset_dev(dev->clk_id); - rcc_clk_enable(dev->clk_id); -} - -/** - * @brief Initialize an I2C device as bus master - * @param dev Device to enable - * @param flags Bitwise or of the following I2C options: - * I2C_FAST_MODE: 400 khz operation, - * I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for - * fast mode), - * I2C_BUS_RESET: Reset the bus and clock out any hung slaves on - * initialization, - * I2C_10BIT_ADDRESSING: Enable 10-bit addressing, - * I2C_REMAP: Remap I2C1 to SCL/PB8 SDA/PB9. - */ -void i2c_master_enable(i2c_dev *dev, uint32 flags) { -#define I2C_CLK (STM32_PCLK1/1000000) - uint32 ccr = 0; - uint32 trise = 0; - - /* PE must be disabled to configure the device */ - ASSERT(!(dev->regs->CR1 & I2C_CR1_PE)); - - if ((dev == I2C1) && (flags & I2C_REMAP)) { - afio_remap(AFIO_REMAP_I2C1); - I2C1->sda_pin = 9; - I2C1->scl_pin = 8; - } - - /* Reset the bus. Clock out any hung slaves. */ - if (flags & I2C_BUS_RESET) { - i2c_bus_reset(dev); - } - - /* Turn on clock and set GPIO modes */ - i2c_init(dev); - gpio_set_mode(dev->gpio_port, dev->sda_pin, GPIO_AF_OUTPUT_OD); - gpio_set_mode(dev->gpio_port, dev->scl_pin, GPIO_AF_OUTPUT_OD); - - /* I2C1 and I2C2 are fed from APB1, clocked at 36MHz */ - i2c_set_input_clk(dev, I2C_CLK); - - if (flags & I2C_FAST_MODE) { - ccr |= I2C_CCR_FS; - - if (flags & I2C_DUTY_16_9) { - /* Tlow/Thigh = 16/9 */ - ccr |= I2C_CCR_DUTY; - ccr |= STM32_PCLK1/(400000 * 25); - } else { - /* Tlow/Thigh = 2 */ - ccr |= STM32_PCLK1/(400000 * 3); - } - - trise = (300 * (I2C_CLK)/1000) + 1; - } else { - /* Tlow/Thigh = 1 */ - ccr = STM32_PCLK1/(100000 * 2); - trise = I2C_CLK + 1; - } - - /* Set minimum required value if CCR < 1*/ - if ((ccr & I2C_CCR_CCR) == 0) { - ccr |= 0x1; - } - - i2c_set_clk_control(dev, ccr); - i2c_set_trise(dev, trise); - - /* Enable event and buffer interrupts */ - nvic_irq_enable(dev->ev_nvic_line); - nvic_irq_enable(dev->er_nvic_line); - i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_BUFFER | I2C_IRQ_ERROR); - - /* - * Important STM32 Errata: - * - * See STM32F10xx8 and STM32F10xxB Errata sheet (Doc ID 14574 Rev 8), - * Section 2.11.1, 2.11.2. - * - * 2.11.1: - * When the EV7, EV7_1, EV6_1, EV6_3, EV2, EV8, and EV3 events are not - * managed before the current byte is being transferred, problems may be - * encountered such as receiving an extra byte, reading the same data twice - * or missing data. - * - * 2.11.2: - * In Master Receiver mode, when closing the communication using - * method 2, the content of the last read data can be corrupted. - * - * If the user software is not able to read the data N-1 before the STOP - * condition is generated on the bus, the content of the shift register - * (data N) will be corrupted. (data N is shifted 1-bit to the left). - * - * ---------------------------------------------------------------------- - * - * In order to ensure that events are not missed, the i2c interrupt must - * not be preempted. We set the i2c interrupt priority to be the highest - * interrupt in the system (priority level 0). All other interrupts have - * been initialized to priority level 16. See nvic_init(). - */ - nvic_irq_set_priority(dev->ev_nvic_line, 0); - nvic_irq_set_priority(dev->er_nvic_line, 0); - - /* Make it go! */ - i2c_peripheral_enable(dev); - - dev->state = I2C_STATE_IDLE; -} - - -/** - * @brief Process an i2c transaction. - * - * Transactions are composed of one or more i2c_msg's, and may be read - * or write tranfers. Multiple i2c_msg's will generate a repeated - * start in between messages. - * - * @param dev I2C device - * @param msgs Messages to send/receive - * @param num Number of messages to send/receive - * @param timeout Bus idle timeout in milliseconds before aborting the - * transfer. 0 denotes no timeout. - * @return 0 on success, - * I2C_ERROR_PROTOCOL if there was a protocol error, - * I2C_ERROR_TIMEOUT if the transfer timed out. - */ -int32 i2c_master_xfer(i2c_dev *dev, - i2c_msg *msgs, - uint16 num, - uint32 timeout) { - int32 rc; - - ASSERT(dev->state == I2C_STATE_IDLE); - - dev->msg = msgs; - dev->msgs_left = num; - dev->timestamp = systick_uptime(); - dev->state = I2C_STATE_BUSY; - - i2c_enable_irq(dev, I2C_IRQ_EVENT); - i2c_start_condition(dev); - - rc = wait_for_state_change(dev, I2C_STATE_XFER_DONE, timeout); - if (rc < 0) { - goto out; - } - - dev->state = I2C_STATE_IDLE; -out: - return rc; -} - - -/** - * @brief Wait for an I2C event, or time out in case of error. - * @param dev I2C device - * @param state I2C_state state to wait for - * @param timeout Timeout, in milliseconds - * @return 0 if target state is reached, a negative value on error. - */ -static inline int32 wait_for_state_change(i2c_dev *dev, - i2c_state state, - uint32 timeout) { - i2c_state tmp; - - while (1) { - tmp = dev->state; - - if (tmp == I2C_STATE_ERROR) { - return I2C_STATE_ERROR; - } - - if (tmp == state) { - return 0; - } - - if (timeout) { - if (systick_uptime() > (dev->timestamp + timeout)) { - /* TODO: overflow? */ - /* TODO: racy? */ - return I2C_ERROR_TIMEOUT; - } - } - } -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file i2c.c + * @brief Inter-Integrated Circuit (I2C) support. + * + * Currently, only master mode is supported. + */ + +#include "libmaple.h" +#include "rcc.h" +#include "gpio.h" +#include "nvic.h" +#include "i2c.h" +#include "string.h" +#include "systick.h" + +static i2c_dev i2c_dev1 = { + .regs = I2C1_BASE, + .gpio_port = &gpiob, + .sda_pin = 7, + .scl_pin = 6, + .clk_id = RCC_I2C1, + .ev_nvic_line = NVIC_I2C1_EV, + .er_nvic_line = NVIC_I2C1_ER, + .state = I2C_STATE_DISABLED +}; +/** I2C1 device */ +i2c_dev* const I2C1 = &i2c_dev1; + +static i2c_dev i2c_dev2 = { + .regs = I2C2_BASE, + .gpio_port = &gpiob, + .sda_pin = 11, + .scl_pin = 10, + .clk_id = RCC_I2C2, + .ev_nvic_line = NVIC_I2C2_EV, + .er_nvic_line = NVIC_I2C2_ER, + .state = I2C_STATE_DISABLED +}; +/** I2C2 device */ +i2c_dev* const I2C2 = &i2c_dev2; + +static inline int32 wait_for_state_change(i2c_dev *dev, + i2c_state state, + uint32 timeout); + +/** + * @brief Fill data register with slave address + * @param dev I2C device + * @param addr Slave address + * @param rw Read/write bit + */ +static inline void i2c_send_slave_addr(i2c_dev *dev, uint32 addr, uint32 rw) { + dev->regs->DR = (addr << 1) | rw; +} + +/* + * Simple debugging trail. Define I2C_DEBUG to turn on. + */ +#ifdef I2C_DEBUG + +#define NR_CRUMBS 128 +static struct crumb crumbs[NR_CRUMBS]; +static uint32 cur_crumb = 0; + +static inline void i2c_drop_crumb(uint32 event, uint32 arg0, uint32 arg1) { + if (cur_crumb < NR_CRUMBS) { + struct crumb *crumb = &crumbs[cur_crumb++]; + crumb->event = event; + crumb->arg0 = arg0; + crumb->arg1 = arg1; + } +} +#define I2C_CRUMB(event, arg0, arg1) i2c_drop_crumb(event, arg0, arg1) + +#else +#define I2C_CRUMB(event, arg0, arg1) +#endif + +struct crumb { + uint32 event; + uint32 arg0; + uint32 arg1; +}; + +enum { + IRQ_ENTRY = 1, + TXE_ONLY = 2, + TXE_BTF = 3, + STOP_SENT = 4, + TEST = 5, + RX_ADDR_START = 6, + RX_ADDR_STOP = 7, + RXNE_ONLY = 8, + RXNE_SENDING = 9, + RXNE_START_SENT = 10, + RXNE_STOP_SENT = 11, + RXNE_DONE = 12, + ERROR_ENTRY = 13, +}; + +/** + * @brief IRQ handler for I2C master. Handles transmission/reception. + * @param dev I2C device + */ +static void i2c_irq_handler(i2c_dev *dev) { + i2c_msg *msg = dev->msg; + + uint8 read = msg->flags & I2C_MSG_READ; + + uint32 sr1 = dev->regs->SR1; + uint32 sr2 = dev->regs->SR2; + I2C_CRUMB(IRQ_ENTRY, sr1, sr2); + + /* + * Reset timeout counter + */ + dev->timestamp = systick_uptime(); + + /* + * EV5: Start condition sent + */ + if (sr1 & I2C_SR1_SB) { + msg->xferred = 0; + i2c_enable_irq(dev, I2C_IRQ_BUFFER); + + /* + * Master receiver + */ + if (read) { + i2c_enable_ack(dev); + } + + i2c_send_slave_addr(dev, msg->addr, read); + sr1 = sr2 = 0; + } + + /* + * EV6: Slave address sent + */ + if (sr1 & I2C_SR1_ADDR) { + /* + * Special case event EV6_1 for master receiver. + * Generate NACK and restart/stop condition after ADDR + * is cleared. + */ + if (read) { + if (msg->length == 1) { + i2c_disable_ack(dev); + if (dev->msgs_left > 1) { + i2c_start_condition(dev); + I2C_CRUMB(RX_ADDR_START, 0, 0); + } else { + i2c_stop_condition(dev); + I2C_CRUMB(RX_ADDR_STOP, 0, 0); + } + } + } else { + /* + * Master transmitter: write first byte to fill shift + * register. We should get another TXE interrupt + * immediately to fill DR again. + */ + if (msg->length != 1) { + i2c_write(dev, msg->data[msg->xferred++]); + } + } + sr1 = sr2 = 0; + } + + /* + * EV8: Master transmitter + * Transmit buffer empty, but we haven't finished transmitting the last + * byte written. + */ + if ((sr1 & I2C_SR1_TXE) && !(sr1 & I2C_SR1_BTF)) { + I2C_CRUMB(TXE_ONLY, 0, 0); + if (dev->msgs_left) { + i2c_write(dev, msg->data[msg->xferred++]); + if (msg->xferred == msg->length) { + /* + * End of this message. Turn off TXE/RXNE and wait for + * BTF to send repeated start or stop condition. + */ + i2c_disable_irq(dev, I2C_IRQ_BUFFER); + dev->msgs_left--; + } + } else { + /* + * This should be impossible... + */ + throb(); + } + sr1 = sr2 = 0; + } + + /* + * EV8_2: Master transmitter + * Last byte sent, program repeated start/stop + */ + if ((sr1 & I2C_SR1_TXE) && (sr1 & I2C_SR1_BTF)) { + I2C_CRUMB(TXE_BTF, 0, 0); + if (dev->msgs_left) { + I2C_CRUMB(TEST, 0, 0); + /* + * Repeated start insanity: We can't disable ITEVTEN or else SB + * won't interrupt, but if we don't disable ITEVTEN, BTF will + * continually interrupt us. What the fuck ST? + */ + i2c_start_condition(dev); + while (!(dev->regs->SR1 & I2C_SR1_SB)) + ; + dev->msg++; + } else { + i2c_stop_condition(dev); + + /* + * Turn off event interrupts to keep BTF from firing until + * the end of the stop condition. Why on earth they didn't + * have a start/stop condition request clear BTF is beyond + * me. + */ + i2c_disable_irq(dev, I2C_IRQ_EVENT); + I2C_CRUMB(STOP_SENT, 0, 0); + dev->state = I2C_STATE_XFER_DONE; + } + sr1 = sr2 = 0; + } + + /* + * EV7: Master Receiver + */ + if (sr1 & I2C_SR1_RXNE) { + I2C_CRUMB(RXNE_ONLY, 0, 0); + msg->data[msg->xferred++] = dev->regs->DR; + + /* + * EV7_1: Second to last byte in the reception? Set NACK and generate + * stop/restart condition in time for the last byte. We'll get one more + * RXNE interrupt before shutting things down. + */ + if (msg->xferred == (msg->length - 1)) { + i2c_disable_ack(dev); + if (dev->msgs_left > 2) { + i2c_start_condition(dev); + I2C_CRUMB(RXNE_START_SENT, 0, 0); + } else { + i2c_stop_condition(dev); + I2C_CRUMB(RXNE_STOP_SENT, 0, 0); + } + } else if (msg->xferred == msg->length) { + dev->msgs_left--; + if (dev->msgs_left == 0) { + /* + * We're done. + */ + I2C_CRUMB(RXNE_DONE, 0, 0); + dev->state = I2C_STATE_XFER_DONE; + } else { + dev->msg++; + } + } + } +} + +void __irq_i2c1_ev(void) { + i2c_irq_handler(&i2c_dev1); +} + +void __irq_i2c2_ev(void) { + i2c_irq_handler(&i2c_dev2); +} + +/** + * @brief Interrupt handler for I2C error conditions + * @param dev I2C device + * @sideeffect Aborts any pending I2C transactions + */ +static void i2c_irq_error_handler(i2c_dev *dev) { + I2C_CRUMB(ERROR_ENTRY, dev->regs->SR1, dev->regs->SR2); + + dev->error_flags = dev->regs->SR2 & (I2C_SR1_BERR | + I2C_SR1_ARLO | + I2C_SR1_AF | + I2C_SR1_OVR); + /* Clear flags */ + dev->regs->SR1 = 0; + dev->regs->SR2 = 0; + + i2c_stop_condition(dev); + i2c_disable_irq(dev, I2C_IRQ_BUFFER | I2C_IRQ_EVENT | I2C_IRQ_ERROR); + dev->state = I2C_STATE_ERROR; +} + +void __irq_i2c1_er(void) { + i2c_irq_error_handler(&i2c_dev1); +} + +void __irq_i2c2_er(void) { + i2c_irq_error_handler(&i2c_dev2); +} + +/** + * @brief Reset an I2C bus. + * + * Reset is accomplished by clocking out pulses until any hung slaves + * release SDA and SCL, then generating a START condition, then a STOP + * condition. + * + * @param dev I2C device + */ +void i2c_bus_reset(const i2c_dev *dev) { + /* Release both lines */ + gpio_write_bit(dev->gpio_port, dev->scl_pin, 1); + gpio_write_bit(dev->gpio_port, dev->sda_pin, 1); + gpio_set_mode(dev->gpio_port, dev->scl_pin, GPIO_OUTPUT_OD); + gpio_set_mode(dev->gpio_port, dev->sda_pin, GPIO_OUTPUT_OD); + + /* + * Make sure the bus is free by clocking it until any slaves release the + * bus. + */ + while (!gpio_read_bit(dev->gpio_port, dev->sda_pin)) { + /* Wait for any clock stretching to finish */ + while (!gpio_read_bit(dev->gpio_port, dev->scl_pin)) + ; + delay_us(10); + + /* Pull low */ + gpio_write_bit(dev->gpio_port, dev->scl_pin, 0); + delay_us(10); + + /* Release high again */ + gpio_write_bit(dev->gpio_port, dev->scl_pin, 1); + delay_us(10); + } + + /* Generate start then stop condition */ + gpio_write_bit(dev->gpio_port, dev->sda_pin, 0); + delay_us(10); + gpio_write_bit(dev->gpio_port, dev->scl_pin, 0); + delay_us(10); + gpio_write_bit(dev->gpio_port, dev->scl_pin, 1); + delay_us(10); + gpio_write_bit(dev->gpio_port, dev->sda_pin, 1); +} + +/** + * @brief Initialize an I2C device and reset its registers to their + * default values. + * @param dev Device to initialize. + */ +void i2c_init(i2c_dev *dev) { + rcc_reset_dev(dev->clk_id); + rcc_clk_enable(dev->clk_id); +} + +/** + * @brief Initialize an I2C device as bus master + * @param dev Device to enable + * @param flags Bitwise or of the following I2C options: + * I2C_FAST_MODE: 400 khz operation, + * I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for + * fast mode), + * I2C_BUS_RESET: Reset the bus and clock out any hung slaves on + * initialization, + * I2C_10BIT_ADDRESSING: Enable 10-bit addressing, + * I2C_REMAP: Remap I2C1 to SCL/PB8 SDA/PB9. + */ +void i2c_master_enable(i2c_dev *dev, uint32 flags) { +#define I2C_CLK (STM32_PCLK1/1000000) + uint32 ccr = 0; + uint32 trise = 0; + + /* PE must be disabled to configure the device */ + ASSERT(!(dev->regs->CR1 & I2C_CR1_PE)); + + if ((dev == I2C1) && (flags & I2C_REMAP)) { + afio_remap(AFIO_REMAP_I2C1); + I2C1->sda_pin = 9; + I2C1->scl_pin = 8; + } + + /* Reset the bus. Clock out any hung slaves. */ + if (flags & I2C_BUS_RESET) { + i2c_bus_reset(dev); + } + + /* Turn on clock and set GPIO modes */ + i2c_init(dev); + gpio_set_mode(dev->gpio_port, dev->sda_pin, GPIO_AF_OUTPUT_OD); + gpio_set_mode(dev->gpio_port, dev->scl_pin, GPIO_AF_OUTPUT_OD); + + /* I2C1 and I2C2 are fed from APB1, clocked at 36MHz */ + i2c_set_input_clk(dev, I2C_CLK); + + if (flags & I2C_FAST_MODE) { + ccr |= I2C_CCR_FS; + + if (flags & I2C_DUTY_16_9) { + /* Tlow/Thigh = 16/9 */ + ccr |= I2C_CCR_DUTY; + ccr |= STM32_PCLK1/(400000 * 25); + } else { + /* Tlow/Thigh = 2 */ + ccr |= STM32_PCLK1/(400000 * 3); + } + + trise = (300 * (I2C_CLK)/1000) + 1; + } else { + /* Tlow/Thigh = 1 */ + ccr = STM32_PCLK1/(100000 * 2); + trise = I2C_CLK + 1; + } + + /* Set minimum required value if CCR < 1*/ + if ((ccr & I2C_CCR_CCR) == 0) { + ccr |= 0x1; + } + + i2c_set_clk_control(dev, ccr); + i2c_set_trise(dev, trise); + + /* Enable event and buffer interrupts */ + nvic_irq_enable(dev->ev_nvic_line); + nvic_irq_enable(dev->er_nvic_line); + i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_BUFFER | I2C_IRQ_ERROR); + + /* + * Important STM32 Errata: + * + * See STM32F10xx8 and STM32F10xxB Errata sheet (Doc ID 14574 Rev 8), + * Section 2.11.1, 2.11.2. + * + * 2.11.1: + * When the EV7, EV7_1, EV6_1, EV6_3, EV2, EV8, and EV3 events are not + * managed before the current byte is being transferred, problems may be + * encountered such as receiving an extra byte, reading the same data twice + * or missing data. + * + * 2.11.2: + * In Master Receiver mode, when closing the communication using + * method 2, the content of the last read data can be corrupted. + * + * If the user software is not able to read the data N-1 before the STOP + * condition is generated on the bus, the content of the shift register + * (data N) will be corrupted. (data N is shifted 1-bit to the left). + * + * ---------------------------------------------------------------------- + * + * In order to ensure that events are not missed, the i2c interrupt must + * not be preempted. We set the i2c interrupt priority to be the highest + * interrupt in the system (priority level 0). All other interrupts have + * been initialized to priority level 16. See nvic_init(). + */ + nvic_irq_set_priority(dev->ev_nvic_line, 0); + nvic_irq_set_priority(dev->er_nvic_line, 0); + + /* Make it go! */ + i2c_peripheral_enable(dev); + + dev->state = I2C_STATE_IDLE; +} + + +/** + * @brief Process an i2c transaction. + * + * Transactions are composed of one or more i2c_msg's, and may be read + * or write tranfers. Multiple i2c_msg's will generate a repeated + * start in between messages. + * + * @param dev I2C device + * @param msgs Messages to send/receive + * @param num Number of messages to send/receive + * @param timeout Bus idle timeout in milliseconds before aborting the + * transfer. 0 denotes no timeout. + * @return 0 on success, + * I2C_ERROR_PROTOCOL if there was a protocol error, + * I2C_ERROR_TIMEOUT if the transfer timed out. + */ +int32 i2c_master_xfer(i2c_dev *dev, + i2c_msg *msgs, + uint16 num, + uint32 timeout) { + int32 rc; + + ASSERT(dev->state == I2C_STATE_IDLE); + + dev->msg = msgs; + dev->msgs_left = num; + dev->timestamp = systick_uptime(); + dev->state = I2C_STATE_BUSY; + + i2c_enable_irq(dev, I2C_IRQ_EVENT); + i2c_start_condition(dev); + + rc = wait_for_state_change(dev, I2C_STATE_XFER_DONE, timeout); + if (rc < 0) { + goto out; + } + + dev->state = I2C_STATE_IDLE; +out: + return rc; +} + + +/** + * @brief Wait for an I2C event, or time out in case of error. + * @param dev I2C device + * @param state I2C_state state to wait for + * @param timeout Timeout, in milliseconds + * @return 0 if target state is reached, a negative value on error. + */ +static inline int32 wait_for_state_change(i2c_dev *dev, + i2c_state state, + uint32 timeout) { + i2c_state tmp; + + while (1) { + tmp = dev->state; + + if (tmp == I2C_STATE_ERROR) { + return I2C_STATE_ERROR; + } + + if (tmp == state) { + return 0; + } + + if (timeout) { + if (systick_uptime() > (dev->timestamp + timeout)) { + /* TODO: overflow? */ + /* TODO: racy? */ + return I2C_ERROR_TIMEOUT; + } + } + } +} diff --git a/Libmaple/libmaple/libmaple/i2c.h b/Libmaple/libmaple/libmaple/i2c.h index 53b4f788..4c60ad71 100644 --- a/Libmaple/libmaple/libmaple/i2c.h +++ b/Libmaple/libmaple/libmaple/i2c.h @@ -1,348 +1,348 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file i2c.h - * @brief Inter-Integrated Circuit (I2C) peripheral support - */ - -#include "libmaple_types.h" -#include "rcc.h" -#include "nvic.h" -#include "gpio.h" - -#ifndef _I2C_H_ -#define _I2C_H_ - -/** I2C register map type */ -typedef struct i2c_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 OAR1; /**< Own address register 1 */ - __io uint32 OAR2; /**< Own address register 2 */ - __io uint32 DR; /**< Data register */ - __io uint32 SR1; /**< Status register 1 */ - __io uint32 SR2; /**< Status register 2 */ - __io uint32 CCR; /**< Clock control register */ - __io uint32 TRISE; /**< TRISE (rise time) register */ -} i2c_reg_map; - -/** I2C device states */ -typedef enum i2c_state { - I2C_STATE_DISABLED = 0, /**< Disabled */ - I2C_STATE_IDLE = 1, /**< Idle */ - I2C_STATE_XFER_DONE = 2, /**< Done with transfer */ - I2C_STATE_BUSY = 3, /**< Busy */ - I2C_STATE_ERROR = -1 /**< Error occurred */ -} i2c_state; - -/** - * @brief I2C message type - */ -typedef struct i2c_msg { - uint16 addr; /**< Address */ -#define I2C_MSG_READ 0x1 -#define I2C_MSG_10BIT_ADDR 0x2 - uint16 flags; /**< Bitwise OR of I2C_MSG_READ and - I2C_MSG_10BIT_ADDR */ - uint16 length; /**< Message length */ - uint16 xferred; /**< Messages transferred */ - uint8 *data; /**< Data */ -} i2c_msg; - -/** - * @brief I2C device type. - */ -typedef struct i2c_dev { - i2c_reg_map *regs; /**< Register map */ - gpio_dev *gpio_port; /**< SDA, SCL pins' GPIO port */ - uint8 sda_pin; /**< SDA bit on gpio_port */ - uint8 scl_pin; /**< SCL bit on gpio_port */ - rcc_clk_id clk_id; /**< RCC clock information */ - nvic_irq_num ev_nvic_line; /**< Event IRQ number */ - nvic_irq_num er_nvic_line; /**< Error IRQ number */ - volatile i2c_state state; /**< Device state */ - uint16 msgs_left; /**< Messages left */ - i2c_msg *msg; /**< Messages */ - volatile uint32 timestamp; /**< For internal use */ - uint32 error_flags; /**< Error flags, set on I2C error condition */ -} i2c_dev; - -/* - * Devices - */ - -extern i2c_dev* const I2C1; -extern i2c_dev* const I2C2; - -/* - * Register map base pointers - */ - -/** I2C1 register map base pointer */ -#define I2C1_BASE ((struct i2c_reg_map*)0x40005400) -/** I2C2 register map base pointer */ -#define I2C2_BASE ((struct i2c_reg_map*)0x40005800) - -/* - * Register bit definitions - */ - -/* Control register 1 */ - -#define I2C_CR1_SWRST BIT(15) // Software reset -#define I2C_CR1_ALERT BIT(13) // SMBus alert -#define I2C_CR1_PEC BIT(12) // Packet error checking -#define I2C_CR1_POS BIT(11) // Acknowledge/PEC position -#define I2C_CR1_ACK BIT(10) // Acknowledge enable -#define I2C_CR1_START BIT(8) // Start generation -#define I2C_CR1_STOP BIT(9) // Stop generation -#define I2C_CR1_PE BIT(0) // Peripheral Enable - -/* Control register 2 */ - -#define I2C_CR2_LAST BIT(12) // DMA last transfer -#define I2C_CR2_DMAEN BIT(11) // DMA requests enable -#define I2C_CR2_ITBUFEN BIT(10) // Buffer interrupt enable -#define I2C_CR2_ITEVTEN BIT(9) // Event interupt enable -#define I2C_CR2_ITERREN BIT(8) // Error interupt enable -#define I2C_CR2_FREQ 0xFFF // Peripheral input frequency - -/* Clock control register */ - -#define I2C_CCR_FS BIT(15) // Fast mode selection -#define I2C_CCR_DUTY BIT(14) // 16/9 duty ratio -#define I2C_CCR_CCR 0xFFF // Clock control bits - -/* Status register 1 */ - -#define I2C_SR1_SB BIT(0) // Start bit -#define I2C_SR1_ADDR BIT(1) // Address sent/matched -#define I2C_SR1_BTF BIT(2) // Byte transfer finished -#define I2C_SR1_ADD10 BIT(3) // 10-bit header sent -#define I2C_SR1_STOPF BIT(4) // Stop detection -#define I2C_SR1_RXNE BIT(6) // Data register not empty -#define I2C_SR1_TXE BIT(7) // Data register empty -#define I2C_SR1_BERR BIT(8) // Bus error -#define I2C_SR1_ARLO BIT(9) // Arbitration lost -#define I2C_SR1_AF BIT(10) // Acknowledge failure -#define I2C_SR1_OVR BIT(11) // Overrun/underrun -#define I2C_SR1_PECERR BIT(12) // PEC Error in reception -#define I2C_SR1_TIMEOUT BIT(14) // Timeout or Tlow error -#define I2C_SR1_SMBALERT BIT(15) // SMBus alert - -/* Status register 2 */ - -#define I2C_SR2_MSL BIT(0) // Master/slave -#define I2C_SR2_BUSY BIT(1) // Bus busy -#define I2C_SR2_TRA BIT(2) // Transmitter/receiver -#define I2C_SR2_GENCALL BIT(4) // General call address -#define I2C_SR2_SMBDEFAULT BIT(5) // SMBus device default address -#define I2C_SR2_SMBHOST BIT(6) // SMBus host header -#define I2C_SR2_DUALF BIT(7) // Dual flag -#define I2C_SR2_PEC 0xFF00 // Packet error checking register - -/* - * Convenience routines - */ - -#ifdef __cplusplus -extern "C" { -#endif - -void i2c_init(i2c_dev *dev); - -/* I2C enable options */ -#define I2C_FAST_MODE BIT(0) // 400 khz -#define I2C_DUTY_16_9 BIT(1) // 16/9 duty ratio -#define I2C_REMAP BIT(2) // Use alternate pin mapping -#define I2C_BUS_RESET BIT(3) // Perform a bus reset -void i2c_master_enable(i2c_dev *dev, uint32 flags); - -#define I2C_ERROR_PROTOCOL (-1) -#define I2C_ERROR_TIMEOUT (-2) -int32 i2c_master_xfer(i2c_dev *dev, i2c_msg *msgs, uint16 num, uint32 timeout); - -void i2c_bus_reset(const i2c_dev *dev); - -/** - * @brief Disable an I2C device - * - * This function disables the corresponding peripheral and marks dev's - * state as I2C_STATE_DISABLED. - * - * @param dev Device to disable. - */ -static inline void i2c_disable(i2c_dev *dev) { - dev->regs->CR1 &= ~I2C_CR1_PE; - dev->state = I2C_STATE_DISABLED; -} - -/** - * @brief Turn on an I2C peripheral - * @param dev Device to enable - */ -static inline void i2c_peripheral_enable(i2c_dev *dev) { - dev->regs->CR1 |= I2C_CR1_PE; -} - -/** - * @brief Turn off an I2C peripheral - * @param dev Device to turn off - */ -static inline void i2c_peripheral_disable(i2c_dev *dev) { - dev->regs->CR1 &= ~I2C_CR1_PE; -} - -/** - * @brief Fill transmit register - * @param dev I2C device - * @param byte Byte to write - */ -static inline void i2c_write(i2c_dev *dev, uint8 byte) { - dev->regs->DR = byte; -} - -/** - * @brief Set input clock frequency, in MHz - * @param dev I2C device - * @param freq Frequency in megahertz (2-36) - */ -static inline void i2c_set_input_clk(i2c_dev *dev, uint32 freq) { - uint32 cr2 = dev->regs->CR2; - cr2 &= ~I2C_CR2_FREQ; - cr2 |= freq; - dev->regs->CR2 = freq; -} - -/** - * @brief Set I2C clock control register. See RM008 - * @param dev I2C device - * @param val Value to use for clock control register (in - * Fast/Standard mode) - */ -static inline void i2c_set_clk_control(i2c_dev *dev, uint32 val) { - uint32 ccr = dev->regs->CCR; - ccr &= ~I2C_CCR_CCR; - ccr |= val; - dev->regs->CCR = ccr; -} - - -/** - * @brief Set SCL rise time - * @param dev I2C device - * @param trise Maximum rise time in fast/standard mode (see RM0008 - * for relevant formula). - */ -static inline void i2c_set_trise(i2c_dev *dev, uint32 trise) { - dev->regs->TRISE = trise; -} - - -/** - * @brief Generate a start condition on the bus. - * @param dev I2C device - */ -static inline void i2c_start_condition(i2c_dev *dev) { - uint32 cr1; - while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | - I2C_CR1_STOP | - I2C_CR1_PEC)) { - ; - } - dev->regs->CR1 |= I2C_CR1_START; -} - -/** - * @brief Generate a stop condition on the bus - * @param dev I2C device - */ -static inline void i2c_stop_condition(i2c_dev *dev) { - uint32 cr1; - while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | - I2C_CR1_STOP | - I2C_CR1_PEC)) { - ; - } - dev->regs->CR1 |= I2C_CR1_STOP; - while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | - I2C_CR1_STOP | - I2C_CR1_PEC)) { - ; - } - -} - -/** - * @brief Enable one or more I2C interrupts - * @param dev I2C device - * @param irqs Bitwise or of: - * I2C_IRQ_ERROR (error interrupt), - * I2C_IRQ_EVENT (event interrupt), and - * I2C_IRQ_BUFFER (buffer interrupt). - */ -#define I2C_IRQ_ERROR I2C_CR2_ITERREN -#define I2C_IRQ_EVENT I2C_CR2_ITEVTEN -#define I2C_IRQ_BUFFER I2C_CR2_ITBUFEN -static inline void i2c_enable_irq(i2c_dev *dev, uint32 irqs) { - dev->regs->CR2 |= irqs; -} - -/** - * @brief Disable one or more I2C interrupts - * @param dev I2C device - * @param irqs Bitwise or of: - * I2C_IRQ_ERROR (error interrupt), - * I2C_IRQ_EVENT (event interrupt), and - * I2C_IRQ_BUFFER (buffer interrupt). - */ -static inline void i2c_disable_irq(i2c_dev *dev, uint32 irqs) { - dev->regs->CR2 &= ~irqs; -} - - -/** - * @brief Enable I2C acknowledgment - * @param dev I2C device - */ -static inline void i2c_enable_ack(i2c_dev *dev) { - dev->regs->CR1 |= I2C_CR1_ACK; -} - -/** - * @brief Disable I2C acknowledgment - * @param dev I2C device - */ -static inline void i2c_disable_ack(i2c_dev *dev) { - dev->regs->CR1 &= ~I2C_CR1_ACK; -} - -#ifdef __cplusplus -} -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file i2c.h + * @brief Inter-Integrated Circuit (I2C) peripheral support + */ + +#include "libmaple_types.h" +#include "rcc.h" +#include "nvic.h" +#include "gpio.h" + +#ifndef _I2C_H_ +#define _I2C_H_ + +/** I2C register map type */ +typedef struct i2c_reg_map { + __io uint32 CR1; /**< Control register 1 */ + __io uint32 CR2; /**< Control register 2 */ + __io uint32 OAR1; /**< Own address register 1 */ + __io uint32 OAR2; /**< Own address register 2 */ + __io uint32 DR; /**< Data register */ + __io uint32 SR1; /**< Status register 1 */ + __io uint32 SR2; /**< Status register 2 */ + __io uint32 CCR; /**< Clock control register */ + __io uint32 TRISE; /**< TRISE (rise time) register */ +} i2c_reg_map; + +/** I2C device states */ +typedef enum i2c_state { + I2C_STATE_DISABLED = 0, /**< Disabled */ + I2C_STATE_IDLE = 1, /**< Idle */ + I2C_STATE_XFER_DONE = 2, /**< Done with transfer */ + I2C_STATE_BUSY = 3, /**< Busy */ + I2C_STATE_ERROR = -1 /**< Error occurred */ +} i2c_state; + +/** + * @brief I2C message type + */ +typedef struct i2c_msg { + uint16 addr; /**< Address */ +#define I2C_MSG_READ 0x1 +#define I2C_MSG_10BIT_ADDR 0x2 + uint16 flags; /**< Bitwise OR of I2C_MSG_READ and + I2C_MSG_10BIT_ADDR */ + uint16 length; /**< Message length */ + uint16 xferred; /**< Messages transferred */ + uint8 *data; /**< Data */ +} i2c_msg; + +/** + * @brief I2C device type. + */ +typedef struct i2c_dev { + i2c_reg_map *regs; /**< Register map */ + gpio_dev *gpio_port; /**< SDA, SCL pins' GPIO port */ + uint8 sda_pin; /**< SDA bit on gpio_port */ + uint8 scl_pin; /**< SCL bit on gpio_port */ + rcc_clk_id clk_id; /**< RCC clock information */ + nvic_irq_num ev_nvic_line; /**< Event IRQ number */ + nvic_irq_num er_nvic_line; /**< Error IRQ number */ + volatile i2c_state state; /**< Device state */ + uint16 msgs_left; /**< Messages left */ + i2c_msg *msg; /**< Messages */ + volatile uint32 timestamp; /**< For internal use */ + uint32 error_flags; /**< Error flags, set on I2C error condition */ +} i2c_dev; + +/* + * Devices + */ + +extern i2c_dev* const I2C1; +extern i2c_dev* const I2C2; + +/* + * Register map base pointers + */ + +/** I2C1 register map base pointer */ +#define I2C1_BASE ((struct i2c_reg_map*)0x40005400) +/** I2C2 register map base pointer */ +#define I2C2_BASE ((struct i2c_reg_map*)0x40005800) + +/* + * Register bit definitions + */ + +/* Control register 1 */ + +#define I2C_CR1_SWRST BIT(15) // Software reset +#define I2C_CR1_ALERT BIT(13) // SMBus alert +#define I2C_CR1_PEC BIT(12) // Packet error checking +#define I2C_CR1_POS BIT(11) // Acknowledge/PEC position +#define I2C_CR1_ACK BIT(10) // Acknowledge enable +#define I2C_CR1_START BIT(8) // Start generation +#define I2C_CR1_STOP BIT(9) // Stop generation +#define I2C_CR1_PE BIT(0) // Peripheral Enable + +/* Control register 2 */ + +#define I2C_CR2_LAST BIT(12) // DMA last transfer +#define I2C_CR2_DMAEN BIT(11) // DMA requests enable +#define I2C_CR2_ITBUFEN BIT(10) // Buffer interrupt enable +#define I2C_CR2_ITEVTEN BIT(9) // Event interupt enable +#define I2C_CR2_ITERREN BIT(8) // Error interupt enable +#define I2C_CR2_FREQ 0xFFF // Peripheral input frequency + +/* Clock control register */ + +#define I2C_CCR_FS BIT(15) // Fast mode selection +#define I2C_CCR_DUTY BIT(14) // 16/9 duty ratio +#define I2C_CCR_CCR 0xFFF // Clock control bits + +/* Status register 1 */ + +#define I2C_SR1_SB BIT(0) // Start bit +#define I2C_SR1_ADDR BIT(1) // Address sent/matched +#define I2C_SR1_BTF BIT(2) // Byte transfer finished +#define I2C_SR1_ADD10 BIT(3) // 10-bit header sent +#define I2C_SR1_STOPF BIT(4) // Stop detection +#define I2C_SR1_RXNE BIT(6) // Data register not empty +#define I2C_SR1_TXE BIT(7) // Data register empty +#define I2C_SR1_BERR BIT(8) // Bus error +#define I2C_SR1_ARLO BIT(9) // Arbitration lost +#define I2C_SR1_AF BIT(10) // Acknowledge failure +#define I2C_SR1_OVR BIT(11) // Overrun/underrun +#define I2C_SR1_PECERR BIT(12) // PEC Error in reception +#define I2C_SR1_TIMEOUT BIT(14) // Timeout or Tlow error +#define I2C_SR1_SMBALERT BIT(15) // SMBus alert + +/* Status register 2 */ + +#define I2C_SR2_MSL BIT(0) // Master/slave +#define I2C_SR2_BUSY BIT(1) // Bus busy +#define I2C_SR2_TRA BIT(2) // Transmitter/receiver +#define I2C_SR2_GENCALL BIT(4) // General call address +#define I2C_SR2_SMBDEFAULT BIT(5) // SMBus device default address +#define I2C_SR2_SMBHOST BIT(6) // SMBus host header +#define I2C_SR2_DUALF BIT(7) // Dual flag +#define I2C_SR2_PEC 0xFF00 // Packet error checking register + +/* + * Convenience routines + */ + +#ifdef __cplusplus +extern "C" { +#endif + +void i2c_init(i2c_dev *dev); + +/* I2C enable options */ +#define I2C_FAST_MODE BIT(0) // 400 khz +#define I2C_DUTY_16_9 BIT(1) // 16/9 duty ratio +#define I2C_REMAP BIT(2) // Use alternate pin mapping +#define I2C_BUS_RESET BIT(3) // Perform a bus reset +void i2c_master_enable(i2c_dev *dev, uint32 flags); + +#define I2C_ERROR_PROTOCOL (-1) +#define I2C_ERROR_TIMEOUT (-2) +int32 i2c_master_xfer(i2c_dev *dev, i2c_msg *msgs, uint16 num, uint32 timeout); + +void i2c_bus_reset(const i2c_dev *dev); + +/** + * @brief Disable an I2C device + * + * This function disables the corresponding peripheral and marks dev's + * state as I2C_STATE_DISABLED. + * + * @param dev Device to disable. + */ +static inline void i2c_disable(i2c_dev *dev) { + dev->regs->CR1 &= ~I2C_CR1_PE; + dev->state = I2C_STATE_DISABLED; +} + +/** + * @brief Turn on an I2C peripheral + * @param dev Device to enable + */ +static inline void i2c_peripheral_enable(i2c_dev *dev) { + dev->regs->CR1 |= I2C_CR1_PE; +} + +/** + * @brief Turn off an I2C peripheral + * @param dev Device to turn off + */ +static inline void i2c_peripheral_disable(i2c_dev *dev) { + dev->regs->CR1 &= ~I2C_CR1_PE; +} + +/** + * @brief Fill transmit register + * @param dev I2C device + * @param byte Byte to write + */ +static inline void i2c_write(i2c_dev *dev, uint8 byte) { + dev->regs->DR = byte; +} + +/** + * @brief Set input clock frequency, in MHz + * @param dev I2C device + * @param freq Frequency in megahertz (2-36) + */ +static inline void i2c_set_input_clk(i2c_dev *dev, uint32 freq) { + uint32 cr2 = dev->regs->CR2; + cr2 &= ~I2C_CR2_FREQ; + cr2 |= freq; + dev->regs->CR2 = freq; +} + +/** + * @brief Set I2C clock control register. See RM008 + * @param dev I2C device + * @param val Value to use for clock control register (in + * Fast/Standard mode) + */ +static inline void i2c_set_clk_control(i2c_dev *dev, uint32 val) { + uint32 ccr = dev->regs->CCR; + ccr &= ~I2C_CCR_CCR; + ccr |= val; + dev->regs->CCR = ccr; +} + + +/** + * @brief Set SCL rise time + * @param dev I2C device + * @param trise Maximum rise time in fast/standard mode (see RM0008 + * for relevant formula). + */ +static inline void i2c_set_trise(i2c_dev *dev, uint32 trise) { + dev->regs->TRISE = trise; +} + + +/** + * @brief Generate a start condition on the bus. + * @param dev I2C device + */ +static inline void i2c_start_condition(i2c_dev *dev) { + uint32 cr1; + while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | + I2C_CR1_STOP | + I2C_CR1_PEC)) { + ; + } + dev->regs->CR1 |= I2C_CR1_START; +} + +/** + * @brief Generate a stop condition on the bus + * @param dev I2C device + */ +static inline void i2c_stop_condition(i2c_dev *dev) { + uint32 cr1; + while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | + I2C_CR1_STOP | + I2C_CR1_PEC)) { + ; + } + dev->regs->CR1 |= I2C_CR1_STOP; + while ((cr1 = dev->regs->CR1) & (I2C_CR1_START | + I2C_CR1_STOP | + I2C_CR1_PEC)) { + ; + } + +} + +/** + * @brief Enable one or more I2C interrupts + * @param dev I2C device + * @param irqs Bitwise or of: + * I2C_IRQ_ERROR (error interrupt), + * I2C_IRQ_EVENT (event interrupt), and + * I2C_IRQ_BUFFER (buffer interrupt). + */ +#define I2C_IRQ_ERROR I2C_CR2_ITERREN +#define I2C_IRQ_EVENT I2C_CR2_ITEVTEN +#define I2C_IRQ_BUFFER I2C_CR2_ITBUFEN +static inline void i2c_enable_irq(i2c_dev *dev, uint32 irqs) { + dev->regs->CR2 |= irqs; +} + +/** + * @brief Disable one or more I2C interrupts + * @param dev I2C device + * @param irqs Bitwise or of: + * I2C_IRQ_ERROR (error interrupt), + * I2C_IRQ_EVENT (event interrupt), and + * I2C_IRQ_BUFFER (buffer interrupt). + */ +static inline void i2c_disable_irq(i2c_dev *dev, uint32 irqs) { + dev->regs->CR2 &= ~irqs; +} + + +/** + * @brief Enable I2C acknowledgment + * @param dev I2C device + */ +static inline void i2c_enable_ack(i2c_dev *dev) { + dev->regs->CR1 |= I2C_CR1_ACK; +} + +/** + * @brief Disable I2C acknowledgment + * @param dev I2C device + */ +static inline void i2c_disable_ack(i2c_dev *dev) { + dev->regs->CR1 &= ~I2C_CR1_ACK; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/iwdg.c b/Libmaple/libmaple/libmaple/iwdg.c index 8660f78e..63c1b2b8 100644 --- a/Libmaple/libmaple/libmaple/iwdg.c +++ b/Libmaple/libmaple/libmaple/iwdg.c @@ -1,62 +1,62 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file iwdg.c - * @brief Independent watchdog (IWDG) support - */ - -#include "iwdg.h" - -/** - * @brief Initialise and start the watchdog - * - * The prescaler and reload set the timeout. For example, a prescaler - * of IWDG_PRE_32 divides the 40 kHz clock by 32 and gives roughly 1 - * ms per reload. - * - * @param prescaler Prescaler for the 40 kHz IWDG clock. - * @param reload Independent watchdog counter reload value. - */ -void iwdg_init(iwdg_prescaler prescaler, uint16 reload) { - IWDG_BASE->KR = IWDG_KR_UNLOCK; - IWDG_BASE->PR = prescaler; - IWDG_BASE->RLR = reload; - - /* Start things off */ - IWDG_BASE->KR = IWDG_KR_START; - iwdg_feed(); -} - -/** - * @brief Reset the IWDG counter. - * - * Calling this function will cause the IWDG counter to be reset to - * its reload value. - */ -void iwdg_feed(void) { - IWDG_BASE->KR = IWDG_KR_FEED; -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Michael Hope. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file iwdg.c + * @brief Independent watchdog (IWDG) support + */ + +#include "iwdg.h" + +/** + * @brief Initialise and start the watchdog + * + * The prescaler and reload set the timeout. For example, a prescaler + * of IWDG_PRE_32 divides the 40 kHz clock by 32 and gives roughly 1 + * ms per reload. + * + * @param prescaler Prescaler for the 40 kHz IWDG clock. + * @param reload Independent watchdog counter reload value. + */ +void iwdg_init(iwdg_prescaler prescaler, uint16 reload) { + IWDG_BASE->KR = IWDG_KR_UNLOCK; + IWDG_BASE->PR = prescaler; + IWDG_BASE->RLR = reload; + + /* Start things off */ + IWDG_BASE->KR = IWDG_KR_START; + iwdg_feed(); +} + +/** + * @brief Reset the IWDG counter. + * + * Calling this function will cause the IWDG counter to be reset to + * its reload value. + */ +void iwdg_feed(void) { + IWDG_BASE->KR = IWDG_KR_FEED; +} diff --git a/Libmaple/libmaple/libmaple/iwdg.h b/Libmaple/libmaple/libmaple/iwdg.h index 336137a3..59e8e18f 100644 --- a/Libmaple/libmaple/libmaple/iwdg.h +++ b/Libmaple/libmaple/libmaple/iwdg.h @@ -1,116 +1,116 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Michael Hope. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file iwdg.h - * @author Michael Hope, Marti Bolivar - * @brief Independent watchdog support. - * - * To use the independent watchdog, first call iwdg_init() with the - * appropriate prescaler and IWDG counter reload values for your - * application. Afterwards, you must periodically call iwdg_feed() - * before the IWDG counter reaches 0 to reset the counter to its - * reload value. If you do not, the chip will reset. - * - * Once started, the independent watchdog cannot be turned off. - */ - -#ifndef _IWDG_H_ -#define _IWDG_H_ - -#include "libmaple_types.h" -#include "util.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - * Register map - */ - -/** Independent watchdog register map type. */ -typedef struct iwdg_reg_map { - __io uint32 KR; /**< Key register. */ - __io uint32 PR; /**< Prescaler register. */ - __io uint32 RLR; /**< Reload register. */ - __io uint32 SR; /**< Status register */ -} iwdg_reg_map; - -/** Independent watchdog base pointer */ -#define IWDG_BASE ((struct iwdg_reg_map*)0x40003000) - -/* - * Register bit definitions - */ - -/* Key register */ - -#define IWDG_KR_UNLOCK 0x5555 -#define IWDG_KR_FEED 0xAAAA -#define IWDG_KR_START 0xCCCC - -/* Prescaler register */ - -#define IWDG_PR_DIV_4 0x0 -#define IWDG_PR_DIV_8 0x1 -#define IWDG_PR_DIV_16 0x2 -#define IWDG_PR_DIV_32 0x3 -#define IWDG_PR_DIV_64 0x4 -#define IWDG_PR_DIV_128 0x5 -#define IWDG_PR_DIV_256 0x6 - -/* Status register */ - -#define IWDG_SR_RVU_BIT 1 -#define IWDG_SR_PVU_BIT 0 - -#define IWDG_SR_RVU BIT(IWDG_SR_RVU_BIT) -#define IWDG_SR_PVU BIT(IWDG_SR_PVU_BIT) - -/** - * @brief Independent watchdog prescalers. - * - * These divide the 40 kHz IWDG clock. - */ -typedef enum iwdg_prescaler { - IWDG_PRE_4 = IWDG_PR_DIV_4, /**< Divide by 4 */ - IWDG_PRE_8 = IWDG_PR_DIV_8, /**< Divide by 8 */ - IWDG_PRE_16 = IWDG_PR_DIV_16, /**< Divide by 16 */ - IWDG_PRE_32 = IWDG_PR_DIV_32, /**< Divide by 32 */ - IWDG_PRE_64 = IWDG_PR_DIV_64, /**< Divide by 64 */ - IWDG_PRE_128 = IWDG_PR_DIV_128, /**< Divide by 128 */ - IWDG_PRE_256 = IWDG_PR_DIV_256 /**< Divide by 256 */ -} iwdg_prescaler; - -void iwdg_init(iwdg_prescaler prescaler, uint16 reload); -void iwdg_feed(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Michael Hope. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file iwdg.h + * @author Michael Hope, Marti Bolivar + * @brief Independent watchdog support. + * + * To use the independent watchdog, first call iwdg_init() with the + * appropriate prescaler and IWDG counter reload values for your + * application. Afterwards, you must periodically call iwdg_feed() + * before the IWDG counter reaches 0 to reset the counter to its + * reload value. If you do not, the chip will reset. + * + * Once started, the independent watchdog cannot be turned off. + */ + +#ifndef _IWDG_H_ +#define _IWDG_H_ + +#include "libmaple_types.h" +#include "util.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * Register map + */ + +/** Independent watchdog register map type. */ +typedef struct iwdg_reg_map { + __io uint32 KR; /**< Key register. */ + __io uint32 PR; /**< Prescaler register. */ + __io uint32 RLR; /**< Reload register. */ + __io uint32 SR; /**< Status register */ +} iwdg_reg_map; + +/** Independent watchdog base pointer */ +#define IWDG_BASE ((struct iwdg_reg_map*)0x40003000) + +/* + * Register bit definitions + */ + +/* Key register */ + +#define IWDG_KR_UNLOCK 0x5555 +#define IWDG_KR_FEED 0xAAAA +#define IWDG_KR_START 0xCCCC + +/* Prescaler register */ + +#define IWDG_PR_DIV_4 0x0 +#define IWDG_PR_DIV_8 0x1 +#define IWDG_PR_DIV_16 0x2 +#define IWDG_PR_DIV_32 0x3 +#define IWDG_PR_DIV_64 0x4 +#define IWDG_PR_DIV_128 0x5 +#define IWDG_PR_DIV_256 0x6 + +/* Status register */ + +#define IWDG_SR_RVU_BIT 1 +#define IWDG_SR_PVU_BIT 0 + +#define IWDG_SR_RVU BIT(IWDG_SR_RVU_BIT) +#define IWDG_SR_PVU BIT(IWDG_SR_PVU_BIT) + +/** + * @brief Independent watchdog prescalers. + * + * These divide the 40 kHz IWDG clock. + */ +typedef enum iwdg_prescaler { + IWDG_PRE_4 = IWDG_PR_DIV_4, /**< Divide by 4 */ + IWDG_PRE_8 = IWDG_PR_DIV_8, /**< Divide by 8 */ + IWDG_PRE_16 = IWDG_PR_DIV_16, /**< Divide by 16 */ + IWDG_PRE_32 = IWDG_PR_DIV_32, /**< Divide by 32 */ + IWDG_PRE_64 = IWDG_PR_DIV_64, /**< Divide by 64 */ + IWDG_PRE_128 = IWDG_PR_DIV_128, /**< Divide by 128 */ + IWDG_PRE_256 = IWDG_PR_DIV_256 /**< Divide by 256 */ +} iwdg_prescaler; + +void iwdg_init(iwdg_prescaler prescaler, uint16 reload); +void iwdg_feed(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/libmaple.h b/Libmaple/libmaple/libmaple/libmaple.h index a7b92e78..10c6c0c0 100644 --- a/Libmaple/libmaple/libmaple/libmaple.h +++ b/Libmaple/libmaple/libmaple/libmaple.h @@ -1,60 +1,60 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple.h - * @brief General include file for libmaple - */ - -#ifndef _LIBMAPLE_H_ -#define _LIBMAPLE_H_ - -#include "libmaple_types.h" -#include "stm32.h" -#include "util.h" -#include "delay.h" - -/* - * Where to put usercode, based on space reserved for bootloader. - * - * FIXME this has no business being here - */ -#if defined(MCU_STM32F103VE) || defined(MCU_STM32F205VE) || defined(MCU_STM32F406VG) - /* e.g., Aeroquad32 */ - #define USER_ADDR_ROM 0x08010000 /* ala42 */ - #define USER_ADDR_RAM 0x20000C00 - #define STACK_TOP 0x20000800 -#elif defined(BOARD_freeflight) -#define USER_ADDR_ROM 0x08000000 -#define USER_ADDR_RAM 0x20000000 -#define STACK_TOP 0x20000800 -#else -#define USER_ADDR_ROM 0x08005000 -#define USER_ADDR_RAM 0x20000C00 -#define STACK_TOP 0x20000800 -#endif -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple.h + * @brief General include file for libmaple + */ + +#ifndef _LIBMAPLE_H_ +#define _LIBMAPLE_H_ + +#include "libmaple_types.h" +#include "stm32.h" +#include "util.h" +#include "delay.h" + +/* + * Where to put usercode, based on space reserved for bootloader. + * + * FIXME this has no business being here + */ +#if defined(MCU_STM32F103VE) || defined(MCU_STM32F205VE) || defined(MCU_STM32F406VG) + /* e.g., Aeroquad32 */ + #define USER_ADDR_ROM 0x08010000 /* ala42 */ + #define USER_ADDR_RAM 0x20000C00 + #define STACK_TOP 0x20000800 +#elif defined(BOARD_freeflight) +#define USER_ADDR_ROM 0x08000000 +#define USER_ADDR_RAM 0x20000000 +#define STACK_TOP 0x20000800 +#else +#define USER_ADDR_ROM 0x08005000 +#define USER_ADDR_RAM 0x20000C00 +#define STACK_TOP 0x20000800 +#endif +#endif + diff --git a/Libmaple/libmaple/libmaple/libmaple_types.h b/Libmaple/libmaple/libmaple/libmaple_types.h index 41869791..17bcfb11 100644 --- a/Libmaple/libmaple/libmaple/libmaple_types.h +++ b/Libmaple/libmaple/libmaple/libmaple_types.h @@ -1,56 +1,56 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file libmaple_types.h - * - * @brief libmaple types - */ - -#ifndef _LIBMAPLE_TYPES_H_ -#define _LIBMAPLE_TYPES_H_ - -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; -typedef unsigned long long uint64; - -typedef signed char int8; -typedef short int16; -typedef int int32; -typedef long long int64; - -typedef void (*voidFuncPtr)(void); - -#define __io volatile -#define __attr_flash __attribute__((section (".USER_FLASH"))) - -#ifndef NULL -#define NULL 0 -#endif - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file libmaple_types.h + * + * @brief libmaple types + */ + +#ifndef _LIBMAPLE_TYPES_H_ +#define _LIBMAPLE_TYPES_H_ + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef unsigned long long uint64; + +typedef signed char int8; +typedef short int16; +typedef int int32; +typedef long long int64; + +typedef void (*voidFuncPtr)(void); + +#define __io volatile +#define __attr_flash __attribute__((section (".USER_FLASH"))) + +#ifndef NULL +#define NULL 0 +#endif + +#endif + diff --git a/Libmaple/libmaple/libmaple/nvic.c b/Libmaple/libmaple/libmaple/nvic.c index 11dafb10..3be5a5ae 100644 --- a/Libmaple/libmaple/libmaple/nvic.c +++ b/Libmaple/libmaple/libmaple/nvic.c @@ -1,85 +1,85 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file nvic.c - * @brief Nested vector interrupt controller support. - */ - -#include "nvic.h" -#include "scb.h" -#include "stm32.h" - -/** - * @brief Set interrupt priority for an interrupt line - * - * Note: The STM32 only implements 4 bits of priority, ignoring the - * lower 4 bits. This means there are only 16 levels of priority. - * Bits[3:0] read as zero and ignore writes. - * - * @param irqn device to set - * @param priority Priority to set, 0 being highest priority and 15 - * being lowest. - */ -void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority) { - if (irqn < 0) { - /* This interrupt is in the system handler block */ - SCB_BASE->SHP[((uint32)irqn & 0xF) - 4] = (priority & 0xF) << 4; - } else { - NVIC_BASE->IP[irqn] = (priority & 0xF) << 4; - } -} - -/** - * @brief Initialize the NVIC - * @param vector_table_address Vector table base address. - * @param offset Offset from vector_table_address. Some restrictions - * apply to the use of nonzero offsets; see ST RM0008 - * and the ARM Cortex M3 Technical Reference Manual. - */ -void nvic_init(uint32 vector_table_address, uint32 offset) { - uint32 i; - - nvic_set_vector_table(vector_table_address, offset); - - /* - * Lower priority level for all peripheral interrupts to lowest - * possible. - */ - for (i = 0; i < STM32_NR_INTERRUPTS; i++) { - nvic_irq_set_priority((nvic_irq_num)i, 0xF); - } - - /* Lower systick interrupt priority to lowest level */ - nvic_irq_set_priority(NVIC_SYSTICK, 0xF); -} - -/** - * Reset the vector table address. - */ -void nvic_set_vector_table(uint32 addr, uint32 offset) { - SCB_BASE->VTOR = addr | (offset & 0x1FFFFF80); -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file nvic.c + * @brief Nested vector interrupt controller support. + */ + +#include "nvic.h" +#include "scb.h" +#include "stm32.h" + +/** + * @brief Set interrupt priority for an interrupt line + * + * Note: The STM32 only implements 4 bits of priority, ignoring the + * lower 4 bits. This means there are only 16 levels of priority. + * Bits[3:0] read as zero and ignore writes. + * + * @param irqn device to set + * @param priority Priority to set, 0 being highest priority and 15 + * being lowest. + */ +void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority) { + if (irqn < 0) { + /* This interrupt is in the system handler block */ + SCB_BASE->SHP[((uint32)irqn & 0xF) - 4] = (priority & 0xF) << 4; + } else { + NVIC_BASE->IP[irqn] = (priority & 0xF) << 4; + } +} + +/** + * @brief Initialize the NVIC + * @param vector_table_address Vector table base address. + * @param offset Offset from vector_table_address. Some restrictions + * apply to the use of nonzero offsets; see ST RM0008 + * and the ARM Cortex M3 Technical Reference Manual. + */ +void nvic_init(uint32 vector_table_address, uint32 offset) { + uint32 i; + + nvic_set_vector_table(vector_table_address, offset); + + /* + * Lower priority level for all peripheral interrupts to lowest + * possible. + */ + for (i = 0; i < STM32_NR_INTERRUPTS; i++) { + nvic_irq_set_priority((nvic_irq_num)i, 0xF); + } + + /* Lower systick interrupt priority to lowest level */ + nvic_irq_set_priority(NVIC_SYSTICK, 0xF); +} + +/** + * Reset the vector table address. + */ +void nvic_set_vector_table(uint32 addr, uint32 offset) { + SCB_BASE->VTOR = addr | (offset & 0x1FFFFF80); +} diff --git a/Libmaple/libmaple/libmaple/nvic.h b/Libmaple/libmaple/libmaple/nvic.h index 7154759a..e3b052d5 100644 --- a/Libmaple/libmaple/libmaple/nvic.h +++ b/Libmaple/libmaple/libmaple/nvic.h @@ -1,241 +1,241 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file nvic.h - * @brief Nested vector interrupt controller support. - * - * Basic usage: - * - * @code - * // Initialise the interrupt controller and point to the vector - * // table at the start of flash. - * nvic_init(0x08000000, 0); - * // Bind in a timer interrupt handler - * timer_attach_interrupt(TIMER_CC1_INTERRUPT, handler); - * // Optionally set the priority - * nvic_irq_set_priority(NVIC_TIMER1_CC, 5); - * // All done, enable all interrupts - * nvic_globalirq_enable(); - * @endcode - */ - -#ifndef _NVIC_H_ -#define _NVIC_H_ - -#include "libmaple_types.h" -#include "util.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/** NVIC register map type. */ -typedef struct nvic_reg_map { - __io uint32 ISER[8]; /**< Interrupt Set Enable Registers */ - uint32 RESERVED0[24]; /**< Reserved */ - __io uint32 ICER[8]; /**< Interrupt Clear Enable Registers */ - uint32 RSERVED1[24]; /**< Reserved */ - __io uint32 ISPR[8]; /**< Interrupt Set Pending Registers */ - uint32 RESERVED2[24]; /**< Reserved */ - __io uint32 ICPR[8]; /**< Interrupt Clear Pending Registers */ - uint32 RESERVED3[24]; /**< Reserved */ - __io uint32 IABR[8]; /**< Interrupt Active bit Registers */ - uint32 RESERVED4[56]; /**< Reserved */ - __io uint8 IP[240]; /**< Interrupt Priority Registers */ - uint32 RESERVED5[644]; /**< Reserved */ - __io uint32 STIR; /**< Software Trigger Interrupt Registers */ -} nvic_reg_map; - -/** NVIC register map base pointer. */ -#define NVIC_BASE ((struct nvic_reg_map*)0xE000E100) - -/** - * @brief Interrupt vector table interrupt numbers. - * - * Each positive-valued enumerator is the position of the - * corresponding interrupt in the vector table. Negative-valued - * enumerators correspond to interrupts controlled by the system - * handler block. - * - * @see scb.h - */ -typedef enum nvic_irq_num { - NVIC_NMI = -14, /**< Non-maskable interrupt */ - NVIC_HARDFAULT = -13, /**< Hard fault (all class of fault) */ - NVIC_MEM_MANAGE = -12, /**< Memory management */ - NVIC_BUS_FAULT = -11, /**< Bus fault: prefetch fault, memory - access fault. */ - NVIC_USAGE_FAULT = -10, /**< Usage fault: Undefined instruction or - illegal state. */ - NVIC_SVC = -5, /**< System service call via SWI insruction */ - NVIC_DEBUG_MON = -4, /**< Debug monitor */ - NVIC_PEND_SVC = -2, /**< Pendable request for system service */ - NVIC_SYSTICK = -1, /**< System tick timer */ - NVIC_WWDG = 0, /**< Window watchdog interrupt */ - NVIC_PVD = 1, /**< PVD through EXTI line detection */ - NVIC_TAMPER = 2, /**< Tamper */ - NVIC_RTC = 3, /**< Real-time clock */ - NVIC_FLASH = 4, /**< Flash */ - NVIC_RCC = 5, /**< Reset and clock control */ - NVIC_EXTI0 = 6, /**< EXTI line 0 */ - NVIC_EXTI1 = 7, /**< EXTI line 1 */ - NVIC_EXTI2 = 8, /**< EXTI line 2 */ - NVIC_EXTI3 = 9, /**< EXTI line 3 */ - NVIC_EXTI4 = 10, /**< EXTI line 4 */ - NVIC_DMA_CH1 = 11, /**< DMA1 channel 1 */ - NVIC_DMA_CH2 = 12, /**< DMA1 channel 2 */ - NVIC_DMA_CH3 = 13, /**< DMA1 channel 3 */ - NVIC_DMA_CH4 = 14, /**< DMA1 channel 4 */ - NVIC_DMA_CH5 = 15, /**< DMA1 channel 5 */ - NVIC_DMA_CH6 = 16, /**< DMA1 channel 6 */ - NVIC_DMA_CH7 = 17, /**< DMA1 channel 7 */ - NVIC_ADC_1_2 = 18, /**< ADC1 and ADC2 */ - NVIC_USB_HP_CAN_TX = 19, /**< USB high priority or CAN TX */ - NVIC_USB_LP_CAN_RX0 = 20, /**< USB low priority or CAN RX0 */ - NVIC_CAN_RX1 = 21, /**< CAN RX1 */ - NVIC_CAN_SCE = 22, /**< CAN SCE */ - NVIC_EXTI_9_5 = 23, /**< EXTI line [9:5] */ - NVIC_TIMER1_BRK = 24, /**< Timer 1 break */ - NVIC_TIMER1_UP = 25, /**< Timer 1 update */ - NVIC_TIMER1_TRG_COM = 26, /**< Timer 1 trigger and commutation */ - NVIC_TIMER1_CC = 27, /**< Timer 1 capture/compare */ - NVIC_TIMER2 = 28, /**< Timer 2 */ - NVIC_TIMER3 = 29, /**< Timer 3 */ - NVIC_TIMER4 = 30, /**< Timer 4 */ - NVIC_I2C1_EV = 31, /**< I2C1 event */ - NVIC_I2C1_ER = 32, /**< I2C1 error */ - NVIC_I2C2_EV = 33, /**< I2C2 event */ - NVIC_I2C2_ER = 34, /**< I2C2 error */ - NVIC_SPI1 = 35, /**< SPI1 */ - NVIC_SPI2 = 36, /**< SPI2 */ - NVIC_USART1 = 37, /**< USART1 */ - NVIC_USART2 = 38, /**< USART2 */ - NVIC_USART3 = 39, /**< USART3 */ - NVIC_EXTI_15_10 = 40, /**< EXTI line [15:10] */ - NVIC_RTCALARM = 41, /**< RTC alarm through EXTI line */ - NVIC_USBWAKEUP = 42, /**< USB wakeup from suspend through - EXTI line */ - NVIC_TIMER8_BRK = 43, /**< Timer 8 break */ - NVIC_TIMER8_UP = 44, /**< Timer 8 update */ - NVIC_TIMER8_TRG_COM = 45, /**< Timer 8 trigger and commutation */ - NVIC_TIMER8_CC = 46, /**< Timer 8 capture/compare */ -#ifdef STM32_HIGH_DENSITY - NVIC_ADC3 = 47, /**< ADC3 */ - NVIC_FSMC = 48, /**< FSMC */ - NVIC_SDIO = 49, /**< SDIO */ - NVIC_TIMER5 = 50, /**< Timer 5 */ - NVIC_SPI3 = 51, /**< SPI3 */ - NVIC_UART4 = 52, /**< UART4 */ - NVIC_UART5 = 53, /**< UART5 */ - NVIC_TIMER6 = 54, /**< Timer 6 */ - NVIC_TIMER7 = 55, /**< Timer 7 */ - NVIC_DMA2_CH1 = 56, /**< DMA2 channel 1 */ - NVIC_DMA2_CH2 = 57, /**< DMA2 channel 2 */ - NVIC_DMA2_CH3 = 58, /**< DMA2 channel 3 */ - NVIC_DMA2_CH_4_5 = 59, /**< DMA2 channels 4 and 5 */ -#endif -} nvic_irq_num; - -/* - * Initialises the interrupt controller and sets all interrupts to the - * lowest priority. - * - * For stand-alone products, the base address is normally the start of - * flash (0x08000000). - * - * @param vector_table_address base address of the vector table - */ -void nvic_init(uint32 vector_table_address, uint32 offset); - -/** - * Sets the base address of the vector table. - */ -void nvic_set_vector_table(uint32 address, uint32 offset); - -void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority); - -/** - * Enables interrupts and configurable fault handlers (clear PRIMASK). - */ -static inline void nvic_globalirq_enable() { - asm volatile("cpsie i"); -} - -/** - * Disable interrupts and configurable fault handlers (set PRIMASK). - */ -static inline void nvic_globalirq_disable() { - asm volatile("cpsid i"); -} - -/** - * @brief Enable interrupt irq_num - * @param irq_num Interrupt to enable - */ -static inline void nvic_irq_enable(nvic_irq_num irq_num) { - if (irq_num < 0) { - return; - } - NVIC_BASE->ISER[irq_num / 32] = BIT(irq_num % 32); -} - -/** - * @brief Disable interrupt irq_num - * @param irq_num Interrupt to disable - */ -static inline void nvic_irq_disable(nvic_irq_num irq_num) { - if (irq_num < 0) { - return; - } - NVIC_BASE->ICER[irq_num / 32] = BIT(irq_num % 32); -} - -/** - * @brief Quickly disable all interrupts. - * - * Calling this function is significantly faster than calling - * nvic_irq_disable() in a loop. - */ -static inline void nvic_irq_disable_all(void) { - /* Note: This only works up to XL density. The fix for - * connectivity line is: - * - * NVIC_BASE->ICER[2] = 0xF; - * - * We don't support connectivity line devices (yet), so leave it - * alone for now. - */ - NVIC_BASE->ICER[0] = 0xFFFFFFFF; - NVIC_BASE->ICER[1] = 0xFFFFFFFF; -} - -#ifdef __cplusplus -} -#endif - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file nvic.h + * @brief Nested vector interrupt controller support. + * + * Basic usage: + * + * @code + * // Initialise the interrupt controller and point to the vector + * // table at the start of flash. + * nvic_init(0x08000000, 0); + * // Bind in a timer interrupt handler + * timer_attach_interrupt(TIMER_CC1_INTERRUPT, handler); + * // Optionally set the priority + * nvic_irq_set_priority(NVIC_TIMER1_CC, 5); + * // All done, enable all interrupts + * nvic_globalirq_enable(); + * @endcode + */ + +#ifndef _NVIC_H_ +#define _NVIC_H_ + +#include "libmaple_types.h" +#include "util.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/** NVIC register map type. */ +typedef struct nvic_reg_map { + __io uint32 ISER[8]; /**< Interrupt Set Enable Registers */ + uint32 RESERVED0[24]; /**< Reserved */ + __io uint32 ICER[8]; /**< Interrupt Clear Enable Registers */ + uint32 RSERVED1[24]; /**< Reserved */ + __io uint32 ISPR[8]; /**< Interrupt Set Pending Registers */ + uint32 RESERVED2[24]; /**< Reserved */ + __io uint32 ICPR[8]; /**< Interrupt Clear Pending Registers */ + uint32 RESERVED3[24]; /**< Reserved */ + __io uint32 IABR[8]; /**< Interrupt Active bit Registers */ + uint32 RESERVED4[56]; /**< Reserved */ + __io uint8 IP[240]; /**< Interrupt Priority Registers */ + uint32 RESERVED5[644]; /**< Reserved */ + __io uint32 STIR; /**< Software Trigger Interrupt Registers */ +} nvic_reg_map; + +/** NVIC register map base pointer. */ +#define NVIC_BASE ((struct nvic_reg_map*)0xE000E100) + +/** + * @brief Interrupt vector table interrupt numbers. + * + * Each positive-valued enumerator is the position of the + * corresponding interrupt in the vector table. Negative-valued + * enumerators correspond to interrupts controlled by the system + * handler block. + * + * @see scb.h + */ +typedef enum nvic_irq_num { + NVIC_NMI = -14, /**< Non-maskable interrupt */ + NVIC_HARDFAULT = -13, /**< Hard fault (all class of fault) */ + NVIC_MEM_MANAGE = -12, /**< Memory management */ + NVIC_BUS_FAULT = -11, /**< Bus fault: prefetch fault, memory + access fault. */ + NVIC_USAGE_FAULT = -10, /**< Usage fault: Undefined instruction or + illegal state. */ + NVIC_SVC = -5, /**< System service call via SWI insruction */ + NVIC_DEBUG_MON = -4, /**< Debug monitor */ + NVIC_PEND_SVC = -2, /**< Pendable request for system service */ + NVIC_SYSTICK = -1, /**< System tick timer */ + NVIC_WWDG = 0, /**< Window watchdog interrupt */ + NVIC_PVD = 1, /**< PVD through EXTI line detection */ + NVIC_TAMPER = 2, /**< Tamper */ + NVIC_RTC = 3, /**< Real-time clock */ + NVIC_FLASH = 4, /**< Flash */ + NVIC_RCC = 5, /**< Reset and clock control */ + NVIC_EXTI0 = 6, /**< EXTI line 0 */ + NVIC_EXTI1 = 7, /**< EXTI line 1 */ + NVIC_EXTI2 = 8, /**< EXTI line 2 */ + NVIC_EXTI3 = 9, /**< EXTI line 3 */ + NVIC_EXTI4 = 10, /**< EXTI line 4 */ + NVIC_DMA_CH1 = 11, /**< DMA1 channel 1 */ + NVIC_DMA_CH2 = 12, /**< DMA1 channel 2 */ + NVIC_DMA_CH3 = 13, /**< DMA1 channel 3 */ + NVIC_DMA_CH4 = 14, /**< DMA1 channel 4 */ + NVIC_DMA_CH5 = 15, /**< DMA1 channel 5 */ + NVIC_DMA_CH6 = 16, /**< DMA1 channel 6 */ + NVIC_DMA_CH7 = 17, /**< DMA1 channel 7 */ + NVIC_ADC_1_2 = 18, /**< ADC1 and ADC2 */ + NVIC_USB_HP_CAN_TX = 19, /**< USB high priority or CAN TX */ + NVIC_USB_LP_CAN_RX0 = 20, /**< USB low priority or CAN RX0 */ + NVIC_CAN_RX1 = 21, /**< CAN RX1 */ + NVIC_CAN_SCE = 22, /**< CAN SCE */ + NVIC_EXTI_9_5 = 23, /**< EXTI line [9:5] */ + NVIC_TIMER1_BRK = 24, /**< Timer 1 break */ + NVIC_TIMER1_UP = 25, /**< Timer 1 update */ + NVIC_TIMER1_TRG_COM = 26, /**< Timer 1 trigger and commutation */ + NVIC_TIMER1_CC = 27, /**< Timer 1 capture/compare */ + NVIC_TIMER2 = 28, /**< Timer 2 */ + NVIC_TIMER3 = 29, /**< Timer 3 */ + NVIC_TIMER4 = 30, /**< Timer 4 */ + NVIC_I2C1_EV = 31, /**< I2C1 event */ + NVIC_I2C1_ER = 32, /**< I2C1 error */ + NVIC_I2C2_EV = 33, /**< I2C2 event */ + NVIC_I2C2_ER = 34, /**< I2C2 error */ + NVIC_SPI1 = 35, /**< SPI1 */ + NVIC_SPI2 = 36, /**< SPI2 */ + NVIC_USART1 = 37, /**< USART1 */ + NVIC_USART2 = 38, /**< USART2 */ + NVIC_USART3 = 39, /**< USART3 */ + NVIC_EXTI_15_10 = 40, /**< EXTI line [15:10] */ + NVIC_RTCALARM = 41, /**< RTC alarm through EXTI line */ + NVIC_USBWAKEUP = 42, /**< USB wakeup from suspend through + EXTI line */ + NVIC_TIMER8_BRK = 43, /**< Timer 8 break */ + NVIC_TIMER8_UP = 44, /**< Timer 8 update */ + NVIC_TIMER8_TRG_COM = 45, /**< Timer 8 trigger and commutation */ + NVIC_TIMER8_CC = 46, /**< Timer 8 capture/compare */ +#ifdef STM32_HIGH_DENSITY + NVIC_ADC3 = 47, /**< ADC3 */ + NVIC_FSMC = 48, /**< FSMC */ + NVIC_SDIO = 49, /**< SDIO */ + NVIC_TIMER5 = 50, /**< Timer 5 */ + NVIC_SPI3 = 51, /**< SPI3 */ + NVIC_UART4 = 52, /**< UART4 */ + NVIC_UART5 = 53, /**< UART5 */ + NVIC_TIMER6 = 54, /**< Timer 6 */ + NVIC_TIMER7 = 55, /**< Timer 7 */ + NVIC_DMA2_CH1 = 56, /**< DMA2 channel 1 */ + NVIC_DMA2_CH2 = 57, /**< DMA2 channel 2 */ + NVIC_DMA2_CH3 = 58, /**< DMA2 channel 3 */ + NVIC_DMA2_CH_4_5 = 59, /**< DMA2 channels 4 and 5 */ +#endif +} nvic_irq_num; + +/* + * Initialises the interrupt controller and sets all interrupts to the + * lowest priority. + * + * For stand-alone products, the base address is normally the start of + * flash (0x08000000). + * + * @param vector_table_address base address of the vector table + */ +void nvic_init(uint32 vector_table_address, uint32 offset); + +/** + * Sets the base address of the vector table. + */ +void nvic_set_vector_table(uint32 address, uint32 offset); + +void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority); + +/** + * Enables interrupts and configurable fault handlers (clear PRIMASK). + */ +static inline void nvic_globalirq_enable() { + asm volatile("cpsie i"); +} + +/** + * Disable interrupts and configurable fault handlers (set PRIMASK). + */ +static inline void nvic_globalirq_disable() { + asm volatile("cpsid i"); +} + +/** + * @brief Enable interrupt irq_num + * @param irq_num Interrupt to enable + */ +static inline void nvic_irq_enable(nvic_irq_num irq_num) { + if (irq_num < 0) { + return; + } + NVIC_BASE->ISER[irq_num / 32] = BIT(irq_num % 32); +} + +/** + * @brief Disable interrupt irq_num + * @param irq_num Interrupt to disable + */ +static inline void nvic_irq_disable(nvic_irq_num irq_num) { + if (irq_num < 0) { + return; + } + NVIC_BASE->ICER[irq_num / 32] = BIT(irq_num % 32); +} + +/** + * @brief Quickly disable all interrupts. + * + * Calling this function is significantly faster than calling + * nvic_irq_disable() in a loop. + */ +static inline void nvic_irq_disable_all(void) { + /* Note: This only works up to XL density. The fix for + * connectivity line is: + * + * NVIC_BASE->ICER[2] = 0xF; + * + * We don't support connectivity line devices (yet), so leave it + * alone for now. + */ + NVIC_BASE->ICER[0] = 0xFFFFFFFF; + NVIC_BASE->ICER[1] = 0xFFFFFFFF; +} + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Libmaple/libmaple/libmaple/pwr.c b/Libmaple/libmaple/libmaple/pwr.c index 5baaa488..ead8b64b 100644 --- a/Libmaple/libmaple/libmaple/pwr.c +++ b/Libmaple/libmaple/libmaple/pwr.c @@ -1,41 +1,41 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file pwr.c - * @brief Power control (PWR) support. - */ - -#include "pwr.h" -#include "rcc.h" - -/** - * Enables the power interface clock, and resets the power device. - */ -void pwr_init(void) { - rcc_clk_enable(RCC_PWR); - rcc_reset_dev(RCC_PWR); -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file pwr.c + * @brief Power control (PWR) support. + */ + +#include "pwr.h" +#include "rcc.h" + +/** + * Enables the power interface clock, and resets the power device. + */ +void pwr_init(void) { + rcc_clk_enable(RCC_PWR); + rcc_reset_dev(RCC_PWR); +} diff --git a/Libmaple/libmaple/libmaple/pwr.h b/Libmaple/libmaple/libmaple/pwr.h index a4f01b11..88b49c04 100644 --- a/Libmaple/libmaple/libmaple/pwr.h +++ b/Libmaple/libmaple/libmaple/pwr.h @@ -1,85 +1,85 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file pwr.h - * @brief Power control (PWR) defines. - */ - -#include "libmaple.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Power interface register map. */ -typedef struct pwr_reg_map { - __io uint32 CR; /**< Control register */ - __io uint32 CSR; /**< Control and status register */ -} pwr_reg_map; - -/** Power peripheral register map base pointer. */ -#define PWR_BASE ((struct pwr_reg_map*)0x40007000) - -/* - * Register bit definitions - */ - -/* Control register */ - -/** Disable backup domain write protection bit */ -#define PWR_CR_DBP 8 -/** Power voltage detector enable bit */ -#define PWR_CR_PVDE 4 -/** Clear standby flag bit */ -#define PWR_CR_CSBF 3 -/** Clear wakeup flag bit */ -#define PWR_CR_CWUF 2 -/** Power down deepsleep bit */ -#define PWR_CR_PDDS 1 -/** Low-power deepsleep bit */ -#define PWR_CR_LPDS 0 - -/* Control and status register */ - -/** Enable wakeup pin bit */ -#define PWR_CSR_EWUP 8 -/** PVD output bit */ -#define PWR_CSR_PVDO 2 -/** Standby flag bit */ -#define PWR_CSR_SBF 1 -/** Wakeup flag bit */ -#define PWR_CSR_WUF 0 - -/* - * Convenience functions - */ - -void pwr_init(void); - -#ifdef __cplusplus -} -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file pwr.h + * @brief Power control (PWR) defines. + */ + +#include "libmaple.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Power interface register map. */ +typedef struct pwr_reg_map { + __io uint32 CR; /**< Control register */ + __io uint32 CSR; /**< Control and status register */ +} pwr_reg_map; + +/** Power peripheral register map base pointer. */ +#define PWR_BASE ((struct pwr_reg_map*)0x40007000) + +/* + * Register bit definitions + */ + +/* Control register */ + +/** Disable backup domain write protection bit */ +#define PWR_CR_DBP 8 +/** Power voltage detector enable bit */ +#define PWR_CR_PVDE 4 +/** Clear standby flag bit */ +#define PWR_CR_CSBF 3 +/** Clear wakeup flag bit */ +#define PWR_CR_CWUF 2 +/** Power down deepsleep bit */ +#define PWR_CR_PDDS 1 +/** Low-power deepsleep bit */ +#define PWR_CR_LPDS 0 + +/* Control and status register */ + +/** Enable wakeup pin bit */ +#define PWR_CSR_EWUP 8 +/** PVD output bit */ +#define PWR_CSR_PVDO 2 +/** Standby flag bit */ +#define PWR_CSR_SBF 1 +/** Wakeup flag bit */ +#define PWR_CSR_WUF 0 + +/* + * Convenience functions + */ + +void pwr_init(void); + +#ifdef __cplusplus +} +#endif diff --git a/Libmaple/libmaple/libmaple/rcc.c b/Libmaple/libmaple/libmaple/rcc.c index 1a3757b1..189ffe2a 100644 --- a/Libmaple/libmaple/libmaple/rcc.c +++ b/Libmaple/libmaple/libmaple/rcc.c @@ -1,37 +1,37 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file rcc.c - * @brief Implements pretty much only the basic clock setup on the - * stm32, clock enable/disable and peripheral reset commands. - */ - -#ifdef STM32F2 -#include "rccF2.c" -#else -#include "rccF1.c" -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file rcc.c + * @brief Implements pretty much only the basic clock setup on the + * stm32, clock enable/disable and peripheral reset commands. + */ + +#ifdef STM32F2 +#include "rccF2.c" +#else +#include "rccF1.c" +#endif diff --git a/Libmaple/libmaple/libmaple/rcc.h b/Libmaple/libmaple/libmaple/rcc.h index c55c6528..6317cbdb 100644 --- a/Libmaple/libmaple/libmaple/rcc.h +++ b/Libmaple/libmaple/libmaple/rcc.h @@ -1,36 +1,36 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file rcc.h - * @brief reset and clock control definitions and prototypes - */ - -#ifdef STM32F2 -#include "rccF2.h" -#else -#include "rccF1.h" -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file rcc.h + * @brief reset and clock control definitions and prototypes + */ + +#ifdef STM32F2 +#include "rccF2.h" +#else +#include "rccF1.h" +#endif diff --git a/Libmaple/libmaple/libmaple/rccF1.c b/Libmaple/libmaple/libmaple/rccF1.c index d0ffc201..9873fbd0 100644 --- a/Libmaple/libmaple/libmaple/rccF1.c +++ b/Libmaple/libmaple/libmaple/rccF1.c @@ -1,228 +1,228 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file rcc.c - * @brief Implements pretty much only the basic clock setup on the - * stm32, clock enable/disable and peripheral reset commands. - */ - -#include "libmaple.h" -#include "flash.h" -#include "rcc.h" -#include "bitband.h" - -#define APB1 RCC_APB1 -#define APB2 RCC_APB2 -#define AHB RCC_AHB - -struct rcc_dev_info { - const rcc_clk_domain clk_domain; - const uint8 line_num; -}; - -/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset - * register bit numbers. */ -static const struct rcc_dev_info rcc_dev_table[] = { - [RCC_GPIOA] = { .clk_domain = APB2, .line_num = 2 }, - [RCC_GPIOB] = { .clk_domain = APB2, .line_num = 3 }, - [RCC_GPIOC] = { .clk_domain = APB2, .line_num = 4 }, - [RCC_GPIOD] = { .clk_domain = APB2, .line_num = 5 }, - [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 }, - [RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 }, - [RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 }, - [RCC_ADC3] = { .clk_domain = APB2, .line_num = 15 }, - [RCC_USART1] = { .clk_domain = APB2, .line_num = 14 }, - [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, - [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, - [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 }, - [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 }, - [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 }, - [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 }, - [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 }, - [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 }, - [RCC_DMA1] = { .clk_domain = AHB, .line_num = 0 }, - [RCC_PWR] = { .clk_domain = APB1, .line_num = 28}, - [RCC_BKP] = { .clk_domain = APB1, .line_num = 27}, - [RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 }, - [RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 }, - [RCC_CRC] = { .clk_domain = AHB, .line_num = 6}, - [RCC_FLITF] = { .clk_domain = AHB, .line_num = 4}, - [RCC_SRAM] = { .clk_domain = AHB, .line_num = 2}, -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - [RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 }, - [RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 }, - [RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 }, - [RCC_UART4] = { .clk_domain = APB1, .line_num = 19 }, - [RCC_UART5] = { .clk_domain = APB1, .line_num = 20 }, - [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, - [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, - [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, - [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 }, - [RCC_FSMC] = { .clk_domain = AHB, .line_num = 8 }, - [RCC_DAC] = { .clk_domain = APB1, .line_num = 29 }, - [RCC_DMA2] = { .clk_domain = AHB, .line_num = 1 }, - [RCC_SDIO] = { .clk_domain = AHB, .line_num = 10 }, - [RCC_SPI3] = { .clk_domain = APB1, .line_num = 15 }, -#endif -#ifdef STM32_XL_DENSITY - [RCC_TIMER9] = { .clk_domain = APB2, .line_num = 19 }, - [RCC_TIMER10] = { .clk_domain = APB2, .line_num = 20 }, - [RCC_TIMER11] = { .clk_domain = APB2, .line_num = 21 }, - [RCC_TIMER12] = { .clk_domain = APB1, .line_num = 6 }, - [RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 }, - [RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 }, -#endif -}; - -/** - * @brief Initialize the clock control system. Initializes the system - * clock source to use the PLL driven by an external oscillator - * @param sysclk_src system clock source, must be PLL - * @param pll_src pll clock source, must be HSE - * @param pll_mul pll multiplier - */ -void rcc_clk_init(rcc_sysclk_src sysclk_src, - rcc_pllsrc pll_src, - rcc_pll_multiplier pll_mul) { - uint32 cfgr = 0; - uint32 cr; - - /* Assume that we're going to clock the chip off the PLL, fed by - * the HSE */ - ASSERT(sysclk_src == RCC_CLKSRC_PLL && - pll_src == RCC_PLLSRC_HSE); - - RCC_BASE->CFGR = pll_src | pll_mul; - - /* Turn on the HSE */ - cr = RCC_BASE->CR; - cr |= RCC_CR_HSEON; - RCC_BASE->CR = cr; - while (!(RCC_BASE->CR & RCC_CR_HSERDY)) - ; - - /* Now the PLL */ - cr |= RCC_CR_PLLON; - RCC_BASE->CR = cr; - while (!(RCC_BASE->CR & RCC_CR_PLLRDY)) - ; - - /* Finally, let's switch over to the PLL */ - cfgr &= ~RCC_CFGR_SW; - cfgr |= RCC_CFGR_SW_PLL; - RCC_BASE->CFGR = cfgr; - while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) - ; -} - -/** - * @brief Turn on the clock line on a peripheral - * @param id Clock ID of the peripheral to turn on. - */ -void rcc_clk_enable(rcc_clk_id id) { - static const __io uint32* enable_regs[] = { - [APB1] = &RCC_BASE->APB1ENR, - [APB2] = &RCC_BASE->APB2ENR, - [AHB] = &RCC_BASE->AHBENR, - }; - - rcc_clk_domain clk_domain = rcc_dev_clk(id); - __io uint32* enr = (__io uint32*)enable_regs[clk_domain]; - uint8 lnum = rcc_dev_table[id].line_num; - - bb_peri_set_bit(enr, lnum, 1); -} - -/** - * @brief Reset a peripheral. - * @param id Clock ID of the peripheral to reset. - */ -void rcc_reset_dev(rcc_clk_id id) { - static const __io uint32* reset_regs[] = { - [APB1] = &RCC_BASE->APB1RSTR, - [APB2] = &RCC_BASE->APB2RSTR, - }; - - rcc_clk_domain clk_domain = rcc_dev_clk(id); - __io void* addr = (__io void*)reset_regs[clk_domain]; - uint8 lnum = rcc_dev_table[id].line_num; - - bb_peri_set_bit(addr, lnum, 1); - bb_peri_set_bit(addr, lnum, 0); -} - -/** - * @brief Get a peripheral's clock domain - * @param id Clock ID of the peripheral whose clock domain to return - * @return Clock source for the given clock ID - */ -rcc_clk_domain rcc_dev_clk(rcc_clk_id id) { - return rcc_dev_table[id].clk_domain; -} - -/** - * @brief Get a peripheral's clock domain speed - * @param id Clock ID of the peripheral whose clock domain speed to return - * @return Clock speed for the given clock ID - */ -uint32 rcc_dev_clk_speed(rcc_clk_id id) { - static const uint32 rcc_dev_clk_speed_table[] = { - [RCC_AHB] = 72000000, - [RCC_APB1] = 36000000, - [RCC_APB2] = 72000000 - }; - return rcc_dev_clk_speed_table[rcc_dev_clk(id)]; -} - -/** - * @brief Get a peripheral's timer clock domain speed - * @param id Clock ID of the peripheral whose clock domain speed to return - * @return Clock speed for the given clock ID - */ -uint32 rcc_dev_timer_clk_speed(rcc_clk_id id) { - return rcc_dev_clk_speed(RCC_APB2); // 72 MHz for all counter -} - -/** - * @brief Set the divider on a peripheral prescaler - * @param prescaler prescaler to set - * @param divider prescaler divider - */ -void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { - static const uint32 masks[] = { - [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE, - [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1, - [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2, - [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE, - [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE, - }; - - uint32 cfgr = RCC_BASE->CFGR; - cfgr &= ~masks[prescaler]; - cfgr |= divider; - RCC_BASE->CFGR = cfgr; -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file rcc.c + * @brief Implements pretty much only the basic clock setup on the + * stm32, clock enable/disable and peripheral reset commands. + */ + +#include "libmaple.h" +#include "flash.h" +#include "rcc.h" +#include "bitband.h" + +#define APB1 RCC_APB1 +#define APB2 RCC_APB2 +#define AHB RCC_AHB + +struct rcc_dev_info { + const rcc_clk_domain clk_domain; + const uint8 line_num; +}; + +/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset + * register bit numbers. */ +static const struct rcc_dev_info rcc_dev_table[] = { + [RCC_GPIOA] = { .clk_domain = APB2, .line_num = 2 }, + [RCC_GPIOB] = { .clk_domain = APB2, .line_num = 3 }, + [RCC_GPIOC] = { .clk_domain = APB2, .line_num = 4 }, + [RCC_GPIOD] = { .clk_domain = APB2, .line_num = 5 }, + [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 }, + [RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 }, + [RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 }, + [RCC_ADC3] = { .clk_domain = APB2, .line_num = 15 }, + [RCC_USART1] = { .clk_domain = APB2, .line_num = 14 }, + [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, + [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, + [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 }, + [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 }, + [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 }, + [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 }, + [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 }, + [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 }, + [RCC_DMA1] = { .clk_domain = AHB, .line_num = 0 }, + [RCC_PWR] = { .clk_domain = APB1, .line_num = 28}, + [RCC_BKP] = { .clk_domain = APB1, .line_num = 27}, + [RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 }, + [RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 }, + [RCC_CRC] = { .clk_domain = AHB, .line_num = 6}, + [RCC_FLITF] = { .clk_domain = AHB, .line_num = 4}, + [RCC_SRAM] = { .clk_domain = AHB, .line_num = 2}, +#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) + [RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 }, + [RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 }, + [RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 }, + [RCC_UART4] = { .clk_domain = APB1, .line_num = 19 }, + [RCC_UART5] = { .clk_domain = APB1, .line_num = 20 }, + [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, + [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, + [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, + [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 }, + [RCC_FSMC] = { .clk_domain = AHB, .line_num = 8 }, + [RCC_DAC] = { .clk_domain = APB1, .line_num = 29 }, + [RCC_DMA2] = { .clk_domain = AHB, .line_num = 1 }, + [RCC_SDIO] = { .clk_domain = AHB, .line_num = 10 }, + [RCC_SPI3] = { .clk_domain = APB1, .line_num = 15 }, +#endif +#ifdef STM32_XL_DENSITY + [RCC_TIMER9] = { .clk_domain = APB2, .line_num = 19 }, + [RCC_TIMER10] = { .clk_domain = APB2, .line_num = 20 }, + [RCC_TIMER11] = { .clk_domain = APB2, .line_num = 21 }, + [RCC_TIMER12] = { .clk_domain = APB1, .line_num = 6 }, + [RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 }, + [RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 }, +#endif +}; + +/** + * @brief Initialize the clock control system. Initializes the system + * clock source to use the PLL driven by an external oscillator + * @param sysclk_src system clock source, must be PLL + * @param pll_src pll clock source, must be HSE + * @param pll_mul pll multiplier + */ +void rcc_clk_init(rcc_sysclk_src sysclk_src, + rcc_pllsrc pll_src, + rcc_pll_multiplier pll_mul) { + uint32 cfgr = 0; + uint32 cr; + + /* Assume that we're going to clock the chip off the PLL, fed by + * the HSE */ + ASSERT(sysclk_src == RCC_CLKSRC_PLL && + pll_src == RCC_PLLSRC_HSE); + + RCC_BASE->CFGR = pll_src | pll_mul; + + /* Turn on the HSE */ + cr = RCC_BASE->CR; + cr |= RCC_CR_HSEON; + RCC_BASE->CR = cr; + while (!(RCC_BASE->CR & RCC_CR_HSERDY)) + ; + + /* Now the PLL */ + cr |= RCC_CR_PLLON; + RCC_BASE->CR = cr; + while (!(RCC_BASE->CR & RCC_CR_PLLRDY)) + ; + + /* Finally, let's switch over to the PLL */ + cfgr &= ~RCC_CFGR_SW; + cfgr |= RCC_CFGR_SW_PLL; + RCC_BASE->CFGR = cfgr; + while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) + ; +} + +/** + * @brief Turn on the clock line on a peripheral + * @param id Clock ID of the peripheral to turn on. + */ +void rcc_clk_enable(rcc_clk_id id) { + static const __io uint32* enable_regs[] = { + [APB1] = &RCC_BASE->APB1ENR, + [APB2] = &RCC_BASE->APB2ENR, + [AHB] = &RCC_BASE->AHBENR, + }; + + rcc_clk_domain clk_domain = rcc_dev_clk(id); + __io uint32* enr = (__io uint32*)enable_regs[clk_domain]; + uint8 lnum = rcc_dev_table[id].line_num; + + bb_peri_set_bit(enr, lnum, 1); +} + +/** + * @brief Reset a peripheral. + * @param id Clock ID of the peripheral to reset. + */ +void rcc_reset_dev(rcc_clk_id id) { + static const __io uint32* reset_regs[] = { + [APB1] = &RCC_BASE->APB1RSTR, + [APB2] = &RCC_BASE->APB2RSTR, + }; + + rcc_clk_domain clk_domain = rcc_dev_clk(id); + __io void* addr = (__io void*)reset_regs[clk_domain]; + uint8 lnum = rcc_dev_table[id].line_num; + + bb_peri_set_bit(addr, lnum, 1); + bb_peri_set_bit(addr, lnum, 0); +} + +/** + * @brief Get a peripheral's clock domain + * @param id Clock ID of the peripheral whose clock domain to return + * @return Clock source for the given clock ID + */ +rcc_clk_domain rcc_dev_clk(rcc_clk_id id) { + return rcc_dev_table[id].clk_domain; +} + +/** + * @brief Get a peripheral's clock domain speed + * @param id Clock ID of the peripheral whose clock domain speed to return + * @return Clock speed for the given clock ID + */ +uint32 rcc_dev_clk_speed(rcc_clk_id id) { + static const uint32 rcc_dev_clk_speed_table[] = { + [RCC_AHB] = 72000000, + [RCC_APB1] = 36000000, + [RCC_APB2] = 72000000 + }; + return rcc_dev_clk_speed_table[rcc_dev_clk(id)]; +} + +/** + * @brief Get a peripheral's timer clock domain speed + * @param id Clock ID of the peripheral whose clock domain speed to return + * @return Clock speed for the given clock ID + */ +uint32 rcc_dev_timer_clk_speed(rcc_clk_id id) { + return rcc_dev_clk_speed(RCC_APB2); // 72 MHz for all counter +} + +/** + * @brief Set the divider on a peripheral prescaler + * @param prescaler prescaler to set + * @param divider prescaler divider + */ +void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { + static const uint32 masks[] = { + [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE, + [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1, + [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2, + [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE, + [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE, + }; + + uint32 cfgr = RCC_BASE->CFGR; + cfgr &= ~masks[prescaler]; + cfgr |= divider; + RCC_BASE->CFGR = cfgr; +} diff --git a/Libmaple/libmaple/libmaple/rccF1.h b/Libmaple/libmaple/libmaple/rccF1.h index e31d4b69..dd79704d 100644 --- a/Libmaple/libmaple/libmaple/rccF1.h +++ b/Libmaple/libmaple/libmaple/rccF1.h @@ -1,572 +1,572 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file rcc.h - * @brief reset and clock control definitions and prototypes - */ - -#include "libmaple_types.h" - -#ifndef _RCC_H_ -#define _RCC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -/** RCC register map type */ -typedef struct rcc_reg_map { - __io uint32 CR; /**< Clock control register */ - __io uint32 CFGR; /**< Clock configuration register */ - __io uint32 CIR; /**< Clock interrupt register */ - __io uint32 APB2RSTR; /**< APB2 peripheral reset register */ - __io uint32 APB1RSTR; /**< APB1 peripheral reset register */ - __io uint32 AHBENR; /**< AHB peripheral clock enable register */ - __io uint32 APB2ENR; /**< APB2 peripheral clock enable register */ - __io uint32 APB1ENR; /**< APB1 peripheral clock enable register */ - __io uint32 BDCR; /**< Backup domain control register */ - __io uint32 CSR; /**< Control/status register */ -} rcc_reg_map; - -/** RCC register map base pointer */ -#define RCC_BASE ((struct rcc_reg_map*)0x40021000) - -/* - * Register bit definitions - */ - -/* Clock control register */ - -#define RCC_CR_PLLRDY_BIT 25 -#define RCC_CR_PLLON_BIT 24 -#define RCC_CR_CSSON_BIT 19 -#define RCC_CR_HSEBYP_BIT 18 -#define RCC_CR_HSERDY_BIT 17 -#define RCC_CR_HSEON_BIT 16 -#define RCC_CR_HSIRDY_BIT 1 -#define RCC_CR_HSION_BIT 0 - -#define RCC_CR_PLLRDY BIT(RCC_CR_PLLRDY_BIT) -#define RCC_CR_PLLON BIT(RCC_CR_PLLON_BIT) -#define RCC_CR_CSSON BIT(RCC_CR_CSSON_BIT) -#define RCC_CR_HSEBYP BIT(RCC_CR_HSEBYP_BIT) -#define RCC_CR_HSERDY BIT(RCC_CR_HSERDY_BIT) -#define RCC_CR_HSEON BIT(RCC_CR_HSEON_BIT) -#define RCC_CR_HSICAL (0xFF << 8) -#define RCC_CR_HSITRIM (0x1F << 3) -#define RCC_CR_HSIRDY BIT(RCC_CR_HSIRDY_BIT) -#define RCC_CR_HSION BIT(RCC_CR_HSION_BIT) - -/* Clock configuration register */ - -#define RCC_CFGR_USBPRE_BIT 22 -#define RCC_CFGR_PLLXTPRE_BIT 17 -#define RCC_CFGR_PLLSRC_BIT 16 - -#define RCC_CFGR_MCO (0x3 << 24) -#define RCC_CFGR_USBPRE BIT(RCC_CFGR_USBPRE_BIT) -#define RCC_CFGR_PLLMUL (0xF << 18) -#define RCC_CFGR_PLLXTPRE BIT(RCC_CFGR_PLLXTPRE_BIT) -#define RCC_CFGR_PLLSRC BIT(RCC_CFGR_PLLSRC_BIT) -#define RCC_CFGR_ADCPRE (0x3 << 14) -#define RCC_CFGR_PPRE2 (0x7 << 11) -#define RCC_CFGR_PPRE1 (0x7 << 8) -#define RCC_CFGR_HPRE (0xF << 4) -#define RCC_CFGR_SWS (0x3 << 2) -#define RCC_CFGR_SWS_PLL (0x2 << 2) -#define RCC_CFGR_SWS_HSE (0x1 << 2) -#define RCC_CFGR_SW 0x3 -#define RCC_CFGR_SW_PLL 0x2 -#define RCC_CFGR_SW_HSE 0x1 - -/* Clock interrupt register */ - -#define RCC_CIR_CSSC_BIT 23 -#define RCC_CIR_PLLRDYC_BIT 20 -#define RCC_CIR_HSERDYC_BIT 19 -#define RCC_CIR_HSIRDYC_BIT 18 -#define RCC_CIR_LSERDYC_BIT 17 -#define RCC_CIR_LSIRDYC_BIT 16 -#define RCC_CIR_PLLRDYIE_BIT 12 -#define RCC_CIR_HSERDYIE_BIT 11 -#define RCC_CIR_HSIRDYIE_BIT 10 -#define RCC_CIR_LSERDYIE_BIT 9 -#define RCC_CIR_LSIRDYIE_BIT 8 -#define RCC_CIR_CSSF_BIT 7 -#define RCC_CIR_PLLRDYF_BIT 4 -#define RCC_CIR_HSERDYF_BIT 3 -#define RCC_CIR_HSIRDYF_BIT 2 -#define RCC_CIR_LSERDYF_BIT 1 -#define RCC_CIR_LSIRDYF_BIT 0 - -#define RCC_CIR_CSSC BIT(RCC_CIR_CSSC_BIT) -#define RCC_CIR_PLLRDYC BIT(RCC_CIR_PLLRDYC_BIT) -#define RCC_CIR_HSERDYC BIT(RCC_CIR_HSERDYC_BIT) -#define RCC_CIR_HSIRDYC BIT(RCC_CIR_HSIRDYC_BIT) -#define RCC_CIR_LSERDYC BIT(RCC_CIR_LSERDYC_BIT) -#define RCC_CIR_LSIRDYC BIT(RCC_CIR_LSIRDYC_BIT) -#define RCC_CIR_PLLRDYIE BIT(RCC_CIR_PLLRDYIE_BIT) -#define RCC_CIR_HSERDYIE BIT(RCC_CIR_HSERDYIE_BIT) -#define RCC_CIR_HSIRDYIE BIT(RCC_CIR_HSIRDYIE_BIT) -#define RCC_CIR_LSERDYIE BIT(RCC_CIR_LSERDYIE_BIT) -#define RCC_CIR_LSIRDYIE BIT(RCC_CIR_LSIRDYIE_BIT) -#define RCC_CIR_CSSF BIT(RCC_CIR_CSSF_BIT) -#define RCC_CIR_PLLRDYF BIT(RCC_CIR_PLLRDYF_BIT) -#define RCC_CIR_HSERDYF BIT(RCC_CIR_HSERDYF_BIT) -#define RCC_CIR_HSIRDYF BIT(RCC_CIR_HSIRDYF_BIT) -#define RCC_CIR_LSERDYF BIT(RCC_CIR_LSERDYF_BIT) -#define RCC_CIR_LSIRDYF BIT(RCC_CIR_LSIRDYF_BIT) - -/* APB2 peripheral reset register */ - -#define RCC_APB2RSTR_TIM11RST_BIT 21 -#define RCC_APB2RSTR_TIM10RST_BIT 20 -#define RCC_APB2RSTR_TIM9RST_BIT 19 -#define RCC_APB2RSTR_ADC3RST_BIT 15 -#define RCC_APB2RSTR_USART1RST_BIT 14 -#define RCC_APB2RSTR_TIM8RST_BIT 13 -#define RCC_APB2RSTR_SPI1RST_BIT 12 -#define RCC_APB2RSTR_TIM1RST_BIT 11 -#define RCC_APB2RSTR_ADC2RST_BIT 10 -#define RCC_APB2RSTR_ADC1RST_BIT 9 -#define RCC_APB2RSTR_IOPGRST_BIT 8 -#define RCC_APB2RSTR_IOPFRST_BIT 7 -#define RCC_APB2RSTR_IOPERST_BIT 6 -#define RCC_APB2RSTR_IOPDRST_BIT 5 -#define RCC_APB2RSTR_IOPCRST_BIT 4 -#define RCC_APB2RSTR_IOPBRST_BIT 3 -#define RCC_APB2RSTR_IOPARST_BIT 2 -#define RCC_APB2RSTR_AFIORST_BIT 0 - -#define RCC_APB2RSTR_TIM11RST BIT(RCC_APB2RSTR_TIM11RST_BIT) -#define RCC_APB2RSTR_TIM10RST BIT(RCC_APB2RSTR_TIM10RST_BIT) -#define RCC_APB2RSTR_TIM9RST BIT(RCC_APB2RSTR_TIM9RST_BIT) -#define RCC_APB2RSTR_ADC3RST BIT(RCC_APB2RSTR_ADC3RST_BIT) -#define RCC_APB2RSTR_USART1RST BIT(RCC_APB2RSTR_USART1RST_BIT) -#define RCC_APB2RSTR_TIM8RST BIT(RCC_APB2RSTR_TIM8RST_BIT) -#define RCC_APB2RSTR_SPI1RST BIT(RCC_APB2RSTR_SPI1RST_BIT) -#define RCC_APB2RSTR_TIM1RST BIT(RCC_APB2RSTR_TIM1RST_BIT) -#define RCC_APB2RSTR_ADC2RST BIT(RCC_APB2RSTR_ADC2RST_BIT) -#define RCC_APB2RSTR_ADC1RST BIT(RCC_APB2RSTR_ADC1RST_BIT) -#define RCC_APB2RSTR_IOPGRST BIT(RCC_APB2RSTR_IOPGRST_BIT) -#define RCC_APB2RSTR_IOPFRST BIT(RCC_APB2RSTR_IOPFRST_BIT) -#define RCC_APB2RSTR_IOPERST BIT(RCC_APB2RSTR_IOPERST_BIT) -#define RCC_APB2RSTR_IOPDRST BIT(RCC_APB2RSTR_IOPDRST_BIT) -#define RCC_APB2RSTR_IOPCRST BIT(RCC_APB2RSTR_IOPCRST_BIT) -#define RCC_APB2RSTR_IOPBRST BIT(RCC_APB2RSTR_IOPBRST_BIT) -#define RCC_APB2RSTR_IOPARST BIT(RCC_APB2RSTR_IOPARST_BIT) -#define RCC_APB2RSTR_AFIORST BIT(RCC_APB2RSTR_AFIORST_BIT) - -/* APB1 peripheral reset register */ - -#define RCC_APB1RSTR_DACRST_BIT 29 -#define RCC_APB1RSTR_PWRRST_BIT 28 -#define RCC_APB1RSTR_BKPRST_BIT 27 -#define RCC_APB1RSTR_CANRST_BIT 25 -#define RCC_APB1RSTR_USBRST_BIT 23 -#define RCC_APB1RSTR_I2C2RST_BIT 22 -#define RCC_APB1RSTR_I2C1RST_BIT 21 -#define RCC_APB1RSTR_UART5RST_BIT 20 -#define RCC_APB1RSTR_UART4RST_BIT 19 -#define RCC_APB1RSTR_USART3RST_BIT 18 -#define RCC_APB1RSTR_USART2RST_BIT 17 -#define RCC_APB1RSTR_SPI3RST_BIT 15 -#define RCC_APB1RSTR_SPI2RST_BIT 14 -#define RCC_APB1RSTR_WWDRST_BIT 11 -#define RCC_APB1RSTR_TIM14RST_BIT 8 -#define RCC_APB1RSTR_TIM13RST_BIT 7 -#define RCC_APB1RSTR_TIM12RST_BIT 6 -#define RCC_APB1RSTR_TIM7RST_BIT 5 -#define RCC_APB1RSTR_TIM6RST_BIT 4 -#define RCC_APB1RSTR_TIM5RST_BIT 3 -#define RCC_APB1RSTR_TIM4RST_BIT 2 -#define RCC_APB1RSTR_TIM3RST_BIT 1 -#define RCC_APB1RSTR_TIM2RST_BIT 0 - -#define RCC_APB1RSTR_DACRST BIT(RCC_APB1RSTR_DACRST_BIT) -#define RCC_APB1RSTR_PWRRST BIT(RCC_APB1RSTR_PWRRST_BIT) -#define RCC_APB1RSTR_BKPRST BIT(RCC_APB1RSTR_BKPRST_BIT) -#define RCC_APB1RSTR_CANRST BIT(RCC_APB1RSTR_CANRST_BIT) -#define RCC_APB1RSTR_USBRST BIT(RCC_APB1RSTR_USBRST_BIT) -#define RCC_APB1RSTR_I2C2RST BIT(RCC_APB1RSTR_I2C2RST_BIT) -#define RCC_APB1RSTR_I2C1RST BIT(RCC_APB1RSTR_I2C1RST_BIT) -#define RCC_APB1RSTR_UART5RST BIT(RCC_APB1RSTR_UART5RST_BIT) -#define RCC_APB1RSTR_UART4RST BIT(RCC_APB1RSTR_UART4RST_BIT) -#define RCC_APB1RSTR_USART3RST BIT(RCC_APB1RSTR_USART3RST_BIT) -#define RCC_APB1RSTR_USART2RST BIT(RCC_APB1RSTR_USART2RST_BIT) -#define RCC_APB1RSTR_SPI3RST BIT(RCC_APB1RSTR_SPI3RST_BIT) -#define RCC_APB1RSTR_SPI2RST BIT(RCC_APB1RSTR_SPI2RST_BIT) -#define RCC_APB1RSTR_WWDRST BIT(RCC_APB1RSTR_WWDRST_BIT) -#define RCC_APB1RSTR_TIM14RST BIT(RCC_APB1RSTR_TIM14RST_BIT) -#define RCC_APB1RSTR_TIM13RST BIT(RCC_APB1RSTR_TIM13RST_BIT) -#define RCC_APB1RSTR_TIM12RST BIT(RCC_APB1RSTR_TIM12RST_BIT) -#define RCC_APB1RSTR_TIM7RST BIT(RCC_APB1RSTR_TIM7RST_BIT) -#define RCC_APB1RSTR_TIM6RST BIT(RCC_APB1RSTR_TIM6RST_BIT) -#define RCC_APB1RSTR_TIM5RST BIT(RCC_APB1RSTR_TIM5RST_BIT) -#define RCC_APB1RSTR_TIM4RST BIT(RCC_APB1RSTR_TIM4RST_BIT) -#define RCC_APB1RSTR_TIM3RST BIT(RCC_APB1RSTR_TIM3RST_BIT) -#define RCC_APB1RSTR_TIM2RST BIT(RCC_APB1RSTR_TIM2RST_BIT) - -/* AHB peripheral clock enable register */ - -#define RCC_AHBENR_SDIOEN_BIT 10 -#define RCC_AHBENR_FSMCEN_BIT 8 -#define RCC_AHBENR_CRCEN_BIT 7 -#define RCC_AHBENR_FLITFEN_BIT 4 -#define RCC_AHBENR_SRAMEN_BIT 2 -#define RCC_AHBENR_DMA2EN_BIT 1 -#define RCC_AHBENR_DMA1EN_BIT 0 - -#define RCC_AHBENR_SDIOEN BIT(RCC_AHBENR_SDIOEN_BIT) -#define RCC_AHBENR_FSMCEN BIT(RCC_AHBENR_FSMCEN_BIT) -#define RCC_AHBENR_CRCEN BIT(RCC_AHBENR_CRCEN_BIT) -#define RCC_AHBENR_FLITFEN BIT(RCC_AHBENR_FLITFEN_BIT) -#define RCC_AHBENR_SRAMEN BIT(RCC_AHBENR_SRAMEN_BIT) -#define RCC_AHBENR_DMA2EN BIT(RCC_AHBENR_DMA2EN_BIT) -#define RCC_AHBENR_DMA1EN BIT(RCC_AHBENR_DMA1EN_BIT) - -/* APB2 peripheral clock enable register */ - -#define RCC_APB2ENR_TIM11EN_BIT 21 -#define RCC_APB2ENR_TIM10EN_BIT 20 -#define RCC_APB2ENR_TIM9EN_BIT 19 -#define RCC_APB2ENR_ADC3EN_BIT 15 -#define RCC_APB2ENR_USART1EN_BIT 14 -#define RCC_APB2ENR_TIM8EN_BIT 13 -#define RCC_APB2ENR_SPI1EN_BIT 12 -#define RCC_APB2ENR_TIM1EN_BIT 11 -#define RCC_APB2ENR_ADC2EN_BIT 10 -#define RCC_APB2ENR_ADC1EN_BIT 9 -#define RCC_APB2ENR_IOPGEN_BIT 8 -#define RCC_APB2ENR_IOPFEN_BIT 7 -#define RCC_APB2ENR_IOPEEN_BIT 6 -#define RCC_APB2ENR_IOPDEN_BIT 5 -#define RCC_APB2ENR_IOPCEN_BIT 4 -#define RCC_APB2ENR_IOPBEN_BIT 3 -#define RCC_APB2ENR_IOPAEN_BIT 2 -#define RCC_APB2ENR_AFIOEN_BIT 0 - -#define RCC_APB2ENR_TIM11EN BIT(RCC_APB2ENR_TIM11EN_BIT) -#define RCC_APB2ENR_TIM10EN BIT(RCC_APB2ENR_TIM10EN_BIT) -#define RCC_APB2ENR_TIM9EN BIT(RCC_APB2ENR_TIM9EN_BIT) -#define RCC_APB2ENR_ADC3EN BIT(RCC_APB2ENR_ADC3EN_BIT) -#define RCC_APB2ENR_USART1EN BIT(RCC_APB2ENR_USART1EN_BIT) -#define RCC_APB2ENR_TIM8EN BIT(RCC_APB2ENR_TIM8EN_BIT) -#define RCC_APB2ENR_SPI1EN BIT(RCC_APB2ENR_SPI1EN_BIT) -#define RCC_APB2ENR_TIM1EN BIT(RCC_APB2ENR_TIM1EN_BIT) -#define RCC_APB2ENR_ADC2EN BIT(RCC_APB2ENR_ADC2EN_BIT) -#define RCC_APB2ENR_ADC1EN BIT(RCC_APB2ENR_ADC1EN_BIT) -#define RCC_APB2ENR_IOPGEN BIT(RCC_APB2ENR_IOPGEN_BIT) -#define RCC_APB2ENR_IOPFEN BIT(RCC_APB2ENR_IOPFEN_BIT) -#define RCC_APB2ENR_IOPEEN BIT(RCC_APB2ENR_IOPEEN_BIT) -#define RCC_APB2ENR_IOPDEN BIT(RCC_APB2ENR_IOPDEN_BIT) -#define RCC_APB2ENR_IOPCEN BIT(RCC_APB2ENR_IOPCEN_BIT) -#define RCC_APB2ENR_IOPBEN BIT(RCC_APB2ENR_IOPBEN_BIT) -#define RCC_APB2ENR_IOPAEN BIT(RCC_APB2ENR_IOPAEN_BIT) -#define RCC_APB2ENR_AFIOEN BIT(RCC_APB2ENR_AFIOEN_BIT) - -/* APB1 peripheral clock enable register */ - -#define RCC_APB1ENR_DACEN_BIT 29 -#define RCC_APB1ENR_PWREN_BIT 28 -#define RCC_APB1ENR_BKPEN_BIT 27 -#define RCC_APB1ENR_CANEN_BIT 25 -#define RCC_APB1ENR_USBEN_BIT 23 -#define RCC_APB1ENR_I2C2EN_BIT 22 -#define RCC_APB1ENR_I2C1EN_BIT 21 -#define RCC_APB1ENR_UART5EN_BIT 20 -#define RCC_APB1ENR_UART4EN_BIT 19 -#define RCC_APB1ENR_USART3EN_BIT 18 -#define RCC_APB1ENR_USART2EN_BIT 17 -#define RCC_APB1ENR_SPI3EN_BIT 15 -#define RCC_APB1ENR_SPI2EN_BIT 14 -#define RCC_APB1ENR_WWDEN_BIT 11 -#define RCC_APB1ENR_TIM14EN_BIT 8 -#define RCC_APB1ENR_TIM13EN_BIT 7 -#define RCC_APB1ENR_TIM12EN_BIT 6 -#define RCC_APB1ENR_TIM7EN_BIT 5 -#define RCC_APB1ENR_TIM6EN_BIT 4 -#define RCC_APB1ENR_TIM5EN_BIT 3 -#define RCC_APB1ENR_TIM4EN_BIT 2 -#define RCC_APB1ENR_TIM3EN_BIT 1 -#define RCC_APB1ENR_TIM2EN_BIT 0 - -#define RCC_APB1ENR_DACEN BIT(RCC_APB1ENR_DACEN_BIT) -#define RCC_APB1ENR_PWREN BIT(RCC_APB1ENR_PWREN_BIT) -#define RCC_APB1ENR_BKPEN BIT(RCC_APB1ENR_BKPEN_BIT) -#define RCC_APB1ENR_CANEN BIT(RCC_APB1ENR_CANEN_BIT) -#define RCC_APB1ENR_USBEN BIT(RCC_APB1ENR_USBEN_BIT) -#define RCC_APB1ENR_I2C2EN BIT(RCC_APB1ENR_I2C2EN_BIT) -#define RCC_APB1ENR_I2C1EN BIT(RCC_APB1ENR_I2C1EN_BIT) -#define RCC_APB1ENR_UART5EN BIT(RCC_APB1ENR_UART5EN_BIT) -#define RCC_APB1ENR_UART4EN BIT(RCC_APB1ENR_UART4EN_BIT) -#define RCC_APB1ENR_USART3EN BIT(RCC_APB1ENR_USART3EN_BIT) -#define RCC_APB1ENR_USART2EN BIT(RCC_APB1ENR_USART2EN_BIT) -#define RCC_APB1ENR_SPI3EN BIT(RCC_APB1ENR_SPI3EN_BIT) -#define RCC_APB1ENR_SPI2EN BIT(RCC_APB1ENR_SPI2EN_BIT) -#define RCC_APB1ENR_WWDEN BIT(RCC_APB1ENR_WWDEN_BIT) -#define RCC_APB1ENR_TIM14EN BIT(RCC_APB1ENR_TIM14EN_BIT) -#define RCC_APB1ENR_TIM13EN BIT(RCC_APB1ENR_TIM13EN_BIT) -#define RCC_APB1ENR_TIM12EN BIT(RCC_APB1ENR_TIM12EN_BIT) -#define RCC_APB1ENR_TIM7EN BIT(RCC_APB1ENR_TIM7EN_BIT) -#define RCC_APB1ENR_TIM6EN BIT(RCC_APB1ENR_TIM6EN_BIT) -#define RCC_APB1ENR_TIM5EN BIT(RCC_APB1ENR_TIM5EN_BIT) -#define RCC_APB1ENR_TIM4EN BIT(RCC_APB1ENR_TIM4EN_BIT) -#define RCC_APB1ENR_TIM3EN BIT(RCC_APB1ENR_TIM3EN_BIT) -#define RCC_APB1ENR_TIM2EN BIT(RCC_APB1ENR_TIM2EN_BIT) - -/* Backup domain control register */ - -#define RCC_BDCR_BDRST_BIT 16 -#define RCC_BDCR_RTCEN_BIT 15 -#define RCC_BDCR_LSEBYP_BIT 2 -#define RCC_BDCR_LSERDY_BIT 1 -#define RCC_BDCR_LSEON_BIT 0 - -#define RCC_BDCR_BDRST BIT(RCC_BDCR_BDRST_BIT) -#define RCC_BDCR_RTCEN BIT(RCC_BDCR_RTC_BIT) -#define RCC_BDCR_RTCSEL (0x3 << 8) -#define RCC_BDCR_RTCSEL_NONE (0x0 << 8) -#define RCC_BDCR_RTCSEL_LSE (0x1 << 8) -#define RCC_BDCR_RTCSEL_HSE (0x3 << 8) -#define RCC_BDCR_LSEBYP BIT(RCC_BDCR_LSEBYP_BIT) -#define RCC_BDCR_LSERDY BIT(RCC_BDCR_LSERDY_BIT) -#define RCC_BDCR_LSEON BIT(RCC_BDCR_LSEON_BIT) - -/* Control/status register */ - -#define RCC_CSR_LPWRRSTF_BIT 31 -#define RCC_CSR_WWDGRSTF_BIT 30 -#define RCC_CSR_IWDGRSTF_BIT 29 -#define RCC_CSR_SFTRSTF_BIT 28 -#define RCC_CSR_PORRSTF_BIT 27 -#define RCC_CSR_PINRSTF_BIT 26 -#define RCC_CSR_RMVF_BIT 24 -#define RCC_CSR_LSIRDY_BIT 1 -#define RCC_CSR_LSION_BIT 0 - -#define RCC_CSR_LPWRRSTF BIT(RCC_CSR_LPWRRSTF_BIT) -#define RCC_CSR_WWDGRSTF BIT(RCC_CSR_WWDGRSTF_BIT) -#define RCC_CSR_IWDGRSTF BIT(RCC_CSR_IWDGRSTF_BIT) -#define RCC_CSR_SFTRSTF BIT(RCC_CSR_SFTRSTF_BIT) -#define RCC_CSR_PORRSTF BIT(RCC_CSR_PORRSTF_BIT) -#define RCC_CSR_PINRSTF BIT(RCC_CSR_PINRSTF_BIT) -#define RCC_CSR_RMVF BIT(RCC_CSR_RMVF_BIT) -#define RCC_CSR_LSIRDY BIT(RCC_CSR_LSIRDY_BIT) -#define RCC_CSR_LSION BIT(RCC_CSR_LSION_BIT) - -/* - * Convenience routines - */ - -/** - * SYSCLK sources - * @see rcc_clk_init() - */ -typedef enum rcc_sysclk_src { - RCC_CLKSRC_HSI = 0x0, - RCC_CLKSRC_HSE = 0x1, - RCC_CLKSRC_PLL = 0x2, -} rcc_sysclk_src; - -/** - * PLL entry clock source - * @see rcc_clk_init() - */ -typedef enum rcc_pllsrc { - RCC_PLLSRC_HSE = (0x1 << 16), - RCC_PLLSRC_HSI_DIV_2 = (0x0 << 16) -} rcc_pllsrc; - -/** - * PLL multipliers - * @see rcc_clk_init() - */ -typedef enum rcc_pll_multiplier { - RCC_PLLMUL_2 = (0x0 << 18), - RCC_PLLMUL_3 = (0x1 << 18), - RCC_PLLMUL_4 = (0x2 << 18), - RCC_PLLMUL_5 = (0x3 << 18), - RCC_PLLMUL_6 = (0x4 << 18), - RCC_PLLMUL_7 = (0x5 << 18), - RCC_PLLMUL_8 = (0x6 << 18), - RCC_PLLMUL_9 = (0x7 << 18), - RCC_PLLMUL_10 = (0x8 << 18), - RCC_PLLMUL_11 = (0x9 << 18), - RCC_PLLMUL_12 = (0xA << 18), - RCC_PLLMUL_13 = (0xB << 18), - RCC_PLLMUL_14 = (0xC << 18), - RCC_PLLMUL_15 = (0xD << 18), - RCC_PLLMUL_16 = (0xE << 18), -} rcc_pll_multiplier; - -/** - * @brief Identifies bus and clock line for a peripheral. - * - * Also generally useful as a unique identifier for that peripheral - * (or its corresponding device struct). - */ -typedef enum rcc_clk_id { - RCC_GPIOA, - RCC_GPIOB, - RCC_GPIOC, - RCC_GPIOD, - RCC_AFIO, - RCC_ADC1, - RCC_ADC2, - RCC_ADC3, - RCC_USART1, - RCC_USART2, - RCC_USART3, - RCC_TIMER1, - RCC_TIMER2, - RCC_TIMER3, - RCC_TIMER4, - RCC_SPI1, - RCC_SPI2, - RCC_DMA1, - RCC_PWR, - RCC_BKP, - RCC_I2C1, - RCC_I2C2, - RCC_CRC, - RCC_FLITF, - RCC_SRAM, -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - RCC_GPIOE, - RCC_GPIOF, - RCC_GPIOG, - RCC_UART4, - RCC_UART5, - RCC_TIMER5, - RCC_TIMER6, - RCC_TIMER7, - RCC_TIMER8, - RCC_FSMC, - RCC_DAC, - RCC_DMA2, - RCC_SDIO, - RCC_SPI3, -#endif -#ifdef STM32_XL_DENSITY - RCC_TIMER9, - RCC_TIMER10, - RCC_TIMER11, - RCC_TIMER12, - RCC_TIMER13, - RCC_TIMER14, -#endif -} rcc_clk_id; - -void rcc_clk_init(rcc_sysclk_src sysclk_src, - rcc_pllsrc pll_src, - rcc_pll_multiplier pll_mul); -void rcc_clk_enable(rcc_clk_id device); -void rcc_reset_dev(rcc_clk_id device); - -typedef enum rcc_clk_domain { - RCC_APB1, - RCC_APB2, - RCC_AHB -} rcc_clk_domain; - -rcc_clk_domain rcc_dev_clk(rcc_clk_id device); - -uint32 rcc_dev_clk_speed(rcc_clk_id id); -uint32 rcc_dev_timer_clk_speed(rcc_clk_id id); - -/** - * Prescaler identifiers - * @see rcc_set_prescaler() - */ -typedef enum rcc_prescaler { - RCC_PRESCALER_AHB, - RCC_PRESCALER_APB1, - RCC_PRESCALER_APB2, - RCC_PRESCALER_USB, - RCC_PRESCALER_ADC -} rcc_prescaler; - -/** - * ADC prescaler dividers - * @see rcc_set_prescaler() - */ -typedef enum rcc_adc_divider { - RCC_ADCPRE_PCLK_DIV_2 = 0x0 << 14, - RCC_ADCPRE_PCLK_DIV_4 = 0x1 << 14, - RCC_ADCPRE_PCLK_DIV_6 = 0x2 << 14, - RCC_ADCPRE_PCLK_DIV_8 = 0x3 << 14, -} rcc_adc_divider; - -/** - * APB1 prescaler dividers - * @see rcc_set_prescaler() - */ -typedef enum rcc_apb1_divider { - RCC_APB1_HCLK_DIV_1 = 0x0 << 8, - RCC_APB1_HCLK_DIV_2 = 0x4 << 8, - RCC_APB1_HCLK_DIV_4 = 0x5 << 8, - RCC_APB1_HCLK_DIV_8 = 0x6 << 8, - RCC_APB1_HCLK_DIV_16 = 0x7 << 8, -} rcc_apb1_divider; - -/** - * APB2 prescaler dividers - * @see rcc_set_prescaler() - */ -typedef enum rcc_apb2_divider { - RCC_APB2_HCLK_DIV_1 = 0x0 << 11, - RCC_APB2_HCLK_DIV_2 = 0x4 << 11, - RCC_APB2_HCLK_DIV_4 = 0x5 << 11, - RCC_APB2_HCLK_DIV_8 = 0x6 << 11, - RCC_APB2_HCLK_DIV_16 = 0x7 << 11, -} rcc_apb2_divider; - -/** - * AHB prescaler dividers - * @see rcc_set_prescaler() - */ -typedef enum rcc_ahb_divider { - RCC_AHB_SYSCLK_DIV_1 = 0x0 << 4, - RCC_AHB_SYSCLK_DIV_2 = 0x8 << 4, - RCC_AHB_SYSCLK_DIV_4 = 0x9 << 4, - RCC_AHB_SYSCLK_DIV_8 = 0xA << 4, - RCC_AHB_SYSCLK_DIV_16 = 0xB << 4, - RCC_AHB_SYSCLK_DIV_32 = 0xC << 4, - RCC_AHB_SYSCLK_DIV_64 = 0xD << 4, - RCC_AHB_SYSCLK_DIV_128 = 0xD << 4, - RCC_AHB_SYSCLK_DIV_256 = 0xE << 4, - RCC_AHB_SYSCLK_DIV_512 = 0xF << 4, -} rcc_ahb_divider; - -void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file rcc.h + * @brief reset and clock control definitions and prototypes + */ + +#include "libmaple_types.h" + +#ifndef _RCC_H_ +#define _RCC_H_ + +#ifdef __cplusplus +extern "C"{ +#endif + +/** RCC register map type */ +typedef struct rcc_reg_map { + __io uint32 CR; /**< Clock control register */ + __io uint32 CFGR; /**< Clock configuration register */ + __io uint32 CIR; /**< Clock interrupt register */ + __io uint32 APB2RSTR; /**< APB2 peripheral reset register */ + __io uint32 APB1RSTR; /**< APB1 peripheral reset register */ + __io uint32 AHBENR; /**< AHB peripheral clock enable register */ + __io uint32 APB2ENR; /**< APB2 peripheral clock enable register */ + __io uint32 APB1ENR; /**< APB1 peripheral clock enable register */ + __io uint32 BDCR; /**< Backup domain control register */ + __io uint32 CSR; /**< Control/status register */ +} rcc_reg_map; + +/** RCC register map base pointer */ +#define RCC_BASE ((struct rcc_reg_map*)0x40021000) + +/* + * Register bit definitions + */ + +/* Clock control register */ + +#define RCC_CR_PLLRDY_BIT 25 +#define RCC_CR_PLLON_BIT 24 +#define RCC_CR_CSSON_BIT 19 +#define RCC_CR_HSEBYP_BIT 18 +#define RCC_CR_HSERDY_BIT 17 +#define RCC_CR_HSEON_BIT 16 +#define RCC_CR_HSIRDY_BIT 1 +#define RCC_CR_HSION_BIT 0 + +#define RCC_CR_PLLRDY BIT(RCC_CR_PLLRDY_BIT) +#define RCC_CR_PLLON BIT(RCC_CR_PLLON_BIT) +#define RCC_CR_CSSON BIT(RCC_CR_CSSON_BIT) +#define RCC_CR_HSEBYP BIT(RCC_CR_HSEBYP_BIT) +#define RCC_CR_HSERDY BIT(RCC_CR_HSERDY_BIT) +#define RCC_CR_HSEON BIT(RCC_CR_HSEON_BIT) +#define RCC_CR_HSICAL (0xFF << 8) +#define RCC_CR_HSITRIM (0x1F << 3) +#define RCC_CR_HSIRDY BIT(RCC_CR_HSIRDY_BIT) +#define RCC_CR_HSION BIT(RCC_CR_HSION_BIT) + +/* Clock configuration register */ + +#define RCC_CFGR_USBPRE_BIT 22 +#define RCC_CFGR_PLLXTPRE_BIT 17 +#define RCC_CFGR_PLLSRC_BIT 16 + +#define RCC_CFGR_MCO (0x3 << 24) +#define RCC_CFGR_USBPRE BIT(RCC_CFGR_USBPRE_BIT) +#define RCC_CFGR_PLLMUL (0xF << 18) +#define RCC_CFGR_PLLXTPRE BIT(RCC_CFGR_PLLXTPRE_BIT) +#define RCC_CFGR_PLLSRC BIT(RCC_CFGR_PLLSRC_BIT) +#define RCC_CFGR_ADCPRE (0x3 << 14) +#define RCC_CFGR_PPRE2 (0x7 << 11) +#define RCC_CFGR_PPRE1 (0x7 << 8) +#define RCC_CFGR_HPRE (0xF << 4) +#define RCC_CFGR_SWS (0x3 << 2) +#define RCC_CFGR_SWS_PLL (0x2 << 2) +#define RCC_CFGR_SWS_HSE (0x1 << 2) +#define RCC_CFGR_SW 0x3 +#define RCC_CFGR_SW_PLL 0x2 +#define RCC_CFGR_SW_HSE 0x1 + +/* Clock interrupt register */ + +#define RCC_CIR_CSSC_BIT 23 +#define RCC_CIR_PLLRDYC_BIT 20 +#define RCC_CIR_HSERDYC_BIT 19 +#define RCC_CIR_HSIRDYC_BIT 18 +#define RCC_CIR_LSERDYC_BIT 17 +#define RCC_CIR_LSIRDYC_BIT 16 +#define RCC_CIR_PLLRDYIE_BIT 12 +#define RCC_CIR_HSERDYIE_BIT 11 +#define RCC_CIR_HSIRDYIE_BIT 10 +#define RCC_CIR_LSERDYIE_BIT 9 +#define RCC_CIR_LSIRDYIE_BIT 8 +#define RCC_CIR_CSSF_BIT 7 +#define RCC_CIR_PLLRDYF_BIT 4 +#define RCC_CIR_HSERDYF_BIT 3 +#define RCC_CIR_HSIRDYF_BIT 2 +#define RCC_CIR_LSERDYF_BIT 1 +#define RCC_CIR_LSIRDYF_BIT 0 + +#define RCC_CIR_CSSC BIT(RCC_CIR_CSSC_BIT) +#define RCC_CIR_PLLRDYC BIT(RCC_CIR_PLLRDYC_BIT) +#define RCC_CIR_HSERDYC BIT(RCC_CIR_HSERDYC_BIT) +#define RCC_CIR_HSIRDYC BIT(RCC_CIR_HSIRDYC_BIT) +#define RCC_CIR_LSERDYC BIT(RCC_CIR_LSERDYC_BIT) +#define RCC_CIR_LSIRDYC BIT(RCC_CIR_LSIRDYC_BIT) +#define RCC_CIR_PLLRDYIE BIT(RCC_CIR_PLLRDYIE_BIT) +#define RCC_CIR_HSERDYIE BIT(RCC_CIR_HSERDYIE_BIT) +#define RCC_CIR_HSIRDYIE BIT(RCC_CIR_HSIRDYIE_BIT) +#define RCC_CIR_LSERDYIE BIT(RCC_CIR_LSERDYIE_BIT) +#define RCC_CIR_LSIRDYIE BIT(RCC_CIR_LSIRDYIE_BIT) +#define RCC_CIR_CSSF BIT(RCC_CIR_CSSF_BIT) +#define RCC_CIR_PLLRDYF BIT(RCC_CIR_PLLRDYF_BIT) +#define RCC_CIR_HSERDYF BIT(RCC_CIR_HSERDYF_BIT) +#define RCC_CIR_HSIRDYF BIT(RCC_CIR_HSIRDYF_BIT) +#define RCC_CIR_LSERDYF BIT(RCC_CIR_LSERDYF_BIT) +#define RCC_CIR_LSIRDYF BIT(RCC_CIR_LSIRDYF_BIT) + +/* APB2 peripheral reset register */ + +#define RCC_APB2RSTR_TIM11RST_BIT 21 +#define RCC_APB2RSTR_TIM10RST_BIT 20 +#define RCC_APB2RSTR_TIM9RST_BIT 19 +#define RCC_APB2RSTR_ADC3RST_BIT 15 +#define RCC_APB2RSTR_USART1RST_BIT 14 +#define RCC_APB2RSTR_TIM8RST_BIT 13 +#define RCC_APB2RSTR_SPI1RST_BIT 12 +#define RCC_APB2RSTR_TIM1RST_BIT 11 +#define RCC_APB2RSTR_ADC2RST_BIT 10 +#define RCC_APB2RSTR_ADC1RST_BIT 9 +#define RCC_APB2RSTR_IOPGRST_BIT 8 +#define RCC_APB2RSTR_IOPFRST_BIT 7 +#define RCC_APB2RSTR_IOPERST_BIT 6 +#define RCC_APB2RSTR_IOPDRST_BIT 5 +#define RCC_APB2RSTR_IOPCRST_BIT 4 +#define RCC_APB2RSTR_IOPBRST_BIT 3 +#define RCC_APB2RSTR_IOPARST_BIT 2 +#define RCC_APB2RSTR_AFIORST_BIT 0 + +#define RCC_APB2RSTR_TIM11RST BIT(RCC_APB2RSTR_TIM11RST_BIT) +#define RCC_APB2RSTR_TIM10RST BIT(RCC_APB2RSTR_TIM10RST_BIT) +#define RCC_APB2RSTR_TIM9RST BIT(RCC_APB2RSTR_TIM9RST_BIT) +#define RCC_APB2RSTR_ADC3RST BIT(RCC_APB2RSTR_ADC3RST_BIT) +#define RCC_APB2RSTR_USART1RST BIT(RCC_APB2RSTR_USART1RST_BIT) +#define RCC_APB2RSTR_TIM8RST BIT(RCC_APB2RSTR_TIM8RST_BIT) +#define RCC_APB2RSTR_SPI1RST BIT(RCC_APB2RSTR_SPI1RST_BIT) +#define RCC_APB2RSTR_TIM1RST BIT(RCC_APB2RSTR_TIM1RST_BIT) +#define RCC_APB2RSTR_ADC2RST BIT(RCC_APB2RSTR_ADC2RST_BIT) +#define RCC_APB2RSTR_ADC1RST BIT(RCC_APB2RSTR_ADC1RST_BIT) +#define RCC_APB2RSTR_IOPGRST BIT(RCC_APB2RSTR_IOPGRST_BIT) +#define RCC_APB2RSTR_IOPFRST BIT(RCC_APB2RSTR_IOPFRST_BIT) +#define RCC_APB2RSTR_IOPERST BIT(RCC_APB2RSTR_IOPERST_BIT) +#define RCC_APB2RSTR_IOPDRST BIT(RCC_APB2RSTR_IOPDRST_BIT) +#define RCC_APB2RSTR_IOPCRST BIT(RCC_APB2RSTR_IOPCRST_BIT) +#define RCC_APB2RSTR_IOPBRST BIT(RCC_APB2RSTR_IOPBRST_BIT) +#define RCC_APB2RSTR_IOPARST BIT(RCC_APB2RSTR_IOPARST_BIT) +#define RCC_APB2RSTR_AFIORST BIT(RCC_APB2RSTR_AFIORST_BIT) + +/* APB1 peripheral reset register */ + +#define RCC_APB1RSTR_DACRST_BIT 29 +#define RCC_APB1RSTR_PWRRST_BIT 28 +#define RCC_APB1RSTR_BKPRST_BIT 27 +#define RCC_APB1RSTR_CANRST_BIT 25 +#define RCC_APB1RSTR_USBRST_BIT 23 +#define RCC_APB1RSTR_I2C2RST_BIT 22 +#define RCC_APB1RSTR_I2C1RST_BIT 21 +#define RCC_APB1RSTR_UART5RST_BIT 20 +#define RCC_APB1RSTR_UART4RST_BIT 19 +#define RCC_APB1RSTR_USART3RST_BIT 18 +#define RCC_APB1RSTR_USART2RST_BIT 17 +#define RCC_APB1RSTR_SPI3RST_BIT 15 +#define RCC_APB1RSTR_SPI2RST_BIT 14 +#define RCC_APB1RSTR_WWDRST_BIT 11 +#define RCC_APB1RSTR_TIM14RST_BIT 8 +#define RCC_APB1RSTR_TIM13RST_BIT 7 +#define RCC_APB1RSTR_TIM12RST_BIT 6 +#define RCC_APB1RSTR_TIM7RST_BIT 5 +#define RCC_APB1RSTR_TIM6RST_BIT 4 +#define RCC_APB1RSTR_TIM5RST_BIT 3 +#define RCC_APB1RSTR_TIM4RST_BIT 2 +#define RCC_APB1RSTR_TIM3RST_BIT 1 +#define RCC_APB1RSTR_TIM2RST_BIT 0 + +#define RCC_APB1RSTR_DACRST BIT(RCC_APB1RSTR_DACRST_BIT) +#define RCC_APB1RSTR_PWRRST BIT(RCC_APB1RSTR_PWRRST_BIT) +#define RCC_APB1RSTR_BKPRST BIT(RCC_APB1RSTR_BKPRST_BIT) +#define RCC_APB1RSTR_CANRST BIT(RCC_APB1RSTR_CANRST_BIT) +#define RCC_APB1RSTR_USBRST BIT(RCC_APB1RSTR_USBRST_BIT) +#define RCC_APB1RSTR_I2C2RST BIT(RCC_APB1RSTR_I2C2RST_BIT) +#define RCC_APB1RSTR_I2C1RST BIT(RCC_APB1RSTR_I2C1RST_BIT) +#define RCC_APB1RSTR_UART5RST BIT(RCC_APB1RSTR_UART5RST_BIT) +#define RCC_APB1RSTR_UART4RST BIT(RCC_APB1RSTR_UART4RST_BIT) +#define RCC_APB1RSTR_USART3RST BIT(RCC_APB1RSTR_USART3RST_BIT) +#define RCC_APB1RSTR_USART2RST BIT(RCC_APB1RSTR_USART2RST_BIT) +#define RCC_APB1RSTR_SPI3RST BIT(RCC_APB1RSTR_SPI3RST_BIT) +#define RCC_APB1RSTR_SPI2RST BIT(RCC_APB1RSTR_SPI2RST_BIT) +#define RCC_APB1RSTR_WWDRST BIT(RCC_APB1RSTR_WWDRST_BIT) +#define RCC_APB1RSTR_TIM14RST BIT(RCC_APB1RSTR_TIM14RST_BIT) +#define RCC_APB1RSTR_TIM13RST BIT(RCC_APB1RSTR_TIM13RST_BIT) +#define RCC_APB1RSTR_TIM12RST BIT(RCC_APB1RSTR_TIM12RST_BIT) +#define RCC_APB1RSTR_TIM7RST BIT(RCC_APB1RSTR_TIM7RST_BIT) +#define RCC_APB1RSTR_TIM6RST BIT(RCC_APB1RSTR_TIM6RST_BIT) +#define RCC_APB1RSTR_TIM5RST BIT(RCC_APB1RSTR_TIM5RST_BIT) +#define RCC_APB1RSTR_TIM4RST BIT(RCC_APB1RSTR_TIM4RST_BIT) +#define RCC_APB1RSTR_TIM3RST BIT(RCC_APB1RSTR_TIM3RST_BIT) +#define RCC_APB1RSTR_TIM2RST BIT(RCC_APB1RSTR_TIM2RST_BIT) + +/* AHB peripheral clock enable register */ + +#define RCC_AHBENR_SDIOEN_BIT 10 +#define RCC_AHBENR_FSMCEN_BIT 8 +#define RCC_AHBENR_CRCEN_BIT 7 +#define RCC_AHBENR_FLITFEN_BIT 4 +#define RCC_AHBENR_SRAMEN_BIT 2 +#define RCC_AHBENR_DMA2EN_BIT 1 +#define RCC_AHBENR_DMA1EN_BIT 0 + +#define RCC_AHBENR_SDIOEN BIT(RCC_AHBENR_SDIOEN_BIT) +#define RCC_AHBENR_FSMCEN BIT(RCC_AHBENR_FSMCEN_BIT) +#define RCC_AHBENR_CRCEN BIT(RCC_AHBENR_CRCEN_BIT) +#define RCC_AHBENR_FLITFEN BIT(RCC_AHBENR_FLITFEN_BIT) +#define RCC_AHBENR_SRAMEN BIT(RCC_AHBENR_SRAMEN_BIT) +#define RCC_AHBENR_DMA2EN BIT(RCC_AHBENR_DMA2EN_BIT) +#define RCC_AHBENR_DMA1EN BIT(RCC_AHBENR_DMA1EN_BIT) + +/* APB2 peripheral clock enable register */ + +#define RCC_APB2ENR_TIM11EN_BIT 21 +#define RCC_APB2ENR_TIM10EN_BIT 20 +#define RCC_APB2ENR_TIM9EN_BIT 19 +#define RCC_APB2ENR_ADC3EN_BIT 15 +#define RCC_APB2ENR_USART1EN_BIT 14 +#define RCC_APB2ENR_TIM8EN_BIT 13 +#define RCC_APB2ENR_SPI1EN_BIT 12 +#define RCC_APB2ENR_TIM1EN_BIT 11 +#define RCC_APB2ENR_ADC2EN_BIT 10 +#define RCC_APB2ENR_ADC1EN_BIT 9 +#define RCC_APB2ENR_IOPGEN_BIT 8 +#define RCC_APB2ENR_IOPFEN_BIT 7 +#define RCC_APB2ENR_IOPEEN_BIT 6 +#define RCC_APB2ENR_IOPDEN_BIT 5 +#define RCC_APB2ENR_IOPCEN_BIT 4 +#define RCC_APB2ENR_IOPBEN_BIT 3 +#define RCC_APB2ENR_IOPAEN_BIT 2 +#define RCC_APB2ENR_AFIOEN_BIT 0 + +#define RCC_APB2ENR_TIM11EN BIT(RCC_APB2ENR_TIM11EN_BIT) +#define RCC_APB2ENR_TIM10EN BIT(RCC_APB2ENR_TIM10EN_BIT) +#define RCC_APB2ENR_TIM9EN BIT(RCC_APB2ENR_TIM9EN_BIT) +#define RCC_APB2ENR_ADC3EN BIT(RCC_APB2ENR_ADC3EN_BIT) +#define RCC_APB2ENR_USART1EN BIT(RCC_APB2ENR_USART1EN_BIT) +#define RCC_APB2ENR_TIM8EN BIT(RCC_APB2ENR_TIM8EN_BIT) +#define RCC_APB2ENR_SPI1EN BIT(RCC_APB2ENR_SPI1EN_BIT) +#define RCC_APB2ENR_TIM1EN BIT(RCC_APB2ENR_TIM1EN_BIT) +#define RCC_APB2ENR_ADC2EN BIT(RCC_APB2ENR_ADC2EN_BIT) +#define RCC_APB2ENR_ADC1EN BIT(RCC_APB2ENR_ADC1EN_BIT) +#define RCC_APB2ENR_IOPGEN BIT(RCC_APB2ENR_IOPGEN_BIT) +#define RCC_APB2ENR_IOPFEN BIT(RCC_APB2ENR_IOPFEN_BIT) +#define RCC_APB2ENR_IOPEEN BIT(RCC_APB2ENR_IOPEEN_BIT) +#define RCC_APB2ENR_IOPDEN BIT(RCC_APB2ENR_IOPDEN_BIT) +#define RCC_APB2ENR_IOPCEN BIT(RCC_APB2ENR_IOPCEN_BIT) +#define RCC_APB2ENR_IOPBEN BIT(RCC_APB2ENR_IOPBEN_BIT) +#define RCC_APB2ENR_IOPAEN BIT(RCC_APB2ENR_IOPAEN_BIT) +#define RCC_APB2ENR_AFIOEN BIT(RCC_APB2ENR_AFIOEN_BIT) + +/* APB1 peripheral clock enable register */ + +#define RCC_APB1ENR_DACEN_BIT 29 +#define RCC_APB1ENR_PWREN_BIT 28 +#define RCC_APB1ENR_BKPEN_BIT 27 +#define RCC_APB1ENR_CANEN_BIT 25 +#define RCC_APB1ENR_USBEN_BIT 23 +#define RCC_APB1ENR_I2C2EN_BIT 22 +#define RCC_APB1ENR_I2C1EN_BIT 21 +#define RCC_APB1ENR_UART5EN_BIT 20 +#define RCC_APB1ENR_UART4EN_BIT 19 +#define RCC_APB1ENR_USART3EN_BIT 18 +#define RCC_APB1ENR_USART2EN_BIT 17 +#define RCC_APB1ENR_SPI3EN_BIT 15 +#define RCC_APB1ENR_SPI2EN_BIT 14 +#define RCC_APB1ENR_WWDEN_BIT 11 +#define RCC_APB1ENR_TIM14EN_BIT 8 +#define RCC_APB1ENR_TIM13EN_BIT 7 +#define RCC_APB1ENR_TIM12EN_BIT 6 +#define RCC_APB1ENR_TIM7EN_BIT 5 +#define RCC_APB1ENR_TIM6EN_BIT 4 +#define RCC_APB1ENR_TIM5EN_BIT 3 +#define RCC_APB1ENR_TIM4EN_BIT 2 +#define RCC_APB1ENR_TIM3EN_BIT 1 +#define RCC_APB1ENR_TIM2EN_BIT 0 + +#define RCC_APB1ENR_DACEN BIT(RCC_APB1ENR_DACEN_BIT) +#define RCC_APB1ENR_PWREN BIT(RCC_APB1ENR_PWREN_BIT) +#define RCC_APB1ENR_BKPEN BIT(RCC_APB1ENR_BKPEN_BIT) +#define RCC_APB1ENR_CANEN BIT(RCC_APB1ENR_CANEN_BIT) +#define RCC_APB1ENR_USBEN BIT(RCC_APB1ENR_USBEN_BIT) +#define RCC_APB1ENR_I2C2EN BIT(RCC_APB1ENR_I2C2EN_BIT) +#define RCC_APB1ENR_I2C1EN BIT(RCC_APB1ENR_I2C1EN_BIT) +#define RCC_APB1ENR_UART5EN BIT(RCC_APB1ENR_UART5EN_BIT) +#define RCC_APB1ENR_UART4EN BIT(RCC_APB1ENR_UART4EN_BIT) +#define RCC_APB1ENR_USART3EN BIT(RCC_APB1ENR_USART3EN_BIT) +#define RCC_APB1ENR_USART2EN BIT(RCC_APB1ENR_USART2EN_BIT) +#define RCC_APB1ENR_SPI3EN BIT(RCC_APB1ENR_SPI3EN_BIT) +#define RCC_APB1ENR_SPI2EN BIT(RCC_APB1ENR_SPI2EN_BIT) +#define RCC_APB1ENR_WWDEN BIT(RCC_APB1ENR_WWDEN_BIT) +#define RCC_APB1ENR_TIM14EN BIT(RCC_APB1ENR_TIM14EN_BIT) +#define RCC_APB1ENR_TIM13EN BIT(RCC_APB1ENR_TIM13EN_BIT) +#define RCC_APB1ENR_TIM12EN BIT(RCC_APB1ENR_TIM12EN_BIT) +#define RCC_APB1ENR_TIM7EN BIT(RCC_APB1ENR_TIM7EN_BIT) +#define RCC_APB1ENR_TIM6EN BIT(RCC_APB1ENR_TIM6EN_BIT) +#define RCC_APB1ENR_TIM5EN BIT(RCC_APB1ENR_TIM5EN_BIT) +#define RCC_APB1ENR_TIM4EN BIT(RCC_APB1ENR_TIM4EN_BIT) +#define RCC_APB1ENR_TIM3EN BIT(RCC_APB1ENR_TIM3EN_BIT) +#define RCC_APB1ENR_TIM2EN BIT(RCC_APB1ENR_TIM2EN_BIT) + +/* Backup domain control register */ + +#define RCC_BDCR_BDRST_BIT 16 +#define RCC_BDCR_RTCEN_BIT 15 +#define RCC_BDCR_LSEBYP_BIT 2 +#define RCC_BDCR_LSERDY_BIT 1 +#define RCC_BDCR_LSEON_BIT 0 + +#define RCC_BDCR_BDRST BIT(RCC_BDCR_BDRST_BIT) +#define RCC_BDCR_RTCEN BIT(RCC_BDCR_RTC_BIT) +#define RCC_BDCR_RTCSEL (0x3 << 8) +#define RCC_BDCR_RTCSEL_NONE (0x0 << 8) +#define RCC_BDCR_RTCSEL_LSE (0x1 << 8) +#define RCC_BDCR_RTCSEL_HSE (0x3 << 8) +#define RCC_BDCR_LSEBYP BIT(RCC_BDCR_LSEBYP_BIT) +#define RCC_BDCR_LSERDY BIT(RCC_BDCR_LSERDY_BIT) +#define RCC_BDCR_LSEON BIT(RCC_BDCR_LSEON_BIT) + +/* Control/status register */ + +#define RCC_CSR_LPWRRSTF_BIT 31 +#define RCC_CSR_WWDGRSTF_BIT 30 +#define RCC_CSR_IWDGRSTF_BIT 29 +#define RCC_CSR_SFTRSTF_BIT 28 +#define RCC_CSR_PORRSTF_BIT 27 +#define RCC_CSR_PINRSTF_BIT 26 +#define RCC_CSR_RMVF_BIT 24 +#define RCC_CSR_LSIRDY_BIT 1 +#define RCC_CSR_LSION_BIT 0 + +#define RCC_CSR_LPWRRSTF BIT(RCC_CSR_LPWRRSTF_BIT) +#define RCC_CSR_WWDGRSTF BIT(RCC_CSR_WWDGRSTF_BIT) +#define RCC_CSR_IWDGRSTF BIT(RCC_CSR_IWDGRSTF_BIT) +#define RCC_CSR_SFTRSTF BIT(RCC_CSR_SFTRSTF_BIT) +#define RCC_CSR_PORRSTF BIT(RCC_CSR_PORRSTF_BIT) +#define RCC_CSR_PINRSTF BIT(RCC_CSR_PINRSTF_BIT) +#define RCC_CSR_RMVF BIT(RCC_CSR_RMVF_BIT) +#define RCC_CSR_LSIRDY BIT(RCC_CSR_LSIRDY_BIT) +#define RCC_CSR_LSION BIT(RCC_CSR_LSION_BIT) + +/* + * Convenience routines + */ + +/** + * SYSCLK sources + * @see rcc_clk_init() + */ +typedef enum rcc_sysclk_src { + RCC_CLKSRC_HSI = 0x0, + RCC_CLKSRC_HSE = 0x1, + RCC_CLKSRC_PLL = 0x2, +} rcc_sysclk_src; + +/** + * PLL entry clock source + * @see rcc_clk_init() + */ +typedef enum rcc_pllsrc { + RCC_PLLSRC_HSE = (0x1 << 16), + RCC_PLLSRC_HSI_DIV_2 = (0x0 << 16) +} rcc_pllsrc; + +/** + * PLL multipliers + * @see rcc_clk_init() + */ +typedef enum rcc_pll_multiplier { + RCC_PLLMUL_2 = (0x0 << 18), + RCC_PLLMUL_3 = (0x1 << 18), + RCC_PLLMUL_4 = (0x2 << 18), + RCC_PLLMUL_5 = (0x3 << 18), + RCC_PLLMUL_6 = (0x4 << 18), + RCC_PLLMUL_7 = (0x5 << 18), + RCC_PLLMUL_8 = (0x6 << 18), + RCC_PLLMUL_9 = (0x7 << 18), + RCC_PLLMUL_10 = (0x8 << 18), + RCC_PLLMUL_11 = (0x9 << 18), + RCC_PLLMUL_12 = (0xA << 18), + RCC_PLLMUL_13 = (0xB << 18), + RCC_PLLMUL_14 = (0xC << 18), + RCC_PLLMUL_15 = (0xD << 18), + RCC_PLLMUL_16 = (0xE << 18), +} rcc_pll_multiplier; + +/** + * @brief Identifies bus and clock line for a peripheral. + * + * Also generally useful as a unique identifier for that peripheral + * (or its corresponding device struct). + */ +typedef enum rcc_clk_id { + RCC_GPIOA, + RCC_GPIOB, + RCC_GPIOC, + RCC_GPIOD, + RCC_AFIO, + RCC_ADC1, + RCC_ADC2, + RCC_ADC3, + RCC_USART1, + RCC_USART2, + RCC_USART3, + RCC_TIMER1, + RCC_TIMER2, + RCC_TIMER3, + RCC_TIMER4, + RCC_SPI1, + RCC_SPI2, + RCC_DMA1, + RCC_PWR, + RCC_BKP, + RCC_I2C1, + RCC_I2C2, + RCC_CRC, + RCC_FLITF, + RCC_SRAM, +#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) + RCC_GPIOE, + RCC_GPIOF, + RCC_GPIOG, + RCC_UART4, + RCC_UART5, + RCC_TIMER5, + RCC_TIMER6, + RCC_TIMER7, + RCC_TIMER8, + RCC_FSMC, + RCC_DAC, + RCC_DMA2, + RCC_SDIO, + RCC_SPI3, +#endif +#ifdef STM32_XL_DENSITY + RCC_TIMER9, + RCC_TIMER10, + RCC_TIMER11, + RCC_TIMER12, + RCC_TIMER13, + RCC_TIMER14, +#endif +} rcc_clk_id; + +void rcc_clk_init(rcc_sysclk_src sysclk_src, + rcc_pllsrc pll_src, + rcc_pll_multiplier pll_mul); +void rcc_clk_enable(rcc_clk_id device); +void rcc_reset_dev(rcc_clk_id device); + +typedef enum rcc_clk_domain { + RCC_APB1, + RCC_APB2, + RCC_AHB +} rcc_clk_domain; + +rcc_clk_domain rcc_dev_clk(rcc_clk_id device); + +uint32 rcc_dev_clk_speed(rcc_clk_id id); +uint32 rcc_dev_timer_clk_speed(rcc_clk_id id); + +/** + * Prescaler identifiers + * @see rcc_set_prescaler() + */ +typedef enum rcc_prescaler { + RCC_PRESCALER_AHB, + RCC_PRESCALER_APB1, + RCC_PRESCALER_APB2, + RCC_PRESCALER_USB, + RCC_PRESCALER_ADC +} rcc_prescaler; + +/** + * ADC prescaler dividers + * @see rcc_set_prescaler() + */ +typedef enum rcc_adc_divider { + RCC_ADCPRE_PCLK_DIV_2 = 0x0 << 14, + RCC_ADCPRE_PCLK_DIV_4 = 0x1 << 14, + RCC_ADCPRE_PCLK_DIV_6 = 0x2 << 14, + RCC_ADCPRE_PCLK_DIV_8 = 0x3 << 14, +} rcc_adc_divider; + +/** + * APB1 prescaler dividers + * @see rcc_set_prescaler() + */ +typedef enum rcc_apb1_divider { + RCC_APB1_HCLK_DIV_1 = 0x0 << 8, + RCC_APB1_HCLK_DIV_2 = 0x4 << 8, + RCC_APB1_HCLK_DIV_4 = 0x5 << 8, + RCC_APB1_HCLK_DIV_8 = 0x6 << 8, + RCC_APB1_HCLK_DIV_16 = 0x7 << 8, +} rcc_apb1_divider; + +/** + * APB2 prescaler dividers + * @see rcc_set_prescaler() + */ +typedef enum rcc_apb2_divider { + RCC_APB2_HCLK_DIV_1 = 0x0 << 11, + RCC_APB2_HCLK_DIV_2 = 0x4 << 11, + RCC_APB2_HCLK_DIV_4 = 0x5 << 11, + RCC_APB2_HCLK_DIV_8 = 0x6 << 11, + RCC_APB2_HCLK_DIV_16 = 0x7 << 11, +} rcc_apb2_divider; + +/** + * AHB prescaler dividers + * @see rcc_set_prescaler() + */ +typedef enum rcc_ahb_divider { + RCC_AHB_SYSCLK_DIV_1 = 0x0 << 4, + RCC_AHB_SYSCLK_DIV_2 = 0x8 << 4, + RCC_AHB_SYSCLK_DIV_4 = 0x9 << 4, + RCC_AHB_SYSCLK_DIV_8 = 0xA << 4, + RCC_AHB_SYSCLK_DIV_16 = 0xB << 4, + RCC_AHB_SYSCLK_DIV_32 = 0xC << 4, + RCC_AHB_SYSCLK_DIV_64 = 0xD << 4, + RCC_AHB_SYSCLK_DIV_128 = 0xD << 4, + RCC_AHB_SYSCLK_DIV_256 = 0xE << 4, + RCC_AHB_SYSCLK_DIV_512 = 0xF << 4, +} rcc_ahb_divider; + +void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/rccF2.c b/Libmaple/libmaple/libmaple/rccF2.c index 5202eaec..bb283e1c 100644 --- a/Libmaple/libmaple/libmaple/rccF2.c +++ b/Libmaple/libmaple/libmaple/rccF2.c @@ -1,683 +1,683 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file rcc.c - * @brief Implements pretty much only the basic clock setup on the - * stm32, clock enable/disable and peripheral reset commands. - */ - -#include "libmaple.h" -#include "flash.h" -#include "rcc.h" -#include "bitband.h" - -#define APB1 RCC_APB1 -#define APB2 RCC_APB2 -#define AHB1 RCC_AHB1 -#define AHB2 RCC_AHB2 -#define AHB3 RCC_AHB3 - -struct rcc_dev_info { - const rcc_clk_domain clk_domain; - const uint8 line_num; -}; - -static uint32 rcc_dev_clk_speed_table[AHB3]; - -/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset - * register bit numbers. */ -static const struct rcc_dev_info rcc_dev_table[] = { - [RCC_GPIOA] = { .clk_domain = AHB1, .line_num = 0 }, //* - [RCC_GPIOB] = { .clk_domain = AHB1, .line_num = 1 }, //* - [RCC_GPIOC] = { .clk_domain = AHB1, .line_num = 2 }, //* - [RCC_GPIOD] = { .clk_domain = AHB1, .line_num = 3 }, //* - -// [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 }, - [RCC_ADC1] = { .clk_domain = APB2, .line_num = 8 }, //* - [RCC_ADC2] = { .clk_domain = APB2, .line_num = 9 }, //* - [RCC_ADC3] = { .clk_domain = APB2, .line_num = 10 }, //* - [RCC_USART1] = { .clk_domain = APB2, .line_num = 4 }, //* - [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, //unchanged - [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, //unchanged - [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 0 }, //* - [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 }, //unchanged - [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 }, //unchanged - [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 }, //unchanged - [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 }, //unchanged - [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 }, //unchanged - [RCC_DMA1] = { .clk_domain = AHB1, .line_num = 21 }, //* - [RCC_PWR] = { .clk_domain = APB1, .line_num = 28}, //unchanged -// [RCC_BKP] = { .clk_domain = AHB1, .line_num = 18}, //* - [RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 }, //unchanged - [RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 }, //unchanged - [RCC_CRC] = { .clk_domain = AHB1, .line_num = 12}, //* -// [RCC_FLITF] = { .clk_domain = AHB, .line_num = 4}, -// [RCC_SRAM] = { .clk_domain = AHB, .line_num = 2}, - - [RCC_GPIOE] = { .clk_domain = AHB1, .line_num = 4 }, //* - [RCC_GPIOF] = { .clk_domain = AHB1, .line_num = 5 }, //* - [RCC_GPIOG] = { .clk_domain = AHB1, .line_num = 6 }, //* - [RCC_UART4] = { .clk_domain = APB1, .line_num = 19 }, //unchanged - [RCC_UART5] = { .clk_domain = APB1, .line_num = 20 }, //unchanged - [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, //unchanged - [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, //unchanged - [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, //unchanged - [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 1 }, //* - [RCC_FSMC] = { .clk_domain = AHB3, .line_num = 0 }, //* - [RCC_DAC] = { .clk_domain = APB1, .line_num = 29 }, //unchanged - [RCC_DMA2] = { .clk_domain = AHB1, .line_num = 22 }, //* - [RCC_SDIO] = { .clk_domain = APB2, .line_num = 11 }, //* - [RCC_SPI3] = { .clk_domain = APB1, .line_num = 15 }, //unchanged - [RCC_TIMER9] = { .clk_domain = APB2, .line_num = 16 }, //* - [RCC_TIMER10] = { .clk_domain = APB2, .line_num = 17 }, //* - [RCC_TIMER11] = { .clk_domain = APB2, .line_num = 18 }, //* - [RCC_TIMER12] = { .clk_domain = APB1, .line_num = 6 }, //unchanged - [RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 }, //unchanged - [RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 }, //unchanged - [RCC_USBFS] = { .clk_domain = AHB2, .line_num = 7 }, //* - [RCC_SYSCFG] = { .clk_domain = APB2, .line_num = 14 }, //* - [RCC_SPI4] = { .clk_domain = APB1, .line_num = 15 }, -}; - -/** - * @brief Initialize the clock control system. Initializes the system - * clock source to use the PLL driven by an external oscillator - * @param sysclk_src system clock source, must be PLL - * @param pll_src pll clock source, must be HSE - * @param pll_mul pll multiplier - */ - -#define HSE_STARTUP_TIMEOUT ((uint16)0x0500) /*!< Time out for HSE start up */ -#define RCC_CFGR_HPRE_DIV1 ((uint32)0x00000000) /*!< SYSCLK not divided */ -#define RCC_CFGR_PPRE1_DIV2 ((uint32)0x00001000) /*!< HCLK divided by 2 */ -#define RCC_CFGR_PPRE1_DIV4 ((uint32)0x00001400) /*!< HCLK divided by 4 */ -#define RCC_CFGR_PPRE2_DIV1 ((uint32)0x00000000) /*!< HCLK not divided */ -#define RCC_CFGR_PPRE2_DIV2 ((uint32)0x00008000) /*!< HCLK divided by 2 */ - -#define RCC_PLLCFGR_PLLSRC_HSE ((uint32)0x00400000) - -/******************* Bits definition for FLASH_ACR register *****************/ -//#define FLASH_ACR_LATENCY ((uint32_t)0x00000007) -#define FLASH_ACR_LATENCY_0WS ((uint32)0x00000000) -#define FLASH_ACR_LATENCY_1WS ((uint32)0x00000001) -#define FLASH_ACR_LATENCY_2WS ((uint32)0x00000002) -#define FLASH_ACR_LATENCY_3WS ((uint32)0x00000003) -#define FLASH_ACR_LATENCY_4WS ((uint32)0x00000004) -#define FLASH_ACR_LATENCY_5WS ((uint32)0x00000005) -#define FLASH_ACR_LATENCY_6WS ((uint32)0x00000006) -#define FLASH_ACR_LATENCY_7WS ((uint32)0x00000007) - -#define FLASH_ACR_PRFTEN ((uint32)0x00000100) -#define FLASH_ACR_ICEN ((uint32)0x00000200) -#define FLASH_ACR_DCEN ((uint32)0x00000400) -#define FLASH_ACR_ICRST ((uint32)0x00000800) -#define FLASH_ACR_DCRST ((uint32)0x00001000) -#define FLASH_ACR_BYTE0_ADDRESS ((uint32)0x40023C00) -#define FLASH_ACR_BYTE2_ADDRESS ((uint32)0x40023C03) - -typedef struct -{ - __io uint32 CR; /*!< PWR power control register, Address offset: 0x00 */ - __io uint32 CSR; /*!< PWR power control/status register, Address offset: 0x04 */ -} PWR_TypeDef; - -#define PWR_BASE (0x40007000) -#define PWR ((PWR_TypeDef *) PWR_BASE) -#define PWR_CR_VOS ((uint16)0x4000) /*!< Regulator voltage scaling output selection */ - -typedef struct -{ - __io uint32 ACR; /*!< FLASH access control register, Address offset: 0x00 */ - __io uint32 KEYR; /*!< FLASH key register, Address offset: 0x04 */ - __io uint32 OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ - __io uint32 SR; /*!< FLASH status register, Address offset: 0x0C */ - __io uint32 CR; /*!< FLASH control register, Address offset: 0x10 */ - __io uint32 OPTCR; /*!< FLASH option control register, Address offset: 0x14 */ -} FLASH_TypeDef; - -#define FLASH_R_BASE (0x40023C00) -#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) -#define RESET 0 - -typedef uint32 uint32_t; - -void SetupClock72MHz() -{ - uint32_t SystemCoreClock = 72000000; - - /******************************************************************************/ - /* PLL (clocked by HSE) used as System clock source */ - /******************************************************************************/ - /************************* PLL Parameters *************************************/ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ - int PLL_M = 4; - int PLL_N = 216; - - /* SYSCLK = PLL_VCO / PLL_P */ - int PLL_P = 6; - - /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ - int PLL_Q = 9; - - - uint32 StartUpCounter = 0, HSEStatus = 0; - rcc_reg_map *RCC = RCC_BASE; - - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Select regulator voltage output Scale 2 mode, System frequency up to 144 MHz */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR &= (uint32_t)~(PWR_CR_VOS); - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 1*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; - - /* PCLK1 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; - - // save bus clock values - rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1); - rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/1); - rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/2); - - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} - - -void SetupClock120MHz() -{ - uint32_t SystemCoreClock = 120000000; - - /******************************************************************************/ - /* PLL (clocked by HSE) used as System clock source */ - /******************************************************************************/ - /************************* PLL Parameters *************************************/ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ - int PLL_M = 8; - int PLL_N = 240; - - /* SYSCLK = PLL_VCO / PLL_P */ - int PLL_P = 2; - - /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ - int PLL_Q = 5; - - - uint32 StartUpCounter = 0, HSEStatus = 0; - rcc_reg_map *RCC = RCC_BASE; - - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Select regulator voltage output Scale 2 mode, System frequency up to 144 MHz */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR &= (uint32_t)~(PWR_CR_VOS); - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; - - /* PCLK1 = HCLK / 4*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; - - // save bus clock values - rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1); - rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/2); - rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/4); - - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS; - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} - - -void SetupClock168MHz() -{ - uint32_t SystemCoreClock = 168000000; - - /******************************************************************************/ - /* PLL (clocked by HSE) used as System clock source */ - /******************************************************************************/ - /************************* PLL Parameters *************************************/ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ - int PLL_M = 8; - int PLL_N = 336; - - /* SYSCLK = PLL_VCO / PLL_P */ - int PLL_P = 2; - - /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ - int PLL_Q = 7; - - - uint32 StartUpCounter = 0, HSEStatus = 0; - rcc_reg_map *RCC = RCC_BASE; - - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR |= PWR_CR_VOS; - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; - - /* PCLK1 = HCLK / 4*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; - - // save bus clock values - rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1); - rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/2); - rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/4); - - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} - - - -void rcc_clk_init(rcc_sysclk_src sysclk_src, - rcc_pllsrc pll_src, - rcc_pll_multiplier pll_mul) { - - //SetupClock72MHz(); -#if STM32_TICKS_PER_US == 168 - SetupClock168MHz(); -#endif -#if STM32_TICKS_PER_US == 120 - SetupClock120MHz(); -#endif -#if STM32_TICKS_PER_US == 72 - SetupClock72MHz(); -#endif -} - - - - -#define PLL_M 8 -#define PLL_N 240 -/* SYSCLK = PLL_VCO / PLL_P */ -#define PLL_P 2 - -/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ -#define PLL_Q 5 - - -void rcc_clk_init2(rcc_sysclk_src sysclk_src, - rcc_pllsrc pll_src, - rcc_pll_multiplier pll_mul) { - -/******************************************************************************/ -/* PLL (clocked by HSE) used as System clock source */ -/******************************************************************************/ - uint32 StartUpCounter = 0, HSEStatus = 0; - rcc_reg_map *pRCC = RCC_BASE; - - /* Enable HSE */ - pRCC->CR |= RCC_CR_HSEON; - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = pRCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((pRCC->CR & RCC_CR_HSERDY) != 0) - { - HSEStatus = 0x01; - } - else - { - HSEStatus = 0x00; - } - - if (HSEStatus == 0x01) - { - /* HCLK = SYSCLK / 1*/ - pRCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - pRCC->CFGR |= RCC_CFGR_PPRE2_DIV2; - - /* PCLK1 = HCLK / 4*/ - pRCC->CFGR |= RCC_CFGR_PPRE1_DIV4; - - /* Configure the main PLL */ - pRCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - pRCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((pRCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - ((FLASH_TypeDef*)FLASH)->ACR = FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS; - - /* Select the main PLL as system clock source */ - pRCC->CFGR &= ~RCC_CFGR_SW; - pRCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((pRCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } - -#if 0 - uint32 cfgr = 0; - uint32 cr; - - /* Assume that we're going to clock the chip off the PLL, fed by - * the HSE */ - ASSERT(sysclk_src == RCC_CLKSRC_PLL && - pll_src == RCC_PLLSRC_HSE); - - RCC_BASE->CFGR = pll_src | pll_mul; - - /* Turn on the HSE */ - cr = RCC_BASE->CR; - cr |= RCC_CR_HSEON; - RCC_BASE->CR = cr; - while (!(RCC_BASE->CR & RCC_CR_HSERDY)) - ; - - /* Now the PLL */ - cr |= RCC_CR_PLLON; - RCC_BASE->CR = cr; - while (!(RCC_BASE->CR & RCC_CR_PLLRDY)) - ; - - /* Finally, let's switch over to the PLL */ - cfgr &= ~RCC_CFGR_SW; - cfgr |= RCC_CFGR_SW_PLL; - RCC_BASE->CFGR = cfgr; - while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) - ; -#endif -} - -/** - * @brief Turn on the clock line on a peripheral - * @param id Clock ID of the peripheral to turn on. - */ -void rcc_clk_enable(rcc_clk_id id) { - static const __io uint32* enable_regs[] = { - [APB1] = &RCC_BASE->APB1ENR, - [APB2] = &RCC_BASE->APB2ENR, - [AHB1] = &RCC_BASE->AHB1ENR, - [AHB2] = &RCC_BASE->AHB2ENR, - [AHB3] = &RCC_BASE->AHB3ENR, - }; - - rcc_clk_domain clk_domain = rcc_dev_clk(id); - __io uint32* enr = (__io uint32*)enable_regs[clk_domain]; - uint8 lnum = rcc_dev_table[id].line_num; - - bb_peri_set_bit(enr, lnum, 1); -} - -/** - * @brief Turn on the clock line on a peripheral - * @param id Clock ID of the peripheral to turn on. - */ -void rcc_clk_disable(rcc_clk_id id) { - static const __io uint32* enable_regs[] = { - [APB1] = &RCC_BASE->APB1ENR, - [APB2] = &RCC_BASE->APB2ENR, - [AHB1] = &RCC_BASE->AHB1ENR, - [AHB2] = &RCC_BASE->AHB2ENR, - [AHB3] = &RCC_BASE->AHB3ENR, - }; - - rcc_clk_domain clk_domain = rcc_dev_clk(id); - __io uint32* enr = (__io uint32*)enable_regs[clk_domain]; - uint8 lnum = rcc_dev_table[id].line_num; - - bb_peri_set_bit(enr, lnum, 0); -} - -/** - * @brief Reset a peripheral. - * @param id Clock ID of the peripheral to reset. - */ -void rcc_reset_dev(rcc_clk_id id) { - static const __io uint32* reset_regs[] = { - [APB1] = &RCC_BASE->APB1RSTR, - [APB2] = &RCC_BASE->APB2RSTR, - [AHB1] = &RCC_BASE->AHB1RSTR, - [AHB2] = &RCC_BASE->AHB2RSTR, - [AHB3] = &RCC_BASE->AHB3RSTR, - }; - - rcc_clk_domain clk_domain = rcc_dev_clk(id); - __io void* addr = (__io void*)reset_regs[clk_domain]; - uint8 lnum = rcc_dev_table[id].line_num; - - bb_peri_set_bit(addr, lnum, 1); - bb_peri_set_bit(addr, lnum, 0); -} - -/** - * @brief Get a peripheral's clock domain - * @param id Clock ID of the peripheral whose clock domain to return - * @return Clock source for the given clock ID - */ -rcc_clk_domain rcc_dev_clk(rcc_clk_id id) { - return rcc_dev_table[id].clk_domain; -} - -/** - * @brief Get a peripheral's clock domain speed - * @param id Clock ID of the peripheral whose clock domain speed to return - * @return Clock speed for the given clock ID - */ -uint32 rcc_dev_clk_speed(rcc_clk_id id) { - return rcc_dev_clk_speed_table[rcc_dev_clk(id)]; -} - -/** - * @brief Get a peripheral's timer clock domain speed - * @param id Clock ID of the peripheral whose clock domain speed to return - * @return Clock speed for the given clock ID - */ -uint32 rcc_dev_timer_clk_speed(rcc_clk_id id) { - return 2*rcc_dev_clk_speed(id); -} - -/** - * @brief Set the divider on a peripheral prescaler - * @param prescaler prescaler to set - * @param divider prescaler divider - */ -void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { -#if 0 - static const uint32 masks[] = { - [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE, - [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1, - [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2, - [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE, - [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE, - }; - - uint32 cfgr = RCC_BASE->CFGR; - cfgr &= ~masks[prescaler]; - cfgr |= divider; - RCC_BASE->CFGR = cfgr; -#endif -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file rcc.c + * @brief Implements pretty much only the basic clock setup on the + * stm32, clock enable/disable and peripheral reset commands. + */ + +#include "libmaple.h" +#include "flash.h" +#include "rcc.h" +#include "bitband.h" + +#define APB1 RCC_APB1 +#define APB2 RCC_APB2 +#define AHB1 RCC_AHB1 +#define AHB2 RCC_AHB2 +#define AHB3 RCC_AHB3 + +struct rcc_dev_info { + const rcc_clk_domain clk_domain; + const uint8 line_num; +}; + +static uint32 rcc_dev_clk_speed_table[AHB3]; + +/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset + * register bit numbers. */ +static const struct rcc_dev_info rcc_dev_table[] = { + [RCC_GPIOA] = { .clk_domain = AHB1, .line_num = 0 }, //* + [RCC_GPIOB] = { .clk_domain = AHB1, .line_num = 1 }, //* + [RCC_GPIOC] = { .clk_domain = AHB1, .line_num = 2 }, //* + [RCC_GPIOD] = { .clk_domain = AHB1, .line_num = 3 }, //* + +// [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 }, + [RCC_ADC1] = { .clk_domain = APB2, .line_num = 8 }, //* + [RCC_ADC2] = { .clk_domain = APB2, .line_num = 9 }, //* + [RCC_ADC3] = { .clk_domain = APB2, .line_num = 10 }, //* + [RCC_USART1] = { .clk_domain = APB2, .line_num = 4 }, //* + [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, //unchanged + [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, //unchanged + [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 0 }, //* + [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 }, //unchanged + [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 }, //unchanged + [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 }, //unchanged + [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 }, //unchanged + [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 }, //unchanged + [RCC_DMA1] = { .clk_domain = AHB1, .line_num = 21 }, //* + [RCC_PWR] = { .clk_domain = APB1, .line_num = 28}, //unchanged +// [RCC_BKP] = { .clk_domain = AHB1, .line_num = 18}, //* + [RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 }, //unchanged + [RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 }, //unchanged + [RCC_CRC] = { .clk_domain = AHB1, .line_num = 12}, //* +// [RCC_FLITF] = { .clk_domain = AHB, .line_num = 4}, +// [RCC_SRAM] = { .clk_domain = AHB, .line_num = 2}, + + [RCC_GPIOE] = { .clk_domain = AHB1, .line_num = 4 }, //* + [RCC_GPIOF] = { .clk_domain = AHB1, .line_num = 5 }, //* + [RCC_GPIOG] = { .clk_domain = AHB1, .line_num = 6 }, //* + [RCC_UART4] = { .clk_domain = APB1, .line_num = 19 }, //unchanged + [RCC_UART5] = { .clk_domain = APB1, .line_num = 20 }, //unchanged + [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, //unchanged + [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, //unchanged + [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, //unchanged + [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 1 }, //* + [RCC_FSMC] = { .clk_domain = AHB3, .line_num = 0 }, //* + [RCC_DAC] = { .clk_domain = APB1, .line_num = 29 }, //unchanged + [RCC_DMA2] = { .clk_domain = AHB1, .line_num = 22 }, //* + [RCC_SDIO] = { .clk_domain = APB2, .line_num = 11 }, //* + [RCC_SPI3] = { .clk_domain = APB1, .line_num = 15 }, //unchanged + [RCC_TIMER9] = { .clk_domain = APB2, .line_num = 16 }, //* + [RCC_TIMER10] = { .clk_domain = APB2, .line_num = 17 }, //* + [RCC_TIMER11] = { .clk_domain = APB2, .line_num = 18 }, //* + [RCC_TIMER12] = { .clk_domain = APB1, .line_num = 6 }, //unchanged + [RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 }, //unchanged + [RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 }, //unchanged + [RCC_USBFS] = { .clk_domain = AHB2, .line_num = 7 }, //* + [RCC_SYSCFG] = { .clk_domain = APB2, .line_num = 14 }, //* + [RCC_SPI4] = { .clk_domain = APB1, .line_num = 15 }, +}; + +/** + * @brief Initialize the clock control system. Initializes the system + * clock source to use the PLL driven by an external oscillator + * @param sysclk_src system clock source, must be PLL + * @param pll_src pll clock source, must be HSE + * @param pll_mul pll multiplier + */ + +#define HSE_STARTUP_TIMEOUT ((uint16)0x0500) /*!< Time out for HSE start up */ +#define RCC_CFGR_HPRE_DIV1 ((uint32)0x00000000) /*!< SYSCLK not divided */ +#define RCC_CFGR_PPRE1_DIV2 ((uint32)0x00001000) /*!< HCLK divided by 2 */ +#define RCC_CFGR_PPRE1_DIV4 ((uint32)0x00001400) /*!< HCLK divided by 4 */ +#define RCC_CFGR_PPRE2_DIV1 ((uint32)0x00000000) /*!< HCLK not divided */ +#define RCC_CFGR_PPRE2_DIV2 ((uint32)0x00008000) /*!< HCLK divided by 2 */ + +#define RCC_PLLCFGR_PLLSRC_HSE ((uint32)0x00400000) + +/******************* Bits definition for FLASH_ACR register *****************/ +//#define FLASH_ACR_LATENCY ((uint32_t)0x00000007) +#define FLASH_ACR_LATENCY_0WS ((uint32)0x00000000) +#define FLASH_ACR_LATENCY_1WS ((uint32)0x00000001) +#define FLASH_ACR_LATENCY_2WS ((uint32)0x00000002) +#define FLASH_ACR_LATENCY_3WS ((uint32)0x00000003) +#define FLASH_ACR_LATENCY_4WS ((uint32)0x00000004) +#define FLASH_ACR_LATENCY_5WS ((uint32)0x00000005) +#define FLASH_ACR_LATENCY_6WS ((uint32)0x00000006) +#define FLASH_ACR_LATENCY_7WS ((uint32)0x00000007) + +#define FLASH_ACR_PRFTEN ((uint32)0x00000100) +#define FLASH_ACR_ICEN ((uint32)0x00000200) +#define FLASH_ACR_DCEN ((uint32)0x00000400) +#define FLASH_ACR_ICRST ((uint32)0x00000800) +#define FLASH_ACR_DCRST ((uint32)0x00001000) +#define FLASH_ACR_BYTE0_ADDRESS ((uint32)0x40023C00) +#define FLASH_ACR_BYTE2_ADDRESS ((uint32)0x40023C03) + +typedef struct +{ + __io uint32 CR; /*!< PWR power control register, Address offset: 0x00 */ + __io uint32 CSR; /*!< PWR power control/status register, Address offset: 0x04 */ +} PWR_TypeDef; + +#define PWR_BASE (0x40007000) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define PWR_CR_VOS ((uint16)0x4000) /*!< Regulator voltage scaling output selection */ + +typedef struct +{ + __io uint32 ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __io uint32 KEYR; /*!< FLASH key register, Address offset: 0x04 */ + __io uint32 OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ + __io uint32 SR; /*!< FLASH status register, Address offset: 0x0C */ + __io uint32 CR; /*!< FLASH control register, Address offset: 0x10 */ + __io uint32 OPTCR; /*!< FLASH option control register, Address offset: 0x14 */ +} FLASH_TypeDef; + +#define FLASH_R_BASE (0x40023C00) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define RESET 0 + +typedef uint32 uint32_t; + +void SetupClock72MHz() +{ + uint32_t SystemCoreClock = 72000000; + + /******************************************************************************/ + /* PLL (clocked by HSE) used as System clock source */ + /******************************************************************************/ + /************************* PLL Parameters *************************************/ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ + int PLL_M = 4; + int PLL_N = 216; + + /* SYSCLK = PLL_VCO / PLL_P */ + int PLL_P = 6; + + /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ + int PLL_Q = 9; + + + uint32 StartUpCounter = 0, HSEStatus = 0; + rcc_reg_map *RCC = RCC_BASE; + + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Select regulator voltage output Scale 2 mode, System frequency up to 144 MHz */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + PWR->CR &= (uint32_t)~(PWR_CR_VOS); + + /* HCLK = SYSCLK / 1*/ + RCC->CFGR |= RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK / 1*/ + RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; + + /* PCLK1 = HCLK / 2*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; + + // save bus clock values + rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1); + rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/1); + rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/2); + + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; + + /* Select the main PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= RCC_CFGR_SW_PLL; + + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} + + +void SetupClock120MHz() +{ + uint32_t SystemCoreClock = 120000000; + + /******************************************************************************/ + /* PLL (clocked by HSE) used as System clock source */ + /******************************************************************************/ + /************************* PLL Parameters *************************************/ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ + int PLL_M = 8; + int PLL_N = 240; + + /* SYSCLK = PLL_VCO / PLL_P */ + int PLL_P = 2; + + /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ + int PLL_Q = 5; + + + uint32 StartUpCounter = 0, HSEStatus = 0; + rcc_reg_map *RCC = RCC_BASE; + + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Select regulator voltage output Scale 2 mode, System frequency up to 144 MHz */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + PWR->CR &= (uint32_t)~(PWR_CR_VOS); + + /* HCLK = SYSCLK / 1*/ + RCC->CFGR |= RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK / 2*/ + RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; + + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; + + // save bus clock values + rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1); + rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/2); + rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/4); + + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS; + + /* Select the main PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= RCC_CFGR_SW_PLL; + + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} + + +void SetupClock168MHz() +{ + uint32_t SystemCoreClock = 168000000; + + /******************************************************************************/ + /* PLL (clocked by HSE) used as System clock source */ + /******************************************************************************/ + /************************* PLL Parameters *************************************/ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ + int PLL_M = 8; + int PLL_N = 336; + + /* SYSCLK = PLL_VCO / PLL_P */ + int PLL_P = 2; + + /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ + int PLL_Q = 7; + + + uint32 StartUpCounter = 0, HSEStatus = 0; + rcc_reg_map *RCC = RCC_BASE; + + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + PWR->CR |= PWR_CR_VOS; + + /* HCLK = SYSCLK / 1*/ + RCC->CFGR |= RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK / 2*/ + RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; + + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; + + // save bus clock values + rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1); + rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/2); + rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/4); + + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; + + /* Select the main PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= RCC_CFGR_SW_PLL; + + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} + + + +void rcc_clk_init(rcc_sysclk_src sysclk_src, + rcc_pllsrc pll_src, + rcc_pll_multiplier pll_mul) { + + //SetupClock72MHz(); +#if STM32_TICKS_PER_US == 168 + SetupClock168MHz(); +#endif +#if STM32_TICKS_PER_US == 120 + SetupClock120MHz(); +#endif +#if STM32_TICKS_PER_US == 72 + SetupClock72MHz(); +#endif +} + + + + +#define PLL_M 8 +#define PLL_N 240 +/* SYSCLK = PLL_VCO / PLL_P */ +#define PLL_P 2 + +/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ +#define PLL_Q 5 + + +void rcc_clk_init2(rcc_sysclk_src sysclk_src, + rcc_pllsrc pll_src, + rcc_pll_multiplier pll_mul) { + +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ + uint32 StartUpCounter = 0, HSEStatus = 0; + rcc_reg_map *pRCC = RCC_BASE; + + /* Enable HSE */ + pRCC->CR |= RCC_CR_HSEON; + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = pRCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((pRCC->CR & RCC_CR_HSERDY) != 0) + { + HSEStatus = 0x01; + } + else + { + HSEStatus = 0x00; + } + + if (HSEStatus == 0x01) + { + /* HCLK = SYSCLK / 1*/ + pRCC->CFGR |= RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK / 2*/ + pRCC->CFGR |= RCC_CFGR_PPRE2_DIV2; + + /* PCLK1 = HCLK / 4*/ + pRCC->CFGR |= RCC_CFGR_PPRE1_DIV4; + + /* Configure the main PLL */ + pRCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + + /* Enable the main PLL */ + pRCC->CR |= RCC_CR_PLLON; + + /* Wait till the main PLL is ready */ + while((pRCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + ((FLASH_TypeDef*)FLASH)->ACR = FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS; + + /* Select the main PLL as system clock source */ + pRCC->CFGR &= ~RCC_CFGR_SW; + pRCC->CFGR |= RCC_CFGR_SW_PLL; + + /* Wait till the main PLL is used as system clock source */ + while ((pRCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } + +#if 0 + uint32 cfgr = 0; + uint32 cr; + + /* Assume that we're going to clock the chip off the PLL, fed by + * the HSE */ + ASSERT(sysclk_src == RCC_CLKSRC_PLL && + pll_src == RCC_PLLSRC_HSE); + + RCC_BASE->CFGR = pll_src | pll_mul; + + /* Turn on the HSE */ + cr = RCC_BASE->CR; + cr |= RCC_CR_HSEON; + RCC_BASE->CR = cr; + while (!(RCC_BASE->CR & RCC_CR_HSERDY)) + ; + + /* Now the PLL */ + cr |= RCC_CR_PLLON; + RCC_BASE->CR = cr; + while (!(RCC_BASE->CR & RCC_CR_PLLRDY)) + ; + + /* Finally, let's switch over to the PLL */ + cfgr &= ~RCC_CFGR_SW; + cfgr |= RCC_CFGR_SW_PLL; + RCC_BASE->CFGR = cfgr; + while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) + ; +#endif +} + +/** + * @brief Turn on the clock line on a peripheral + * @param id Clock ID of the peripheral to turn on. + */ +void rcc_clk_enable(rcc_clk_id id) { + static const __io uint32* enable_regs[] = { + [APB1] = &RCC_BASE->APB1ENR, + [APB2] = &RCC_BASE->APB2ENR, + [AHB1] = &RCC_BASE->AHB1ENR, + [AHB2] = &RCC_BASE->AHB2ENR, + [AHB3] = &RCC_BASE->AHB3ENR, + }; + + rcc_clk_domain clk_domain = rcc_dev_clk(id); + __io uint32* enr = (__io uint32*)enable_regs[clk_domain]; + uint8 lnum = rcc_dev_table[id].line_num; + + bb_peri_set_bit(enr, lnum, 1); +} + +/** + * @brief Turn on the clock line on a peripheral + * @param id Clock ID of the peripheral to turn on. + */ +void rcc_clk_disable(rcc_clk_id id) { + static const __io uint32* enable_regs[] = { + [APB1] = &RCC_BASE->APB1ENR, + [APB2] = &RCC_BASE->APB2ENR, + [AHB1] = &RCC_BASE->AHB1ENR, + [AHB2] = &RCC_BASE->AHB2ENR, + [AHB3] = &RCC_BASE->AHB3ENR, + }; + + rcc_clk_domain clk_domain = rcc_dev_clk(id); + __io uint32* enr = (__io uint32*)enable_regs[clk_domain]; + uint8 lnum = rcc_dev_table[id].line_num; + + bb_peri_set_bit(enr, lnum, 0); +} + +/** + * @brief Reset a peripheral. + * @param id Clock ID of the peripheral to reset. + */ +void rcc_reset_dev(rcc_clk_id id) { + static const __io uint32* reset_regs[] = { + [APB1] = &RCC_BASE->APB1RSTR, + [APB2] = &RCC_BASE->APB2RSTR, + [AHB1] = &RCC_BASE->AHB1RSTR, + [AHB2] = &RCC_BASE->AHB2RSTR, + [AHB3] = &RCC_BASE->AHB3RSTR, + }; + + rcc_clk_domain clk_domain = rcc_dev_clk(id); + __io void* addr = (__io void*)reset_regs[clk_domain]; + uint8 lnum = rcc_dev_table[id].line_num; + + bb_peri_set_bit(addr, lnum, 1); + bb_peri_set_bit(addr, lnum, 0); +} + +/** + * @brief Get a peripheral's clock domain + * @param id Clock ID of the peripheral whose clock domain to return + * @return Clock source for the given clock ID + */ +rcc_clk_domain rcc_dev_clk(rcc_clk_id id) { + return rcc_dev_table[id].clk_domain; +} + +/** + * @brief Get a peripheral's clock domain speed + * @param id Clock ID of the peripheral whose clock domain speed to return + * @return Clock speed for the given clock ID + */ +uint32 rcc_dev_clk_speed(rcc_clk_id id) { + return rcc_dev_clk_speed_table[rcc_dev_clk(id)]; +} + +/** + * @brief Get a peripheral's timer clock domain speed + * @param id Clock ID of the peripheral whose clock domain speed to return + * @return Clock speed for the given clock ID + */ +uint32 rcc_dev_timer_clk_speed(rcc_clk_id id) { + return 2*rcc_dev_clk_speed(id); +} + +/** + * @brief Set the divider on a peripheral prescaler + * @param prescaler prescaler to set + * @param divider prescaler divider + */ +void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { +#if 0 + static const uint32 masks[] = { + [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE, + [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1, + [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2, + [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE, + [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE, + }; + + uint32 cfgr = RCC_BASE->CFGR; + cfgr &= ~masks[prescaler]; + cfgr |= divider; + RCC_BASE->CFGR = cfgr; +#endif +} diff --git a/Libmaple/libmaple/libmaple/rccF2.h b/Libmaple/libmaple/libmaple/rccF2.h index 4d74192d..9982e554 100644 --- a/Libmaple/libmaple/libmaple/rccF2.h +++ b/Libmaple/libmaple/libmaple/rccF2.h @@ -1,600 +1,600 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file rcc.h - * @brief reset and clock control definitions and prototypes - */ - -#include "libmaple_types.h" - -#ifndef _RCC_H_ -#define _RCC_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -/** RCC register map type */ -typedef struct -{ - __io uint32 CR; /*!< RCC clock control register, Address offset: 0x00 */ - __io uint32 PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ - __io uint32 CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ - __io uint32 CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ - __io uint32 AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ - __io uint32 AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ - __io uint32 AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ - uint32 RESERVED0; /*!< Reserved, 0x1C */ - __io uint32 APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ - __io uint32 APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ - uint32 RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ - __io uint32 AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ - __io uint32 AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ - __io uint32 AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ - uint32 RESERVED2; /*!< Reserved, 0x3C */ - __io uint32 APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ - __io uint32 APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ - uint32 RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ - __io uint32 AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ - __io uint32 AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ - __io uint32 AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ - uint32 RESERVED4; /*!< Reserved, 0x5C */ - __io uint32 APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ - __io uint32 APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ - uint32 RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ - __io uint32 BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ - __io uint32 CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ - uint32 RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ - __io uint32 SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ - __io uint32 PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ -} rcc_reg_map; - -/** RCC register map base pointer */ -//#define RCC_BASE ((struct rcc_reg_map*)0x40021000) -#define RCC_BASE ((rcc_reg_map*)0x40023800) - -/* - * Register bit definitions - */ - -/* Clock control register */ - -#define RCC_CR_PLLRDY_BIT 25 -#define RCC_CR_PLLON_BIT 24 -#define RCC_CR_CSSON_BIT 19 -#define RCC_CR_HSEBYP_BIT 18 -#define RCC_CR_HSERDY_BIT 17 -#define RCC_CR_HSEON_BIT 16 -#define RCC_CR_HSIRDY_BIT 1 -#define RCC_CR_HSION_BIT 0 - -#define RCC_CR_PLLRDY BIT(RCC_CR_PLLRDY_BIT) -#define RCC_CR_PLLON BIT(RCC_CR_PLLON_BIT) -#define RCC_CR_CSSON BIT(RCC_CR_CSSON_BIT) -#define RCC_CR_HSEBYP BIT(RCC_CR_HSEBYP_BIT) -#define RCC_CR_HSERDY BIT(RCC_CR_HSERDY_BIT) -#define RCC_CR_HSEON BIT(RCC_CR_HSEON_BIT) -#define RCC_CR_HSICAL (0xFF << 8) -#define RCC_CR_HSITRIM (0x1F << 3) -#define RCC_CR_HSIRDY BIT(RCC_CR_HSIRDY_BIT) -#define RCC_CR_HSION BIT(RCC_CR_HSION_BIT) - -/* Clock configuration register */ - -#define RCC_CFGR_USBPRE_BIT 22 -#define RCC_CFGR_PLLXTPRE_BIT 17 -#define RCC_CFGR_PLLSRC_BIT 16 - -#define RCC_CFGR_MCO (0x3 << 24) -#define RCC_CFGR_USBPRE BIT(RCC_CFGR_USBPRE_BIT) -#define RCC_CFGR_PLLMUL (0xF << 18) -#define RCC_CFGR_PLLXTPRE BIT(RCC_CFGR_PLLXTPRE_BIT) -#define RCC_CFGR_PLLSRC BIT(RCC_CFGR_PLLSRC_BIT) -#define RCC_CFGR_ADCPRE (0x3 << 14) -#define RCC_CFGR_PPRE2 (0x7 << 11) -#define RCC_CFGR_PPRE1 (0x7 << 8) -#define RCC_CFGR_HPRE (0xF << 4) -#define RCC_CFGR_SWS (0x3 << 2) -#define RCC_CFGR_SWS_PLL (0x2 << 2) -#define RCC_CFGR_SWS_HSE (0x1 << 2) -#define RCC_CFGR_SW 0x3 -#define RCC_CFGR_SW_PLL 0x2 -#define RCC_CFGR_SW_HSE 0x1 - -/* Clock interrupt register */ - -#define RCC_CIR_CSSC_BIT 23 -#define RCC_CIR_PLLRDYC_BIT 20 -#define RCC_CIR_HSERDYC_BIT 19 -#define RCC_CIR_HSIRDYC_BIT 18 -#define RCC_CIR_LSERDYC_BIT 17 -#define RCC_CIR_LSIRDYC_BIT 16 -#define RCC_CIR_PLLRDYIE_BIT 12 -#define RCC_CIR_HSERDYIE_BIT 11 -#define RCC_CIR_HSIRDYIE_BIT 10 -#define RCC_CIR_LSERDYIE_BIT 9 -#define RCC_CIR_LSIRDYIE_BIT 8 -#define RCC_CIR_CSSF_BIT 7 -#define RCC_CIR_PLLRDYF_BIT 4 -#define RCC_CIR_HSERDYF_BIT 3 -#define RCC_CIR_HSIRDYF_BIT 2 -#define RCC_CIR_LSERDYF_BIT 1 -#define RCC_CIR_LSIRDYF_BIT 0 - -#define RCC_CIR_CSSC BIT(RCC_CIR_CSSC_BIT) -#define RCC_CIR_PLLRDYC BIT(RCC_CIR_PLLRDYC_BIT) -#define RCC_CIR_HSERDYC BIT(RCC_CIR_HSERDYC_BIT) -#define RCC_CIR_HSIRDYC BIT(RCC_CIR_HSIRDYC_BIT) -#define RCC_CIR_LSERDYC BIT(RCC_CIR_LSERDYC_BIT) -#define RCC_CIR_LSIRDYC BIT(RCC_CIR_LSIRDYC_BIT) -#define RCC_CIR_PLLRDYIE BIT(RCC_CIR_PLLRDYIE_BIT) -#define RCC_CIR_HSERDYIE BIT(RCC_CIR_HSERDYIE_BIT) -#define RCC_CIR_HSIRDYIE BIT(RCC_CIR_HSIRDYIE_BIT) -#define RCC_CIR_LSERDYIE BIT(RCC_CIR_LSERDYIE_BIT) -#define RCC_CIR_LSIRDYIE BIT(RCC_CIR_LSIRDYIE_BIT) -#define RCC_CIR_CSSF BIT(RCC_CIR_CSSF_BIT) -#define RCC_CIR_PLLRDYF BIT(RCC_CIR_PLLRDYF_BIT) -#define RCC_CIR_HSERDYF BIT(RCC_CIR_HSERDYF_BIT) -#define RCC_CIR_HSIRDYF BIT(RCC_CIR_HSIRDYF_BIT) -#define RCC_CIR_LSERDYF BIT(RCC_CIR_LSERDYF_BIT) -#define RCC_CIR_LSIRDYF BIT(RCC_CIR_LSIRDYF_BIT) - -/* APB2 peripheral reset register */ - -#define RCC_APB2RSTR_TIM11RST_BIT 21 -#define RCC_APB2RSTR_TIM10RST_BIT 20 -#define RCC_APB2RSTR_TIM9RST_BIT 19 -#define RCC_APB2RSTR_ADC3RST_BIT 15 -#define RCC_APB2RSTR_USART1RST_BIT 14 -#define RCC_APB2RSTR_TIM8RST_BIT 13 -#define RCC_APB2RSTR_SPI1RST_BIT 12 -#define RCC_APB2RSTR_TIM1RST_BIT 11 -#define RCC_APB2RSTR_ADC2RST_BIT 10 -#define RCC_APB2RSTR_ADC1RST_BIT 9 -#define RCC_APB2RSTR_IOPGRST_BIT 8 -#define RCC_APB2RSTR_IOPFRST_BIT 7 -#define RCC_APB2RSTR_IOPERST_BIT 6 -#define RCC_APB2RSTR_IOPDRST_BIT 5 -#define RCC_APB2RSTR_IOPCRST_BIT 4 -#define RCC_APB2RSTR_IOPBRST_BIT 3 -#define RCC_APB2RSTR_IOPARST_BIT 2 -#define RCC_APB2RSTR_AFIORST_BIT 0 - -#define RCC_APB2RSTR_TIM11RST BIT(RCC_APB2RSTR_TIM11RST_BIT) -#define RCC_APB2RSTR_TIM10RST BIT(RCC_APB2RSTR_TIM10RST_BIT) -#define RCC_APB2RSTR_TIM9RST BIT(RCC_APB2RSTR_TIM9RST_BIT) -#define RCC_APB2RSTR_ADC3RST BIT(RCC_APB2RSTR_ADC3RST_BIT) -#define RCC_APB2RSTR_USART1RST BIT(RCC_APB2RSTR_USART1RST_BIT) -#define RCC_APB2RSTR_TIM8RST BIT(RCC_APB2RSTR_TIM8RST_BIT) -#define RCC_APB2RSTR_SPI1RST BIT(RCC_APB2RSTR_SPI1RST_BIT) -#define RCC_APB2RSTR_TIM1RST BIT(RCC_APB2RSTR_TIM1RST_BIT) -#define RCC_APB2RSTR_ADC2RST BIT(RCC_APB2RSTR_ADC2RST_BIT) -#define RCC_APB2RSTR_ADC1RST BIT(RCC_APB2RSTR_ADC1RST_BIT) -#define RCC_APB2RSTR_IOPGRST BIT(RCC_APB2RSTR_IOPGRST_BIT) -#define RCC_APB2RSTR_IOPFRST BIT(RCC_APB2RSTR_IOPFRST_BIT) -#define RCC_APB2RSTR_IOPERST BIT(RCC_APB2RSTR_IOPERST_BIT) -#define RCC_APB2RSTR_IOPDRST BIT(RCC_APB2RSTR_IOPDRST_BIT) -#define RCC_APB2RSTR_IOPCRST BIT(RCC_APB2RSTR_IOPCRST_BIT) -#define RCC_APB2RSTR_IOPBRST BIT(RCC_APB2RSTR_IOPBRST_BIT) -#define RCC_APB2RSTR_IOPARST BIT(RCC_APB2RSTR_IOPARST_BIT) -#define RCC_APB2RSTR_AFIORST BIT(RCC_APB2RSTR_AFIORST_BIT) - -/* APB1 peripheral reset register */ - -#define RCC_APB1RSTR_DACRST_BIT 29 -#define RCC_APB1RSTR_PWRRST_BIT 28 -#define RCC_APB1RSTR_BKPRST_BIT 27 -#define RCC_APB1RSTR_CANRST_BIT 25 -#define RCC_APB1RSTR_USBRST_BIT 23 -#define RCC_APB1RSTR_I2C2RST_BIT 22 -#define RCC_APB1RSTR_I2C1RST_BIT 21 -#define RCC_APB1RSTR_UART5RST_BIT 20 -#define RCC_APB1RSTR_UART4RST_BIT 19 -#define RCC_APB1RSTR_USART3RST_BIT 18 -#define RCC_APB1RSTR_USART2RST_BIT 17 -#define RCC_APB1RSTR_SPI3RST_BIT 15 -#define RCC_APB1RSTR_SPI2RST_BIT 14 -#define RCC_APB1RSTR_WWDRST_BIT 11 -#define RCC_APB1RSTR_TIM14RST_BIT 8 -#define RCC_APB1RSTR_TIM13RST_BIT 7 -#define RCC_APB1RSTR_TIM12RST_BIT 6 -#define RCC_APB1RSTR_TIM7RST_BIT 5 -#define RCC_APB1RSTR_TIM6RST_BIT 4 -#define RCC_APB1RSTR_TIM5RST_BIT 3 -#define RCC_APB1RSTR_TIM4RST_BIT 2 -#define RCC_APB1RSTR_TIM3RST_BIT 1 -#define RCC_APB1RSTR_TIM2RST_BIT 0 - -#define RCC_APB1RSTR_DACRST BIT(RCC_APB1RSTR_DACRST_BIT) -#define RCC_APB1RSTR_PWRRST BIT(RCC_APB1RSTR_PWRRST_BIT) -#define RCC_APB1RSTR_BKPRST BIT(RCC_APB1RSTR_BKPRST_BIT) -#define RCC_APB1RSTR_CANRST BIT(RCC_APB1RSTR_CANRST_BIT) -#define RCC_APB1RSTR_USBRST BIT(RCC_APB1RSTR_USBRST_BIT) -#define RCC_APB1RSTR_I2C2RST BIT(RCC_APB1RSTR_I2C2RST_BIT) -#define RCC_APB1RSTR_I2C1RST BIT(RCC_APB1RSTR_I2C1RST_BIT) -#define RCC_APB1RSTR_UART5RST BIT(RCC_APB1RSTR_UART5RST_BIT) -#define RCC_APB1RSTR_UART4RST BIT(RCC_APB1RSTR_UART4RST_BIT) -#define RCC_APB1RSTR_USART3RST BIT(RCC_APB1RSTR_USART3RST_BIT) -#define RCC_APB1RSTR_USART2RST BIT(RCC_APB1RSTR_USART2RST_BIT) -#define RCC_APB1RSTR_SPI3RST BIT(RCC_APB1RSTR_SPI3RST_BIT) -#define RCC_APB1RSTR_SPI2RST BIT(RCC_APB1RSTR_SPI2RST_BIT) -#define RCC_APB1RSTR_WWDRST BIT(RCC_APB1RSTR_WWDRST_BIT) -#define RCC_APB1RSTR_TIM14RST BIT(RCC_APB1RSTR_TIM14RST_BIT) -#define RCC_APB1RSTR_TIM13RST BIT(RCC_APB1RSTR_TIM13RST_BIT) -#define RCC_APB1RSTR_TIM12RST BIT(RCC_APB1RSTR_TIM12RST_BIT) -#define RCC_APB1RSTR_TIM7RST BIT(RCC_APB1RSTR_TIM7RST_BIT) -#define RCC_APB1RSTR_TIM6RST BIT(RCC_APB1RSTR_TIM6RST_BIT) -#define RCC_APB1RSTR_TIM5RST BIT(RCC_APB1RSTR_TIM5RST_BIT) -#define RCC_APB1RSTR_TIM4RST BIT(RCC_APB1RSTR_TIM4RST_BIT) -#define RCC_APB1RSTR_TIM3RST BIT(RCC_APB1RSTR_TIM3RST_BIT) -#define RCC_APB1RSTR_TIM2RST BIT(RCC_APB1RSTR_TIM2RST_BIT) - -/* AHB peripheral clock enable register */ - -#define RCC_AHBENR_SDIOEN_BIT 10 -#define RCC_AHBENR_FSMCEN_BIT 8 -#define RCC_AHBENR_CRCEN_BIT 7 -#define RCC_AHBENR_FLITFEN_BIT 4 -#define RCC_AHBENR_SRAMEN_BIT 2 -#define RCC_AHBENR_DMA2EN_BIT 1 -#define RCC_AHBENR_DMA1EN_BIT 0 - -#define RCC_AHBENR_SDIOEN BIT(RCC_AHBENR_SDIOEN_BIT) -#define RCC_AHBENR_FSMCEN BIT(RCC_AHBENR_FSMCEN_BIT) -#define RCC_AHBENR_CRCEN BIT(RCC_AHBENR_CRCEN_BIT) -#define RCC_AHBENR_FLITFEN BIT(RCC_AHBENR_FLITFEN_BIT) -#define RCC_AHBENR_SRAMEN BIT(RCC_AHBENR_SRAMEN_BIT) -#define RCC_AHBENR_DMA2EN BIT(RCC_AHBENR_DMA2EN_BIT) -#define RCC_AHBENR_DMA1EN BIT(RCC_AHBENR_DMA1EN_BIT) - -/* APB2 peripheral clock enable register */ - -#define RCC_APB2ENR_TIM11EN_BIT 21 -#define RCC_APB2ENR_TIM10EN_BIT 20 -#define RCC_APB2ENR_TIM9EN_BIT 19 -#define RCC_APB2ENR_ADC3EN_BIT 15 -#define RCC_APB2ENR_USART1EN_BIT 14 -#define RCC_APB2ENR_TIM8EN_BIT 13 -#define RCC_APB2ENR_SPI1EN_BIT 12 -#define RCC_APB2ENR_TIM1EN_BIT 11 -#define RCC_APB2ENR_ADC2EN_BIT 10 -#define RCC_APB2ENR_ADC1EN_BIT 9 -#define RCC_APB2ENR_IOPGEN_BIT 8 -#define RCC_APB2ENR_IOPFEN_BIT 7 -#define RCC_APB2ENR_IOPEEN_BIT 6 -#define RCC_APB2ENR_IOPDEN_BIT 5 -#define RCC_APB2ENR_IOPCEN_BIT 4 -#define RCC_APB2ENR_IOPBEN_BIT 3 -#define RCC_APB2ENR_IOPAEN_BIT 2 -#define RCC_APB2ENR_AFIOEN_BIT 0 - -#define RCC_APB2ENR_TIM11EN BIT(RCC_APB2ENR_TIM11EN_BIT) -#define RCC_APB2ENR_TIM10EN BIT(RCC_APB2ENR_TIM10EN_BIT) -#define RCC_APB2ENR_TIM9EN BIT(RCC_APB2ENR_TIM9EN_BIT) -#define RCC_APB2ENR_ADC3EN BIT(RCC_APB2ENR_ADC3EN_BIT) -#define RCC_APB2ENR_USART1EN BIT(RCC_APB2ENR_USART1EN_BIT) -#define RCC_APB2ENR_TIM8EN BIT(RCC_APB2ENR_TIM8EN_BIT) -#define RCC_APB2ENR_SPI1EN BIT(RCC_APB2ENR_SPI1EN_BIT) -#define RCC_APB2ENR_TIM1EN BIT(RCC_APB2ENR_TIM1EN_BIT) -#define RCC_APB2ENR_ADC2EN BIT(RCC_APB2ENR_ADC2EN_BIT) -#define RCC_APB2ENR_ADC1EN BIT(RCC_APB2ENR_ADC1EN_BIT) -#define RCC_APB2ENR_IOPGEN BIT(RCC_APB2ENR_IOPGEN_BIT) -#define RCC_APB2ENR_IOPFEN BIT(RCC_APB2ENR_IOPFEN_BIT) -#define RCC_APB2ENR_IOPEEN BIT(RCC_APB2ENR_IOPEEN_BIT) -#define RCC_APB2ENR_IOPDEN BIT(RCC_APB2ENR_IOPDEN_BIT) -#define RCC_APB2ENR_IOPCEN BIT(RCC_APB2ENR_IOPCEN_BIT) -#define RCC_APB2ENR_IOPBEN BIT(RCC_APB2ENR_IOPBEN_BIT) -#define RCC_APB2ENR_IOPAEN BIT(RCC_APB2ENR_IOPAEN_BIT) -#define RCC_APB2ENR_AFIOEN BIT(RCC_APB2ENR_AFIOEN_BIT) - -/* APB1 peripheral clock enable register */ - -#define RCC_APB1ENR_DACEN_BIT 29 -#define RCC_APB1ENR_PWREN_BIT 28 -#define RCC_APB1ENR_BKPEN_BIT 27 -#define RCC_APB1ENR_CANEN_BIT 25 -#define RCC_APB1ENR_USBEN_BIT 23 -#define RCC_APB1ENR_I2C2EN_BIT 22 -#define RCC_APB1ENR_I2C1EN_BIT 21 -#define RCC_APB1ENR_UART5EN_BIT 20 -#define RCC_APB1ENR_UART4EN_BIT 19 -#define RCC_APB1ENR_USART3EN_BIT 18 -#define RCC_APB1ENR_USART2EN_BIT 17 -#define RCC_APB1ENR_SPI3EN_BIT 15 -#define RCC_APB1ENR_SPI2EN_BIT 14 -#define RCC_APB1ENR_WWDEN_BIT 11 -#define RCC_APB1ENR_TIM14EN_BIT 8 -#define RCC_APB1ENR_TIM13EN_BIT 7 -#define RCC_APB1ENR_TIM12EN_BIT 6 -#define RCC_APB1ENR_TIM7EN_BIT 5 -#define RCC_APB1ENR_TIM6EN_BIT 4 -#define RCC_APB1ENR_TIM5EN_BIT 3 -#define RCC_APB1ENR_TIM4EN_BIT 2 -#define RCC_APB1ENR_TIM3EN_BIT 1 -#define RCC_APB1ENR_TIM2EN_BIT 0 - -#define RCC_APB1ENR_DACEN BIT(RCC_APB1ENR_DACEN_BIT) -#define RCC_APB1ENR_PWREN BIT(RCC_APB1ENR_PWREN_BIT) -#define RCC_APB1ENR_BKPEN BIT(RCC_APB1ENR_BKPEN_BIT) -#define RCC_APB1ENR_CANEN BIT(RCC_APB1ENR_CANEN_BIT) -#define RCC_APB1ENR_USBEN BIT(RCC_APB1ENR_USBEN_BIT) -#define RCC_APB1ENR_I2C2EN BIT(RCC_APB1ENR_I2C2EN_BIT) -#define RCC_APB1ENR_I2C1EN BIT(RCC_APB1ENR_I2C1EN_BIT) -#define RCC_APB1ENR_UART5EN BIT(RCC_APB1ENR_UART5EN_BIT) -#define RCC_APB1ENR_UART4EN BIT(RCC_APB1ENR_UART4EN_BIT) -#define RCC_APB1ENR_USART3EN BIT(RCC_APB1ENR_USART3EN_BIT) -#define RCC_APB1ENR_USART2EN BIT(RCC_APB1ENR_USART2EN_BIT) -#define RCC_APB1ENR_SPI3EN BIT(RCC_APB1ENR_SPI3EN_BIT) -#define RCC_APB1ENR_SPI2EN BIT(RCC_APB1ENR_SPI2EN_BIT) -#define RCC_APB1ENR_WWDEN BIT(RCC_APB1ENR_WWDEN_BIT) -#define RCC_APB1ENR_TIM14EN BIT(RCC_APB1ENR_TIM14EN_BIT) -#define RCC_APB1ENR_TIM13EN BIT(RCC_APB1ENR_TIM13EN_BIT) -#define RCC_APB1ENR_TIM12EN BIT(RCC_APB1ENR_TIM12EN_BIT) -#define RCC_APB1ENR_TIM7EN BIT(RCC_APB1ENR_TIM7EN_BIT) -#define RCC_APB1ENR_TIM6EN BIT(RCC_APB1ENR_TIM6EN_BIT) -#define RCC_APB1ENR_TIM5EN BIT(RCC_APB1ENR_TIM5EN_BIT) -#define RCC_APB1ENR_TIM4EN BIT(RCC_APB1ENR_TIM4EN_BIT) -#define RCC_APB1ENR_TIM3EN BIT(RCC_APB1ENR_TIM3EN_BIT) -#define RCC_APB1ENR_TIM2EN BIT(RCC_APB1ENR_TIM2EN_BIT) - -/* Backup domain control register */ - -#define RCC_BDCR_BDRST_BIT 16 -#define RCC_BDCR_RTCEN_BIT 15 -#define RCC_BDCR_LSEBYP_BIT 2 -#define RCC_BDCR_LSERDY_BIT 1 -#define RCC_BDCR_LSEON_BIT 0 - -#define RCC_BDCR_BDRST BIT(RCC_BDCR_BDRST_BIT) -#define RCC_BDCR_RTCEN BIT(RCC_BDCR_RTC_BIT) -#define RCC_BDCR_RTCSEL (0x3 << 8) -#define RCC_BDCR_RTCSEL_NONE (0x0 << 8) -#define RCC_BDCR_RTCSEL_LSE (0x1 << 8) -#define RCC_BDCR_RTCSEL_HSE (0x3 << 8) -#define RCC_BDCR_LSEBYP BIT(RCC_BDCR_LSEBYP_BIT) -#define RCC_BDCR_LSERDY BIT(RCC_BDCR_LSERDY_BIT) -#define RCC_BDCR_LSEON BIT(RCC_BDCR_LSEON_BIT) - -/* Control/status register */ - -#define RCC_CSR_LPWRRSTF_BIT 31 -#define RCC_CSR_WWDGRSTF_BIT 30 -#define RCC_CSR_IWDGRSTF_BIT 29 -#define RCC_CSR_SFTRSTF_BIT 28 -#define RCC_CSR_PORRSTF_BIT 27 -#define RCC_CSR_PINRSTF_BIT 26 -#define RCC_CSR_RMVF_BIT 24 -#define RCC_CSR_LSIRDY_BIT 1 -#define RCC_CSR_LSION_BIT 0 - -#define RCC_CSR_LPWRRSTF BIT(RCC_CSR_LPWRRSTF_BIT) -#define RCC_CSR_WWDGRSTF BIT(RCC_CSR_WWDGRSTF_BIT) -#define RCC_CSR_IWDGRSTF BIT(RCC_CSR_IWDGRSTF_BIT) -#define RCC_CSR_SFTRSTF BIT(RCC_CSR_SFTRSTF_BIT) -#define RCC_CSR_PORRSTF BIT(RCC_CSR_PORRSTF_BIT) -#define RCC_CSR_PINRSTF BIT(RCC_CSR_PINRSTF_BIT) -#define RCC_CSR_RMVF BIT(RCC_CSR_RMVF_BIT) -#define RCC_CSR_LSIRDY BIT(RCC_CSR_LSIRDY_BIT) -#define RCC_CSR_LSION BIT(RCC_CSR_LSION_BIT) - -/* - * Convenience routines - */ - -/** - * SYSCLK sources - * @see rcc_clk_init() - */ -typedef enum rcc_sysclk_src { - RCC_CLKSRC_HSI = 0x0, - RCC_CLKSRC_HSE = 0x1, - RCC_CLKSRC_PLL = 0x2, -} rcc_sysclk_src; - -/** - * PLL entry clock source - * @see rcc_clk_init() - */ -typedef enum rcc_pllsrc { - RCC_PLLSRC_HSE = (0x1 << 16), - RCC_PLLSRC_HSI_DIV_2 = (0x0 << 16) -} rcc_pllsrc; - -/** - * PLL multipliers - * @see rcc_clk_init() - */ -typedef enum rcc_pll_multiplier { - RCC_PLLMUL_2 = (0x0 << 18), - RCC_PLLMUL_3 = (0x1 << 18), - RCC_PLLMUL_4 = (0x2 << 18), - RCC_PLLMUL_5 = (0x3 << 18), - RCC_PLLMUL_6 = (0x4 << 18), - RCC_PLLMUL_7 = (0x5 << 18), - RCC_PLLMUL_8 = (0x6 << 18), - RCC_PLLMUL_9 = (0x7 << 18), - RCC_PLLMUL_10 = (0x8 << 18), - RCC_PLLMUL_11 = (0x9 << 18), - RCC_PLLMUL_12 = (0xA << 18), - RCC_PLLMUL_13 = (0xB << 18), - RCC_PLLMUL_14 = (0xC << 18), - RCC_PLLMUL_15 = (0xD << 18), - RCC_PLLMUL_16 = (0xE << 18), -} rcc_pll_multiplier; - -/** - * @brief Identifies bus and clock line for a peripheral. - * - * Also generally useful as a unique identifier for that peripheral - * (or its corresponding device struct). - */ -typedef enum rcc_clk_id { - RCC_GPIOA, - RCC_GPIOB, - RCC_GPIOC, - RCC_GPIOD, -// RCC_AFIO, - RCC_ADC1, - RCC_ADC2, - RCC_ADC3, - RCC_USART1, - RCC_USART2, - RCC_USART3, - RCC_TIMER1, - RCC_TIMER2, - RCC_TIMER3, - RCC_TIMER4, - RCC_SPI1, - RCC_SPI2, - RCC_DMA1, - RCC_PWR, -// RCC_BKP, - RCC_I2C1, - RCC_I2C2, - RCC_CRC, -// RCC_FLITF, -// RCC_SRAM, - RCC_GPIOE, - RCC_GPIOF, - RCC_GPIOG, - RCC_UART4, - RCC_UART5, - RCC_TIMER5, - RCC_TIMER6, - RCC_TIMER7, - RCC_TIMER8, - RCC_FSMC, - RCC_DAC, - RCC_DMA2, - RCC_SDIO, - RCC_SPI3, - RCC_TIMER9, - RCC_TIMER10, - RCC_TIMER11, - RCC_TIMER12, - RCC_TIMER13, - RCC_TIMER14, - RCC_USBFS, - RCC_SYSCFG, - RCC_SPI4 -} rcc_clk_id; - -void rcc_clk_init(rcc_sysclk_src sysclk_src, - rcc_pllsrc pll_src, - rcc_pll_multiplier pll_mul); -void rcc_clk_disable(rcc_clk_id device); -void rcc_clk_enable(rcc_clk_id device); -void rcc_reset_dev(rcc_clk_id device); - -void SetupClock72MHz(); -void SetupClock120MHz(); -void SetupClock168MHz(); - -typedef enum rcc_clk_domain { - RCC_APB1, - RCC_APB2, - RCC_AHB1, - RCC_AHB2, - RCC_AHB3 -} rcc_clk_domain; - -rcc_clk_domain rcc_dev_clk(rcc_clk_id device); - -uint32 rcc_dev_clk_speed(rcc_clk_id id); -uint32 rcc_dev_timer_clk_speed(rcc_clk_id id); - -/** - * Prescaler identifiers - * @see rcc_set_prescaler() - */ -typedef enum rcc_prescaler { - RCC_PRESCALER_AHB, - RCC_PRESCALER_APB1, - RCC_PRESCALER_APB2, - RCC_PRESCALER_USB, - RCC_PRESCALER_ADC -} rcc_prescaler; - -/** - * ADC prescaler dividers - * @see rcc_set_prescaler() - */ -typedef enum rcc_adc_divider { - RCC_ADCPRE_PCLK_DIV_2 = 0x0 << 14, - RCC_ADCPRE_PCLK_DIV_4 = 0x1 << 14, - RCC_ADCPRE_PCLK_DIV_6 = 0x2 << 14, - RCC_ADCPRE_PCLK_DIV_8 = 0x3 << 14, -} rcc_adc_divider; - -/** - * APB1 prescaler dividers - * @see rcc_set_prescaler() - */ -typedef enum rcc_apb1_divider { - RCC_APB1_HCLK_DIV_1 = 0x0 << 8, - RCC_APB1_HCLK_DIV_2 = 0x4 << 8, - RCC_APB1_HCLK_DIV_4 = 0x5 << 8, - RCC_APB1_HCLK_DIV_8 = 0x6 << 8, - RCC_APB1_HCLK_DIV_16 = 0x7 << 8, -} rcc_apb1_divider; - -/** - * APB2 prescaler dividers - * @see rcc_set_prescaler() - */ -typedef enum rcc_apb2_divider { - RCC_APB2_HCLK_DIV_1 = 0x0 << 11, - RCC_APB2_HCLK_DIV_2 = 0x4 << 11, - RCC_APB2_HCLK_DIV_4 = 0x5 << 11, - RCC_APB2_HCLK_DIV_8 = 0x6 << 11, - RCC_APB2_HCLK_DIV_16 = 0x7 << 11, -} rcc_apb2_divider; - -/** - * AHB prescaler dividers - * @see rcc_set_prescaler() - */ -typedef enum rcc_ahb_divider { - RCC_AHB_SYSCLK_DIV_1 = 0x0 << 4, - RCC_AHB_SYSCLK_DIV_2 = 0x8 << 4, - RCC_AHB_SYSCLK_DIV_4 = 0x9 << 4, - RCC_AHB_SYSCLK_DIV_8 = 0xA << 4, - RCC_AHB_SYSCLK_DIV_16 = 0xB << 4, - RCC_AHB_SYSCLK_DIV_32 = 0xC << 4, - RCC_AHB_SYSCLK_DIV_64 = 0xD << 4, - RCC_AHB_SYSCLK_DIV_128 = 0xD << 4, - RCC_AHB_SYSCLK_DIV_256 = 0xE << 4, - RCC_AHB_SYSCLK_DIV_512 = 0xF << 4, -} rcc_ahb_divider; - -void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file rcc.h + * @brief reset and clock control definitions and prototypes + */ + +#include "libmaple_types.h" + +#ifndef _RCC_H_ +#define _RCC_H_ + +#ifdef __cplusplus +extern "C"{ +#endif + +/** RCC register map type */ +typedef struct +{ + __io uint32 CR; /*!< RCC clock control register, Address offset: 0x00 */ + __io uint32 PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ + __io uint32 CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ + __io uint32 CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ + __io uint32 AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ + __io uint32 AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ + __io uint32 AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ + uint32 RESERVED0; /*!< Reserved, 0x1C */ + __io uint32 APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ + __io uint32 APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ + uint32 RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ + __io uint32 AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ + __io uint32 AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ + __io uint32 AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ + uint32 RESERVED2; /*!< Reserved, 0x3C */ + __io uint32 APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ + __io uint32 APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ + uint32 RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ + __io uint32 AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ + __io uint32 AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ + __io uint32 AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ + uint32 RESERVED4; /*!< Reserved, 0x5C */ + __io uint32 APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ + __io uint32 APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ + uint32 RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ + __io uint32 BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ + __io uint32 CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ + uint32 RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ + __io uint32 SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ + __io uint32 PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ +} rcc_reg_map; + +/** RCC register map base pointer */ +//#define RCC_BASE ((struct rcc_reg_map*)0x40021000) +#define RCC_BASE ((rcc_reg_map*)0x40023800) + +/* + * Register bit definitions + */ + +/* Clock control register */ + +#define RCC_CR_PLLRDY_BIT 25 +#define RCC_CR_PLLON_BIT 24 +#define RCC_CR_CSSON_BIT 19 +#define RCC_CR_HSEBYP_BIT 18 +#define RCC_CR_HSERDY_BIT 17 +#define RCC_CR_HSEON_BIT 16 +#define RCC_CR_HSIRDY_BIT 1 +#define RCC_CR_HSION_BIT 0 + +#define RCC_CR_PLLRDY BIT(RCC_CR_PLLRDY_BIT) +#define RCC_CR_PLLON BIT(RCC_CR_PLLON_BIT) +#define RCC_CR_CSSON BIT(RCC_CR_CSSON_BIT) +#define RCC_CR_HSEBYP BIT(RCC_CR_HSEBYP_BIT) +#define RCC_CR_HSERDY BIT(RCC_CR_HSERDY_BIT) +#define RCC_CR_HSEON BIT(RCC_CR_HSEON_BIT) +#define RCC_CR_HSICAL (0xFF << 8) +#define RCC_CR_HSITRIM (0x1F << 3) +#define RCC_CR_HSIRDY BIT(RCC_CR_HSIRDY_BIT) +#define RCC_CR_HSION BIT(RCC_CR_HSION_BIT) + +/* Clock configuration register */ + +#define RCC_CFGR_USBPRE_BIT 22 +#define RCC_CFGR_PLLXTPRE_BIT 17 +#define RCC_CFGR_PLLSRC_BIT 16 + +#define RCC_CFGR_MCO (0x3 << 24) +#define RCC_CFGR_USBPRE BIT(RCC_CFGR_USBPRE_BIT) +#define RCC_CFGR_PLLMUL (0xF << 18) +#define RCC_CFGR_PLLXTPRE BIT(RCC_CFGR_PLLXTPRE_BIT) +#define RCC_CFGR_PLLSRC BIT(RCC_CFGR_PLLSRC_BIT) +#define RCC_CFGR_ADCPRE (0x3 << 14) +#define RCC_CFGR_PPRE2 (0x7 << 11) +#define RCC_CFGR_PPRE1 (0x7 << 8) +#define RCC_CFGR_HPRE (0xF << 4) +#define RCC_CFGR_SWS (0x3 << 2) +#define RCC_CFGR_SWS_PLL (0x2 << 2) +#define RCC_CFGR_SWS_HSE (0x1 << 2) +#define RCC_CFGR_SW 0x3 +#define RCC_CFGR_SW_PLL 0x2 +#define RCC_CFGR_SW_HSE 0x1 + +/* Clock interrupt register */ + +#define RCC_CIR_CSSC_BIT 23 +#define RCC_CIR_PLLRDYC_BIT 20 +#define RCC_CIR_HSERDYC_BIT 19 +#define RCC_CIR_HSIRDYC_BIT 18 +#define RCC_CIR_LSERDYC_BIT 17 +#define RCC_CIR_LSIRDYC_BIT 16 +#define RCC_CIR_PLLRDYIE_BIT 12 +#define RCC_CIR_HSERDYIE_BIT 11 +#define RCC_CIR_HSIRDYIE_BIT 10 +#define RCC_CIR_LSERDYIE_BIT 9 +#define RCC_CIR_LSIRDYIE_BIT 8 +#define RCC_CIR_CSSF_BIT 7 +#define RCC_CIR_PLLRDYF_BIT 4 +#define RCC_CIR_HSERDYF_BIT 3 +#define RCC_CIR_HSIRDYF_BIT 2 +#define RCC_CIR_LSERDYF_BIT 1 +#define RCC_CIR_LSIRDYF_BIT 0 + +#define RCC_CIR_CSSC BIT(RCC_CIR_CSSC_BIT) +#define RCC_CIR_PLLRDYC BIT(RCC_CIR_PLLRDYC_BIT) +#define RCC_CIR_HSERDYC BIT(RCC_CIR_HSERDYC_BIT) +#define RCC_CIR_HSIRDYC BIT(RCC_CIR_HSIRDYC_BIT) +#define RCC_CIR_LSERDYC BIT(RCC_CIR_LSERDYC_BIT) +#define RCC_CIR_LSIRDYC BIT(RCC_CIR_LSIRDYC_BIT) +#define RCC_CIR_PLLRDYIE BIT(RCC_CIR_PLLRDYIE_BIT) +#define RCC_CIR_HSERDYIE BIT(RCC_CIR_HSERDYIE_BIT) +#define RCC_CIR_HSIRDYIE BIT(RCC_CIR_HSIRDYIE_BIT) +#define RCC_CIR_LSERDYIE BIT(RCC_CIR_LSERDYIE_BIT) +#define RCC_CIR_LSIRDYIE BIT(RCC_CIR_LSIRDYIE_BIT) +#define RCC_CIR_CSSF BIT(RCC_CIR_CSSF_BIT) +#define RCC_CIR_PLLRDYF BIT(RCC_CIR_PLLRDYF_BIT) +#define RCC_CIR_HSERDYF BIT(RCC_CIR_HSERDYF_BIT) +#define RCC_CIR_HSIRDYF BIT(RCC_CIR_HSIRDYF_BIT) +#define RCC_CIR_LSERDYF BIT(RCC_CIR_LSERDYF_BIT) +#define RCC_CIR_LSIRDYF BIT(RCC_CIR_LSIRDYF_BIT) + +/* APB2 peripheral reset register */ + +#define RCC_APB2RSTR_TIM11RST_BIT 21 +#define RCC_APB2RSTR_TIM10RST_BIT 20 +#define RCC_APB2RSTR_TIM9RST_BIT 19 +#define RCC_APB2RSTR_ADC3RST_BIT 15 +#define RCC_APB2RSTR_USART1RST_BIT 14 +#define RCC_APB2RSTR_TIM8RST_BIT 13 +#define RCC_APB2RSTR_SPI1RST_BIT 12 +#define RCC_APB2RSTR_TIM1RST_BIT 11 +#define RCC_APB2RSTR_ADC2RST_BIT 10 +#define RCC_APB2RSTR_ADC1RST_BIT 9 +#define RCC_APB2RSTR_IOPGRST_BIT 8 +#define RCC_APB2RSTR_IOPFRST_BIT 7 +#define RCC_APB2RSTR_IOPERST_BIT 6 +#define RCC_APB2RSTR_IOPDRST_BIT 5 +#define RCC_APB2RSTR_IOPCRST_BIT 4 +#define RCC_APB2RSTR_IOPBRST_BIT 3 +#define RCC_APB2RSTR_IOPARST_BIT 2 +#define RCC_APB2RSTR_AFIORST_BIT 0 + +#define RCC_APB2RSTR_TIM11RST BIT(RCC_APB2RSTR_TIM11RST_BIT) +#define RCC_APB2RSTR_TIM10RST BIT(RCC_APB2RSTR_TIM10RST_BIT) +#define RCC_APB2RSTR_TIM9RST BIT(RCC_APB2RSTR_TIM9RST_BIT) +#define RCC_APB2RSTR_ADC3RST BIT(RCC_APB2RSTR_ADC3RST_BIT) +#define RCC_APB2RSTR_USART1RST BIT(RCC_APB2RSTR_USART1RST_BIT) +#define RCC_APB2RSTR_TIM8RST BIT(RCC_APB2RSTR_TIM8RST_BIT) +#define RCC_APB2RSTR_SPI1RST BIT(RCC_APB2RSTR_SPI1RST_BIT) +#define RCC_APB2RSTR_TIM1RST BIT(RCC_APB2RSTR_TIM1RST_BIT) +#define RCC_APB2RSTR_ADC2RST BIT(RCC_APB2RSTR_ADC2RST_BIT) +#define RCC_APB2RSTR_ADC1RST BIT(RCC_APB2RSTR_ADC1RST_BIT) +#define RCC_APB2RSTR_IOPGRST BIT(RCC_APB2RSTR_IOPGRST_BIT) +#define RCC_APB2RSTR_IOPFRST BIT(RCC_APB2RSTR_IOPFRST_BIT) +#define RCC_APB2RSTR_IOPERST BIT(RCC_APB2RSTR_IOPERST_BIT) +#define RCC_APB2RSTR_IOPDRST BIT(RCC_APB2RSTR_IOPDRST_BIT) +#define RCC_APB2RSTR_IOPCRST BIT(RCC_APB2RSTR_IOPCRST_BIT) +#define RCC_APB2RSTR_IOPBRST BIT(RCC_APB2RSTR_IOPBRST_BIT) +#define RCC_APB2RSTR_IOPARST BIT(RCC_APB2RSTR_IOPARST_BIT) +#define RCC_APB2RSTR_AFIORST BIT(RCC_APB2RSTR_AFIORST_BIT) + +/* APB1 peripheral reset register */ + +#define RCC_APB1RSTR_DACRST_BIT 29 +#define RCC_APB1RSTR_PWRRST_BIT 28 +#define RCC_APB1RSTR_BKPRST_BIT 27 +#define RCC_APB1RSTR_CANRST_BIT 25 +#define RCC_APB1RSTR_USBRST_BIT 23 +#define RCC_APB1RSTR_I2C2RST_BIT 22 +#define RCC_APB1RSTR_I2C1RST_BIT 21 +#define RCC_APB1RSTR_UART5RST_BIT 20 +#define RCC_APB1RSTR_UART4RST_BIT 19 +#define RCC_APB1RSTR_USART3RST_BIT 18 +#define RCC_APB1RSTR_USART2RST_BIT 17 +#define RCC_APB1RSTR_SPI3RST_BIT 15 +#define RCC_APB1RSTR_SPI2RST_BIT 14 +#define RCC_APB1RSTR_WWDRST_BIT 11 +#define RCC_APB1RSTR_TIM14RST_BIT 8 +#define RCC_APB1RSTR_TIM13RST_BIT 7 +#define RCC_APB1RSTR_TIM12RST_BIT 6 +#define RCC_APB1RSTR_TIM7RST_BIT 5 +#define RCC_APB1RSTR_TIM6RST_BIT 4 +#define RCC_APB1RSTR_TIM5RST_BIT 3 +#define RCC_APB1RSTR_TIM4RST_BIT 2 +#define RCC_APB1RSTR_TIM3RST_BIT 1 +#define RCC_APB1RSTR_TIM2RST_BIT 0 + +#define RCC_APB1RSTR_DACRST BIT(RCC_APB1RSTR_DACRST_BIT) +#define RCC_APB1RSTR_PWRRST BIT(RCC_APB1RSTR_PWRRST_BIT) +#define RCC_APB1RSTR_BKPRST BIT(RCC_APB1RSTR_BKPRST_BIT) +#define RCC_APB1RSTR_CANRST BIT(RCC_APB1RSTR_CANRST_BIT) +#define RCC_APB1RSTR_USBRST BIT(RCC_APB1RSTR_USBRST_BIT) +#define RCC_APB1RSTR_I2C2RST BIT(RCC_APB1RSTR_I2C2RST_BIT) +#define RCC_APB1RSTR_I2C1RST BIT(RCC_APB1RSTR_I2C1RST_BIT) +#define RCC_APB1RSTR_UART5RST BIT(RCC_APB1RSTR_UART5RST_BIT) +#define RCC_APB1RSTR_UART4RST BIT(RCC_APB1RSTR_UART4RST_BIT) +#define RCC_APB1RSTR_USART3RST BIT(RCC_APB1RSTR_USART3RST_BIT) +#define RCC_APB1RSTR_USART2RST BIT(RCC_APB1RSTR_USART2RST_BIT) +#define RCC_APB1RSTR_SPI3RST BIT(RCC_APB1RSTR_SPI3RST_BIT) +#define RCC_APB1RSTR_SPI2RST BIT(RCC_APB1RSTR_SPI2RST_BIT) +#define RCC_APB1RSTR_WWDRST BIT(RCC_APB1RSTR_WWDRST_BIT) +#define RCC_APB1RSTR_TIM14RST BIT(RCC_APB1RSTR_TIM14RST_BIT) +#define RCC_APB1RSTR_TIM13RST BIT(RCC_APB1RSTR_TIM13RST_BIT) +#define RCC_APB1RSTR_TIM12RST BIT(RCC_APB1RSTR_TIM12RST_BIT) +#define RCC_APB1RSTR_TIM7RST BIT(RCC_APB1RSTR_TIM7RST_BIT) +#define RCC_APB1RSTR_TIM6RST BIT(RCC_APB1RSTR_TIM6RST_BIT) +#define RCC_APB1RSTR_TIM5RST BIT(RCC_APB1RSTR_TIM5RST_BIT) +#define RCC_APB1RSTR_TIM4RST BIT(RCC_APB1RSTR_TIM4RST_BIT) +#define RCC_APB1RSTR_TIM3RST BIT(RCC_APB1RSTR_TIM3RST_BIT) +#define RCC_APB1RSTR_TIM2RST BIT(RCC_APB1RSTR_TIM2RST_BIT) + +/* AHB peripheral clock enable register */ + +#define RCC_AHBENR_SDIOEN_BIT 10 +#define RCC_AHBENR_FSMCEN_BIT 8 +#define RCC_AHBENR_CRCEN_BIT 7 +#define RCC_AHBENR_FLITFEN_BIT 4 +#define RCC_AHBENR_SRAMEN_BIT 2 +#define RCC_AHBENR_DMA2EN_BIT 1 +#define RCC_AHBENR_DMA1EN_BIT 0 + +#define RCC_AHBENR_SDIOEN BIT(RCC_AHBENR_SDIOEN_BIT) +#define RCC_AHBENR_FSMCEN BIT(RCC_AHBENR_FSMCEN_BIT) +#define RCC_AHBENR_CRCEN BIT(RCC_AHBENR_CRCEN_BIT) +#define RCC_AHBENR_FLITFEN BIT(RCC_AHBENR_FLITFEN_BIT) +#define RCC_AHBENR_SRAMEN BIT(RCC_AHBENR_SRAMEN_BIT) +#define RCC_AHBENR_DMA2EN BIT(RCC_AHBENR_DMA2EN_BIT) +#define RCC_AHBENR_DMA1EN BIT(RCC_AHBENR_DMA1EN_BIT) + +/* APB2 peripheral clock enable register */ + +#define RCC_APB2ENR_TIM11EN_BIT 21 +#define RCC_APB2ENR_TIM10EN_BIT 20 +#define RCC_APB2ENR_TIM9EN_BIT 19 +#define RCC_APB2ENR_ADC3EN_BIT 15 +#define RCC_APB2ENR_USART1EN_BIT 14 +#define RCC_APB2ENR_TIM8EN_BIT 13 +#define RCC_APB2ENR_SPI1EN_BIT 12 +#define RCC_APB2ENR_TIM1EN_BIT 11 +#define RCC_APB2ENR_ADC2EN_BIT 10 +#define RCC_APB2ENR_ADC1EN_BIT 9 +#define RCC_APB2ENR_IOPGEN_BIT 8 +#define RCC_APB2ENR_IOPFEN_BIT 7 +#define RCC_APB2ENR_IOPEEN_BIT 6 +#define RCC_APB2ENR_IOPDEN_BIT 5 +#define RCC_APB2ENR_IOPCEN_BIT 4 +#define RCC_APB2ENR_IOPBEN_BIT 3 +#define RCC_APB2ENR_IOPAEN_BIT 2 +#define RCC_APB2ENR_AFIOEN_BIT 0 + +#define RCC_APB2ENR_TIM11EN BIT(RCC_APB2ENR_TIM11EN_BIT) +#define RCC_APB2ENR_TIM10EN BIT(RCC_APB2ENR_TIM10EN_BIT) +#define RCC_APB2ENR_TIM9EN BIT(RCC_APB2ENR_TIM9EN_BIT) +#define RCC_APB2ENR_ADC3EN BIT(RCC_APB2ENR_ADC3EN_BIT) +#define RCC_APB2ENR_USART1EN BIT(RCC_APB2ENR_USART1EN_BIT) +#define RCC_APB2ENR_TIM8EN BIT(RCC_APB2ENR_TIM8EN_BIT) +#define RCC_APB2ENR_SPI1EN BIT(RCC_APB2ENR_SPI1EN_BIT) +#define RCC_APB2ENR_TIM1EN BIT(RCC_APB2ENR_TIM1EN_BIT) +#define RCC_APB2ENR_ADC2EN BIT(RCC_APB2ENR_ADC2EN_BIT) +#define RCC_APB2ENR_ADC1EN BIT(RCC_APB2ENR_ADC1EN_BIT) +#define RCC_APB2ENR_IOPGEN BIT(RCC_APB2ENR_IOPGEN_BIT) +#define RCC_APB2ENR_IOPFEN BIT(RCC_APB2ENR_IOPFEN_BIT) +#define RCC_APB2ENR_IOPEEN BIT(RCC_APB2ENR_IOPEEN_BIT) +#define RCC_APB2ENR_IOPDEN BIT(RCC_APB2ENR_IOPDEN_BIT) +#define RCC_APB2ENR_IOPCEN BIT(RCC_APB2ENR_IOPCEN_BIT) +#define RCC_APB2ENR_IOPBEN BIT(RCC_APB2ENR_IOPBEN_BIT) +#define RCC_APB2ENR_IOPAEN BIT(RCC_APB2ENR_IOPAEN_BIT) +#define RCC_APB2ENR_AFIOEN BIT(RCC_APB2ENR_AFIOEN_BIT) + +/* APB1 peripheral clock enable register */ + +#define RCC_APB1ENR_DACEN_BIT 29 +#define RCC_APB1ENR_PWREN_BIT 28 +#define RCC_APB1ENR_BKPEN_BIT 27 +#define RCC_APB1ENR_CANEN_BIT 25 +#define RCC_APB1ENR_USBEN_BIT 23 +#define RCC_APB1ENR_I2C2EN_BIT 22 +#define RCC_APB1ENR_I2C1EN_BIT 21 +#define RCC_APB1ENR_UART5EN_BIT 20 +#define RCC_APB1ENR_UART4EN_BIT 19 +#define RCC_APB1ENR_USART3EN_BIT 18 +#define RCC_APB1ENR_USART2EN_BIT 17 +#define RCC_APB1ENR_SPI3EN_BIT 15 +#define RCC_APB1ENR_SPI2EN_BIT 14 +#define RCC_APB1ENR_WWDEN_BIT 11 +#define RCC_APB1ENR_TIM14EN_BIT 8 +#define RCC_APB1ENR_TIM13EN_BIT 7 +#define RCC_APB1ENR_TIM12EN_BIT 6 +#define RCC_APB1ENR_TIM7EN_BIT 5 +#define RCC_APB1ENR_TIM6EN_BIT 4 +#define RCC_APB1ENR_TIM5EN_BIT 3 +#define RCC_APB1ENR_TIM4EN_BIT 2 +#define RCC_APB1ENR_TIM3EN_BIT 1 +#define RCC_APB1ENR_TIM2EN_BIT 0 + +#define RCC_APB1ENR_DACEN BIT(RCC_APB1ENR_DACEN_BIT) +#define RCC_APB1ENR_PWREN BIT(RCC_APB1ENR_PWREN_BIT) +#define RCC_APB1ENR_BKPEN BIT(RCC_APB1ENR_BKPEN_BIT) +#define RCC_APB1ENR_CANEN BIT(RCC_APB1ENR_CANEN_BIT) +#define RCC_APB1ENR_USBEN BIT(RCC_APB1ENR_USBEN_BIT) +#define RCC_APB1ENR_I2C2EN BIT(RCC_APB1ENR_I2C2EN_BIT) +#define RCC_APB1ENR_I2C1EN BIT(RCC_APB1ENR_I2C1EN_BIT) +#define RCC_APB1ENR_UART5EN BIT(RCC_APB1ENR_UART5EN_BIT) +#define RCC_APB1ENR_UART4EN BIT(RCC_APB1ENR_UART4EN_BIT) +#define RCC_APB1ENR_USART3EN BIT(RCC_APB1ENR_USART3EN_BIT) +#define RCC_APB1ENR_USART2EN BIT(RCC_APB1ENR_USART2EN_BIT) +#define RCC_APB1ENR_SPI3EN BIT(RCC_APB1ENR_SPI3EN_BIT) +#define RCC_APB1ENR_SPI2EN BIT(RCC_APB1ENR_SPI2EN_BIT) +#define RCC_APB1ENR_WWDEN BIT(RCC_APB1ENR_WWDEN_BIT) +#define RCC_APB1ENR_TIM14EN BIT(RCC_APB1ENR_TIM14EN_BIT) +#define RCC_APB1ENR_TIM13EN BIT(RCC_APB1ENR_TIM13EN_BIT) +#define RCC_APB1ENR_TIM12EN BIT(RCC_APB1ENR_TIM12EN_BIT) +#define RCC_APB1ENR_TIM7EN BIT(RCC_APB1ENR_TIM7EN_BIT) +#define RCC_APB1ENR_TIM6EN BIT(RCC_APB1ENR_TIM6EN_BIT) +#define RCC_APB1ENR_TIM5EN BIT(RCC_APB1ENR_TIM5EN_BIT) +#define RCC_APB1ENR_TIM4EN BIT(RCC_APB1ENR_TIM4EN_BIT) +#define RCC_APB1ENR_TIM3EN BIT(RCC_APB1ENR_TIM3EN_BIT) +#define RCC_APB1ENR_TIM2EN BIT(RCC_APB1ENR_TIM2EN_BIT) + +/* Backup domain control register */ + +#define RCC_BDCR_BDRST_BIT 16 +#define RCC_BDCR_RTCEN_BIT 15 +#define RCC_BDCR_LSEBYP_BIT 2 +#define RCC_BDCR_LSERDY_BIT 1 +#define RCC_BDCR_LSEON_BIT 0 + +#define RCC_BDCR_BDRST BIT(RCC_BDCR_BDRST_BIT) +#define RCC_BDCR_RTCEN BIT(RCC_BDCR_RTC_BIT) +#define RCC_BDCR_RTCSEL (0x3 << 8) +#define RCC_BDCR_RTCSEL_NONE (0x0 << 8) +#define RCC_BDCR_RTCSEL_LSE (0x1 << 8) +#define RCC_BDCR_RTCSEL_HSE (0x3 << 8) +#define RCC_BDCR_LSEBYP BIT(RCC_BDCR_LSEBYP_BIT) +#define RCC_BDCR_LSERDY BIT(RCC_BDCR_LSERDY_BIT) +#define RCC_BDCR_LSEON BIT(RCC_BDCR_LSEON_BIT) + +/* Control/status register */ + +#define RCC_CSR_LPWRRSTF_BIT 31 +#define RCC_CSR_WWDGRSTF_BIT 30 +#define RCC_CSR_IWDGRSTF_BIT 29 +#define RCC_CSR_SFTRSTF_BIT 28 +#define RCC_CSR_PORRSTF_BIT 27 +#define RCC_CSR_PINRSTF_BIT 26 +#define RCC_CSR_RMVF_BIT 24 +#define RCC_CSR_LSIRDY_BIT 1 +#define RCC_CSR_LSION_BIT 0 + +#define RCC_CSR_LPWRRSTF BIT(RCC_CSR_LPWRRSTF_BIT) +#define RCC_CSR_WWDGRSTF BIT(RCC_CSR_WWDGRSTF_BIT) +#define RCC_CSR_IWDGRSTF BIT(RCC_CSR_IWDGRSTF_BIT) +#define RCC_CSR_SFTRSTF BIT(RCC_CSR_SFTRSTF_BIT) +#define RCC_CSR_PORRSTF BIT(RCC_CSR_PORRSTF_BIT) +#define RCC_CSR_PINRSTF BIT(RCC_CSR_PINRSTF_BIT) +#define RCC_CSR_RMVF BIT(RCC_CSR_RMVF_BIT) +#define RCC_CSR_LSIRDY BIT(RCC_CSR_LSIRDY_BIT) +#define RCC_CSR_LSION BIT(RCC_CSR_LSION_BIT) + +/* + * Convenience routines + */ + +/** + * SYSCLK sources + * @see rcc_clk_init() + */ +typedef enum rcc_sysclk_src { + RCC_CLKSRC_HSI = 0x0, + RCC_CLKSRC_HSE = 0x1, + RCC_CLKSRC_PLL = 0x2, +} rcc_sysclk_src; + +/** + * PLL entry clock source + * @see rcc_clk_init() + */ +typedef enum rcc_pllsrc { + RCC_PLLSRC_HSE = (0x1 << 16), + RCC_PLLSRC_HSI_DIV_2 = (0x0 << 16) +} rcc_pllsrc; + +/** + * PLL multipliers + * @see rcc_clk_init() + */ +typedef enum rcc_pll_multiplier { + RCC_PLLMUL_2 = (0x0 << 18), + RCC_PLLMUL_3 = (0x1 << 18), + RCC_PLLMUL_4 = (0x2 << 18), + RCC_PLLMUL_5 = (0x3 << 18), + RCC_PLLMUL_6 = (0x4 << 18), + RCC_PLLMUL_7 = (0x5 << 18), + RCC_PLLMUL_8 = (0x6 << 18), + RCC_PLLMUL_9 = (0x7 << 18), + RCC_PLLMUL_10 = (0x8 << 18), + RCC_PLLMUL_11 = (0x9 << 18), + RCC_PLLMUL_12 = (0xA << 18), + RCC_PLLMUL_13 = (0xB << 18), + RCC_PLLMUL_14 = (0xC << 18), + RCC_PLLMUL_15 = (0xD << 18), + RCC_PLLMUL_16 = (0xE << 18), +} rcc_pll_multiplier; + +/** + * @brief Identifies bus and clock line for a peripheral. + * + * Also generally useful as a unique identifier for that peripheral + * (or its corresponding device struct). + */ +typedef enum rcc_clk_id { + RCC_GPIOA, + RCC_GPIOB, + RCC_GPIOC, + RCC_GPIOD, +// RCC_AFIO, + RCC_ADC1, + RCC_ADC2, + RCC_ADC3, + RCC_USART1, + RCC_USART2, + RCC_USART3, + RCC_TIMER1, + RCC_TIMER2, + RCC_TIMER3, + RCC_TIMER4, + RCC_SPI1, + RCC_SPI2, + RCC_DMA1, + RCC_PWR, +// RCC_BKP, + RCC_I2C1, + RCC_I2C2, + RCC_CRC, +// RCC_FLITF, +// RCC_SRAM, + RCC_GPIOE, + RCC_GPIOF, + RCC_GPIOG, + RCC_UART4, + RCC_UART5, + RCC_TIMER5, + RCC_TIMER6, + RCC_TIMER7, + RCC_TIMER8, + RCC_FSMC, + RCC_DAC, + RCC_DMA2, + RCC_SDIO, + RCC_SPI3, + RCC_TIMER9, + RCC_TIMER10, + RCC_TIMER11, + RCC_TIMER12, + RCC_TIMER13, + RCC_TIMER14, + RCC_USBFS, + RCC_SYSCFG, + RCC_SPI4 +} rcc_clk_id; + +void rcc_clk_init(rcc_sysclk_src sysclk_src, + rcc_pllsrc pll_src, + rcc_pll_multiplier pll_mul); +void rcc_clk_disable(rcc_clk_id device); +void rcc_clk_enable(rcc_clk_id device); +void rcc_reset_dev(rcc_clk_id device); + +void SetupClock72MHz(); +void SetupClock120MHz(); +void SetupClock168MHz(); + +typedef enum rcc_clk_domain { + RCC_APB1, + RCC_APB2, + RCC_AHB1, + RCC_AHB2, + RCC_AHB3 +} rcc_clk_domain; + +rcc_clk_domain rcc_dev_clk(rcc_clk_id device); + +uint32 rcc_dev_clk_speed(rcc_clk_id id); +uint32 rcc_dev_timer_clk_speed(rcc_clk_id id); + +/** + * Prescaler identifiers + * @see rcc_set_prescaler() + */ +typedef enum rcc_prescaler { + RCC_PRESCALER_AHB, + RCC_PRESCALER_APB1, + RCC_PRESCALER_APB2, + RCC_PRESCALER_USB, + RCC_PRESCALER_ADC +} rcc_prescaler; + +/** + * ADC prescaler dividers + * @see rcc_set_prescaler() + */ +typedef enum rcc_adc_divider { + RCC_ADCPRE_PCLK_DIV_2 = 0x0 << 14, + RCC_ADCPRE_PCLK_DIV_4 = 0x1 << 14, + RCC_ADCPRE_PCLK_DIV_6 = 0x2 << 14, + RCC_ADCPRE_PCLK_DIV_8 = 0x3 << 14, +} rcc_adc_divider; + +/** + * APB1 prescaler dividers + * @see rcc_set_prescaler() + */ +typedef enum rcc_apb1_divider { + RCC_APB1_HCLK_DIV_1 = 0x0 << 8, + RCC_APB1_HCLK_DIV_2 = 0x4 << 8, + RCC_APB1_HCLK_DIV_4 = 0x5 << 8, + RCC_APB1_HCLK_DIV_8 = 0x6 << 8, + RCC_APB1_HCLK_DIV_16 = 0x7 << 8, +} rcc_apb1_divider; + +/** + * APB2 prescaler dividers + * @see rcc_set_prescaler() + */ +typedef enum rcc_apb2_divider { + RCC_APB2_HCLK_DIV_1 = 0x0 << 11, + RCC_APB2_HCLK_DIV_2 = 0x4 << 11, + RCC_APB2_HCLK_DIV_4 = 0x5 << 11, + RCC_APB2_HCLK_DIV_8 = 0x6 << 11, + RCC_APB2_HCLK_DIV_16 = 0x7 << 11, +} rcc_apb2_divider; + +/** + * AHB prescaler dividers + * @see rcc_set_prescaler() + */ +typedef enum rcc_ahb_divider { + RCC_AHB_SYSCLK_DIV_1 = 0x0 << 4, + RCC_AHB_SYSCLK_DIV_2 = 0x8 << 4, + RCC_AHB_SYSCLK_DIV_4 = 0x9 << 4, + RCC_AHB_SYSCLK_DIV_8 = 0xA << 4, + RCC_AHB_SYSCLK_DIV_16 = 0xB << 4, + RCC_AHB_SYSCLK_DIV_32 = 0xC << 4, + RCC_AHB_SYSCLK_DIV_64 = 0xD << 4, + RCC_AHB_SYSCLK_DIV_128 = 0xD << 4, + RCC_AHB_SYSCLK_DIV_256 = 0xE << 4, + RCC_AHB_SYSCLK_DIV_512 = 0xF << 4, +} rcc_ahb_divider; + +void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/ring_buffer.h b/Libmaple/libmaple/libmaple/ring_buffer.h index ba366fdf..c443bc38 100644 --- a/Libmaple/libmaple/libmaple/ring_buffer.h +++ b/Libmaple/libmaple/libmaple/ring_buffer.h @@ -1,189 +1,189 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file ring_buffer.h - * @brief Simple circular buffer - * - * This implementation is not thread-safe. In particular, none of - * these functions is guaranteed re-entrant. - */ - -#ifndef _RING_BUFFER_H_ -#define _RING_BUFFER_H_ - -#include "libmaple_types.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/** - * Ring buffer type. - * - * The buffer is empty when head == tail. - * - * The buffer is full when the head is one byte in front of the tail, - * modulo buffer length. - * - * One byte is left free to distinguish empty from full. */ -typedef struct ring_buffer { - volatile uint8 *buf; /**< Buffer items are stored into */ - uint16 head; /**< Index of the next item to remove */ - uint16 tail; /**< Index where the next item will get inserted */ - uint16 size; /**< Buffer capacity minus one */ -} ring_buffer; - -/** - * Initialise a ring buffer. - * - * @param rb Instance to initialise - * - * @param size Number of items in buf. The ring buffer will always - * leave one element unoccupied, so the maximum number of - * elements it can store will be size - 1. Thus, size - * must be at least 2. - * - * @param buf Buffer to store items into - */ -static inline void rb_init(ring_buffer *rb, uint16 size, uint8 *buf) { - rb->head = 0; - rb->tail = 0; - rb->size = size - 1; - rb->buf = buf; -} - -/** - * @brief Return the number of elements stored in the ring buffer. - * @param rb Buffer whose elements to count. - */ -static inline uint16 rb_full_count(ring_buffer *rb) { - __io ring_buffer *arb = rb; - int32 size = arb->tail - arb->head; - if (arb->tail < arb->head) { - size += arb->size + 1; - } - return (uint16)size; -} - -/** - * @brief Returns true if and only if the ring buffer is full. - * @param rb Buffer to test. - */ -static inline int rb_is_full(ring_buffer *rb) { - return (rb->tail + 1 == rb->head) || - (rb->tail == rb->size && rb->head == 0); -} - -/** - * @brief Returns true if and only if the ring buffer is empty. - * @param rb Buffer to test. - */ -static inline int rb_is_empty(ring_buffer *rb) { - return rb->head == rb->tail; -} - -/** - * Append element onto the end of a ring buffer. - * @param rb Buffer to append onto. - * @param element Value to append. - */ -static inline void rb_insert(ring_buffer *rb, uint8 element) { - rb->buf[rb->tail] = element; - rb->tail = (rb->tail == rb->size) ? 0 : rb->tail + 1; -} - -/** - * @brief Remove and return the first item from a ring buffer. - * @param rb Buffer to remove from, must contain at least one element. - */ -static inline uint8 rb_remove(ring_buffer *rb) { - uint8 ch = rb->buf[rb->head]; - rb->head = (rb->head == rb->size) ? 0 : rb->head + 1; - return ch; -} - -/** - * @brief Attempt to remove the first item from a ring buffer. - * - * If the ring buffer is nonempty, removes and returns its first item. - * If it is empty, does nothing and returns a negative value. - * - * @param rb Buffer to attempt to remove from. - */ -static inline int16 rb_safe_remove(ring_buffer *rb) { - return rb_is_empty(rb) ? -1 : rb_remove(rb); -} - -/** - * @brief Attempt to insert an element into a ring buffer. - * - * @param rb Buffer to insert into. - * @param element Value to insert into rb. - * @sideeffect If rb is not full, appends element onto buffer. - * @return If element was appended, then true; otherwise, false. */ -static inline int rb_safe_insert(ring_buffer *rb, uint8 element) { - if (rb_is_full(rb)) { - return 0; - } - rb_insert(rb, element); - return 1; -} - -/** - * @brief Append an item onto the end of a non-full ring buffer. - * - * If the buffer is full, removes its first item, then inserts the new - * element at the end. - * - * @param rb Ring buffer to insert into. - * @param element Value to insert into ring buffer. - * @return On success, returns -1. If an element was popped, returns - * the popped value. - */ -static inline int rb_push_insert(ring_buffer *rb, uint8 element) { - int ret = -1; - if (rb_is_full(rb)) { - ret = rb_remove(rb); - } - rb_insert(rb, element); - return ret; -} - -/** - * @brief Discard all items from a ring buffer. - * @param rb Ring buffer to discard all items from. - */ -static inline void rb_reset(ring_buffer *rb) { - rb->tail = rb->head; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file ring_buffer.h + * @brief Simple circular buffer + * + * This implementation is not thread-safe. In particular, none of + * these functions is guaranteed re-entrant. + */ + +#ifndef _RING_BUFFER_H_ +#define _RING_BUFFER_H_ + +#include "libmaple_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/** + * Ring buffer type. + * + * The buffer is empty when head == tail. + * + * The buffer is full when the head is one byte in front of the tail, + * modulo buffer length. + * + * One byte is left free to distinguish empty from full. */ +typedef struct ring_buffer { + volatile uint8 *buf; /**< Buffer items are stored into */ + uint16 head; /**< Index of the next item to remove */ + uint16 tail; /**< Index where the next item will get inserted */ + uint16 size; /**< Buffer capacity minus one */ +} ring_buffer; + +/** + * Initialise a ring buffer. + * + * @param rb Instance to initialise + * + * @param size Number of items in buf. The ring buffer will always + * leave one element unoccupied, so the maximum number of + * elements it can store will be size - 1. Thus, size + * must be at least 2. + * + * @param buf Buffer to store items into + */ +static inline void rb_init(ring_buffer *rb, uint16 size, uint8 *buf) { + rb->head = 0; + rb->tail = 0; + rb->size = size - 1; + rb->buf = buf; +} + +/** + * @brief Return the number of elements stored in the ring buffer. + * @param rb Buffer whose elements to count. + */ +static inline uint16 rb_full_count(ring_buffer *rb) { + __io ring_buffer *arb = rb; + int32 size = arb->tail - arb->head; + if (arb->tail < arb->head) { + size += arb->size + 1; + } + return (uint16)size; +} + +/** + * @brief Returns true if and only if the ring buffer is full. + * @param rb Buffer to test. + */ +static inline int rb_is_full(ring_buffer *rb) { + return (rb->tail + 1 == rb->head) || + (rb->tail == rb->size && rb->head == 0); +} + +/** + * @brief Returns true if and only if the ring buffer is empty. + * @param rb Buffer to test. + */ +static inline int rb_is_empty(ring_buffer *rb) { + return rb->head == rb->tail; +} + +/** + * Append element onto the end of a ring buffer. + * @param rb Buffer to append onto. + * @param element Value to append. + */ +static inline void rb_insert(ring_buffer *rb, uint8 element) { + rb->buf[rb->tail] = element; + rb->tail = (rb->tail == rb->size) ? 0 : rb->tail + 1; +} + +/** + * @brief Remove and return the first item from a ring buffer. + * @param rb Buffer to remove from, must contain at least one element. + */ +static inline uint8 rb_remove(ring_buffer *rb) { + uint8 ch = rb->buf[rb->head]; + rb->head = (rb->head == rb->size) ? 0 : rb->head + 1; + return ch; +} + +/** + * @brief Attempt to remove the first item from a ring buffer. + * + * If the ring buffer is nonempty, removes and returns its first item. + * If it is empty, does nothing and returns a negative value. + * + * @param rb Buffer to attempt to remove from. + */ +static inline int16 rb_safe_remove(ring_buffer *rb) { + return rb_is_empty(rb) ? -1 : rb_remove(rb); +} + +/** + * @brief Attempt to insert an element into a ring buffer. + * + * @param rb Buffer to insert into. + * @param element Value to insert into rb. + * @sideeffect If rb is not full, appends element onto buffer. + * @return If element was appended, then true; otherwise, false. */ +static inline int rb_safe_insert(ring_buffer *rb, uint8 element) { + if (rb_is_full(rb)) { + return 0; + } + rb_insert(rb, element); + return 1; +} + +/** + * @brief Append an item onto the end of a non-full ring buffer. + * + * If the buffer is full, removes its first item, then inserts the new + * element at the end. + * + * @param rb Ring buffer to insert into. + * @param element Value to insert into ring buffer. + * @return On success, returns -1. If an element was popped, returns + * the popped value. + */ +static inline int rb_push_insert(ring_buffer *rb, uint8 element) { + int ret = -1; + if (rb_is_full(rb)) { + ret = rb_remove(rb); + } + rb_insert(rb, element); + return ret; +} + +/** + * @brief Discard all items from a ring buffer. + * @param rb Ring buffer to discard all items from. + */ +static inline void rb_reset(ring_buffer *rb) { + rb->tail = rb->head; +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif + diff --git a/Libmaple/libmaple/libmaple/rules.mk b/Libmaple/libmaple/libmaple/rules.mk index a6b151f7..164fc9a6 100644 --- a/Libmaple/libmaple/libmaple/rules.mk +++ b/Libmaple/libmaple/libmaple/rules.mk @@ -1,93 +1,93 @@ -# Standard things -sp := $(sp).x -dirstack_$(sp) := $(d) -d := $(dir) -BUILDDIRS += $(BUILD_PATH)/$(d) -ifneq ($(MCU_FAMILY), STM32F2) -BUILDDIRS += $(BUILD_PATH)/$(d)/usb -BUILDDIRS += $(BUILD_PATH)/$(d)/usb/usb_lib -LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH) -I$(LIBMAPLE_PATH)/usb -I$(LIBMAPLE_PATH)/usb/usb_lib -else -BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_Device_Library/Core/src -BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_Device_Library/Class/cdc/src -BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_OTG_Driver/src -BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/VCP -LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH) -I$(LIBMAPLE_PATH)/usbF4 -endif - - -# Local flags -CFLAGS_$(d) = -I$(d) $(LIBMAPLE_INCLUDES) -Wall -Werror - -# Local rules and targets -# bkp.c - -cSRCS_$(d) := adc.c \ - dac.c \ - dma.c \ - exti.c \ - flash.c \ - fsmc.c \ - gpio.c \ - iwdg.c \ - nvic.c \ - pwr.c \ - i2c.c \ - rcc.c \ - spi.c \ - syscalls.c \ - systick.c \ - timer.c \ - usart.c \ - util.c - -ifneq ($(MCU_FAMILY), STM32F2) - cSRCS_$(d) += \ - usb/descriptors.c \ - usb/usb.c \ - usb/usb_callbacks.c \ - usb/usb_hardware.c \ - usb/usb_lib/usb_core.c \ - usb/usb_lib/usb_init.c \ - usb/usb_lib/usb_int.c \ - usb/usb_lib/usb_mem.c \ - usb/usb_lib/usb_regs.c -else - V=1 - cSRCS_$(d) += \ - usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c \ - usbF4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c \ - usbF4/STM32_USB_Device_Library/Core/src/usbd_req.c \ - usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c \ - usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c \ - usbF4/STM32_USB_OTG_Driver/src/usb_core.c \ - usbF4/STM32_USB_OTG_Driver/src/usb_dcd_int.c \ - usbF4/VCP/usb_bsp.c \ - usbF4/VCP/usbd_cdc_vcp.c \ - usbF4/VCP/usbd_desc.c \ - usbF4/VCP/usbd_usr.c \ - usbF4/usb.c \ - usbF4/VCP/misc.c -endif - -ifneq ($(MCU_FAMILY), STM32F2) - cSRCS_$(d) += bkp.c -endif - -sSRCS_$(d) := exc.S - -cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) -sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%) - -OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) -DEPS_$(d) := $(OBJS_$(d):%.o=%.d) - -$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) -$(OBJS_$(d)): TGT_ASFLAGS := - -TGT_BIN += $(OBJS_$(d)) - -# Standard things --include $(DEPS_$(d)) -d := $(dirstack_$(sp)) -sp := $(basename $(sp)) +# Standard things +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) +BUILDDIRS += $(BUILD_PATH)/$(d) +ifneq ($(MCU_FAMILY), STM32F2) +BUILDDIRS += $(BUILD_PATH)/$(d)/usb +BUILDDIRS += $(BUILD_PATH)/$(d)/usb/usb_lib +LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH) -I$(LIBMAPLE_PATH)/usb -I$(LIBMAPLE_PATH)/usb/usb_lib +else +BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_Device_Library/Core/src +BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_Device_Library/Class/cdc/src +BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_OTG_Driver/src +BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/VCP +LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH) -I$(LIBMAPLE_PATH)/usbF4 +endif + + +# Local flags +CFLAGS_$(d) = -I$(d) $(LIBMAPLE_INCLUDES) -Wall -Werror + +# Local rules and targets +# bkp.c + +cSRCS_$(d) := adc.c \ + dac.c \ + dma.c \ + exti.c \ + flash.c \ + fsmc.c \ + gpio.c \ + iwdg.c \ + nvic.c \ + pwr.c \ + i2c.c \ + rcc.c \ + spi.c \ + syscalls.c \ + systick.c \ + timer.c \ + usart.c \ + util.c + +ifneq ($(MCU_FAMILY), STM32F2) + cSRCS_$(d) += \ + usb/descriptors.c \ + usb/usb.c \ + usb/usb_callbacks.c \ + usb/usb_hardware.c \ + usb/usb_lib/usb_core.c \ + usb/usb_lib/usb_init.c \ + usb/usb_lib/usb_int.c \ + usb/usb_lib/usb_mem.c \ + usb/usb_lib/usb_regs.c +else + V=1 + cSRCS_$(d) += \ + usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c \ + usbF4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c \ + usbF4/STM32_USB_Device_Library/Core/src/usbd_req.c \ + usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c \ + usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c \ + usbF4/STM32_USB_OTG_Driver/src/usb_core.c \ + usbF4/STM32_USB_OTG_Driver/src/usb_dcd_int.c \ + usbF4/VCP/usb_bsp.c \ + usbF4/VCP/usbd_cdc_vcp.c \ + usbF4/VCP/usbd_desc.c \ + usbF4/VCP/usbd_usr.c \ + usbF4/usb.c \ + usbF4/VCP/misc.c +endif + +ifneq ($(MCU_FAMILY), STM32F2) + cSRCS_$(d) += bkp.c +endif + +sSRCS_$(d) := exc.S + +cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%) + +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) +DEPS_$(d) := $(OBJS_$(d):%.o=%.d) + +$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) +$(OBJS_$(d)): TGT_ASFLAGS := + +TGT_BIN += $(OBJS_$(d)) + +# Standard things +-include $(DEPS_$(d)) +d := $(dirstack_$(sp)) +sp := $(basename $(sp)) diff --git a/Libmaple/libmaple/libmaple/scb.h b/Libmaple/libmaple/libmaple/scb.h index 90af035e..d9cd8c92 100644 --- a/Libmaple/libmaple/libmaple/scb.h +++ b/Libmaple/libmaple/libmaple/scb.h @@ -1,65 +1,65 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file scb.h - * @brief System control block header - */ - -#include "libmaple_types.h" - -#ifndef _SCB_H_ -#define _SCB_H_ - -/** System control block register map type */ -typedef struct scb_reg_map { - __io uint32 CPUID; /**< CPU ID Base Register */ - __io uint32 ICSR; /**< Interrupt Control State Register */ - __io uint32 VTOR; /**< Vector Table Offset Register */ - __io uint32 AIRCR; /**< Application Interrupt / Reset Control Register */ - __io uint32 SCR; /**< System Control Register */ - __io uint32 CCR; /**< Configuration Control Register */ - __io uint8 SHP[12]; /**< System Handlers Priority Registers - (4-7, 8-11, 12-15) */ - __io uint32 SHCSR; /**< System Handler Control and State Register */ - __io uint32 CFSR; /**< Configurable Fault Status Register */ - __io uint32 HFSR; /**< Hard Fault Status Register */ - __io uint32 DFSR; /**< Debug Fault Status Register */ - __io uint32 MMFAR; /**< Mem Manage Address Register */ - __io uint32 BFAR; /**< Bus Fault Address Register */ - __io uint32 AFSR; /**< Auxiliary Fault Status Register */ - __io uint32 PFR[2]; /**< Processor Feature Register */ - __io uint32 DFR; /**< Debug Feature Register */ - __io uint32 ADR; /**< Auxiliary Feature Register */ - __io uint32 MMFR[4]; /**< Memory Model Feature Register */ - __io uint32 ISAR[5]; /**< ISA Feature Register */ -} scb_reg_map; - -/** System control block register map base pointer */ -#define SCB_BASE ((struct scb_reg_map*)0xE000ED00) - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file scb.h + * @brief System control block header + */ + +#include "libmaple_types.h" + +#ifndef _SCB_H_ +#define _SCB_H_ + +/** System control block register map type */ +typedef struct scb_reg_map { + __io uint32 CPUID; /**< CPU ID Base Register */ + __io uint32 ICSR; /**< Interrupt Control State Register */ + __io uint32 VTOR; /**< Vector Table Offset Register */ + __io uint32 AIRCR; /**< Application Interrupt / Reset Control Register */ + __io uint32 SCR; /**< System Control Register */ + __io uint32 CCR; /**< Configuration Control Register */ + __io uint8 SHP[12]; /**< System Handlers Priority Registers + (4-7, 8-11, 12-15) */ + __io uint32 SHCSR; /**< System Handler Control and State Register */ + __io uint32 CFSR; /**< Configurable Fault Status Register */ + __io uint32 HFSR; /**< Hard Fault Status Register */ + __io uint32 DFSR; /**< Debug Fault Status Register */ + __io uint32 MMFAR; /**< Mem Manage Address Register */ + __io uint32 BFAR; /**< Bus Fault Address Register */ + __io uint32 AFSR; /**< Auxiliary Fault Status Register */ + __io uint32 PFR[2]; /**< Processor Feature Register */ + __io uint32 DFR; /**< Debug Feature Register */ + __io uint32 ADR; /**< Auxiliary Feature Register */ + __io uint32 MMFR[4]; /**< Memory Model Feature Register */ + __io uint32 ISAR[5]; /**< ISA Feature Register */ +} scb_reg_map; + +/** System control block register map base pointer */ +#define SCB_BASE ((struct scb_reg_map*)0xE000ED00) + +#endif + diff --git a/Libmaple/libmaple/libmaple/spi.c b/Libmaple/libmaple/libmaple/spi.c index 4d2f5a3f..1b58e990 100644 --- a/Libmaple/libmaple/libmaple/spi.c +++ b/Libmaple/libmaple/libmaple/spi.c @@ -1,258 +1,258 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file spi.c - * @author Marti Bolivar - * @brief Serial Peripheral Interface (SPI) support. - * Currently, there is no Integrated Interchip Sound (I2S) support. - */ - -#include "spi.h" -#include "bitband.h" - -static void spi_reconfigure(spi_dev *dev, uint32 cr1_config); - -/* - * SPI devices - */ - -static spi_dev spi1 = { - .regs = SPI1_BASE, - .clk_id = RCC_SPI1, - .irq_num = NVIC_SPI1, -}; -/** SPI device 1 */ -spi_dev *SPI1 = &spi1; - -static spi_dev spi2 = { - .regs = SPI2_BASE, - .clk_id = RCC_SPI2, - .irq_num = NVIC_SPI2, -}; -/** SPI device 2 */ -spi_dev *SPI2 = &spi2; - -#ifdef STM32_HIGH_DENSITY -static spi_dev spi3 = { - .regs = SPI3_BASE, - .clk_id = RCC_SPI3, - .irq_num = NVIC_SPI3, -}; -/** SPI device 3 */ -spi_dev *SPI3 = &spi3; -#endif - -#ifdef STM32F2 -static spi_dev spi4 = { - .regs = SPI3_BASE, - .clk_id = RCC_SPI4, - .irq_num = NVIC_SPI3, -}; -/** SPI device 3 remapped*/ -spi_dev *SPI4 = &spi4; -#endif - -/* - * SPI convenience routines - */ - -/** - * @brief Initialize and reset a SPI device. - * @param dev Device to initialize and reset. - */ -void spi_init(spi_dev *dev) { - rcc_clk_enable(dev->clk_id); - rcc_reset_dev(dev->clk_id); -} - -/** - * @brief Configure GPIO bit modes for use as a SPI port's pins. - * @param as_master If true, configure bits for use as a bus master. - * Otherwise, configure bits for use as slave. - * @param nss_dev NSS pin's GPIO device - * @param comm_dev SCK, MISO, MOSI pins' GPIO device - * @param nss_bit NSS pin's GPIO bit on nss_dev - * @param sck_bit SCK pin's GPIO bit on comm_dev - * @param miso_bit MISO pin's GPIO bit on comm_dev - * @param mosi_bit MOSI pin's GPIO bit on comm_dev - */ -void spi_gpio_cfg(uint8 as_master, - gpio_dev *nss_dev, - uint8 nss_bit, - gpio_dev *comm_dev, - uint8 sck_bit, - uint8 miso_bit, - uint8 mosi_bit) { - if (as_master) { - if(nss_dev != NULL) { - gpio_set_mode(nss_dev, nss_bit, GPIO_OUTPUT_PP); - } - gpio_set_mode(comm_dev, sck_bit, GPIO_AF_OUTPUT_PP); - //gpio_set_mode(comm_dev, miso_bit, GPIO_INPUT_FLOATING); - gpio_set_mode(comm_dev, miso_bit, GPIO_AF_INPUT_PD); - gpio_set_mode(comm_dev, mosi_bit, GPIO_AF_OUTPUT_PP); - } else { - if(nss_dev != NULL) { - gpio_set_mode(nss_dev, nss_bit, GPIO_INPUT_FLOATING); - } - gpio_set_mode(comm_dev, sck_bit, GPIO_INPUT_FLOATING); - gpio_set_mode(comm_dev, miso_bit, GPIO_AF_OUTPUT_PP); - gpio_set_mode(comm_dev, mosi_bit, GPIO_INPUT_FLOATING); - } -} - -/** - * @brief Configure and enable a SPI device as bus master. - * - * The device's peripheral will be disabled before being reconfigured. - * - * @param dev Device to configure as bus master - * @param baud Bus baud rate - * @param mode SPI mode - * @param flags Logical OR of spi_cfg_flag values. - * @see spi_cfg_flag - */ -void spi_master_enable(spi_dev *dev, - spi_baud_rate baud, - spi_mode mode, - uint32 flags) { - spi_reconfigure(dev, baud | flags | SPI_CR1_MSTR | mode); -} - -/** - * @brief Configure and enable a SPI device as a bus slave. - * - * The device's peripheral will be disabled before being reconfigured. - * - * @param dev Device to configure as a bus slave - * @param mode SPI mode - * @param flags Logical OR of spi_cfg_flag values. - * @see spi_cfg_flag - */ -void spi_slave_enable(spi_dev *dev, spi_mode mode, uint32 flags) { - spi_reconfigure(dev, flags | mode); -} - -/** - * @brief Nonblocking SPI transmit. - * @param dev SPI port to use for transmission - * @param buf Buffer to transmit. The sizeof buf's elements are - * inferred from dev's data frame format (i.e., are - * correctly treated as 8-bit or 16-bit quantities). - * @param len Maximum number of elements to transmit. - * @return Number of elements transmitted. - */ -uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) { - uint32 txed = 0; - uint8 byte_frame = spi_dff(dev) == SPI_DFF_8_BIT; - while (spi_is_tx_empty(dev) && (txed < len)) { - if (byte_frame) { - dev->regs->DR = ((const uint8*)buf)[txed++]; - } else { - dev->regs->DR = ((const uint16*)buf)[txed++]; - } - } - return txed; -} - -/** - * @brief Call a function on each SPI port - * @param fn Function to call. - */ -void spi_foreach(void (*fn)(spi_dev*)) { - fn(SPI1); - fn(SPI2); -#ifdef STM32_HIGH_DENSITY - fn(SPI3); -#endif -#ifdef STM32F2 - fn(SPI4); -#endif -} - -/** - * @brief Enable a SPI peripheral - * @param dev Device to enable - */ -void spi_peripheral_enable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR1, SPI_CR1_SPE_BIT, 1); -} - -/** - * @brief Disable a SPI peripheral - * @param dev Device to disable - */ -void spi_peripheral_disable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR1, SPI_CR1_SPE_BIT, 0); -} - -/** - * @brief Enable DMA requests whenever the transmit buffer is empty - * @param dev SPI device on which to enable TX DMA requests - */ -void spi_tx_dma_enable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_TXDMAEN_BIT, 1); -} - -/** - * @brief Disable DMA requests whenever the transmit buffer is empty - * @param dev SPI device on which to disable TX DMA requests - */ -void spi_tx_dma_disable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_TXDMAEN_BIT, 0); -} - -/** - * @brief Enable DMA requests whenever the receive buffer is empty - * @param dev SPI device on which to enable RX DMA requests - */ -void spi_rx_dma_enable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_RXDMAEN_BIT, 1); -} - -/** - * @brief Disable DMA requests whenever the receive buffer is empty - * @param dev SPI device on which to disable RX DMA requests - */ -void spi_rx_dma_disable(spi_dev *dev) { - bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_RXDMAEN_BIT, 0); -} - -/* - * SPI auxiliary routines - */ - -static void spi_reconfigure(spi_dev *dev, uint32 cr1_config) { - spi_irq_disable(dev, SPI_INTERRUPTS_ALL); - spi_peripheral_disable(dev); - dev->regs->CR1 = cr1_config; - spi_peripheral_enable(dev); -} - -/* - * IRQ handlers (TODO) - */ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file spi.c + * @author Marti Bolivar + * @brief Serial Peripheral Interface (SPI) support. + * Currently, there is no Integrated Interchip Sound (I2S) support. + */ + +#include "spi.h" +#include "bitband.h" + +static void spi_reconfigure(spi_dev *dev, uint32 cr1_config); + +/* + * SPI devices + */ + +static spi_dev spi1 = { + .regs = SPI1_BASE, + .clk_id = RCC_SPI1, + .irq_num = NVIC_SPI1, +}; +/** SPI device 1 */ +spi_dev *SPI1 = &spi1; + +static spi_dev spi2 = { + .regs = SPI2_BASE, + .clk_id = RCC_SPI2, + .irq_num = NVIC_SPI2, +}; +/** SPI device 2 */ +spi_dev *SPI2 = &spi2; + +#ifdef STM32_HIGH_DENSITY +static spi_dev spi3 = { + .regs = SPI3_BASE, + .clk_id = RCC_SPI3, + .irq_num = NVIC_SPI3, +}; +/** SPI device 3 */ +spi_dev *SPI3 = &spi3; +#endif + +#ifdef STM32F2 +static spi_dev spi4 = { + .regs = SPI3_BASE, + .clk_id = RCC_SPI4, + .irq_num = NVIC_SPI3, +}; +/** SPI device 3 remapped*/ +spi_dev *SPI4 = &spi4; +#endif + +/* + * SPI convenience routines + */ + +/** + * @brief Initialize and reset a SPI device. + * @param dev Device to initialize and reset. + */ +void spi_init(spi_dev *dev) { + rcc_clk_enable(dev->clk_id); + rcc_reset_dev(dev->clk_id); +} + +/** + * @brief Configure GPIO bit modes for use as a SPI port's pins. + * @param as_master If true, configure bits for use as a bus master. + * Otherwise, configure bits for use as slave. + * @param nss_dev NSS pin's GPIO device + * @param comm_dev SCK, MISO, MOSI pins' GPIO device + * @param nss_bit NSS pin's GPIO bit on nss_dev + * @param sck_bit SCK pin's GPIO bit on comm_dev + * @param miso_bit MISO pin's GPIO bit on comm_dev + * @param mosi_bit MOSI pin's GPIO bit on comm_dev + */ +void spi_gpio_cfg(uint8 as_master, + gpio_dev *nss_dev, + uint8 nss_bit, + gpio_dev *comm_dev, + uint8 sck_bit, + uint8 miso_bit, + uint8 mosi_bit) { + if (as_master) { + if(nss_dev != NULL) { + gpio_set_mode(nss_dev, nss_bit, GPIO_OUTPUT_PP); + } + gpio_set_mode(comm_dev, sck_bit, GPIO_AF_OUTPUT_PP); + //gpio_set_mode(comm_dev, miso_bit, GPIO_INPUT_FLOATING); + gpio_set_mode(comm_dev, miso_bit, GPIO_AF_INPUT_PD); + gpio_set_mode(comm_dev, mosi_bit, GPIO_AF_OUTPUT_PP); + } else { + if(nss_dev != NULL) { + gpio_set_mode(nss_dev, nss_bit, GPIO_INPUT_FLOATING); + } + gpio_set_mode(comm_dev, sck_bit, GPIO_INPUT_FLOATING); + gpio_set_mode(comm_dev, miso_bit, GPIO_AF_OUTPUT_PP); + gpio_set_mode(comm_dev, mosi_bit, GPIO_INPUT_FLOATING); + } +} + +/** + * @brief Configure and enable a SPI device as bus master. + * + * The device's peripheral will be disabled before being reconfigured. + * + * @param dev Device to configure as bus master + * @param baud Bus baud rate + * @param mode SPI mode + * @param flags Logical OR of spi_cfg_flag values. + * @see spi_cfg_flag + */ +void spi_master_enable(spi_dev *dev, + spi_baud_rate baud, + spi_mode mode, + uint32 flags) { + spi_reconfigure(dev, baud | flags | SPI_CR1_MSTR | mode); +} + +/** + * @brief Configure and enable a SPI device as a bus slave. + * + * The device's peripheral will be disabled before being reconfigured. + * + * @param dev Device to configure as a bus slave + * @param mode SPI mode + * @param flags Logical OR of spi_cfg_flag values. + * @see spi_cfg_flag + */ +void spi_slave_enable(spi_dev *dev, spi_mode mode, uint32 flags) { + spi_reconfigure(dev, flags | mode); +} + +/** + * @brief Nonblocking SPI transmit. + * @param dev SPI port to use for transmission + * @param buf Buffer to transmit. The sizeof buf's elements are + * inferred from dev's data frame format (i.e., are + * correctly treated as 8-bit or 16-bit quantities). + * @param len Maximum number of elements to transmit. + * @return Number of elements transmitted. + */ +uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) { + uint32 txed = 0; + uint8 byte_frame = spi_dff(dev) == SPI_DFF_8_BIT; + while (spi_is_tx_empty(dev) && (txed < len)) { + if (byte_frame) { + dev->regs->DR = ((const uint8*)buf)[txed++]; + } else { + dev->regs->DR = ((const uint16*)buf)[txed++]; + } + } + return txed; +} + +/** + * @brief Call a function on each SPI port + * @param fn Function to call. + */ +void spi_foreach(void (*fn)(spi_dev*)) { + fn(SPI1); + fn(SPI2); +#ifdef STM32_HIGH_DENSITY + fn(SPI3); +#endif +#ifdef STM32F2 + fn(SPI4); +#endif +} + +/** + * @brief Enable a SPI peripheral + * @param dev Device to enable + */ +void spi_peripheral_enable(spi_dev *dev) { + bb_peri_set_bit(&dev->regs->CR1, SPI_CR1_SPE_BIT, 1); +} + +/** + * @brief Disable a SPI peripheral + * @param dev Device to disable + */ +void spi_peripheral_disable(spi_dev *dev) { + bb_peri_set_bit(&dev->regs->CR1, SPI_CR1_SPE_BIT, 0); +} + +/** + * @brief Enable DMA requests whenever the transmit buffer is empty + * @param dev SPI device on which to enable TX DMA requests + */ +void spi_tx_dma_enable(spi_dev *dev) { + bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_TXDMAEN_BIT, 1); +} + +/** + * @brief Disable DMA requests whenever the transmit buffer is empty + * @param dev SPI device on which to disable TX DMA requests + */ +void spi_tx_dma_disable(spi_dev *dev) { + bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_TXDMAEN_BIT, 0); +} + +/** + * @brief Enable DMA requests whenever the receive buffer is empty + * @param dev SPI device on which to enable RX DMA requests + */ +void spi_rx_dma_enable(spi_dev *dev) { + bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_RXDMAEN_BIT, 1); +} + +/** + * @brief Disable DMA requests whenever the receive buffer is empty + * @param dev SPI device on which to disable RX DMA requests + */ +void spi_rx_dma_disable(spi_dev *dev) { + bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_RXDMAEN_BIT, 0); +} + +/* + * SPI auxiliary routines + */ + +static void spi_reconfigure(spi_dev *dev, uint32 cr1_config) { + spi_irq_disable(dev, SPI_INTERRUPTS_ALL); + spi_peripheral_disable(dev); + dev->regs->CR1 = cr1_config; + spi_peripheral_enable(dev); +} + +/* + * IRQ handlers (TODO) + */ diff --git a/Libmaple/libmaple/libmaple/spi.h b/Libmaple/libmaple/libmaple/spi.h index ca697d37..004fb8d6 100644 --- a/Libmaple/libmaple/libmaple/spi.h +++ b/Libmaple/libmaple/libmaple/spi.h @@ -1,459 +1,459 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file spi.h - * @author Marti Bolivar - * @brief Serial Peripheral Interface (SPI) and Integrated - * Interchip Sound (I2S) peripheral support. - * - * I2S support is currently limited to register maps and bit definitions. - */ - -#ifndef _SPI_H_ -#define _SPI_H_ - -#include "libmaple_types.h" -#include "rcc.h" -#include "nvic.h" -#include "gpio.h" -#include "util.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Register maps - */ - -/** SPI register map type. */ -typedef struct spi_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SR; /**< Status register */ - __io uint32 DR; /**< Data register */ - __io uint32 CRCPR; /**< CRC polynomial register */ - __io uint32 RXCRCR; /**< RX CRC register */ - __io uint32 TXCRCR; /**< TX CRC register */ - __io uint32 I2SCFGR; /**< I2S configuration register */ - __io uint32 I2SPR; /**< I2S prescaler register */ -} spi_reg_map; - -/** SPI1 register map base pointer */ -#define SPI1_BASE ((struct spi_reg_map*)0x40013000) -/** SPI2 register map base pointer */ -#define SPI2_BASE ((struct spi_reg_map*)0x40003800) -/** SPI3 register map base pointer */ -#define SPI3_BASE ((struct spi_reg_map*)0x40003C00) - -/* - * Register bit definitions - */ - -/* Control register 1 */ - -#define SPI_CR1_BIDIMODE_BIT 15 -#define SPI_CR1_BIDIOE_BIT 14 -#define SPI_CR1_CRCEN_BIT 13 -#define SPI_CR1_CRCNEXT_BIT 12 -#define SPI_CR1_DFF_BIT 11 -#define SPI_CR1_RXONLY_BIT 10 -#define SPI_CR1_SSM_BIT 9 -#define SPI_CR1_SSI_BIT 8 -#define SPI_CR1_LSBFIRST_BIT 7 -#define SPI_CR1_SPE_BIT 6 -#define SPI_CR1_MSTR_BIT 2 -#define SPI_CR1_CPOL_BIT 1 -#define SPI_CR1_CPHA_BIT 0 - -#define SPI_CR1_BIDIMODE BIT(SPI_CR1_BIDIMODE_BIT) -#define SPI_CR1_BIDIMODE_2_LINE (0x0 << SPI_CR1_BIDIMODE_BIT) -#define SPI_CR1_BIDIMODE_1_LINE (0x1 << SPI_CR1_BIDIMODE_BIT) -#define SPI_CR1_BIDIOE BIT(SPI_CR1_BIDIOE_BIT) -#define SPI_CR1_CRCEN BIT(SPI_CR1_CRCEN_BIT) -#define SPI_CR1_CRCNEXT BIT(SPI_CR1_CRCNEXT_BIT) -#define SPI_CR1_DFF BIT(SPI_CR1_DFF_BIT) -#define SPI_CR1_DFF_8_BIT (0x0 << SPI_CR1_DFF_BIT) -#define SPI_CR1_DFF_16_BIT (0x1 << SPI_CR1_DFF_BIT) -#define SPI_CR1_RXONLY BIT(SPI_CR1_RXONLY_BIT) -#define SPI_CR1_SSM BIT(SPI_CR1_SSM_BIT) -#define SPI_CR1_SSI BIT(SPI_CR1_SSI_BIT) -#define SPI_CR1_LSBFIRST BIT(SPI_CR1_LSBFIRST_BIT) -#define SPI_CR1_SPE BIT(SPI_CR1_SPE_BIT) -#define SPI_CR1_BR (0x7 << 3) -#define SPI_CR1_BR_PCLK_DIV_2 (0x0 << 3) -#define SPI_CR1_BR_PCLK_DIV_4 (0x1 << 3) -#define SPI_CR1_BR_PCLK_DIV_8 (0x2 << 3) -#define SPI_CR1_BR_PCLK_DIV_16 (0x3 << 3) -#define SPI_CR1_BR_PCLK_DIV_32 (0x4 << 3) -#define SPI_CR1_BR_PCLK_DIV_64 (0x5 << 3) -#define SPI_CR1_BR_PCLK_DIV_128 (0x6 << 3) -#define SPI_CR1_BR_PCLK_DIV_256 (0x7 << 3) -#define SPI_CR1_MSTR BIT(SPI_CR1_MSTR_BIT) -#define SPI_CR1_CPOL BIT(SPI_CR1_CPOL_BIT) -#define SPI_CR1_CPOL_LOW (0x0 << SPI_CR1_CPOL_BIT) -#define SPI_CR1_CPOL_HIGH (0x1 << SPI_CR1_CPOL_BIT) -#define SPI_CR1_CPHA BIT(SPI_CR1_CPHA_BIT) - -/* Control register 2 */ - -/* RM0008-ism: SPI CR2 has "TXDMAEN" and "RXDMAEN" bits, while the - * USARTs have CR3 "DMAR" and "DMAT" bits. */ - -#define SPI_CR2_TXEIE_BIT 7 -#define SPI_CR2_RXNEIE_BIT 6 -#define SPI_CR2_ERRIE_BIT 5 -#define SPI_CR2_SSOE_BIT 2 -#define SPI_CR2_TXDMAEN_BIT 1 -#define SPI_CR2_RXDMAEN_BIT 0 - -#define SPI_CR2_TXEIE BIT(SPI_CR2_TXEIE_BIT) -#define SPI_CR2_RXNEIE BIT(SPI_CR2_RXNEIE_BIT) -#define SPI_CR2_ERRIE BIT(SPI_CR2_ERRIE_BIT) -#define SPI_CR2_SSOE BIT(SPI_CR2_SSOE_BIT) -#define SPI_CR2_TXDMAEN BIT(SPI_CR2_TXDMAEN_BIT) -#define SPI_CR2_RXDMAEN BIT(SPI_CR2_RXDMAEN_BIT) - -/* Status register */ - -#define SPI_SR_BSY_BIT 7 -#define SPI_SR_OVR_BIT 6 -#define SPI_SR_MODF_BIT 5 -#define SPI_SR_CRCERR_BIT 4 -#define SPI_SR_UDR_BIT 3 -#define SPI_SR_CHSIDE_BIT 2 -#define SPI_SR_TXE_BIT 1 -#define SPI_SR_RXNE_BIT 0 - -#define SPI_SR_BSY BIT(SPI_SR_BSY_BIT) -#define SPI_SR_OVR BIT(SPI_SR_OVR_BIT) -#define SPI_SR_MODF BIT(SPI_SR_MODF_BIT) -#define SPI_SR_CRCERR BIT(SPI_SR_CRCERR_BIT) -#define SPI_SR_UDR BIT(SPI_SR_UDR_BIT) -#define SPI_SR_CHSIDE BIT(SPI_SR_CHSIDE_BIT) -#define SPI_SR_CHSIDE_LEFT (0x0 << SPI_SR_CHSIDE_BIT) -#define SPI_SR_CHSIDE_RIGHT (0x1 << SPI_SR_CHSIDE_BIT) -#define SPI_SR_TXE BIT(SPI_SR_TXE_BIT) -#define SPI_SR_RXNE BIT(SPI_SR_RXNE_BIT) - -/* I2S configuration register */ - -/* RM0008-ism: CR1 has "CPOL", I2SCFGR has "CKPOL". */ - -#define SPI_I2SCFGR_I2SMOD_BIT 11 -#define SPI_I2SCFGR_I2SE_BIT 10 -#define SPI_I2SCFGR_PCMSYNC_BIT 7 -#define SPI_I2SCFGR_CKPOL_BIT 3 -#define SPI_I2SCFGR_CHLEN_BIT 0 - -#define SPI_I2SCFGR_I2SMOD BIT(SPI_I2SCFGR_I2SMOD_BIT) -#define SPI_I2SCFGR_I2SMOD_SPI (0x0 << SPI_I2SCFGR_I2SMOD_BIT) -#define SPI_I2SCFGR_I2SMOD_I2S (0x1 << SPI_I2SCFGR_I2SMOD_BIT) -#define SPI_I2SCFGR_I2SE BIT(SPI_I2SCFGR_I2SE_BIT) -#define SPI_I2SCFGR_I2SCFG (0x3 << 8) -#define SPI_I2SCFGR_I2SCFG_SLAVE_TX (0x0 << 8) -#define SPI_I2SCFGR_I2SCFG_SLAVE_RX (0x1 << 8) -#define SPI_I2SCFGR_I2SCFG_MASTER_TX (0x2 << 8) -#define SPI_I2SCFGR_I2SCFG_MASTER_RX (0x3 << 8) -#define SPI_I2SCFGR_PCMSYNC BIT(SPI_I2SCFGR_PCMSYNC_BIT) -#define SPI_I2SCFGR_PCMSYNC_SHORT (0x0 << SPI_I2SCFGR_PCMSYNC_BIT) -#define SPI_I2SCFGR_PCMSYNC_LONG (0x1 << SPI_I2SCFGR_PCMSYNC_BIT) -#define SPI_I2SCFGR_I2SSTD (0x3 << 4) -#define SPI_I2SCFGR_I2SSTD_PHILLIPS (0x0 << 4) -#define SPI_I2SCFGR_I2SSTD_MSB (0x1 << 4) -#define SPI_I2SCFGR_I2SSTD_LSB (0x2 << 4) -#define SPI_I2SCFGR_I2SSTD_PCM (0x3 << 4) -#define SPI_I2SCFGR_CKPOL BIT(SPI_I2SCFGR_CKPOL_BIT) -#define SPI_I2SCFGR_CKPOL_LOW (0x0 << SPI_I2SCFGR_CKPOL_BIT) -#define SPI_I2SCFGR_CKPOL_HIGH (0x1 << SPI_I2SCFGR_CKPOL_BIT) -#define SPI_I2SCFGR_DATLEN (0x3 << 1) -#define SPI_I2SCFGR_DATLEN_16_BIT (0x0 << 1) -#define SPI_I2SCFGR_DATLEN_24_BIT (0x1 << 1) -#define SPI_I2SCFGR_DATLEN_32_BIT (0x2 << 1) -#define SPI_I2SCFGR_CHLEN BIT(SPI_I2SCFGR_CHLEN_BIT) -#define SPI_I2SCFGR_CHLEN_16_BIT (0x0 << SPI_I2SCFGR_CHLEN_BIT) -#define SPI_I2SCFGR_CHLEN_32_BIT (0x1 << SPI_I2SCFGR_CHLEN_BIT) - -/* - * Devices - */ - -/** SPI device type */ -typedef struct spi_dev { - spi_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ - nvic_irq_num irq_num; /**< NVIC interrupt number */ -} spi_dev; - -extern spi_dev *SPI1; -extern spi_dev *SPI2; -#ifdef STM32_HIGH_DENSITY -extern spi_dev *SPI3; -#endif -#ifdef STM32F2 -extern spi_dev *SPI4; -#endif - -/* - * SPI Convenience functions - */ - -void spi_init(spi_dev *dev); - -void spi_gpio_cfg(uint8 as_master, - gpio_dev *nss_dev, - uint8 nss_bit, - gpio_dev *comm_dev, - uint8 sck_bit, - uint8 miso_bit, - uint8 mosi_bit); - -/** - * @brief SPI mode configuration. - * - * Determines a combination of clock polarity (CPOL), which determines - * idle state of the clock line, and clock phase (CPHA), which - * determines which clock edge triggers data capture. - */ -typedef enum spi_mode { - SPI_MODE_0, /**< Clock line idles low (0), data capture on first - clock transition. */ - SPI_MODE_1, /**< Clock line idles low (0), data capture on second - clock transition */ - SPI_MODE_2, /**< Clock line idles high (1), data capture on first - clock transition. */ - SPI_MODE_3 /**< Clock line idles high (1), data capture on - second clock transition. */ -} spi_mode; - -/** - * @brief SPI baud rate configuration, as a divisor of f_PCLK, the - * PCLK clock frequency. - */ -typedef enum spi_baud_rate { - SPI_BAUD_PCLK_DIV_2 = SPI_CR1_BR_PCLK_DIV_2, /**< f_PCLK/2 */ - SPI_BAUD_PCLK_DIV_4 = SPI_CR1_BR_PCLK_DIV_4, /**< f_PCLK/4 */ - SPI_BAUD_PCLK_DIV_8 = SPI_CR1_BR_PCLK_DIV_8, /**< f_PCLK/8 */ - SPI_BAUD_PCLK_DIV_16 = SPI_CR1_BR_PCLK_DIV_16, /**< f_PCLK/16 */ - SPI_BAUD_PCLK_DIV_32 = SPI_CR1_BR_PCLK_DIV_32, /**< f_PCLK/32 */ - SPI_BAUD_PCLK_DIV_64 = SPI_CR1_BR_PCLK_DIV_64, /**< f_PCLK/64 */ - SPI_BAUD_PCLK_DIV_128 = SPI_CR1_BR_PCLK_DIV_128, /**< f_PCLK/128 */ - SPI_BAUD_PCLK_DIV_256 = SPI_CR1_BR_PCLK_DIV_256, /**< f_PCLK/256 */ -} spi_baud_rate; - -/** - * @brief SPI initialization flags. - * @see spi_master_enable() - * @see spi_slave_enable() - */ -typedef enum spi_cfg_flag { - SPI_BIDIMODE = SPI_CR1_BIDIMODE, /**< Bidirectional mode enable */ - SPI_BIDIOE = SPI_CR1_BIDIOE, /**< Output enable in bidirectional - mode */ - SPI_CRCEN = SPI_CR1_CRCEN, /**< Cyclic redundancy check (CRC) - enable */ - SPI_DFF_8_BIT = SPI_CR1_DFF_8_BIT, /**< 8-bit data frame format (this is - the default) */ - SPI_DFF_16_BIT = SPI_CR1_DFF_16_BIT, /**< 16-bit data frame format */ - SPI_RX_ONLY = SPI_CR1_RXONLY, /**< Receive only */ - SPI_SW_SLAVE = SPI_CR1_SSM, /**< Software slave management */ - SPI_SOFT_SS = SPI_CR1_SSI, /**< Software (internal) slave - select. This flag only has an - effect when used in combination - with SPI_SW_SLAVE. */ - SPI_FRAME_LSB = SPI_CR1_LSBFIRST, /**< LSB-first (little-endian) frame - format */ - SPI_FRAME_MSB = 0, /**< MSB-first (big-endian) frame - format (this is the default) */ -} spi_cfg_flag; - -void spi_master_enable(spi_dev *dev, - spi_baud_rate baud, - spi_mode mode, - uint32 flags); - -void spi_slave_enable(spi_dev *dev, - spi_mode mode, - uint32 flags); - -uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len); - -void spi_foreach(void (*fn)(spi_dev (*dev))); - -void spi_peripheral_enable(spi_dev *dev); -void spi_peripheral_disable(spi_dev *dev); - -void spi_tx_dma_enable(spi_dev *dev); -void spi_tx_dma_disable(spi_dev *dev); - -void spi_rx_dma_enable(spi_dev *dev); -void spi_rx_dma_disable(spi_dev *dev); - -/** - * @brief Determine if a SPI peripheral is enabled. - * @param dev SPI device - * @return True, if and only if dev's peripheral is enabled. - */ -static inline uint8 spi_is_enabled(spi_dev *dev) { - return dev->regs->CR1 & SPI_CR1_SPE_BIT; -} - -/** - * @brief Disable all SPI peripherals - */ -static inline void spi_peripheral_disable_all(void) { - spi_foreach(spi_peripheral_disable); -} - -/** Available SPI interrupts */ -typedef enum spi_interrupt { - SPI_TXE_INTERRUPT = SPI_CR2_TXEIE, /**< TX buffer empty interrupt */ - SPI_RXNE_INTERRUPT = SPI_CR2_RXNEIE, /**< RX buffer not empty interrupt */ - SPI_ERR_INTERRUPT = SPI_CR2_ERRIE /**< - * Error interrupt (CRC, overrun, - * and mode fault errors for SPI; - * underrun, overrun errors for I2S) - */ -} spi_interrupt; - -/** - * @brief Mask for all spi_interrupt values - * @see spi_interrupt - */ -#define SPI_INTERRUPTS_ALL (SPI_TXE_INTERRUPT | \ - SPI_RXNE_INTERRUPT | \ - SPI_ERR_INTERRUPT) - -/** - * @brief Enable SPI interrupt requests - * @param dev SPI device - * @param interrupt_flags Bitwise OR of spi_interrupt values to enable - * @see spi_interrupt - */ -static inline void spi_irq_enable(spi_dev *dev, uint32 interrupt_flags) { - dev->regs->CR2 |= interrupt_flags; - nvic_irq_enable(dev->irq_num); -} - -/** - * @brief Disable SPI interrupt requests - * @param dev SPI device - * @param interrupt_flags Bitwise OR of spi_interrupt values to disable - * @see spi_interrupt - */ -static inline void spi_irq_disable(spi_dev *dev, uint32 interrupt_flags) { - dev->regs->CR2 &= ~interrupt_flags; -} - -/** - * @brief Get the data frame format flags with which a SPI port is - * configured. - * @param dev SPI device whose data frame format to get. - * @return SPI_DFF_8_BIT, if dev has an 8-bit data frame format. - * Otherwise, SPI_DFF_16_BIT. - */ -static inline spi_cfg_flag spi_dff(spi_dev *dev) { - return ((dev->regs->CR1 & SPI_CR1_DFF) == SPI_CR1_DFF_8_BIT ? - SPI_DFF_8_BIT : - SPI_DFF_16_BIT); -} - -/** - * @brief Determine whether the device's peripheral receive (RX) - * register is empty. - * @param dev SPI device - * @return true, iff dev's RX register is empty. - */ -static inline uint8 spi_is_rx_nonempty(spi_dev *dev) { - return dev->regs->SR & SPI_SR_RXNE; -} - -/** - * @brief Retrieve the contents of the device's peripheral receive - * (RX) register. - * - * You may only call this function when the RX register is nonempty. - * Calling this function clears the contents of the RX register. - * - * @param dev SPI device - * @return Contents of dev's peripheral RX register - * @see spi_is_rx_reg_nonempty() - */ -static inline uint16 spi_rx_reg(spi_dev *dev) { - return (uint16)dev->regs->DR; -} - -/** - * @brief Determine whether the device's peripheral transmit (TX) - * register is empty. - * @param dev SPI device - * @return true, iff dev's TX register is empty. - */ -static inline uint8 spi_is_tx_empty(spi_dev *dev) { - return dev->regs->SR & SPI_SR_TXE; -} - -/** - * @brief Load a value into the device's peripheral transmit (TX) register. - * - * You may only call this function when the TX register is empty. - * Calling this function loads val into the peripheral's TX register. - * If the device is properly configured, this will initiate a - * transmission, the completion of which will cause the TX register to - * be empty again. - * - * @param dev SPI device - * @param val Value to load into the TX register. If the SPI data - * frame format is 8 bit, the value must be right-aligned. - * @see spi_is_tx_reg_empty() - * @see spi_init() - * @see spi_master_enable() - * @see spi_slave_enable() - */ -static inline void spi_tx_reg(spi_dev *dev, uint16 val) { - dev->regs->DR = val; -} - -/** - * @brief Determine whether the device's peripheral busy (SPI_SR_BSY) - * flag is set. - * @param dev SPI device - * @return true, iff dev's BSY flag is set. - */ -static inline uint8 spi_is_busy(spi_dev *dev) { - return dev->regs->SR & SPI_SR_BSY; -} - -/* - * I2S convenience functions (TODO) - */ - -#ifdef __cplusplus -} -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file spi.h + * @author Marti Bolivar + * @brief Serial Peripheral Interface (SPI) and Integrated + * Interchip Sound (I2S) peripheral support. + * + * I2S support is currently limited to register maps and bit definitions. + */ + +#ifndef _SPI_H_ +#define _SPI_H_ + +#include "libmaple_types.h" +#include "rcc.h" +#include "nvic.h" +#include "gpio.h" +#include "util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Register maps + */ + +/** SPI register map type. */ +typedef struct spi_reg_map { + __io uint32 CR1; /**< Control register 1 */ + __io uint32 CR2; /**< Control register 2 */ + __io uint32 SR; /**< Status register */ + __io uint32 DR; /**< Data register */ + __io uint32 CRCPR; /**< CRC polynomial register */ + __io uint32 RXCRCR; /**< RX CRC register */ + __io uint32 TXCRCR; /**< TX CRC register */ + __io uint32 I2SCFGR; /**< I2S configuration register */ + __io uint32 I2SPR; /**< I2S prescaler register */ +} spi_reg_map; + +/** SPI1 register map base pointer */ +#define SPI1_BASE ((struct spi_reg_map*)0x40013000) +/** SPI2 register map base pointer */ +#define SPI2_BASE ((struct spi_reg_map*)0x40003800) +/** SPI3 register map base pointer */ +#define SPI3_BASE ((struct spi_reg_map*)0x40003C00) + +/* + * Register bit definitions + */ + +/* Control register 1 */ + +#define SPI_CR1_BIDIMODE_BIT 15 +#define SPI_CR1_BIDIOE_BIT 14 +#define SPI_CR1_CRCEN_BIT 13 +#define SPI_CR1_CRCNEXT_BIT 12 +#define SPI_CR1_DFF_BIT 11 +#define SPI_CR1_RXONLY_BIT 10 +#define SPI_CR1_SSM_BIT 9 +#define SPI_CR1_SSI_BIT 8 +#define SPI_CR1_LSBFIRST_BIT 7 +#define SPI_CR1_SPE_BIT 6 +#define SPI_CR1_MSTR_BIT 2 +#define SPI_CR1_CPOL_BIT 1 +#define SPI_CR1_CPHA_BIT 0 + +#define SPI_CR1_BIDIMODE BIT(SPI_CR1_BIDIMODE_BIT) +#define SPI_CR1_BIDIMODE_2_LINE (0x0 << SPI_CR1_BIDIMODE_BIT) +#define SPI_CR1_BIDIMODE_1_LINE (0x1 << SPI_CR1_BIDIMODE_BIT) +#define SPI_CR1_BIDIOE BIT(SPI_CR1_BIDIOE_BIT) +#define SPI_CR1_CRCEN BIT(SPI_CR1_CRCEN_BIT) +#define SPI_CR1_CRCNEXT BIT(SPI_CR1_CRCNEXT_BIT) +#define SPI_CR1_DFF BIT(SPI_CR1_DFF_BIT) +#define SPI_CR1_DFF_8_BIT (0x0 << SPI_CR1_DFF_BIT) +#define SPI_CR1_DFF_16_BIT (0x1 << SPI_CR1_DFF_BIT) +#define SPI_CR1_RXONLY BIT(SPI_CR1_RXONLY_BIT) +#define SPI_CR1_SSM BIT(SPI_CR1_SSM_BIT) +#define SPI_CR1_SSI BIT(SPI_CR1_SSI_BIT) +#define SPI_CR1_LSBFIRST BIT(SPI_CR1_LSBFIRST_BIT) +#define SPI_CR1_SPE BIT(SPI_CR1_SPE_BIT) +#define SPI_CR1_BR (0x7 << 3) +#define SPI_CR1_BR_PCLK_DIV_2 (0x0 << 3) +#define SPI_CR1_BR_PCLK_DIV_4 (0x1 << 3) +#define SPI_CR1_BR_PCLK_DIV_8 (0x2 << 3) +#define SPI_CR1_BR_PCLK_DIV_16 (0x3 << 3) +#define SPI_CR1_BR_PCLK_DIV_32 (0x4 << 3) +#define SPI_CR1_BR_PCLK_DIV_64 (0x5 << 3) +#define SPI_CR1_BR_PCLK_DIV_128 (0x6 << 3) +#define SPI_CR1_BR_PCLK_DIV_256 (0x7 << 3) +#define SPI_CR1_MSTR BIT(SPI_CR1_MSTR_BIT) +#define SPI_CR1_CPOL BIT(SPI_CR1_CPOL_BIT) +#define SPI_CR1_CPOL_LOW (0x0 << SPI_CR1_CPOL_BIT) +#define SPI_CR1_CPOL_HIGH (0x1 << SPI_CR1_CPOL_BIT) +#define SPI_CR1_CPHA BIT(SPI_CR1_CPHA_BIT) + +/* Control register 2 */ + +/* RM0008-ism: SPI CR2 has "TXDMAEN" and "RXDMAEN" bits, while the + * USARTs have CR3 "DMAR" and "DMAT" bits. */ + +#define SPI_CR2_TXEIE_BIT 7 +#define SPI_CR2_RXNEIE_BIT 6 +#define SPI_CR2_ERRIE_BIT 5 +#define SPI_CR2_SSOE_BIT 2 +#define SPI_CR2_TXDMAEN_BIT 1 +#define SPI_CR2_RXDMAEN_BIT 0 + +#define SPI_CR2_TXEIE BIT(SPI_CR2_TXEIE_BIT) +#define SPI_CR2_RXNEIE BIT(SPI_CR2_RXNEIE_BIT) +#define SPI_CR2_ERRIE BIT(SPI_CR2_ERRIE_BIT) +#define SPI_CR2_SSOE BIT(SPI_CR2_SSOE_BIT) +#define SPI_CR2_TXDMAEN BIT(SPI_CR2_TXDMAEN_BIT) +#define SPI_CR2_RXDMAEN BIT(SPI_CR2_RXDMAEN_BIT) + +/* Status register */ + +#define SPI_SR_BSY_BIT 7 +#define SPI_SR_OVR_BIT 6 +#define SPI_SR_MODF_BIT 5 +#define SPI_SR_CRCERR_BIT 4 +#define SPI_SR_UDR_BIT 3 +#define SPI_SR_CHSIDE_BIT 2 +#define SPI_SR_TXE_BIT 1 +#define SPI_SR_RXNE_BIT 0 + +#define SPI_SR_BSY BIT(SPI_SR_BSY_BIT) +#define SPI_SR_OVR BIT(SPI_SR_OVR_BIT) +#define SPI_SR_MODF BIT(SPI_SR_MODF_BIT) +#define SPI_SR_CRCERR BIT(SPI_SR_CRCERR_BIT) +#define SPI_SR_UDR BIT(SPI_SR_UDR_BIT) +#define SPI_SR_CHSIDE BIT(SPI_SR_CHSIDE_BIT) +#define SPI_SR_CHSIDE_LEFT (0x0 << SPI_SR_CHSIDE_BIT) +#define SPI_SR_CHSIDE_RIGHT (0x1 << SPI_SR_CHSIDE_BIT) +#define SPI_SR_TXE BIT(SPI_SR_TXE_BIT) +#define SPI_SR_RXNE BIT(SPI_SR_RXNE_BIT) + +/* I2S configuration register */ + +/* RM0008-ism: CR1 has "CPOL", I2SCFGR has "CKPOL". */ + +#define SPI_I2SCFGR_I2SMOD_BIT 11 +#define SPI_I2SCFGR_I2SE_BIT 10 +#define SPI_I2SCFGR_PCMSYNC_BIT 7 +#define SPI_I2SCFGR_CKPOL_BIT 3 +#define SPI_I2SCFGR_CHLEN_BIT 0 + +#define SPI_I2SCFGR_I2SMOD BIT(SPI_I2SCFGR_I2SMOD_BIT) +#define SPI_I2SCFGR_I2SMOD_SPI (0x0 << SPI_I2SCFGR_I2SMOD_BIT) +#define SPI_I2SCFGR_I2SMOD_I2S (0x1 << SPI_I2SCFGR_I2SMOD_BIT) +#define SPI_I2SCFGR_I2SE BIT(SPI_I2SCFGR_I2SE_BIT) +#define SPI_I2SCFGR_I2SCFG (0x3 << 8) +#define SPI_I2SCFGR_I2SCFG_SLAVE_TX (0x0 << 8) +#define SPI_I2SCFGR_I2SCFG_SLAVE_RX (0x1 << 8) +#define SPI_I2SCFGR_I2SCFG_MASTER_TX (0x2 << 8) +#define SPI_I2SCFGR_I2SCFG_MASTER_RX (0x3 << 8) +#define SPI_I2SCFGR_PCMSYNC BIT(SPI_I2SCFGR_PCMSYNC_BIT) +#define SPI_I2SCFGR_PCMSYNC_SHORT (0x0 << SPI_I2SCFGR_PCMSYNC_BIT) +#define SPI_I2SCFGR_PCMSYNC_LONG (0x1 << SPI_I2SCFGR_PCMSYNC_BIT) +#define SPI_I2SCFGR_I2SSTD (0x3 << 4) +#define SPI_I2SCFGR_I2SSTD_PHILLIPS (0x0 << 4) +#define SPI_I2SCFGR_I2SSTD_MSB (0x1 << 4) +#define SPI_I2SCFGR_I2SSTD_LSB (0x2 << 4) +#define SPI_I2SCFGR_I2SSTD_PCM (0x3 << 4) +#define SPI_I2SCFGR_CKPOL BIT(SPI_I2SCFGR_CKPOL_BIT) +#define SPI_I2SCFGR_CKPOL_LOW (0x0 << SPI_I2SCFGR_CKPOL_BIT) +#define SPI_I2SCFGR_CKPOL_HIGH (0x1 << SPI_I2SCFGR_CKPOL_BIT) +#define SPI_I2SCFGR_DATLEN (0x3 << 1) +#define SPI_I2SCFGR_DATLEN_16_BIT (0x0 << 1) +#define SPI_I2SCFGR_DATLEN_24_BIT (0x1 << 1) +#define SPI_I2SCFGR_DATLEN_32_BIT (0x2 << 1) +#define SPI_I2SCFGR_CHLEN BIT(SPI_I2SCFGR_CHLEN_BIT) +#define SPI_I2SCFGR_CHLEN_16_BIT (0x0 << SPI_I2SCFGR_CHLEN_BIT) +#define SPI_I2SCFGR_CHLEN_32_BIT (0x1 << SPI_I2SCFGR_CHLEN_BIT) + +/* + * Devices + */ + +/** SPI device type */ +typedef struct spi_dev { + spi_reg_map *regs; /**< Register map */ + rcc_clk_id clk_id; /**< RCC clock information */ + nvic_irq_num irq_num; /**< NVIC interrupt number */ +} spi_dev; + +extern spi_dev *SPI1; +extern spi_dev *SPI2; +#ifdef STM32_HIGH_DENSITY +extern spi_dev *SPI3; +#endif +#ifdef STM32F2 +extern spi_dev *SPI4; +#endif + +/* + * SPI Convenience functions + */ + +void spi_init(spi_dev *dev); + +void spi_gpio_cfg(uint8 as_master, + gpio_dev *nss_dev, + uint8 nss_bit, + gpio_dev *comm_dev, + uint8 sck_bit, + uint8 miso_bit, + uint8 mosi_bit); + +/** + * @brief SPI mode configuration. + * + * Determines a combination of clock polarity (CPOL), which determines + * idle state of the clock line, and clock phase (CPHA), which + * determines which clock edge triggers data capture. + */ +typedef enum spi_mode { + SPI_MODE_0, /**< Clock line idles low (0), data capture on first + clock transition. */ + SPI_MODE_1, /**< Clock line idles low (0), data capture on second + clock transition */ + SPI_MODE_2, /**< Clock line idles high (1), data capture on first + clock transition. */ + SPI_MODE_3 /**< Clock line idles high (1), data capture on + second clock transition. */ +} spi_mode; + +/** + * @brief SPI baud rate configuration, as a divisor of f_PCLK, the + * PCLK clock frequency. + */ +typedef enum spi_baud_rate { + SPI_BAUD_PCLK_DIV_2 = SPI_CR1_BR_PCLK_DIV_2, /**< f_PCLK/2 */ + SPI_BAUD_PCLK_DIV_4 = SPI_CR1_BR_PCLK_DIV_4, /**< f_PCLK/4 */ + SPI_BAUD_PCLK_DIV_8 = SPI_CR1_BR_PCLK_DIV_8, /**< f_PCLK/8 */ + SPI_BAUD_PCLK_DIV_16 = SPI_CR1_BR_PCLK_DIV_16, /**< f_PCLK/16 */ + SPI_BAUD_PCLK_DIV_32 = SPI_CR1_BR_PCLK_DIV_32, /**< f_PCLK/32 */ + SPI_BAUD_PCLK_DIV_64 = SPI_CR1_BR_PCLK_DIV_64, /**< f_PCLK/64 */ + SPI_BAUD_PCLK_DIV_128 = SPI_CR1_BR_PCLK_DIV_128, /**< f_PCLK/128 */ + SPI_BAUD_PCLK_DIV_256 = SPI_CR1_BR_PCLK_DIV_256, /**< f_PCLK/256 */ +} spi_baud_rate; + +/** + * @brief SPI initialization flags. + * @see spi_master_enable() + * @see spi_slave_enable() + */ +typedef enum spi_cfg_flag { + SPI_BIDIMODE = SPI_CR1_BIDIMODE, /**< Bidirectional mode enable */ + SPI_BIDIOE = SPI_CR1_BIDIOE, /**< Output enable in bidirectional + mode */ + SPI_CRCEN = SPI_CR1_CRCEN, /**< Cyclic redundancy check (CRC) + enable */ + SPI_DFF_8_BIT = SPI_CR1_DFF_8_BIT, /**< 8-bit data frame format (this is + the default) */ + SPI_DFF_16_BIT = SPI_CR1_DFF_16_BIT, /**< 16-bit data frame format */ + SPI_RX_ONLY = SPI_CR1_RXONLY, /**< Receive only */ + SPI_SW_SLAVE = SPI_CR1_SSM, /**< Software slave management */ + SPI_SOFT_SS = SPI_CR1_SSI, /**< Software (internal) slave + select. This flag only has an + effect when used in combination + with SPI_SW_SLAVE. */ + SPI_FRAME_LSB = SPI_CR1_LSBFIRST, /**< LSB-first (little-endian) frame + format */ + SPI_FRAME_MSB = 0, /**< MSB-first (big-endian) frame + format (this is the default) */ +} spi_cfg_flag; + +void spi_master_enable(spi_dev *dev, + spi_baud_rate baud, + spi_mode mode, + uint32 flags); + +void spi_slave_enable(spi_dev *dev, + spi_mode mode, + uint32 flags); + +uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len); + +void spi_foreach(void (*fn)(spi_dev (*dev))); + +void spi_peripheral_enable(spi_dev *dev); +void spi_peripheral_disable(spi_dev *dev); + +void spi_tx_dma_enable(spi_dev *dev); +void spi_tx_dma_disable(spi_dev *dev); + +void spi_rx_dma_enable(spi_dev *dev); +void spi_rx_dma_disable(spi_dev *dev); + +/** + * @brief Determine if a SPI peripheral is enabled. + * @param dev SPI device + * @return True, if and only if dev's peripheral is enabled. + */ +static inline uint8 spi_is_enabled(spi_dev *dev) { + return dev->regs->CR1 & SPI_CR1_SPE_BIT; +} + +/** + * @brief Disable all SPI peripherals + */ +static inline void spi_peripheral_disable_all(void) { + spi_foreach(spi_peripheral_disable); +} + +/** Available SPI interrupts */ +typedef enum spi_interrupt { + SPI_TXE_INTERRUPT = SPI_CR2_TXEIE, /**< TX buffer empty interrupt */ + SPI_RXNE_INTERRUPT = SPI_CR2_RXNEIE, /**< RX buffer not empty interrupt */ + SPI_ERR_INTERRUPT = SPI_CR2_ERRIE /**< + * Error interrupt (CRC, overrun, + * and mode fault errors for SPI; + * underrun, overrun errors for I2S) + */ +} spi_interrupt; + +/** + * @brief Mask for all spi_interrupt values + * @see spi_interrupt + */ +#define SPI_INTERRUPTS_ALL (SPI_TXE_INTERRUPT | \ + SPI_RXNE_INTERRUPT | \ + SPI_ERR_INTERRUPT) + +/** + * @brief Enable SPI interrupt requests + * @param dev SPI device + * @param interrupt_flags Bitwise OR of spi_interrupt values to enable + * @see spi_interrupt + */ +static inline void spi_irq_enable(spi_dev *dev, uint32 interrupt_flags) { + dev->regs->CR2 |= interrupt_flags; + nvic_irq_enable(dev->irq_num); +} + +/** + * @brief Disable SPI interrupt requests + * @param dev SPI device + * @param interrupt_flags Bitwise OR of spi_interrupt values to disable + * @see spi_interrupt + */ +static inline void spi_irq_disable(spi_dev *dev, uint32 interrupt_flags) { + dev->regs->CR2 &= ~interrupt_flags; +} + +/** + * @brief Get the data frame format flags with which a SPI port is + * configured. + * @param dev SPI device whose data frame format to get. + * @return SPI_DFF_8_BIT, if dev has an 8-bit data frame format. + * Otherwise, SPI_DFF_16_BIT. + */ +static inline spi_cfg_flag spi_dff(spi_dev *dev) { + return ((dev->regs->CR1 & SPI_CR1_DFF) == SPI_CR1_DFF_8_BIT ? + SPI_DFF_8_BIT : + SPI_DFF_16_BIT); +} + +/** + * @brief Determine whether the device's peripheral receive (RX) + * register is empty. + * @param dev SPI device + * @return true, iff dev's RX register is empty. + */ +static inline uint8 spi_is_rx_nonempty(spi_dev *dev) { + return dev->regs->SR & SPI_SR_RXNE; +} + +/** + * @brief Retrieve the contents of the device's peripheral receive + * (RX) register. + * + * You may only call this function when the RX register is nonempty. + * Calling this function clears the contents of the RX register. + * + * @param dev SPI device + * @return Contents of dev's peripheral RX register + * @see spi_is_rx_reg_nonempty() + */ +static inline uint16 spi_rx_reg(spi_dev *dev) { + return (uint16)dev->regs->DR; +} + +/** + * @brief Determine whether the device's peripheral transmit (TX) + * register is empty. + * @param dev SPI device + * @return true, iff dev's TX register is empty. + */ +static inline uint8 spi_is_tx_empty(spi_dev *dev) { + return dev->regs->SR & SPI_SR_TXE; +} + +/** + * @brief Load a value into the device's peripheral transmit (TX) register. + * + * You may only call this function when the TX register is empty. + * Calling this function loads val into the peripheral's TX register. + * If the device is properly configured, this will initiate a + * transmission, the completion of which will cause the TX register to + * be empty again. + * + * @param dev SPI device + * @param val Value to load into the TX register. If the SPI data + * frame format is 8 bit, the value must be right-aligned. + * @see spi_is_tx_reg_empty() + * @see spi_init() + * @see spi_master_enable() + * @see spi_slave_enable() + */ +static inline void spi_tx_reg(spi_dev *dev, uint16 val) { + dev->regs->DR = val; +} + +/** + * @brief Determine whether the device's peripheral busy (SPI_SR_BSY) + * flag is set. + * @param dev SPI device + * @return true, iff dev's BSY flag is set. + */ +static inline uint8 spi_is_busy(spi_dev *dev) { + return dev->regs->SR & SPI_SR_BSY; +} + +/* + * I2S convenience functions (TODO) + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/stm32.h b/Libmaple/libmaple/libmaple/stm32.h index de7f7251..0d4deaa4 100644 --- a/Libmaple/libmaple/libmaple/stm32.h +++ b/Libmaple/libmaple/libmaple/stm32.h @@ -1,220 +1,220 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file stm32.h - * @brief STM32 chip-specific definitions - */ - -#ifndef _STM32_H_ -#define _STM32_H_ - -/* - * User-specific configuration. - * - * The #defines here depend upon how libmaple is used. Because of the - * potential for a mismatch between them and the actual libmaple - * usage, you should try to keep their number to an absolute minimum. - */ - -#ifdef __DOXYGEN_PREDEFINED_HACK - - /** @brief APB1 clock speed, in Hz. */ - #define STM32_PCLK1 - /** @brief APB2 clock speed, in Hz. */ - #define STM32_PCLK2 - - /** Deprecated. Use STM32_PCLK1 instead. */ - #define PCLK1 - /** Deprecated. Use STM32_PCLK2 instead. */ - #define PCLK2 - -#endif - -#ifndef STM32_PCLK1 -#define STM32_PCLK1 36000000U -#endif -#ifndef PCLK1 -#define PCLK1 STM32_PCLK1 -#endif -#if PCLK1 != STM32_PCLK1 -#error "(Deprecated) PCLK1 differs from STM32_PCLK1" -#endif - -#ifndef STM32_PCLK2 -#define STM32_PCLK2 72000000U -#endif -#ifndef PCLK2 -#define PCLK2 STM32_PCLK2 -#endif -#if PCLK2 != STM32_PCLK2 -#error "(Deprecated) PCLK2 differs from STM32_PCLK2" -#endif - -/* - * Density-specific configuration. - */ - -#ifdef __DOXYGEN_PREDEFINED_HACK - - /** - * @brief Number of interrupts in the NVIC. - * - * This define is automatically generated whenever the proper - * density is defined (currently, this is restricted to defining - * one of STM32_MEDIUM_DENSITY and STM32_HIGH_DENSITY). - */ - #define STM32_NR_INTERRUPTS - - /** Deprecated. Use STM32_NR_INTERRUPTS instead. */ - #define NR_INTERRUPTS - -#endif - -#ifdef STM32_MEDIUM_DENSITY - #define STM32_NR_INTERRUPTS 43 -#elif defined(STM32_HIGH_DENSITY) - #define STM32_NR_INTERRUPTS 60 -#else -#error "No STM32 board type defined!" -#endif - -#define NR_INTERRUPTS STM32_NR_INTERRUPTS - -/* - * MCU-specific configuration. - */ - -#ifdef __DOXYGEN_PREDEFINED_HACK - - /** - * Number of GPIO ports. - */ - #define STM32_NR_GPIO_PORTS - - /** - * @brief Multiplier to convert microseconds into loop iterations - * in delay_us(). - * - * @see delay_us() - */ - #define STM32_DELAY_US_MULT - - /** - * @brief Pointer to end of built-in SRAM. - * - * Points to the address which is 1 byte past the last valid - * SRAM address. - */ - #define STM32_SRAM_END - - /** Deprecated. Use STM32_NR_GPIO_PORTS instead. */ - #define NR_GPIO_PORTS - /** Deprecated. Use STM32_DELAY_US_MULT instead. */ - #define DELAY_US_MULT - -#endif - -#if defined(MCU_STM32F103RB) - /* e.g., LeafLabs Maple */ - - #define STM32_NR_GPIO_PORTS 4 - #define STM32_DELAY_US_MULT 12 - #define STM32_SRAM_END ((void*)0x20005000) - - #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS - #define DELAY_US_MULT STM32_DELAY_US_MULT - -#elif defined(MCU_STM32F103ZE) - /* e.g., LeafLabs Maple Native */ - - #define STM32_NR_GPIO_PORTS 7 - #define STM32_DELAY_US_MULT 12 - #define STM32_SRAM_END ((void*)0x20010000) - - #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS - #define DELAY_US_MULT STM32_DELAY_US_MULT - -#elif defined(MCU_STM32F103CB) - /* e.g., LeafLabs Maple Mini */ - - /* This STM32_NR_GPIO_PORTS value is not, strictly speaking, true. - * But only pins 0 and 1 exist, and they're used for OSC on the - * Mini, so we'll live with this for now. */ - #define STM32_NR_GPIO_PORTS 3 - #define STM32_DELAY_US_MULT 12 - #define STM32_SRAM_END ((void*)0x20005000) - - #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS - #define DELAY_US_MULT STM32_DELAY_US_MULT - -#elif defined(MCU_STM32F103RE) - /* e.g., LeafLabs Maple RET6 edition */ - - #define STM32_NR_GPIO_PORTS 4 - #define STM32_DELAY_US_MULT 12 - #define STM32_SRAM_END ((void*)0x20010000) - - #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS - #define DELAY_US_MULT STM32_DELAY_US_MULT - -#elif defined(MCU_STM32F103VE) - /* e.g., LeafLabs Maple Native */ - - #define STM32_NR_GPIO_PORTS 5 - #define STM32_DELAY_US_MULT 12 - #define STM32_SRAM_END ((void*)0x20010000) - - #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS - #define DELAY_US_MULT STM32_DELAY_US_MULT - -#elif defined(MCU_STM32F205VE) - #define STM32_TICKS_PER_US 120 - #define STM32_NR_GPIO_PORTS 5 - #define STM32_DELAY_US_MULT (STM32_TICKS_PER_US/3) - #define STM32_SRAM_END ((void*)0x20010000) - - #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS - #define DELAY_US_MULT STM32_DELAY_US_MULT - -#elif defined(MCU_STM32F406VG) - #define STM32_TICKS_PER_US 168 - #define STM32_NR_GPIO_PORTS 5 - #define STM32_DELAY_US_MULT (STM32_TICKS_PER_US/3) - #define STM32_SRAM_END ((void*)0x20010000) - //#define STM32_SRAM_END ((void*)0x20030000) - - #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS - #define DELAY_US_MULT STM32_DELAY_US_MULT - -#else - -#error "No MCU type specified. Add something like -DMCU_STM32F103RB " \ - "to your compiler arguments (probably in a Makefile)." - -#endif - -#endif /* _STM32_H_ */ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file stm32.h + * @brief STM32 chip-specific definitions + */ + +#ifndef _STM32_H_ +#define _STM32_H_ + +/* + * User-specific configuration. + * + * The #defines here depend upon how libmaple is used. Because of the + * potential for a mismatch between them and the actual libmaple + * usage, you should try to keep their number to an absolute minimum. + */ + +#ifdef __DOXYGEN_PREDEFINED_HACK + + /** @brief APB1 clock speed, in Hz. */ + #define STM32_PCLK1 + /** @brief APB2 clock speed, in Hz. */ + #define STM32_PCLK2 + + /** Deprecated. Use STM32_PCLK1 instead. */ + #define PCLK1 + /** Deprecated. Use STM32_PCLK2 instead. */ + #define PCLK2 + +#endif + +#ifndef STM32_PCLK1 +#define STM32_PCLK1 36000000U +#endif +#ifndef PCLK1 +#define PCLK1 STM32_PCLK1 +#endif +#if PCLK1 != STM32_PCLK1 +#error "(Deprecated) PCLK1 differs from STM32_PCLK1" +#endif + +#ifndef STM32_PCLK2 +#define STM32_PCLK2 72000000U +#endif +#ifndef PCLK2 +#define PCLK2 STM32_PCLK2 +#endif +#if PCLK2 != STM32_PCLK2 +#error "(Deprecated) PCLK2 differs from STM32_PCLK2" +#endif + +/* + * Density-specific configuration. + */ + +#ifdef __DOXYGEN_PREDEFINED_HACK + + /** + * @brief Number of interrupts in the NVIC. + * + * This define is automatically generated whenever the proper + * density is defined (currently, this is restricted to defining + * one of STM32_MEDIUM_DENSITY and STM32_HIGH_DENSITY). + */ + #define STM32_NR_INTERRUPTS + + /** Deprecated. Use STM32_NR_INTERRUPTS instead. */ + #define NR_INTERRUPTS + +#endif + +#ifdef STM32_MEDIUM_DENSITY + #define STM32_NR_INTERRUPTS 43 +#elif defined(STM32_HIGH_DENSITY) + #define STM32_NR_INTERRUPTS 60 +#else +#error "No STM32 board type defined!" +#endif + +#define NR_INTERRUPTS STM32_NR_INTERRUPTS + +/* + * MCU-specific configuration. + */ + +#ifdef __DOXYGEN_PREDEFINED_HACK + + /** + * Number of GPIO ports. + */ + #define STM32_NR_GPIO_PORTS + + /** + * @brief Multiplier to convert microseconds into loop iterations + * in delay_us(). + * + * @see delay_us() + */ + #define STM32_DELAY_US_MULT + + /** + * @brief Pointer to end of built-in SRAM. + * + * Points to the address which is 1 byte past the last valid + * SRAM address. + */ + #define STM32_SRAM_END + + /** Deprecated. Use STM32_NR_GPIO_PORTS instead. */ + #define NR_GPIO_PORTS + /** Deprecated. Use STM32_DELAY_US_MULT instead. */ + #define DELAY_US_MULT + +#endif + +#if defined(MCU_STM32F103RB) + /* e.g., LeafLabs Maple */ + + #define STM32_NR_GPIO_PORTS 4 + #define STM32_DELAY_US_MULT 12 + #define STM32_SRAM_END ((void*)0x20005000) + + #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS + #define DELAY_US_MULT STM32_DELAY_US_MULT + +#elif defined(MCU_STM32F103ZE) + /* e.g., LeafLabs Maple Native */ + + #define STM32_NR_GPIO_PORTS 7 + #define STM32_DELAY_US_MULT 12 + #define STM32_SRAM_END ((void*)0x20010000) + + #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS + #define DELAY_US_MULT STM32_DELAY_US_MULT + +#elif defined(MCU_STM32F103CB) + /* e.g., LeafLabs Maple Mini */ + + /* This STM32_NR_GPIO_PORTS value is not, strictly speaking, true. + * But only pins 0 and 1 exist, and they're used for OSC on the + * Mini, so we'll live with this for now. */ + #define STM32_NR_GPIO_PORTS 3 + #define STM32_DELAY_US_MULT 12 + #define STM32_SRAM_END ((void*)0x20005000) + + #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS + #define DELAY_US_MULT STM32_DELAY_US_MULT + +#elif defined(MCU_STM32F103RE) + /* e.g., LeafLabs Maple RET6 edition */ + + #define STM32_NR_GPIO_PORTS 4 + #define STM32_DELAY_US_MULT 12 + #define STM32_SRAM_END ((void*)0x20010000) + + #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS + #define DELAY_US_MULT STM32_DELAY_US_MULT + +#elif defined(MCU_STM32F103VE) + /* e.g., LeafLabs Maple Native */ + + #define STM32_NR_GPIO_PORTS 5 + #define STM32_DELAY_US_MULT 12 + #define STM32_SRAM_END ((void*)0x20010000) + + #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS + #define DELAY_US_MULT STM32_DELAY_US_MULT + +#elif defined(MCU_STM32F205VE) + #define STM32_TICKS_PER_US 120 + #define STM32_NR_GPIO_PORTS 5 + #define STM32_DELAY_US_MULT (STM32_TICKS_PER_US/3) + #define STM32_SRAM_END ((void*)0x20010000) + + #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS + #define DELAY_US_MULT STM32_DELAY_US_MULT + +#elif defined(MCU_STM32F406VG) + #define STM32_TICKS_PER_US 168 + #define STM32_NR_GPIO_PORTS 5 + #define STM32_DELAY_US_MULT (STM32_TICKS_PER_US/3) + #define STM32_SRAM_END ((void*)0x20010000) + //#define STM32_SRAM_END ((void*)0x20030000) + + #define NR_GPIO_PORTS STM32_NR_GPIO_PORTS + #define DELAY_US_MULT STM32_DELAY_US_MULT + +#else + +#error "No MCU type specified. Add something like -DMCU_STM32F103RB " \ + "to your compiler arguments (probably in a Makefile)." + +#endif + +#endif /* _STM32_H_ */ diff --git a/Libmaple/libmaple/libmaple/syscalls.c b/Libmaple/libmaple/libmaple/syscalls.c index 6b37e270..8a579452 100644 --- a/Libmaple/libmaple/libmaple/syscalls.c +++ b/Libmaple/libmaple/libmaple/syscalls.c @@ -1,167 +1,167 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file syscalls.c - * @brief Low level system routines used by Newlib for basic I/O and - * memory allocation. - */ - -#include "libmaple.h" - -#include -#include - -/* If CONFIG_HEAP_START (or CONFIG_HEAP_END) isn't defined, then - * assume _lm_heap_start (resp. _lm_heap_end) is appropriately set by - * the linker */ -#ifndef CONFIG_HEAP_START -extern char _lm_heap_start; -#define CONFIG_HEAP_START ((caddr_t)&_lm_heap_start) -#endif -#ifndef CONFIG_HEAP_END -extern char _lm_heap_end; -#define CONFIG_HEAP_END ((caddr_t)&_lm_heap_end) -#endif - -/* - * _sbrk -- Increment the program break. - * - * Get incr bytes more RAM (for use by the heap). malloc() and - * friends call this function behind the scenes. - */ -caddr_t _sbrk(int incr) { - static caddr_t pbreak = NULL; /* current program break */ - caddr_t ret; - - if (pbreak == NULL) { - pbreak = CONFIG_HEAP_START; - } - - if ((CONFIG_HEAP_END - pbreak < incr) || - (pbreak - CONFIG_HEAP_START < -incr)) { - errno = ENOMEM; - return (caddr_t)-1; - } - - ret = pbreak; - pbreak += incr; - return ret; -} - -int _open(const char *path, int flags, ...) { - return 1; -} - -int _close(int fd) { - return 0; -} - -int _fstat(int fd, struct stat *st) { - st->st_mode = S_IFCHR; - return 0; -} - -int _isatty(int fd) { - return 1; -} - -int isatty(int fd) { - return 1; -} - -int _lseek(int fd, off_t pos, int whence) { - return -1; -} - -unsigned char getch(void) { - return 0; -} - - -int _read(int fd, char *buf, size_t cnt) { - *buf = getch(); - - return 1; -} - -void putch(unsigned char c) { -} - -void cgets(char *s, int bufsize) { - char *p; - int c; - int i; - - for (i = 0; i < bufsize; i++) { - *(s+i) = 0; - } -// memset(s, 0, bufsize); - - p = s; - - for (p = s; p < s + bufsize-1;) { - c = getch(); - switch (c) { - case '\r' : - case '\n' : - putch('\r'); - putch('\n'); - *p = '\n'; - return; - - case '\b' : - if (p > s) { - *p-- = 0; - putch('\b'); - putch(' '); - putch('\b'); - } - break; - - default : - putch(c); - *p++ = c; - break; - } - } - return; -} - -int _write(int fd, const char *buf, size_t cnt) { - int i; - - for (i = 0; i < cnt; i++) - putch(buf[i]); - - return cnt; -} - -/* Override fgets() in newlib with a version that does line editing */ -char *fgets(char *s, int bufsize, void *f) { - cgets(s, bufsize); - return s; -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file syscalls.c + * @brief Low level system routines used by Newlib for basic I/O and + * memory allocation. + */ + +#include "libmaple.h" + +#include +#include + +/* If CONFIG_HEAP_START (or CONFIG_HEAP_END) isn't defined, then + * assume _lm_heap_start (resp. _lm_heap_end) is appropriately set by + * the linker */ +#ifndef CONFIG_HEAP_START +extern char _lm_heap_start; +#define CONFIG_HEAP_START ((caddr_t)&_lm_heap_start) +#endif +#ifndef CONFIG_HEAP_END +extern char _lm_heap_end; +#define CONFIG_HEAP_END ((caddr_t)&_lm_heap_end) +#endif + +/* + * _sbrk -- Increment the program break. + * + * Get incr bytes more RAM (for use by the heap). malloc() and + * friends call this function behind the scenes. + */ +caddr_t _sbrk(int incr) { + static caddr_t pbreak = NULL; /* current program break */ + caddr_t ret; + + if (pbreak == NULL) { + pbreak = CONFIG_HEAP_START; + } + + if ((CONFIG_HEAP_END - pbreak < incr) || + (pbreak - CONFIG_HEAP_START < -incr)) { + errno = ENOMEM; + return (caddr_t)-1; + } + + ret = pbreak; + pbreak += incr; + return ret; +} + +int _open(const char *path, int flags, ...) { + return 1; +} + +int _close(int fd) { + return 0; +} + +int _fstat(int fd, struct stat *st) { + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int fd) { + return 1; +} + +int isatty(int fd) { + return 1; +} + +int _lseek(int fd, off_t pos, int whence) { + return -1; +} + +unsigned char getch(void) { + return 0; +} + + +int _read(int fd, char *buf, size_t cnt) { + *buf = getch(); + + return 1; +} + +void putch(unsigned char c) { +} + +void cgets(char *s, int bufsize) { + char *p; + int c; + int i; + + for (i = 0; i < bufsize; i++) { + *(s+i) = 0; + } +// memset(s, 0, bufsize); + + p = s; + + for (p = s; p < s + bufsize-1;) { + c = getch(); + switch (c) { + case '\r' : + case '\n' : + putch('\r'); + putch('\n'); + *p = '\n'; + return; + + case '\b' : + if (p > s) { + *p-- = 0; + putch('\b'); + putch(' '); + putch('\b'); + } + break; + + default : + putch(c); + *p++ = c; + break; + } + } + return; +} + +int _write(int fd, const char *buf, size_t cnt) { + int i; + + for (i = 0; i < cnt; i++) + putch(buf[i]); + + return cnt; +} + +/* Override fgets() in newlib with a version that does line editing */ +char *fgets(char *s, int bufsize, void *f) { + cgets(s, bufsize); + return s; +} diff --git a/Libmaple/libmaple/libmaple/systick.c b/Libmaple/libmaple/libmaple/systick.c index fedacfea..dbe773ce 100644 --- a/Libmaple/libmaple/libmaple/systick.c +++ b/Libmaple/libmaple/libmaple/systick.c @@ -1,91 +1,91 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file systick.c - * @brief System timer interrupt handler and initialization routines - */ - -#include "systick.h" -#include "nvic.h" -volatile uint32 systick_uptime_millis; -static void (*systick_user_callback)(void); - -/** - * @brief Initialize and enable SysTick. - * - * Clocks the system timer with the core clock, turns it on, and - * enables interrupts. - * - * @param reload_val Appropriate reload counter to tick every 1 ms. - */ -void systick_init(uint32 reload_val) { - SYSTICK_BASE->RVR = reload_val; - systick_enable(); -} - -/** - * Clock the system timer with the core clock, but don't turn it - * on or enable interrupt. - */ -void systick_disable() { - SYSTICK_BASE->CSR = SYSTICK_CSR_CLKSOURCE_CORE; -} - -/** - * Clock the system timer with the core clock and turn it on; - * interrupt every 1 ms, for systick_timer_millis. - */ -void systick_enable() { - /* re-enables init registers without changing reload val */ - SYSTICK_BASE->CSR = (SYSTICK_CSR_CLKSOURCE_CORE | - SYSTICK_CSR_ENABLE | - SYSTICK_CSR_TICKINT_PEND); -} - -/** - * @brief Attach a callback to be called from the SysTick exception handler. - * - * To detach a callback, call this function again with a null argument. - */ -void systick_attach_callback(void (*callback)(void)) { - systick_user_callback = callback; -} - -/* - * SysTick ISR - */ - -void __exc_systick(void) { - nvic_globalirq_disable(); - systick_check_underflow(); - systick_uptime_millis++; - nvic_globalirq_enable(); - - if (systick_user_callback) { - systick_user_callback(); - } -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file systick.c + * @brief System timer interrupt handler and initialization routines + */ + +#include "systick.h" +#include "nvic.h" +volatile uint32 systick_uptime_millis; +static void (*systick_user_callback)(void); + +/** + * @brief Initialize and enable SysTick. + * + * Clocks the system timer with the core clock, turns it on, and + * enables interrupts. + * + * @param reload_val Appropriate reload counter to tick every 1 ms. + */ +void systick_init(uint32 reload_val) { + SYSTICK_BASE->RVR = reload_val; + systick_enable(); +} + +/** + * Clock the system timer with the core clock, but don't turn it + * on or enable interrupt. + */ +void systick_disable() { + SYSTICK_BASE->CSR = SYSTICK_CSR_CLKSOURCE_CORE; +} + +/** + * Clock the system timer with the core clock and turn it on; + * interrupt every 1 ms, for systick_timer_millis. + */ +void systick_enable() { + /* re-enables init registers without changing reload val */ + SYSTICK_BASE->CSR = (SYSTICK_CSR_CLKSOURCE_CORE | + SYSTICK_CSR_ENABLE | + SYSTICK_CSR_TICKINT_PEND); +} + +/** + * @brief Attach a callback to be called from the SysTick exception handler. + * + * To detach a callback, call this function again with a null argument. + */ +void systick_attach_callback(void (*callback)(void)) { + systick_user_callback = callback; +} + +/* + * SysTick ISR + */ + +void __exc_systick(void) { + nvic_globalirq_disable(); + systick_check_underflow(); + systick_uptime_millis++; + nvic_globalirq_enable(); + + if (systick_user_callback) { + systick_user_callback(); + } +} diff --git a/Libmaple/libmaple/libmaple/systick.h b/Libmaple/libmaple/libmaple/systick.h index 3286e5b3..6ec33644 100644 --- a/Libmaple/libmaple/libmaple/systick.h +++ b/Libmaple/libmaple/libmaple/systick.h @@ -1,117 +1,117 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file systick.h - * - * @brief Various system timer definitions - */ - -#ifndef _SYSTICK_H_ -#define _SYSTICK_H_ - -#include "libmaple_types.h" -#include "util.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/** SysTick register map type */ -typedef struct systick_reg_map { - __io uint32 CSR; /**< Control and status register */ - __io uint32 RVR; /**< Reload value register */ - __io uint32 CNT; /**< Current value register ("count") */ - __io uint32 CVR; /**< Calibration value register */ -} systick_reg_map; - -/** SysTick register map base pointer */ -#define SYSTICK_BASE ((struct systick_reg_map*)0xE000E010) - -/* - * Register bit definitions. - */ - -/* Control and status register */ - -#define SYSTICK_CSR_COUNTFLAG BIT(16) -#define SYSTICK_CSR_CLKSOURCE BIT(2) -#define SYSTICK_CSR_CLKSOURCE_EXTERNAL 0 -#define SYSTICK_CSR_CLKSOURCE_CORE BIT(2) -#define SYSTICK_CSR_TICKINT BIT(1) -#define SYSTICK_CSR_TICKINT_PEND BIT(1) -#define SYSTICK_CSR_TICKINT_NO_PEND 0 -#define SYSTICK_CSR_ENABLE BIT(0) -#define SYSTICK_CSR_ENABLE_MULTISHOT BIT(0) -#define SYSTICK_CSR_ENABLE_DISABLED 0 - -/* Calibration value register */ - -#define SYSTICK_CVR_NOREF BIT(31) -#define SYSTICK_CVR_SKEW BIT(30) -#define SYSTICK_CVR_TENMS 0xFFFFFF - -/** System elapsed time, in milliseconds */ -extern volatile uint32 systick_uptime_millis; - -/** - * @brief Returns the system uptime, in milliseconds. - */ -static inline uint32 systick_uptime(void) { - return systick_uptime_millis; -} - - -void systick_init(uint32 reload_val); -void systick_disable(); -void systick_enable(); - -/** - * @brief Returns the current value of the SysTick counter. - */ -static inline uint32 systick_get_count(void) { - return SYSTICK_BASE->CNT; -} - -/** - * @brief Check for underflow. - * - * This function returns 1 if the SysTick timer has counted to 0 since - * the last time it was called. However, any reads of any part of the - * SysTick Control and Status Register SYSTICK_BASE->CSR will - * interfere with this functionality. See the ARM Cortex M3 Technical - * Reference Manual for more details (e.g. Table 8-3 in revision r1p1). - */ -static inline uint32 systick_check_underflow(void) { - return SYSTICK_BASE->CSR & SYSTICK_CSR_COUNTFLAG; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file systick.h + * + * @brief Various system timer definitions + */ + +#ifndef _SYSTICK_H_ +#define _SYSTICK_H_ + +#include "libmaple_types.h" +#include "util.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/** SysTick register map type */ +typedef struct systick_reg_map { + __io uint32 CSR; /**< Control and status register */ + __io uint32 RVR; /**< Reload value register */ + __io uint32 CNT; /**< Current value register ("count") */ + __io uint32 CVR; /**< Calibration value register */ +} systick_reg_map; + +/** SysTick register map base pointer */ +#define SYSTICK_BASE ((struct systick_reg_map*)0xE000E010) + +/* + * Register bit definitions. + */ + +/* Control and status register */ + +#define SYSTICK_CSR_COUNTFLAG BIT(16) +#define SYSTICK_CSR_CLKSOURCE BIT(2) +#define SYSTICK_CSR_CLKSOURCE_EXTERNAL 0 +#define SYSTICK_CSR_CLKSOURCE_CORE BIT(2) +#define SYSTICK_CSR_TICKINT BIT(1) +#define SYSTICK_CSR_TICKINT_PEND BIT(1) +#define SYSTICK_CSR_TICKINT_NO_PEND 0 +#define SYSTICK_CSR_ENABLE BIT(0) +#define SYSTICK_CSR_ENABLE_MULTISHOT BIT(0) +#define SYSTICK_CSR_ENABLE_DISABLED 0 + +/* Calibration value register */ + +#define SYSTICK_CVR_NOREF BIT(31) +#define SYSTICK_CVR_SKEW BIT(30) +#define SYSTICK_CVR_TENMS 0xFFFFFF + +/** System elapsed time, in milliseconds */ +extern volatile uint32 systick_uptime_millis; + +/** + * @brief Returns the system uptime, in milliseconds. + */ +static inline uint32 systick_uptime(void) { + return systick_uptime_millis; +} + + +void systick_init(uint32 reload_val); +void systick_disable(); +void systick_enable(); + +/** + * @brief Returns the current value of the SysTick counter. + */ +static inline uint32 systick_get_count(void) { + return SYSTICK_BASE->CNT; +} + +/** + * @brief Check for underflow. + * + * This function returns 1 if the SysTick timer has counted to 0 since + * the last time it was called. However, any reads of any part of the + * SysTick Control and Status Register SYSTICK_BASE->CSR will + * interfere with this functionality. See the ARM Cortex M3 Technical + * Reference Manual for more details (e.g. Table 8-3 in revision r1p1). + */ +static inline uint32 systick_check_underflow(void) { + return SYSTICK_BASE->CSR & SYSTICK_CSR_COUNTFLAG; +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif + diff --git a/Libmaple/libmaple/libmaple/timer.c b/Libmaple/libmaple/libmaple/timer.c index afc69596..83e9ace3 100644 --- a/Libmaple/libmaple/libmaple/timer.c +++ b/Libmaple/libmaple/libmaple/timer.c @@ -1,480 +1,480 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file timer.c - * @author Marti Bolivar - * @brief New-style timer interface - */ - -#include "timer.h" - -/* Just like the corresponding DIER bits: - * [0] = Update handler; - * [1,2,3,4] = capture/compare 1,2,3,4 handlers, respectively; - * [5] = COM; - * [6] = TRG; - * [7] = BRK. */ -#define NR_ADV_HANDLERS 8 -/* Update, capture/compare 1,2,3,4; ; trigger. */ -#define NR_GEN_HANDLERS 7 -/* Update only. */ -#define NR_BAS_HANDLERS 1 - -static timer_dev timer1 = { - .regs = { .adv = TIMER1_BASE }, - .clk_id = RCC_TIMER1, - .type = TIMER_ADVANCED, - .handlers = { [NR_ADV_HANDLERS - 1] = 0 }, -}; -/** Timer 1 device (advanced) */ -timer_dev *TIMER1 = &timer1; - -static timer_dev timer2 = { - .regs = { .gen = TIMER2_BASE }, - .clk_id = RCC_TIMER2, - .type = TIMER_GENERAL, - .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, -}; -/** Timer 2 device (general-purpose) */ -timer_dev *TIMER2 = &timer2; - -static timer_dev timer3 = { - .regs = { .gen = TIMER3_BASE }, - .clk_id = RCC_TIMER3, - .type = TIMER_GENERAL, - .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, -}; -/** Timer 3 device (general-purpose) */ -timer_dev *TIMER3 = &timer3; - -static timer_dev timer4 = { - .regs = { .gen = TIMER4_BASE }, - .clk_id = RCC_TIMER4, - .type = TIMER_GENERAL, - .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, -}; -/** Timer 4 device (general-purpose) */ -timer_dev *TIMER4 = &timer4; - -#ifdef STM32_HIGH_DENSITY -static timer_dev timer5 = { - .regs = { .gen = TIMER5_BASE }, - .clk_id = RCC_TIMER5, - .type = TIMER_GENERAL, - .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, -}; -/** Timer 5 device (general-purpose) */ -timer_dev *TIMER5 = &timer5; - -static timer_dev timer6 = { - .regs = { .bas = TIMER6_BASE }, - .clk_id = RCC_TIMER6, - .type = TIMER_BASIC, - .handlers = { [NR_BAS_HANDLERS - 1] = 0 }, -}; -/** Timer 6 device (basic) */ -timer_dev *TIMER6 = &timer6; - -static timer_dev timer7 = { - .regs = { .bas = TIMER7_BASE }, - .clk_id = RCC_TIMER7, - .type = TIMER_BASIC, - .handlers = { [NR_BAS_HANDLERS - 1] = 0 }, -}; -/** Timer 7 device (basic) */ -timer_dev *TIMER7 = &timer7; - -static timer_dev timer8 = { - .regs = { .adv = TIMER8_BASE }, - .clk_id = RCC_TIMER8, - .type = TIMER_ADVANCED, - .handlers = { [NR_ADV_HANDLERS - 1] = 0 }, -}; -/** Timer 8 device (advanced) */ -timer_dev *TIMER8 = &timer8; -#endif - -/* - * Convenience routines - */ - -static void disable_channel(timer_dev *dev, uint8 channel); -static void pwm_mode(timer_dev *dev, uint8 channel); -static void output_compare_mode(timer_dev *dev, uint8 channel); - -static inline void enable_irq(timer_dev *dev, uint8 interrupt); - -/** - * Initialize a timer, and reset its register map. - * @param dev Timer to initialize - */ -void timer_init(timer_dev *dev) { - rcc_clk_enable(dev->clk_id); - rcc_reset_dev(dev->clk_id); -} - -/** - * @brief Disable a timer. - * - * The timer will stop counting, all DMA requests and interrupts will - * be disabled, and no state changes will be output. - * - * @param dev Timer to disable. - */ -void timer_disable(timer_dev *dev) { - (dev->regs).bas->CR1 = 0; - (dev->regs).bas->DIER = 0; - switch (dev->type) { - case TIMER_ADVANCED: /* fall-through */ - case TIMER_GENERAL: - (dev->regs).gen->CCER = 0; - break; - case TIMER_BASIC: - break; - } -} - -/** - * Sets the mode of an individual timer channel. - * - * Note that not all timers can be configured in every mode. For - * example, basic timers cannot be configured to output compare mode. - * Be sure to use a timer which is appropriate for the mode you want. - * - * @param dev Timer whose channel mode to set - * @param channel Relevant channel - * @param mode New timer mode for channel - */ -void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) { - ASSERT_FAULT(channel > 0 && channel <= 4); - - /* TODO decide about the basic timers */ - ASSERT(dev->type != TIMER_BASIC); - if (dev->type == TIMER_BASIC) - return; - - switch (mode) { - case TIMER_DISABLED: - disable_channel(dev, channel); - break; - case TIMER_PWM: - pwm_mode(dev, channel); - break; - case TIMER_OUTPUT_COMPARE: - output_compare_mode(dev, channel); - break; - } -} - -/** - * @brief Call a function on timer devices. - * @param fn Function to call on each timer device. - */ -void timer_foreach(void (*fn)(timer_dev*)) { - fn(TIMER1); - fn(TIMER2); - fn(TIMER3); - fn(TIMER4); -#ifdef STM32_HIGH_DENSITY - fn(TIMER5); - fn(TIMER6); - fn(TIMER7); - fn(TIMER8); -#endif -} - -/** - * @brief Attach a timer interrupt. - * @param dev Timer device - * @param interrupt Interrupt number to attach to; this may be any - * timer_interrupt_id or timer_channel value appropriate - * for the timer. - * @param handler Handler to attach to the given interrupt. - * @see timer_interrupt_id - * @see timer_channel - */ -void timer_attach_interrupt(timer_dev *dev, - uint8 interrupt, - voidFuncPtr handler) { - dev->handlers[interrupt] = handler; - timer_enable_irq(dev, interrupt); - enable_irq(dev, interrupt); -} - -/** - * @brief Detach a timer interrupt. - * @param dev Timer device - * @param interrupt Interrupt number to detach; this may be any - * timer_interrupt_id or timer_channel value appropriate - * for the timer. - * @see timer_interrupt_id - * @see timer_channel - */ -void timer_detach_interrupt(timer_dev *dev, uint8 interrupt) { - timer_disable_irq(dev, interrupt); - dev->handlers[interrupt] = NULL; -} - -/* - * IRQ handlers - */ - -static inline void dispatch_adv_brk(timer_dev *dev); -static inline void dispatch_adv_up(timer_dev *dev); -static inline void dispatch_adv_trg_com(timer_dev *dev); -static inline void dispatch_adv_cc(timer_dev *dev); -static inline void dispatch_general(timer_dev *dev); -static inline void dispatch_basic(timer_dev *dev); - -void __irq_tim1_brk(void) { - dispatch_adv_brk(TIMER1); -} - -void __irq_tim1_up(void) { - dispatch_adv_up(TIMER1); -} - -void __irq_tim1_trg_com(void) { - dispatch_adv_trg_com(TIMER1); -} - -void __irq_tim1_cc(void) { - dispatch_adv_cc(TIMER1); -} - -void __irq_tim2(void) { - dispatch_general(TIMER2); -} - -void __irq_tim3(void) { - dispatch_general(TIMER3); -} - -void __irq_tim4(void) { - dispatch_general(TIMER4); -} - -#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) - -void __irq_tim5(void) { - dispatch_general(TIMER5); -} - -void __irq_tim6(void) { - dispatch_basic(TIMER6); -} - -void __irq_tim7(void) { - dispatch_basic(TIMER7); -} - -void __irq_tim8_brk(void) { - dispatch_adv_brk(TIMER8); -} - -void __irq_tim8_up(void) { - dispatch_adv_up(TIMER8); -} - -void __irq_tim8_trg_com(void) { - dispatch_adv_trg_com(TIMER8); -} - -void __irq_tim8_cc(void) { - dispatch_adv_cc(TIMER8); -} -#endif - -/* Note: the following dispatch routines make use of the fact that - * DIER interrupt enable bits and SR interrupt flags have common bit - * positions. Thus, ANDing DIER and SR lets us check if an interrupt - * is enabled and if it has occurred simultaneously. - */ - -/* A special-case dispatch routine for single-interrupt NVIC lines. - * This function assumes that the interrupt corresponding to `iid' has - * in fact occurred (i.e., it doesn't check DIER & SR). */ -static inline void dispatch_single_irq(timer_dev *dev, - timer_interrupt_id iid, - uint32 irq_mask) { - timer_bas_reg_map *regs = (dev->regs).bas; - void (*handler)(void) = dev->handlers[iid]; - if (handler) { - handler(); - regs->SR &= ~irq_mask; - } -} - -/* For dispatch routines which service multiple interrupts. */ -#define handle_irq(dier_sr, irq_mask, handlers, iid, handled_irq) do { \ - if ((dier_sr) & (irq_mask)) { \ - void (*__handler)(void) = (handlers)[iid]; \ - if (__handler) { \ - __handler(); \ - handled_irq |= (irq_mask); \ - } \ - } \ - } while (0) - -static inline void dispatch_adv_brk(timer_dev *dev) { - dispatch_single_irq(dev, TIMER_BREAK_INTERRUPT, TIMER_SR_BIF); -} - -static inline void dispatch_adv_up(timer_dev *dev) { - dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); -} - -static inline void dispatch_adv_trg_com(timer_dev *dev) { - timer_adv_reg_map *regs = (dev->regs).adv; - uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; - uint32 handled = 0; /* Logical OR of SR interrupt flags we end up - * handling. We clear these. User handlers - * must clear overcapture flags, to avoid - * wasting time in output mode. */ - - handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_COMIF, hs, TIMER_COM_INTERRUPT, handled); - - regs->SR &= ~handled; -} - -static inline void dispatch_adv_cc(timer_dev *dev) { - timer_adv_reg_map *regs = (dev->regs).adv; - uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; - uint32 handled = 0; - - handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC3IF, hs, TIMER_CC3_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); - - regs->SR &= ~handled; -} - -static inline void dispatch_general(timer_dev *dev) { - timer_gen_reg_map *regs = (dev->regs).gen; - uint32 dsr = regs->DIER & regs->SR; - void (**hs)(void) = dev->handlers; - uint32 handled = 0; - - handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC3IF, hs, TIMER_CC3_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); - handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); - - regs->SR &= ~handled; -} - -static inline void dispatch_basic(timer_dev *dev) { - dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); -} - -/* - * Utilities - */ - -static void disable_channel(timer_dev *dev, uint8 channel) { - timer_detach_interrupt(dev, channel); - timer_cc_disable(dev, channel); -} - -static void pwm_mode(timer_dev *dev, uint8 channel) { - timer_disable_irq(dev, channel); - timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE); - timer_cc_enable(dev, channel); -} - -static void output_compare_mode(timer_dev *dev, uint8 channel) { - timer_oc_set_mode(dev, channel, TIMER_OC_MODE_ACTIVE_ON_MATCH, 0); - timer_cc_enable(dev, channel); -} - -static void enable_advanced_irq(timer_dev *dev, timer_interrupt_id id); -static void enable_nonmuxed_irq(timer_dev *dev); - -static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid) { - if (dev->type == TIMER_ADVANCED) { - enable_advanced_irq(dev, iid); - } else { - enable_nonmuxed_irq(dev); - } -} - -static void enable_advanced_irq(timer_dev *dev, timer_interrupt_id id) { - uint8 is_timer1 = dev->clk_id == RCC_TIMER1; - - switch (id) { - case TIMER_UPDATE_INTERRUPT: - nvic_irq_enable(is_timer1 ? NVIC_TIMER1_UP : NVIC_TIMER8_UP); - break; - case TIMER_CC1_INTERRUPT: - case TIMER_CC2_INTERRUPT: - case TIMER_CC3_INTERRUPT: - case TIMER_CC4_INTERRUPT: - nvic_irq_enable(is_timer1 ? NVIC_TIMER1_CC : NVIC_TIMER8_CC); - break; - case TIMER_COM_INTERRUPT: - case TIMER_TRG_INTERRUPT: - nvic_irq_enable(is_timer1 ? NVIC_TIMER1_TRG_COM : NVIC_TIMER8_TRG_COM); - break; - case TIMER_BREAK_INTERRUPT: - nvic_irq_enable(is_timer1 ? NVIC_TIMER1_BRK : NVIC_TIMER8_BRK); - break; - } -} - -static void enable_nonmuxed_irq(timer_dev *dev) { - switch (dev->clk_id) { - case RCC_TIMER2: - nvic_irq_enable(NVIC_TIMER2); - break; - case RCC_TIMER3: - nvic_irq_enable(NVIC_TIMER3); - break; - case RCC_TIMER4: - nvic_irq_enable(NVIC_TIMER4); - break; -#ifdef STM32_HIGH_DENSITY - case RCC_TIMER5: - nvic_irq_enable(NVIC_TIMER5); - break; - case RCC_TIMER6: - nvic_irq_enable(NVIC_TIMER6); - break; - case RCC_TIMER7: - nvic_irq_enable(NVIC_TIMER7); - break; -#endif - default: - ASSERT_FAULT(0); - break; - } -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file timer.c + * @author Marti Bolivar + * @brief New-style timer interface + */ + +#include "timer.h" + +/* Just like the corresponding DIER bits: + * [0] = Update handler; + * [1,2,3,4] = capture/compare 1,2,3,4 handlers, respectively; + * [5] = COM; + * [6] = TRG; + * [7] = BRK. */ +#define NR_ADV_HANDLERS 8 +/* Update, capture/compare 1,2,3,4; ; trigger. */ +#define NR_GEN_HANDLERS 7 +/* Update only. */ +#define NR_BAS_HANDLERS 1 + +static timer_dev timer1 = { + .regs = { .adv = TIMER1_BASE }, + .clk_id = RCC_TIMER1, + .type = TIMER_ADVANCED, + .handlers = { [NR_ADV_HANDLERS - 1] = 0 }, +}; +/** Timer 1 device (advanced) */ +timer_dev *TIMER1 = &timer1; + +static timer_dev timer2 = { + .regs = { .gen = TIMER2_BASE }, + .clk_id = RCC_TIMER2, + .type = TIMER_GENERAL, + .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, +}; +/** Timer 2 device (general-purpose) */ +timer_dev *TIMER2 = &timer2; + +static timer_dev timer3 = { + .regs = { .gen = TIMER3_BASE }, + .clk_id = RCC_TIMER3, + .type = TIMER_GENERAL, + .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, +}; +/** Timer 3 device (general-purpose) */ +timer_dev *TIMER3 = &timer3; + +static timer_dev timer4 = { + .regs = { .gen = TIMER4_BASE }, + .clk_id = RCC_TIMER4, + .type = TIMER_GENERAL, + .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, +}; +/** Timer 4 device (general-purpose) */ +timer_dev *TIMER4 = &timer4; + +#ifdef STM32_HIGH_DENSITY +static timer_dev timer5 = { + .regs = { .gen = TIMER5_BASE }, + .clk_id = RCC_TIMER5, + .type = TIMER_GENERAL, + .handlers = { [NR_GEN_HANDLERS - 1] = 0 }, +}; +/** Timer 5 device (general-purpose) */ +timer_dev *TIMER5 = &timer5; + +static timer_dev timer6 = { + .regs = { .bas = TIMER6_BASE }, + .clk_id = RCC_TIMER6, + .type = TIMER_BASIC, + .handlers = { [NR_BAS_HANDLERS - 1] = 0 }, +}; +/** Timer 6 device (basic) */ +timer_dev *TIMER6 = &timer6; + +static timer_dev timer7 = { + .regs = { .bas = TIMER7_BASE }, + .clk_id = RCC_TIMER7, + .type = TIMER_BASIC, + .handlers = { [NR_BAS_HANDLERS - 1] = 0 }, +}; +/** Timer 7 device (basic) */ +timer_dev *TIMER7 = &timer7; + +static timer_dev timer8 = { + .regs = { .adv = TIMER8_BASE }, + .clk_id = RCC_TIMER8, + .type = TIMER_ADVANCED, + .handlers = { [NR_ADV_HANDLERS - 1] = 0 }, +}; +/** Timer 8 device (advanced) */ +timer_dev *TIMER8 = &timer8; +#endif + +/* + * Convenience routines + */ + +static void disable_channel(timer_dev *dev, uint8 channel); +static void pwm_mode(timer_dev *dev, uint8 channel); +static void output_compare_mode(timer_dev *dev, uint8 channel); + +static inline void enable_irq(timer_dev *dev, uint8 interrupt); + +/** + * Initialize a timer, and reset its register map. + * @param dev Timer to initialize + */ +void timer_init(timer_dev *dev) { + rcc_clk_enable(dev->clk_id); + rcc_reset_dev(dev->clk_id); +} + +/** + * @brief Disable a timer. + * + * The timer will stop counting, all DMA requests and interrupts will + * be disabled, and no state changes will be output. + * + * @param dev Timer to disable. + */ +void timer_disable(timer_dev *dev) { + (dev->regs).bas->CR1 = 0; + (dev->regs).bas->DIER = 0; + switch (dev->type) { + case TIMER_ADVANCED: /* fall-through */ + case TIMER_GENERAL: + (dev->regs).gen->CCER = 0; + break; + case TIMER_BASIC: + break; + } +} + +/** + * Sets the mode of an individual timer channel. + * + * Note that not all timers can be configured in every mode. For + * example, basic timers cannot be configured to output compare mode. + * Be sure to use a timer which is appropriate for the mode you want. + * + * @param dev Timer whose channel mode to set + * @param channel Relevant channel + * @param mode New timer mode for channel + */ +void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) { + ASSERT_FAULT(channel > 0 && channel <= 4); + + /* TODO decide about the basic timers */ + ASSERT(dev->type != TIMER_BASIC); + if (dev->type == TIMER_BASIC) + return; + + switch (mode) { + case TIMER_DISABLED: + disable_channel(dev, channel); + break; + case TIMER_PWM: + pwm_mode(dev, channel); + break; + case TIMER_OUTPUT_COMPARE: + output_compare_mode(dev, channel); + break; + } +} + +/** + * @brief Call a function on timer devices. + * @param fn Function to call on each timer device. + */ +void timer_foreach(void (*fn)(timer_dev*)) { + fn(TIMER1); + fn(TIMER2); + fn(TIMER3); + fn(TIMER4); +#ifdef STM32_HIGH_DENSITY + fn(TIMER5); + fn(TIMER6); + fn(TIMER7); + fn(TIMER8); +#endif +} + +/** + * @brief Attach a timer interrupt. + * @param dev Timer device + * @param interrupt Interrupt number to attach to; this may be any + * timer_interrupt_id or timer_channel value appropriate + * for the timer. + * @param handler Handler to attach to the given interrupt. + * @see timer_interrupt_id + * @see timer_channel + */ +void timer_attach_interrupt(timer_dev *dev, + uint8 interrupt, + voidFuncPtr handler) { + dev->handlers[interrupt] = handler; + timer_enable_irq(dev, interrupt); + enable_irq(dev, interrupt); +} + +/** + * @brief Detach a timer interrupt. + * @param dev Timer device + * @param interrupt Interrupt number to detach; this may be any + * timer_interrupt_id or timer_channel value appropriate + * for the timer. + * @see timer_interrupt_id + * @see timer_channel + */ +void timer_detach_interrupt(timer_dev *dev, uint8 interrupt) { + timer_disable_irq(dev, interrupt); + dev->handlers[interrupt] = NULL; +} + +/* + * IRQ handlers + */ + +static inline void dispatch_adv_brk(timer_dev *dev); +static inline void dispatch_adv_up(timer_dev *dev); +static inline void dispatch_adv_trg_com(timer_dev *dev); +static inline void dispatch_adv_cc(timer_dev *dev); +static inline void dispatch_general(timer_dev *dev); +static inline void dispatch_basic(timer_dev *dev); + +void __irq_tim1_brk(void) { + dispatch_adv_brk(TIMER1); +} + +void __irq_tim1_up(void) { + dispatch_adv_up(TIMER1); +} + +void __irq_tim1_trg_com(void) { + dispatch_adv_trg_com(TIMER1); +} + +void __irq_tim1_cc(void) { + dispatch_adv_cc(TIMER1); +} + +void __irq_tim2(void) { + dispatch_general(TIMER2); +} + +void __irq_tim3(void) { + dispatch_general(TIMER3); +} + +void __irq_tim4(void) { + dispatch_general(TIMER4); +} + +#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) + +void __irq_tim5(void) { + dispatch_general(TIMER5); +} + +void __irq_tim6(void) { + dispatch_basic(TIMER6); +} + +void __irq_tim7(void) { + dispatch_basic(TIMER7); +} + +void __irq_tim8_brk(void) { + dispatch_adv_brk(TIMER8); +} + +void __irq_tim8_up(void) { + dispatch_adv_up(TIMER8); +} + +void __irq_tim8_trg_com(void) { + dispatch_adv_trg_com(TIMER8); +} + +void __irq_tim8_cc(void) { + dispatch_adv_cc(TIMER8); +} +#endif + +/* Note: the following dispatch routines make use of the fact that + * DIER interrupt enable bits and SR interrupt flags have common bit + * positions. Thus, ANDing DIER and SR lets us check if an interrupt + * is enabled and if it has occurred simultaneously. + */ + +/* A special-case dispatch routine for single-interrupt NVIC lines. + * This function assumes that the interrupt corresponding to `iid' has + * in fact occurred (i.e., it doesn't check DIER & SR). */ +static inline void dispatch_single_irq(timer_dev *dev, + timer_interrupt_id iid, + uint32 irq_mask) { + timer_bas_reg_map *regs = (dev->regs).bas; + void (*handler)(void) = dev->handlers[iid]; + if (handler) { + handler(); + regs->SR &= ~irq_mask; + } +} + +/* For dispatch routines which service multiple interrupts. */ +#define handle_irq(dier_sr, irq_mask, handlers, iid, handled_irq) do { \ + if ((dier_sr) & (irq_mask)) { \ + void (*__handler)(void) = (handlers)[iid]; \ + if (__handler) { \ + __handler(); \ + handled_irq |= (irq_mask); \ + } \ + } \ + } while (0) + +static inline void dispatch_adv_brk(timer_dev *dev) { + dispatch_single_irq(dev, TIMER_BREAK_INTERRUPT, TIMER_SR_BIF); +} + +static inline void dispatch_adv_up(timer_dev *dev) { + dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); +} + +static inline void dispatch_adv_trg_com(timer_dev *dev) { + timer_adv_reg_map *regs = (dev->regs).adv; + uint32 dsr = regs->DIER & regs->SR; + void (**hs)(void) = dev->handlers; + uint32 handled = 0; /* Logical OR of SR interrupt flags we end up + * handling. We clear these. User handlers + * must clear overcapture flags, to avoid + * wasting time in output mode. */ + + handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_COMIF, hs, TIMER_COM_INTERRUPT, handled); + + regs->SR &= ~handled; +} + +static inline void dispatch_adv_cc(timer_dev *dev) { + timer_adv_reg_map *regs = (dev->regs).adv; + uint32 dsr = regs->DIER & regs->SR; + void (**hs)(void) = dev->handlers; + uint32 handled = 0; + + handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC3IF, hs, TIMER_CC3_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); + + regs->SR &= ~handled; +} + +static inline void dispatch_general(timer_dev *dev) { + timer_gen_reg_map *regs = (dev->regs).gen; + uint32 dsr = regs->DIER & regs->SR; + void (**hs)(void) = dev->handlers; + uint32 handled = 0; + + handle_irq(dsr, TIMER_SR_TIF, hs, TIMER_TRG_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC4IF, hs, TIMER_CC4_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC3IF, hs, TIMER_CC3_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC2IF, hs, TIMER_CC2_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_CC1IF, hs, TIMER_CC1_INTERRUPT, handled); + handle_irq(dsr, TIMER_SR_UIF, hs, TIMER_UPDATE_INTERRUPT, handled); + + regs->SR &= ~handled; +} + +static inline void dispatch_basic(timer_dev *dev) { + dispatch_single_irq(dev, TIMER_UPDATE_INTERRUPT, TIMER_SR_UIF); +} + +/* + * Utilities + */ + +static void disable_channel(timer_dev *dev, uint8 channel) { + timer_detach_interrupt(dev, channel); + timer_cc_disable(dev, channel); +} + +static void pwm_mode(timer_dev *dev, uint8 channel) { + timer_disable_irq(dev, channel); + timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE); + timer_cc_enable(dev, channel); +} + +static void output_compare_mode(timer_dev *dev, uint8 channel) { + timer_oc_set_mode(dev, channel, TIMER_OC_MODE_ACTIVE_ON_MATCH, 0); + timer_cc_enable(dev, channel); +} + +static void enable_advanced_irq(timer_dev *dev, timer_interrupt_id id); +static void enable_nonmuxed_irq(timer_dev *dev); + +static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid) { + if (dev->type == TIMER_ADVANCED) { + enable_advanced_irq(dev, iid); + } else { + enable_nonmuxed_irq(dev); + } +} + +static void enable_advanced_irq(timer_dev *dev, timer_interrupt_id id) { + uint8 is_timer1 = dev->clk_id == RCC_TIMER1; + + switch (id) { + case TIMER_UPDATE_INTERRUPT: + nvic_irq_enable(is_timer1 ? NVIC_TIMER1_UP : NVIC_TIMER8_UP); + break; + case TIMER_CC1_INTERRUPT: + case TIMER_CC2_INTERRUPT: + case TIMER_CC3_INTERRUPT: + case TIMER_CC4_INTERRUPT: + nvic_irq_enable(is_timer1 ? NVIC_TIMER1_CC : NVIC_TIMER8_CC); + break; + case TIMER_COM_INTERRUPT: + case TIMER_TRG_INTERRUPT: + nvic_irq_enable(is_timer1 ? NVIC_TIMER1_TRG_COM : NVIC_TIMER8_TRG_COM); + break; + case TIMER_BREAK_INTERRUPT: + nvic_irq_enable(is_timer1 ? NVIC_TIMER1_BRK : NVIC_TIMER8_BRK); + break; + } +} + +static void enable_nonmuxed_irq(timer_dev *dev) { + switch (dev->clk_id) { + case RCC_TIMER2: + nvic_irq_enable(NVIC_TIMER2); + break; + case RCC_TIMER3: + nvic_irq_enable(NVIC_TIMER3); + break; + case RCC_TIMER4: + nvic_irq_enable(NVIC_TIMER4); + break; +#ifdef STM32_HIGH_DENSITY + case RCC_TIMER5: + nvic_irq_enable(NVIC_TIMER5); + break; + case RCC_TIMER6: + nvic_irq_enable(NVIC_TIMER6); + break; + case RCC_TIMER7: + nvic_irq_enable(NVIC_TIMER7); + break; +#endif + default: + ASSERT_FAULT(0); + break; + } +} diff --git a/Libmaple/libmaple/libmaple/timer.h b/Libmaple/libmaple/libmaple/timer.h index 4e1f3f16..fce6345b 100644 --- a/Libmaple/libmaple/libmaple/timer.h +++ b/Libmaple/libmaple/libmaple/timer.h @@ -1,1027 +1,1027 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file timer.h - * @author Marti Bolivar - * @brief New-style timer interface. - * - * Replaces old timers.h implementation. - */ - -#ifndef _TIMERS_H_ -#define _TIMERS_H_ - -#include "libmaple.h" -#include "rcc.h" -#include "nvic.h" -#include "bitband.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - * Register maps and devices - */ - -/** Advanced control timer register map type */ -typedef struct timer_adv_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SMCR; /**< Slave mode control register */ - __io uint32 DIER; /**< DMA/Interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - __io uint32 CCMR1; /**< Capture/compare mode register 1 */ - __io uint32 CCMR2; /**< Capture/compare mode register 2 */ - __io uint32 CCER; /**< Capture/compare enable register */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ - __io uint32 RCR; /**< Repetition counter register */ - __io uint32 CCR1; /**< Capture/compare register 1 */ - __io uint32 CCR2; /**< Capture/compare register 2 */ - __io uint32 CCR3; /**< Capture/compare register 3 */ - __io uint32 CCR4; /**< Capture/compare register 4 */ - __io uint32 BDTR; /**< Break and dead-time register */ - __io uint32 DCR; /**< DMA control register */ - __io uint32 DMAR; /**< DMA address for full transfer */ -} timer_adv_reg_map; - -/** General purpose timer register map type */ -typedef struct timer_gen_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 SMCR; /**< Slave mode control register */ - __io uint32 DIER; /**< DMA/Interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - __io uint32 CCMR1; /**< Capture/compare mode register 1 */ - __io uint32 CCMR2; /**< Capture/compare mode register 2 */ - __io uint32 CCER; /**< Capture/compare enable register */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ - const uint32 RESERVED1; /**< Reserved */ - __io uint32 CCR1; /**< Capture/compare register 1 */ - __io uint32 CCR2; /**< Capture/compare register 2 */ - __io uint32 CCR3; /**< Capture/compare register 3 */ - __io uint32 CCR4; /**< Capture/compare register 4 */ - const uint32 RESERVED2; /**< Reserved */ - __io uint32 DCR; /**< DMA control register */ - __io uint32 DMAR; /**< DMA address for full transfer */ -} timer_gen_reg_map; - -/** Basic timer register map type */ -typedef struct timer_bas_reg_map { - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - const uint32 RESERVED1; /**< Reserved */ - __io uint32 DIER; /**< DMA/Interrupt enable register */ - __io uint32 SR; /**< Status register */ - __io uint32 EGR; /**< Event generation register */ - const uint32 RESERVED2; /**< Reserved */ - const uint32 RESERVED3; /**< Reserved */ - const uint32 RESERVED4; /**< Reserved */ - __io uint32 CNT; /**< Counter */ - __io uint32 PSC; /**< Prescaler */ - __io uint32 ARR; /**< Auto-reload register */ -} timer_bas_reg_map; - - -#ifdef STM32F2 - /** Timer 1 register map base pointer */ - #define TIMER1_BASE ((struct timer_adv_reg_map*)0x40010000) -#else - /** Timer 1 register map base pointer */ - #define TIMER1_BASE ((struct timer_adv_reg_map*)0x40012C00) -#endif -/** Timer 2 register map base pointer */ -#define TIMER2_BASE ((struct timer_gen_reg_map*)0x40000000) -/** Timer 3 register map base pointer */ -#define TIMER3_BASE ((struct timer_gen_reg_map*)0x40000400) -/** Timer 4 register map base pointer */ -#define TIMER4_BASE ((struct timer_gen_reg_map*)0x40000800) -#ifdef STM32_HIGH_DENSITY -/** Timer 5 register map base pointer */ -#define TIMER5_BASE ((struct timer_gen_reg_map*)0x40000C00) -/** Timer 6 register map base pointer */ -#define TIMER6_BASE ((struct timer_bas_reg_map*)0x40001000) -/** Timer 7 register map base pointer */ -#define TIMER7_BASE ((struct timer_bas_reg_map*)0x40001400) - -#ifdef STM32F2 - /** Timer 8 register map base pointer */ - #define TIMER8_BASE ((struct timer_adv_reg_map*)0x40010400) -#else - /** Timer 8 register map base pointer */ - #define TIMER8_BASE ((struct timer_adv_reg_map*)0x40013400) -#endif -#endif - -/* - * Timer devices - */ - -/** - * @brief Timer register map type. - * - * Just holds a pointer to the correct type of register map, based on - * the timer's type. - */ -typedef union timer_reg_map { - timer_adv_reg_map *adv; /**< Advanced register map */ - timer_gen_reg_map *gen; /**< General purpose register map */ - timer_bas_reg_map *bas; /**< Basic register map */ -} timer_reg_map; - -/** - * @brief Timer type - * - * Type marker for timer_dev. - * - * @see timer_dev - */ -typedef enum timer_type { - TIMER_ADVANCED, /**< Advanced type */ - TIMER_GENERAL, /**< General purpose type */ - TIMER_BASIC /**< Basic type */ -} timer_type; - -/** Timer device type */ -typedef struct timer_dev { - timer_reg_map regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ - timer_type type; /**< Timer's type */ - voidFuncPtr handlers[]; /**< User IRQ handlers */ -} timer_dev; - -extern timer_dev *TIMER1; -extern timer_dev *TIMER2; -extern timer_dev *TIMER3; -extern timer_dev *TIMER4; -#ifdef STM32_HIGH_DENSITY -extern timer_dev *TIMER5; -extern timer_dev *TIMER6; -extern timer_dev *TIMER7; -extern timer_dev *TIMER8; -#endif - -/* - * Register bit definitions - */ - -/* Control register 1 (CR1) */ - -#define TIMER_CR1_ARPE_BIT 7 -#define TIMER_CR1_DIR_BIT 4 -#define TIMER_CR1_OPM_BIT 3 -#define TIMER_CR1_URS_BIT 2 -#define TIMER_CR1_UDIS_BIT 1 -#define TIMER_CR1_CEN_BIT 0 - -#define TIMER_CR1_CKD (0x3 << 8) -#define TIMER_CR1_CKD_1TCKINT (0x0 << 8) -#define TIMER_CR1_CKD_2TCKINT (0x1 << 8) -#define TIMER_CR1_CKD_4TICKINT (0x2 << 8) -#define TIMER_CR1_ARPE BIT(TIMER_CR1_ARPE_BIT) -#define TIMER_CR1_CKD_CMS (0x3 << 5) -#define TIMER_CR1_CKD_CMS_EDGE (0x0 << 5) -#define TIMER_CR1_CKD_CMS_CENTER1 (0x1 << 5) -#define TIMER_CR1_CKD_CMS_CENTER2 (0x2 << 5) -#define TIMER_CR1_CKD_CMS_CENTER3 (0x3 << 5) -#define TIMER_CR1_DIR BIT(TIMER_CR1_DIR_BIT) -#define TIMER_CR1_OPM BIT(TIMER_CR1_OPM_BIT) -#define TIMER_CR1_URS BIT(TIMER_CR1_URS_BIT) -#define TIMER_CR1_UDIS BIT(TIMER_CR1_UDIS_BIT) -#define TIMER_CR1_CEN BIT(TIMER_CR1_CEN_BIT) - -/* Control register 2 (CR2) */ - -#define TIMER_CR2_OIS4_BIT 14 -#define TIMER_CR2_OIS3N_BIT 13 -#define TIMER_CR2_OIS3_BIT 12 -#define TIMER_CR2_OIS2N_BIT 11 -#define TIMER_CR2_OIS2_BIT 10 -#define TIMER_CR2_OIS1N_BIT 9 -#define TIMER_CR2_OIS1_BIT 8 -#define TIMER_CR2_TI1S_BIT 7 /* tills? yikes */ -#define TIMER_CR2_CCDS_BIT 3 -#define TIMER_CR2_CCUS_BIT 2 -#define TIMER_CR2_CCPC_BIT 0 - -#define TIMER_CR2_OIS4 BIT(TIMER_CR2_OIS4_BIT) -#define TIMER_CR2_OIS3N BIT(TIMER_CR2_OIS3N_BIT) -#define TIMER_CR2_OIS3 BIT(TIMER_CR2_OIS3_BIT) -#define TIMER_CR2_OIS2N BIT(TIMER_CR2_OIS2N_BIT) -#define TIMER_CR2_OIS2 BIT(TIMER_CR2_OIS2_BIT) -#define TIMER_CR2_OIS1N BIT(TIMER_CR2_OIS1N_BIT) -#define TIMER_CR2_OIS1 BIT(TIMER_CR2_OIS1_BIT) -#define TIMER_CR2_TI1S BIT(TIMER_CR2_TI1S_BIT) -#define TIMER_CR2_MMS (0x7 << 4) -#define TIMER_CR2_MMS_RESET (0x0 << 4) -#define TIMER_CR2_MMS_ENABLE (0x1 << 4) -#define TIMER_CR2_MMS_UPDATE (0x2 << 4) -#define TIMER_CR2_MMS_COMPARE_PULSE (0x3 << 4) -#define TIMER_CR2_MMS_COMPARE_OC1REF (0x4 << 4) -#define TIMER_CR2_MMS_COMPARE_OC2REF (0x5 << 4) -#define TIMER_CR2_MMS_COMPARE_OC3REF (0x6 << 4) -#define TIMER_CR2_MMS_COMPARE_OC4REF (0x7 << 4) -#define TIMER_CR2_CCDS BIT(TIMER_CR2_CCDS_BIT) -#define TIMER_CR2_CCUS BIT(TIMER_CR2_CCUS_BIT) -#define TIMER_CR2_CCPC BIT(TIMER_CR2_CCPC_BIT) - -/* Slave mode control register (SMCR) */ - -#define TIMER_SMCR_ETP_BIT 15 -#define TIMER_SMCR_ECE_BIT 14 -#define TIMER_SMCR_MSM_BIT 7 - -#define TIMER_SMCR_ETP BIT(TIMER_SMCR_ETP_BIT) -#define TIMER_SMCR_ECE BIT(TIMER_SMCR_ECE_BIT) -#define TIMER_SMCR_ETPS (0x3 << 12) -#define TIMER_SMCR_ETPS_OFF (0x0 << 12) -#define TIMER_SMCR_ETPS_DIV2 (0x1 << 12) -#define TIMER_SMCR_ETPS_DIV4 (0x2 << 12) -#define TIMER_SMCR_ETPS_DIV8 (0x3 << 12) -#define TIMER_SMCR_ETF (0xF << 12) -#define TIMER_SMCR_MSM BIT(TIMER_SMCR_MSM_BIT) -#define TIMER_SMCR_TS (0x3 << 4) -#define TIMER_SMCR_TS_ITR0 (0x0 << 4) -#define TIMER_SMCR_TS_ITR1 (0x1 << 4) -#define TIMER_SMCR_TS_ITR2 (0x2 << 4) -#define TIMER_SMCR_TS_ITR3 (0x3 << 4) -#define TIMER_SMCR_TS_TI1F_ED (0x4 << 4) -#define TIMER_SMCR_TS_TI1FP1 (0x5 << 4) -#define TIMER_SMCR_TS_TI2FP2 (0x6 << 4) -#define TIMER_SMCR_TS_ETRF (0x7 << 4) -#define TIMER_SMCR_SMS 0x3 -#define TIMER_SMCR_SMS_DISABLED 0x0 -#define TIMER_SMCR_SMS_ENCODER1 0x1 -#define TIMER_SMCR_SMS_ENCODER2 0x2 -#define TIMER_SMCR_SMS_ENCODER3 0x3 -#define TIMER_SMCR_SMS_RESET 0x4 -#define TIMER_SMCR_SMS_GATED 0x5 -#define TIMER_SMCR_SMS_TRIGGER 0x6 -#define TIMER_SMCR_SMS_EXTERNAL 0x7 - -/* DMA/Interrupt enable register (DIER) */ - -#define TIMER_DIER_TDE_BIT 14 -#define TIMER_DIER_CC4DE_BIT 12 -#define TIMER_DIER_CC3DE_BIT 11 -#define TIMER_DIER_CC2DE_BIT 10 -#define TIMER_DIER_CC1DE_BIT 9 -#define TIMER_DIER_UDE_BIT 8 -#define TIMER_DIER_TIE_BIT 6 -#define TIMER_DIER_CC4IE_BIT 4 -#define TIMER_DIER_CC3IE_BIT 3 -#define TIMER_DIER_CC2IE_BIT 2 -#define TIMER_DIER_CC1IE_BIT 1 -#define TIMER_DIER_UIE_BIT 0 - -#define TIMER_DIER_TDE BIT(TIMER_DIER_TDE_BIT) -#define TIMER_DIER_CC4DE BIT(TIMER_DIER_CC4DE_BIT) -#define TIMER_DIER_CC3DE BIT(TIMER_DIER_CC3DE_BIT) -#define TIMER_DIER_CC2DE BIT(TIMER_DIER_CC2DE_BIT) -#define TIMER_DIER_CC1DE BIT(TIMER_DIER_CC1DE_BIT) -#define TIMER_DIER_UDE BIT(TIMER_DIER_UDE_BIT) -#define TIMER_DIER_TIE BIT(TIMER_DIER_TIE_BIT) -#define TIMER_DIER_CC4IE BIT(TIMER_DIER_CC4IE_BIT) -#define TIMER_DIER_CC3IE BIT(TIMER_DIER_CC3IE_BIT) -#define TIMER_DIER_CC2IE BIT(TIMER_DIER_CC2IE_BIT) -#define TIMER_DIER_CC1IE BIT(TIMER_DIER_CC1IE_BIT) -#define TIMER_DIER_UIE BIT(TIMER_DIER_UIE_BIT) - -/* Status register (SR) */ - -#define TIMER_SR_CC4OF_BIT 12 -#define TIMER_SR_CC3OF_BIT 11 -#define TIMER_SR_CC2OF_BIT 10 -#define TIMER_SR_CC1OF_BIT 9 -#define TIMER_SR_BIF_BIT 7 -#define TIMER_SR_TIF_BIT 6 -#define TIMER_SR_COMIF_BIT 5 -#define TIMER_SR_CC4IF_BIT 4 -#define TIMER_SR_CC3IF_BIT 3 -#define TIMER_SR_CC2IF_BIT 2 -#define TIMER_SR_CC1IF_BIT 1 -#define TIMER_SR_UIF_BIT 0 - -#define TIMER_SR_CC4OF BIT(TIMER_SR_CC4OF_BIT) -#define TIMER_SR_CC3OF BIT(TIMER_SR_CC3OF_BIT) -#define TIMER_SR_CC2OF BIT(TIMER_SR_CC2OF_BIT) -#define TIMER_SR_CC1OF BIT(TIMER_SR_CC1OF_BIT) -#define TIMER_SR_BIF BIT(TIMER_SR_BIF_BIT) -#define TIMER_SR_TIF BIT(TIMER_SR_TIF_BIT) -#define TIMER_SR_COMIF BIT(TIMER_SR_COMIF_BIT) -#define TIMER_SR_CC4IF BIT(TIMER_SR_CC4IF_BIT) -#define TIMER_SR_CC3IF BIT(TIMER_SR_CC3IF_BIT) -#define TIMER_SR_CC2IF BIT(TIMER_SR_CC2IF_BIT) -#define TIMER_SR_CC1IF BIT(TIMER_SR_CC1IF_BIT) -#define TIMER_SR_UIF BIT(TIMER_SR_UIF_BIT) - -/* Event generation register (EGR) */ - -#define TIMER_EGR_TG_BIT 6 -#define TIMER_EGR_CC4G_BIT 4 -#define TIMER_EGR_CC3G_BIT 3 -#define TIMER_EGR_CC2G_BIT 2 -#define TIMER_EGR_CC1G_BIT 1 -#define TIMER_EGR_UG_BIT 0 - -#define TIMER_EGR_TG BIT(TIMER_EGR_TG_BIT) -#define TIMER_EGR_CC4G BIT(TIMER_EGR_CC4G_BIT) -#define TIMER_EGR_CC3G BIT(TIMER_EGR_CC3G_BIT) -#define TIMER_EGR_CC2G BIT(TIMER_EGR_CC2G_BIT) -#define TIMER_EGR_CC1G BIT(TIMER_EGR_CC1G_BIT) -#define TIMER_EGR_UG BIT(TIMER_EGR_UG_BIT) - -/* Capture/compare mode registers, common values */ - -#define TIMER_CCMR_CCS_OUTPUT 0x0 -#define TIMER_CCMR_CCS_INPUT_TI1 0x1 -#define TIMER_CCMR_CCS_INPUT_TI2 0x2 -#define TIMER_CCMR_CCS_INPUT_TRC 0x3 - -/* Capture/compare mode register 1 (CCMR1) */ - -#define TIMER_CCMR1_OC2CE_BIT 15 -#define TIMER_CCMR1_OC2PE_BIT 11 -#define TIMER_CCMR1_OC2FE_BIT 10 -#define TIMER_CCMR1_OC1CE_BIT 7 -#define TIMER_CCMR1_OC1PE_BIT 3 -#define TIMER_CCMR1_OC1FE_BIT 2 - -#define TIMER_CCMR1_OC2CE BIT(TIMER_CCMR1_OC2CE_BIT) -#define TIMER_CCMR1_OC2M (0x3 << 12) -#define TIMER_CCMR1_IC2F (0xF << 12) -#define TIMER_CCMR1_OC2PE BIT(TIMER_CCMR1_OC2PE_BIT) -#define TIMER_CCMR1_OC2FE BIT(TIMER_CCMR1_OC2FE_BIT) -#define TIMER_CCMR1_IC2PSC (0x3 << 10) -#define TIMER_CCMR1_CC2S (0x3 << 8) -#define TIMER_CCMR1_CC2S_OUTPUT (TIMER_CCMR_CCS_OUTPUT << 8) -#define TIMER_CCMR1_CC2S_INPUT_TI1 (TIMER_CCMR_CCS_INPUT_TI1 << 8) -#define TIMER_CCMR1_CC2S_INPUT_TI2 (TIMER_CCMR_CCS_INPUT_TI2 << 8) -#define TIMER_CCMR1_CC2S_INPUT_TRC (TIMER_CCMR_CCS_INPUT_TRC << 8) -#define TIMER_CCMR1_OC1CE BIT(TIMER_CCMR1_OC1CE_BIT) -#define TIMER_CCMR1_OC1M (0x3 << 4) -#define TIMER_CCMR1_IC1F (0xF << 4) -#define TIMER_CCMR1_OC1PE BIT(TIMER_CCMR1_OC1PE_BIT) -#define TIMER_CCMR1_OC1FE BIT(TIMER_CCMR1_OC1FE_BIT) -#define TIMER_CCMR1_IC1PSC (0x3 << 2) -#define TIMER_CCMR1_CC1S 0x3 -#define TIMER_CCMR1_CC1S_OUTPUT TIMER_CCMR_CCS_OUTPUT -#define TIMER_CCMR1_CC1S_INPUT_TI1 TIMER_CCMR_CCS_INPUT_TI1 -#define TIMER_CCMR1_CC1S_INPUT_TI2 TIMER_CCMR_CCS_INPUT_TI2 -#define TIMER_CCMR1_CC1S_INPUT_TRC TIMER_CCMR_CCS_INPUT_TRC - -/* Capture/compare mode register 2 (CCMR2) */ - -#define TIMER_CCMR2_OC4CE_BIT 15 -#define TIMER_CCMR2_OC4PE_BIT 11 -#define TIMER_CCMR2_OC4FE_BIT 10 -#define TIMER_CCMR2_OC3CE_BIT 7 -#define TIMER_CCMR2_OC3PE_BIT 3 -#define TIMER_CCMR2_OC3FE_BIT 2 - -#define TIMER_CCMR2_OC4CE BIT(TIMER_CCMR2_OC4CE_BIT) -#define TIMER_CCMR2_OC4M (0x3 << 12) -#define TIMER_CCMR2_IC2F (0xF << 12) -#define TIMER_CCMR2_OC4PE BIT(TIMER_CCMR2_OC4PE_BIT) -#define TIMER_CCMR2_OC4FE BIT(TIMER_CCMR2_OC4FE_BIT) -#define TIMER_CCMR2_IC2PSC (0x3 << 10) -#define TIMER_CCMR2_CC4S (0x3 << 8) -#define TIMER_CCMR1_CC4S_OUTPUT (TIMER_CCMR_CCS_OUTPUT << 8) -#define TIMER_CCMR1_CC4S_INPUT_TI1 (TIMER_CCMR_CCS_INPUT_TI1 << 8) -#define TIMER_CCMR1_CC4S_INPUT_TI2 (TIMER_CCMR_CCS_INPUT_TI2 << 8) -#define TIMER_CCMR1_CC4S_INPUT_TRC (TIMER_CCMR_CCS_INPUT_TRC << 8) -#define TIMER_CCMR2_OC3CE BIT(TIMER_CCMR2_OC3CE_BIT) -#define TIMER_CCMR2_OC3M (0x3 << 4) -#define TIMER_CCMR2_IC1F (0xF << 4) -#define TIMER_CCMR2_OC3PE BIT(TIMER_CCMR2_OC3PE_BIT) -#define TIMER_CCMR2_OC3FE BIT(TIMER_CCMR2_OC3FE_BIT) -#define TIMER_CCMR2_IC1PSC (0x3 << 2) -#define TIMER_CCMR2_CC3S 0x3 -#define TIMER_CCMR1_CC3S_OUTPUT TIMER_CCMR_CCS_OUTPUT -#define TIMER_CCMR1_CC3S_INPUT_TI1 TIMER_CCMR_CCS_INPUT_TI1 -#define TIMER_CCMR1_CC3S_INPUT_TI2 TIMER_CCMR_CCS_INPUT_TI2 -#define TIMER_CCMR1_CC3S_INPUT_TRC TIMER_CCMR_CCS_INPUT_TRC - -/* Capture/compare enable register (CCER) */ - -#define TIMER_CCER_CC4P_BIT 13 -#define TIMER_CCER_CC4E_BIT 12 -#define TIMER_CCER_CC3P_BIT 9 -#define TIMER_CCER_CC3E_BIT 8 -#define TIMER_CCER_CC2P_BIT 5 -#define TIMER_CCER_CC2E_BIT 4 -#define TIMER_CCER_CC1P_BIT 1 -#define TIMER_CCER_CC1E_BIT 0 - -#define TIMER_CCER_CC4P BIT(TIMER_CCER_CC4P_BIT) -#define TIMER_CCER_CC4E BIT(TIMER_CCER_CC4E_BIT) -#define TIMER_CCER_CC3P BIT(TIMER_CCER_CC3P_BIT) -#define TIMER_CCER_CC3E BIT(TIMER_CCER_CC3E_BIT) -#define TIMER_CCER_CC2P BIT(TIMER_CCER_CC2P_BIT) -#define TIMER_CCER_CC2E BIT(TIMER_CCER_CC2E_BIT) -#define TIMER_CCER_CC1P BIT(TIMER_CCER_CC1P_BIT) -#define TIMER_CCER_CC1E BIT(TIMER_CCER_CC1E_BIT) - -/* Break and dead-time register (BDTR) */ - -#define TIMER_BDTR_MOE_BIT 15 -#define TIMER_BDTR_AOE_BIT 14 -#define TIMER_BDTR_BKP_BIT 13 -#define TIMER_BDTR_BKE_BIT 12 -#define TIMER_BDTR_OSSR_BIT 11 -#define TIMER_BDTR_OSSI_BIT 10 - -#define TIMER_BDTR_MOE BIT(TIMER_BDTR_MOE_BIT) -#define TIMER_BDTR_AOE BIT(TIMER_BDTR_AOE_BIT) -#define TIMER_BDTR_BKP BIT(TIMER_BDTR_BKP_BIT) -#define TIMER_BDTR_BKE BIT(TIMER_BDTR_BKE_BIT) -#define TIMER_BDTR_OSSR BIT(TIMER_BDTR_OSSR_BIT) -#define TIMER_BDTR_OSSI BIT(TIMER_BDTR_OSSI_BIT) -#define TIMER_BDTR_LOCK (0x3 << 8) -#define TIMER_BDTR_LOCK_OFF (0x0 << 8) -#define TIMER_BDTR_LOCK_LEVEL1 (0x1 << 8) -#define TIMER_BDTR_LOCK_LEVEL2 (0x2 << 8) -#define TIMER_BDTR_LOCK_LEVEL3 (0x3 << 8) -#define TIMER_BDTR_DTG 0xFF - -/* DMA control register (DCR) */ - -#define TIMER_DCR_DBL (0x1F << 8) -#define TIMER_DCR_DBL_1BYTE (0x0 << 8) -#define TIMER_DCR_DBL_2BYTE (0x1 << 8) -#define TIMER_DCR_DBL_3BYTE (0x2 << 8) -#define TIMER_DCR_DBL_4BYTE (0x3 << 8) -#define TIMER_DCR_DBL_5BYTE (0x4 << 8) -#define TIMER_DCR_DBL_6BYTE (0x5 << 8) -#define TIMER_DCR_DBL_7BYTE (0x6 << 8) -#define TIMER_DCR_DBL_8BYTE (0x7 << 8) -#define TIMER_DCR_DBL_9BYTE (0x8 << 8) -#define TIMER_DCR_DBL_10BYTE (0x9 << 8) -#define TIMER_DCR_DBL_11BYTE (0xA << 8) -#define TIMER_DCR_DBL_12BYTE (0xB << 8) -#define TIMER_DCR_DBL_13BYTE (0xC << 8) -#define TIMER_DCR_DBL_14BYTE (0xD << 8) -#define TIMER_DCR_DBL_15BYTE (0xE << 8) -#define TIMER_DCR_DBL_16BYTE (0xF << 8) -#define TIMER_DCR_DBL_17BYTE (0x10 << 8) -#define TIMER_DCR_DBL_18BYTE (0x11 << 8) -#define TIMER_DCR_DBA 0x1F -#define TIMER_DCR_DBA_CR1 0x0 -#define TIMER_DCR_DBA_CR2 0x1 -#define TIMER_DCR_DBA_SMCR 0x2 -#define TIMER_DCR_DBA_DIER 0x3 -#define TIMER_DCR_DBA_SR 0x4 -#define TIMER_DCR_DBA_EGR 0x5 -#define TIMER_DCR_DBA_CCMR1 0x6 -#define TIMER_DCR_DBA_CCMR2 0x7 -#define TIMER_DCR_DBA_CCER 0x8 -#define TIMER_DCR_DBA_CNT 0x9 -#define TIMER_DCR_DBA_PSC 0xA -#define TIMER_DCR_DBA_ARR 0xB -#define TIMER_DCR_DBA_RCR 0xC -#define TIMER_DCR_DBA_CCR1 0xD -#define TIMER_DCR_DBA_CCR2 0xE -#define TIMER_DCR_DBA_CCR3 0xF -#define TIMER_DCR_DBA_CCR4 0x10 -#define TIMER_DCR_DBA_BDTR 0x11 -#define TIMER_DCR_DBA_DCR 0x12 -#define TIMER_DCR_DBA_DMAR 0x13 - -/* - * Convenience routines - */ - -/** - * Used to configure the behavior of a timer channel. Note that not - * all timers can be configured in every mode. - */ -/* TODO TIMER_PWM_CENTER_ALIGNED, TIMER_INPUT_CAPTURE, TIMER_ONE_PULSE */ -typedef enum timer_mode { - TIMER_DISABLED, /**< In this mode, the timer stops counting, - channel interrupts are detached, and no state - changes are output. */ - TIMER_PWM, /**< PWM output mode. This is the default mode for pins - after initialization. */ - /* TIMER_PWM_CENTER_ALIGNED, /\**< Center-aligned PWM output mode. *\/ */ - TIMER_OUTPUT_COMPARE, /**< In this mode, the timer counts from 0 - to its reload value repeatedly; every - time the counter value reaches one of - the channel compare values, the - corresponding interrupt is fired. */ - /* TIMER_INPUT_CAPTURE, /\**< In this mode, the timer can measure the */ - /* pulse lengths of input signals. *\/ */ - /* TIMER_ONE_PULSE /\**< In this mode, the timer can generate a single */ - /* pulse on a GPIO pin for a specified amount of */ - /* time. *\/ */ -} timer_mode; - -/** Timer channel numbers */ -typedef enum timer_channel { - TIMER_CH1 = 1, /**< Channel 1 */ - TIMER_CH2 = 2, /**< Channel 2 */ - TIMER_CH3 = 3, /**< Channel 3 */ - TIMER_CH4 = 4 /**< Channel 4 */ -} timer_channel; - -/* - * Note: Don't require timer_channel arguments! We want to be able to say - * - * for (int channel = 1; channel <= 4; channel++) { - * ... - * } - * - * without the compiler yelling at us. - */ - -void timer_init(timer_dev *dev); -void timer_disable(timer_dev *dev); -void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode); -void timer_foreach(void (*fn)(timer_dev*)); - -/** - * @brief Timer interrupt number. - * - * Not all timers support all of these values; see the descriptions - * for each value. - */ -typedef enum timer_interrupt_id { - TIMER_UPDATE_INTERRUPT, /**< Update interrupt, available on all timers. */ - TIMER_CC1_INTERRUPT, /**< Capture/compare 1 interrupt, available - on general and advanced timers only. */ - TIMER_CC2_INTERRUPT, /**< Capture/compare 2 interrupt, general and - advanced timers only. */ - TIMER_CC3_INTERRUPT, /**< Capture/compare 3 interrupt, general and - advanced timers only. */ - TIMER_CC4_INTERRUPT, /**< Capture/compare 4 interrupt, general and - advanced timers only. */ - TIMER_COM_INTERRUPT, /**< COM interrupt, advanced timers only */ - TIMER_TRG_INTERRUPT, /**< Trigger interrupt, general and advanced - timers only */ - TIMER_BREAK_INTERRUPT /**< Break interrupt, advanced timers only. */ -} timer_interrupt_id; - -void timer_attach_interrupt(timer_dev *dev, - uint8 interrupt, - voidFuncPtr handler); -void timer_detach_interrupt(timer_dev *dev, uint8 interrupt); - -/** - * Initialize all timer devices on the chip. - */ -static inline void timer_init_all(void) { - timer_foreach(timer_init); -} - -/** - * Disables all timers on the device. - */ -static inline void timer_disable_all(void) { - timer_foreach(timer_disable); -} - -/** - * @brief Stop a timer's counter from changing. - * - * Does not affect the timer's mode or other settings. - * - * @param dev Device whose counter to pause. - */ -static inline void timer_pause(timer_dev *dev) { - *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 0; -} - -/** - * @brief Start a timer's counter. - * - * Does not affect the timer's mode or other settings. - * - * @param dev Device whose counter to resume - */ -static inline void timer_resume(timer_dev *dev) { - *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 1; -} - -/** - * @brief Returns the timer's counter value. - * - * This value is likely to be inaccurate if the counter is running - * with a low prescaler. - * - * @param dev Timer whose counter to return - */ -static inline uint16 timer_get_count(timer_dev *dev) { - return (uint16)(dev->regs).bas->CNT; -} - -/** - * @brief Sets the counter value for the given timer. - * @param dev Timer whose counter to set - * @param value New counter value - */ -static inline void timer_set_count(timer_dev *dev, uint16 value) { - (dev->regs).bas->CNT = value; -} - -/** - * @brief Returns the given timer's prescaler. - * - * Note that if the timer's prescaler is set (e.g. via - * timer_set_prescaler() or accessing a TIMx_PSC register), the value - * returned by this function will reflect the new setting, but the - * timer's counter will only reflect the new prescaler at the next - * update event. - * - * @param dev Timer whose prescaler to return - * @see timer_generate_update() - */ -static inline uint16 timer_get_prescaler(timer_dev *dev) { - return (uint16)(dev->regs).bas->PSC; -} - -/** - * @brief Set a timer's prescale value. - * - * Divides the input clock by (PSC+1). The new value will not take - * effect until the next update event. - * - * @param dev Timer whose prescaler to set - * @param psc New prescaler value - * @see timer_generate_update() - */ -static inline void timer_set_prescaler(timer_dev *dev, uint16 psc) { - (dev->regs).bas->PSC = psc; -} - -/** - * @brief Returns a timer's reload value. - * @param dev Timer whose reload value to return - */ -static inline uint16 timer_get_reload(timer_dev *dev) { - return (uint16)(dev->regs).bas->ARR; -} - -/** - * @brief Set a timer's reload value. - * @param dev Timer whose reload value to set - * @param arr New reload value to use. Takes effect at next update event. - * @see timer_generate_update() - */ -static inline void timer_set_reload(timer_dev *dev, uint16 arr) { - (dev->regs).bas->ARR = arr; -} - -/** - * @brief Get the compare value for the given timer channel. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel whose compare value to get. - */ -static inline uint16 timer_get_compare(timer_dev *dev, uint8 channel) { - __io uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); - return *ccr; -} - -/** - * @brief Set the compare value for the given timer channel. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel whose compare value to set. - * @param value New compare value. - */ -static inline void timer_set_compare(timer_dev *dev, - uint8 channel, - uint16 value) { - __io uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); - *ccr = value; -} - -/** - * @brief Generate an update event for the given timer. - * - * Normally, this will cause the prescaler and auto-reload values in - * the PSC and ARR registers to take immediate effect. However, this - * function will do nothing if the UDIS bit is set in the timer's CR1 - * register (UDIS is cleared by default). - * - * @param dev Timer device to generate an update for. - */ -static inline void timer_generate_update(timer_dev *dev) { - *bb_perip(&(dev->regs).bas->EGR, TIMER_EGR_UG_BIT) = 1; -} - -/** - * @brief Enable a timer's trigger DMA request - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL - */ -static inline void timer_dma_enable_trg_req(timer_dev *dev) { - *bb_perip(&(dev->regs).gen->DIER, TIMER_DIER_TDE_BIT) = 1; -} - -/** - * @brief Disable a timer's trigger DMA request - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL - */ -static inline void timer_dma_disable_trg_req(timer_dev *dev) { - *bb_perip(&(dev->regs).gen->DIER, TIMER_DIER_TDE_BIT) = 0; -} - -/** - * @brief Enable a timer channel's DMA request. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL - * @param channel Channel whose DMA request to enable. - */ -static inline void timer_dma_enable_req(timer_dev *dev, uint8 channel) { - *bb_perip(&(dev->regs).gen->DIER, channel + 8) = 1; -} - -/** - * @brief Disable a timer channel's DMA request. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel whose DMA request to disable. - */ -static inline void timer_dma_disable_req(timer_dev *dev, uint8 channel) { - *bb_perip(&(dev->regs).gen->DIER, channel + 8) = 0; -} - -/** - * @brief Enable a timer interrupt. - * @param dev Timer device. - * @param interrupt Interrupt number to enable; this may be any - * timer_interrupt_id value appropriate for the timer. - * @see timer_interrupt_id - * @see timer_channel - */ -static inline void timer_enable_irq(timer_dev *dev, uint8 interrupt) { - *bb_perip(&(dev->regs).adv->DIER, interrupt) = 1; -} - -/** - * @brief Disable a timer interrupt. - * @param dev Timer device. - * @param interrupt Interrupt number to disable; this may be any - * timer_interrupt_id value appropriate for the timer. - * @see timer_interrupt_id - * @see timer_channel - */ -static inline void timer_disable_irq(timer_dev *dev, uint8 interrupt) { - *bb_perip(&(dev->regs).adv->DIER, interrupt) = 0; -} - -/** - * @brief Enable a timer channel's capture/compare signal. - * - * If the channel is configured as output, the corresponding output - * compare signal will be output on the corresponding output pin. If - * the channel is configured as input, enables capture of the counter - * value into the input capture/compare register. - * - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel to enable, from 1 to 4. - */ -static inline void timer_cc_enable(timer_dev *dev, uint8 channel) { - *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1)) = 1; -} - -/** - * @brief Disable a timer channel's output compare or input capture signal. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel to disable, from 1 to 4. - * @see timer_cc_enable() - */ -static inline void timer_cc_disable(timer_dev *dev, uint8 channel) { - *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1)) = 0; -} - -/** - * @brief Get a channel's capture/compare output polarity - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel whose capture/compare output polarity to get. - * @return Polarity, either 0 or 1. - * @see timer_cc_set_polarity() - */ -static inline uint8 timer_cc_get_pol(timer_dev *dev, uint8 channel) { - return *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1) + 1); -} - -/** - * @brief Set a timer channel's capture/compare output polarity. - * - * If the timer channel is configured as output: polarity == 0 means - * the output channel will be active high; polarity == 1 means active - * low. - * - * If the timer channel is configured as input: polarity == 0 means - * capture is done on the rising edge of ICn; when used as an external - * trigger, ICn is non-inverted. polarity == 1 means capture is done - * on the falling edge of ICn; when used as an external trigger, ICn - * is inverted. - * - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel whose capture/compare output polarity to set. - * @param pol New polarity, 0 or 1. - */ -static inline void timer_cc_set_pol(timer_dev *dev, uint8 channel, uint8 pol) { - *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1) + 1) = pol; -} - -/** - * @brief Get a timer's DMA burst length. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @return Number of bytes to be transferred per DMA request, from 1 to 18. - */ -static inline uint8 timer_dma_get_burst_len(timer_dev *dev) { - uint32 dbl = ((dev->regs).gen->DCR & TIMER_DCR_DBL) >> 8; - return dbl + 1; /* 0 means 1 byte, etc. */ -} - -/** - * @brief Set a timer's DMA burst length. - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param length DMA burst length; i.e., number of bytes to transfer - * per DMA request, from 1 to 18. - */ -static inline void timer_dma_set_burst_len(timer_dev *dev, uint8 length) { - uint32 tmp = (dev->regs).gen->DCR; - tmp &= ~TIMER_DCR_DBL; - tmp |= (length - 1) << 8; - (dev->regs).gen->DCR = tmp; -} - -/** - * @brief Timer DMA base address. - * - * Defines the base address for DMA transfers. - */ -typedef enum timer_dma_base_addr { - TIMER_DMA_BASE_CR1 = TIMER_DCR_DBA_CR1, /**< Base is control register 1 */ - TIMER_DMA_BASE_CR2 = TIMER_DCR_DBA_CR2, /**< Base is control register 2 */ - TIMER_DMA_BASE_SMCR = TIMER_DCR_DBA_SMCR, /**< Base is slave mode - control register */ - TIMER_DMA_BASE_DIER = TIMER_DCR_DBA_DIER, /**< Base is DMA interrupt enable - register */ - TIMER_DMA_BASE_SR = TIMER_DCR_DBA_SR, /**< Base is status register */ - TIMER_DMA_BASE_EGR = TIMER_DCR_DBA_EGR, /**< Base is event generation - register */ - TIMER_DMA_BASE_CCMR1 = TIMER_DCR_DBA_CCMR1, /**< Base is capture/compare - mode register 1 */ - TIMER_DMA_BASE_CCMR2 = TIMER_DCR_DBA_CCMR2, /**< Base is capture/compare - mode register 2 */ - TIMER_DMA_BASE_CCER = TIMER_DCR_DBA_CCER, /**< Base is capture/compare - enable register */ - TIMER_DMA_BASE_CNT = TIMER_DCR_DBA_CNT, /**< Base is counter */ - TIMER_DMA_BASE_PSC = TIMER_DCR_DBA_PSC, /**< Base is prescaler */ - TIMER_DMA_BASE_ARR = TIMER_DCR_DBA_ARR, /**< Base is auto-reload - register */ - TIMER_DMA_BASE_RCR = TIMER_DCR_DBA_RCR, /**< Base is repetition - counter register */ - TIMER_DMA_BASE_CCR1 = TIMER_DCR_DBA_CCR1, /**< Base is capture/compare - register 1 */ - TIMER_DMA_BASE_CCR2 = TIMER_DCR_DBA_CCR2, /**< Base is capture/compare - register 2 */ - TIMER_DMA_BASE_CCR3 = TIMER_DCR_DBA_CCR3, /**< Base is capture/compare - register 3 */ - TIMER_DMA_BASE_CCR4 = TIMER_DCR_DBA_CCR4, /**< Base is capture/compare - register 4 */ - TIMER_DMA_BASE_BDTR = TIMER_DCR_DBA_BDTR, /**< Base is break and - dead-time register */ - TIMER_DMA_BASE_DCR = TIMER_DCR_DBA_DCR, /**< Base is DMA control - register */ - TIMER_DMA_BASE_DMAR = TIMER_DCR_DBA_DMAR /**< Base is DMA address for - full transfer */ -} timer_dma_base_addr; - -/** - * @brief Get the timer's DMA base address. - * - * Some restrictions apply; see ST RM0008. - * - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @return DMA base address - */ -static inline timer_dma_base_addr timer_dma_get_base_addr(timer_dev *dev) { - uint32 dcr = (dev->regs).gen->DCR; - return (timer_dma_base_addr)(dcr & TIMER_DCR_DBA); -} - -/** - * @brief Set the timer's DMA base address. - * - * Some restrictions apply; see ST RM0008. - * - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param dma_base DMA base address. - */ -static inline void timer_dma_set_base_addr(timer_dev *dev, - timer_dma_base_addr dma_base) { - uint32 tmp = (dev->regs).gen->DCR; - tmp &= ~TIMER_DCR_DBA; - tmp |= dma_base; - (dev->regs).gen->DCR = tmp; -} - -/** - * Timer output compare modes. - */ -typedef enum timer_oc_mode { - TIMER_OC_MODE_FROZEN = 0 << 4, /**< Frozen: comparison between output - compare register and counter has no - effect on the outputs. */ - TIMER_OC_MODE_ACTIVE_ON_MATCH = 1 << 4, /**< OCxREF signal is forced - high when the count matches - the channel capture/compare - register. */ - TIMER_OC_MODE_INACTIVE_ON_MATCH = 2 << 4, /**< OCxREF signal is forced - low when the counter matches - the channel capture/compare - register. */ - TIMER_OC_MODE_TOGGLE = 3 << 4, /**< OCxREF toggles when counter - matches the cannel capture/compare - register. */ - TIMER_OC_MODE_FORCE_INACTIVE = 4 << 4, /**< OCxREF is forced low. */ - TIMER_OC_MODE_FORCE_ACTIVE = 5 << 4, /**< OCxREF is forced high. */ - TIMER_OC_MODE_PWM_1 = 6 << 4, /**< PWM mode 1. In upcounting, channel is - active as long as count is less than - channel capture/compare register, else - inactive. In downcounting, channel is - inactive as long as count exceeds - capture/compare register, else - active. */ - TIMER_OC_MODE_PWM_2 = 7 << 4 /**< PWM mode 2. In upcounting, channel is - inactive as long as count is less than - capture/compare register, else active. - In downcounting, channel is active as - long as count exceeds capture/compare - register, else inactive. */ -} timer_oc_mode; - -/** - * Timer output compare mode flags. - * @see timer_oc_set_mode() - */ -typedef enum timer_oc_mode_flags { - TIMER_OC_CE = BIT(7), /**< Output compare clear enable. */ - TIMER_OC_PE = BIT(3), /**< Output compare preload enable. */ - TIMER_OC_FE = BIT(2) /**< Output compare fast enable. */ -} timer_oc_mode_flags; - -/** - * @brief Configure a channel's output compare mode. - * - * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. - * @param channel Channel to configure in output compare mode. - * @param mode Timer mode to set. - * @param flags OR of timer_oc_mode_flags. - * @see timer_oc_mode - * @see timer_oc_mode_flags - */ -static inline void timer_oc_set_mode(timer_dev *dev, - uint8 channel, - timer_oc_mode mode, - uint8 flags) { - uint8 bit0 = channel & 1; - //uint8 bit1 = (channel >> 1) & 1; // original - uint8 bit1 = ((channel-1) >> 1) & 1; // fixed - /* channel == 1,2 -> CCMR1; channel == 3,4 -> CCMR2 */ - __io uint32 *ccmr = &(dev->regs).gen->CCMR1 + bit1; - /* channel == 1,3 -> shift = 0, channel == 2,4 -> shift = 8 */ - uint8 shift = 8 * (1 - bit0); - - uint32 tmp = *ccmr; - tmp &= ~(0xFF << shift); - tmp |= (mode | flags | TIMER_CCMR_CCS_OUTPUT) << shift; - *ccmr = tmp; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file timer.h + * @author Marti Bolivar + * @brief New-style timer interface. + * + * Replaces old timers.h implementation. + */ + +#ifndef _TIMERS_H_ +#define _TIMERS_H_ + +#include "libmaple.h" +#include "rcc.h" +#include "nvic.h" +#include "bitband.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * Register maps and devices + */ + +/** Advanced control timer register map type */ +typedef struct timer_adv_reg_map { + __io uint32 CR1; /**< Control register 1 */ + __io uint32 CR2; /**< Control register 2 */ + __io uint32 SMCR; /**< Slave mode control register */ + __io uint32 DIER; /**< DMA/Interrupt enable register */ + __io uint32 SR; /**< Status register */ + __io uint32 EGR; /**< Event generation register */ + __io uint32 CCMR1; /**< Capture/compare mode register 1 */ + __io uint32 CCMR2; /**< Capture/compare mode register 2 */ + __io uint32 CCER; /**< Capture/compare enable register */ + __io uint32 CNT; /**< Counter */ + __io uint32 PSC; /**< Prescaler */ + __io uint32 ARR; /**< Auto-reload register */ + __io uint32 RCR; /**< Repetition counter register */ + __io uint32 CCR1; /**< Capture/compare register 1 */ + __io uint32 CCR2; /**< Capture/compare register 2 */ + __io uint32 CCR3; /**< Capture/compare register 3 */ + __io uint32 CCR4; /**< Capture/compare register 4 */ + __io uint32 BDTR; /**< Break and dead-time register */ + __io uint32 DCR; /**< DMA control register */ + __io uint32 DMAR; /**< DMA address for full transfer */ +} timer_adv_reg_map; + +/** General purpose timer register map type */ +typedef struct timer_gen_reg_map { + __io uint32 CR1; /**< Control register 1 */ + __io uint32 CR2; /**< Control register 2 */ + __io uint32 SMCR; /**< Slave mode control register */ + __io uint32 DIER; /**< DMA/Interrupt enable register */ + __io uint32 SR; /**< Status register */ + __io uint32 EGR; /**< Event generation register */ + __io uint32 CCMR1; /**< Capture/compare mode register 1 */ + __io uint32 CCMR2; /**< Capture/compare mode register 2 */ + __io uint32 CCER; /**< Capture/compare enable register */ + __io uint32 CNT; /**< Counter */ + __io uint32 PSC; /**< Prescaler */ + __io uint32 ARR; /**< Auto-reload register */ + const uint32 RESERVED1; /**< Reserved */ + __io uint32 CCR1; /**< Capture/compare register 1 */ + __io uint32 CCR2; /**< Capture/compare register 2 */ + __io uint32 CCR3; /**< Capture/compare register 3 */ + __io uint32 CCR4; /**< Capture/compare register 4 */ + const uint32 RESERVED2; /**< Reserved */ + __io uint32 DCR; /**< DMA control register */ + __io uint32 DMAR; /**< DMA address for full transfer */ +} timer_gen_reg_map; + +/** Basic timer register map type */ +typedef struct timer_bas_reg_map { + __io uint32 CR1; /**< Control register 1 */ + __io uint32 CR2; /**< Control register 2 */ + const uint32 RESERVED1; /**< Reserved */ + __io uint32 DIER; /**< DMA/Interrupt enable register */ + __io uint32 SR; /**< Status register */ + __io uint32 EGR; /**< Event generation register */ + const uint32 RESERVED2; /**< Reserved */ + const uint32 RESERVED3; /**< Reserved */ + const uint32 RESERVED4; /**< Reserved */ + __io uint32 CNT; /**< Counter */ + __io uint32 PSC; /**< Prescaler */ + __io uint32 ARR; /**< Auto-reload register */ +} timer_bas_reg_map; + + +#ifdef STM32F2 + /** Timer 1 register map base pointer */ + #define TIMER1_BASE ((struct timer_adv_reg_map*)0x40010000) +#else + /** Timer 1 register map base pointer */ + #define TIMER1_BASE ((struct timer_adv_reg_map*)0x40012C00) +#endif +/** Timer 2 register map base pointer */ +#define TIMER2_BASE ((struct timer_gen_reg_map*)0x40000000) +/** Timer 3 register map base pointer */ +#define TIMER3_BASE ((struct timer_gen_reg_map*)0x40000400) +/** Timer 4 register map base pointer */ +#define TIMER4_BASE ((struct timer_gen_reg_map*)0x40000800) +#ifdef STM32_HIGH_DENSITY +/** Timer 5 register map base pointer */ +#define TIMER5_BASE ((struct timer_gen_reg_map*)0x40000C00) +/** Timer 6 register map base pointer */ +#define TIMER6_BASE ((struct timer_bas_reg_map*)0x40001000) +/** Timer 7 register map base pointer */ +#define TIMER7_BASE ((struct timer_bas_reg_map*)0x40001400) + +#ifdef STM32F2 + /** Timer 8 register map base pointer */ + #define TIMER8_BASE ((struct timer_adv_reg_map*)0x40010400) +#else + /** Timer 8 register map base pointer */ + #define TIMER8_BASE ((struct timer_adv_reg_map*)0x40013400) +#endif +#endif + +/* + * Timer devices + */ + +/** + * @brief Timer register map type. + * + * Just holds a pointer to the correct type of register map, based on + * the timer's type. + */ +typedef union timer_reg_map { + timer_adv_reg_map *adv; /**< Advanced register map */ + timer_gen_reg_map *gen; /**< General purpose register map */ + timer_bas_reg_map *bas; /**< Basic register map */ +} timer_reg_map; + +/** + * @brief Timer type + * + * Type marker for timer_dev. + * + * @see timer_dev + */ +typedef enum timer_type { + TIMER_ADVANCED, /**< Advanced type */ + TIMER_GENERAL, /**< General purpose type */ + TIMER_BASIC /**< Basic type */ +} timer_type; + +/** Timer device type */ +typedef struct timer_dev { + timer_reg_map regs; /**< Register map */ + rcc_clk_id clk_id; /**< RCC clock information */ + timer_type type; /**< Timer's type */ + voidFuncPtr handlers[]; /**< User IRQ handlers */ +} timer_dev; + +extern timer_dev *TIMER1; +extern timer_dev *TIMER2; +extern timer_dev *TIMER3; +extern timer_dev *TIMER4; +#ifdef STM32_HIGH_DENSITY +extern timer_dev *TIMER5; +extern timer_dev *TIMER6; +extern timer_dev *TIMER7; +extern timer_dev *TIMER8; +#endif + +/* + * Register bit definitions + */ + +/* Control register 1 (CR1) */ + +#define TIMER_CR1_ARPE_BIT 7 +#define TIMER_CR1_DIR_BIT 4 +#define TIMER_CR1_OPM_BIT 3 +#define TIMER_CR1_URS_BIT 2 +#define TIMER_CR1_UDIS_BIT 1 +#define TIMER_CR1_CEN_BIT 0 + +#define TIMER_CR1_CKD (0x3 << 8) +#define TIMER_CR1_CKD_1TCKINT (0x0 << 8) +#define TIMER_CR1_CKD_2TCKINT (0x1 << 8) +#define TIMER_CR1_CKD_4TICKINT (0x2 << 8) +#define TIMER_CR1_ARPE BIT(TIMER_CR1_ARPE_BIT) +#define TIMER_CR1_CKD_CMS (0x3 << 5) +#define TIMER_CR1_CKD_CMS_EDGE (0x0 << 5) +#define TIMER_CR1_CKD_CMS_CENTER1 (0x1 << 5) +#define TIMER_CR1_CKD_CMS_CENTER2 (0x2 << 5) +#define TIMER_CR1_CKD_CMS_CENTER3 (0x3 << 5) +#define TIMER_CR1_DIR BIT(TIMER_CR1_DIR_BIT) +#define TIMER_CR1_OPM BIT(TIMER_CR1_OPM_BIT) +#define TIMER_CR1_URS BIT(TIMER_CR1_URS_BIT) +#define TIMER_CR1_UDIS BIT(TIMER_CR1_UDIS_BIT) +#define TIMER_CR1_CEN BIT(TIMER_CR1_CEN_BIT) + +/* Control register 2 (CR2) */ + +#define TIMER_CR2_OIS4_BIT 14 +#define TIMER_CR2_OIS3N_BIT 13 +#define TIMER_CR2_OIS3_BIT 12 +#define TIMER_CR2_OIS2N_BIT 11 +#define TIMER_CR2_OIS2_BIT 10 +#define TIMER_CR2_OIS1N_BIT 9 +#define TIMER_CR2_OIS1_BIT 8 +#define TIMER_CR2_TI1S_BIT 7 /* tills? yikes */ +#define TIMER_CR2_CCDS_BIT 3 +#define TIMER_CR2_CCUS_BIT 2 +#define TIMER_CR2_CCPC_BIT 0 + +#define TIMER_CR2_OIS4 BIT(TIMER_CR2_OIS4_BIT) +#define TIMER_CR2_OIS3N BIT(TIMER_CR2_OIS3N_BIT) +#define TIMER_CR2_OIS3 BIT(TIMER_CR2_OIS3_BIT) +#define TIMER_CR2_OIS2N BIT(TIMER_CR2_OIS2N_BIT) +#define TIMER_CR2_OIS2 BIT(TIMER_CR2_OIS2_BIT) +#define TIMER_CR2_OIS1N BIT(TIMER_CR2_OIS1N_BIT) +#define TIMER_CR2_OIS1 BIT(TIMER_CR2_OIS1_BIT) +#define TIMER_CR2_TI1S BIT(TIMER_CR2_TI1S_BIT) +#define TIMER_CR2_MMS (0x7 << 4) +#define TIMER_CR2_MMS_RESET (0x0 << 4) +#define TIMER_CR2_MMS_ENABLE (0x1 << 4) +#define TIMER_CR2_MMS_UPDATE (0x2 << 4) +#define TIMER_CR2_MMS_COMPARE_PULSE (0x3 << 4) +#define TIMER_CR2_MMS_COMPARE_OC1REF (0x4 << 4) +#define TIMER_CR2_MMS_COMPARE_OC2REF (0x5 << 4) +#define TIMER_CR2_MMS_COMPARE_OC3REF (0x6 << 4) +#define TIMER_CR2_MMS_COMPARE_OC4REF (0x7 << 4) +#define TIMER_CR2_CCDS BIT(TIMER_CR2_CCDS_BIT) +#define TIMER_CR2_CCUS BIT(TIMER_CR2_CCUS_BIT) +#define TIMER_CR2_CCPC BIT(TIMER_CR2_CCPC_BIT) + +/* Slave mode control register (SMCR) */ + +#define TIMER_SMCR_ETP_BIT 15 +#define TIMER_SMCR_ECE_BIT 14 +#define TIMER_SMCR_MSM_BIT 7 + +#define TIMER_SMCR_ETP BIT(TIMER_SMCR_ETP_BIT) +#define TIMER_SMCR_ECE BIT(TIMER_SMCR_ECE_BIT) +#define TIMER_SMCR_ETPS (0x3 << 12) +#define TIMER_SMCR_ETPS_OFF (0x0 << 12) +#define TIMER_SMCR_ETPS_DIV2 (0x1 << 12) +#define TIMER_SMCR_ETPS_DIV4 (0x2 << 12) +#define TIMER_SMCR_ETPS_DIV8 (0x3 << 12) +#define TIMER_SMCR_ETF (0xF << 12) +#define TIMER_SMCR_MSM BIT(TIMER_SMCR_MSM_BIT) +#define TIMER_SMCR_TS (0x3 << 4) +#define TIMER_SMCR_TS_ITR0 (0x0 << 4) +#define TIMER_SMCR_TS_ITR1 (0x1 << 4) +#define TIMER_SMCR_TS_ITR2 (0x2 << 4) +#define TIMER_SMCR_TS_ITR3 (0x3 << 4) +#define TIMER_SMCR_TS_TI1F_ED (0x4 << 4) +#define TIMER_SMCR_TS_TI1FP1 (0x5 << 4) +#define TIMER_SMCR_TS_TI2FP2 (0x6 << 4) +#define TIMER_SMCR_TS_ETRF (0x7 << 4) +#define TIMER_SMCR_SMS 0x3 +#define TIMER_SMCR_SMS_DISABLED 0x0 +#define TIMER_SMCR_SMS_ENCODER1 0x1 +#define TIMER_SMCR_SMS_ENCODER2 0x2 +#define TIMER_SMCR_SMS_ENCODER3 0x3 +#define TIMER_SMCR_SMS_RESET 0x4 +#define TIMER_SMCR_SMS_GATED 0x5 +#define TIMER_SMCR_SMS_TRIGGER 0x6 +#define TIMER_SMCR_SMS_EXTERNAL 0x7 + +/* DMA/Interrupt enable register (DIER) */ + +#define TIMER_DIER_TDE_BIT 14 +#define TIMER_DIER_CC4DE_BIT 12 +#define TIMER_DIER_CC3DE_BIT 11 +#define TIMER_DIER_CC2DE_BIT 10 +#define TIMER_DIER_CC1DE_BIT 9 +#define TIMER_DIER_UDE_BIT 8 +#define TIMER_DIER_TIE_BIT 6 +#define TIMER_DIER_CC4IE_BIT 4 +#define TIMER_DIER_CC3IE_BIT 3 +#define TIMER_DIER_CC2IE_BIT 2 +#define TIMER_DIER_CC1IE_BIT 1 +#define TIMER_DIER_UIE_BIT 0 + +#define TIMER_DIER_TDE BIT(TIMER_DIER_TDE_BIT) +#define TIMER_DIER_CC4DE BIT(TIMER_DIER_CC4DE_BIT) +#define TIMER_DIER_CC3DE BIT(TIMER_DIER_CC3DE_BIT) +#define TIMER_DIER_CC2DE BIT(TIMER_DIER_CC2DE_BIT) +#define TIMER_DIER_CC1DE BIT(TIMER_DIER_CC1DE_BIT) +#define TIMER_DIER_UDE BIT(TIMER_DIER_UDE_BIT) +#define TIMER_DIER_TIE BIT(TIMER_DIER_TIE_BIT) +#define TIMER_DIER_CC4IE BIT(TIMER_DIER_CC4IE_BIT) +#define TIMER_DIER_CC3IE BIT(TIMER_DIER_CC3IE_BIT) +#define TIMER_DIER_CC2IE BIT(TIMER_DIER_CC2IE_BIT) +#define TIMER_DIER_CC1IE BIT(TIMER_DIER_CC1IE_BIT) +#define TIMER_DIER_UIE BIT(TIMER_DIER_UIE_BIT) + +/* Status register (SR) */ + +#define TIMER_SR_CC4OF_BIT 12 +#define TIMER_SR_CC3OF_BIT 11 +#define TIMER_SR_CC2OF_BIT 10 +#define TIMER_SR_CC1OF_BIT 9 +#define TIMER_SR_BIF_BIT 7 +#define TIMER_SR_TIF_BIT 6 +#define TIMER_SR_COMIF_BIT 5 +#define TIMER_SR_CC4IF_BIT 4 +#define TIMER_SR_CC3IF_BIT 3 +#define TIMER_SR_CC2IF_BIT 2 +#define TIMER_SR_CC1IF_BIT 1 +#define TIMER_SR_UIF_BIT 0 + +#define TIMER_SR_CC4OF BIT(TIMER_SR_CC4OF_BIT) +#define TIMER_SR_CC3OF BIT(TIMER_SR_CC3OF_BIT) +#define TIMER_SR_CC2OF BIT(TIMER_SR_CC2OF_BIT) +#define TIMER_SR_CC1OF BIT(TIMER_SR_CC1OF_BIT) +#define TIMER_SR_BIF BIT(TIMER_SR_BIF_BIT) +#define TIMER_SR_TIF BIT(TIMER_SR_TIF_BIT) +#define TIMER_SR_COMIF BIT(TIMER_SR_COMIF_BIT) +#define TIMER_SR_CC4IF BIT(TIMER_SR_CC4IF_BIT) +#define TIMER_SR_CC3IF BIT(TIMER_SR_CC3IF_BIT) +#define TIMER_SR_CC2IF BIT(TIMER_SR_CC2IF_BIT) +#define TIMER_SR_CC1IF BIT(TIMER_SR_CC1IF_BIT) +#define TIMER_SR_UIF BIT(TIMER_SR_UIF_BIT) + +/* Event generation register (EGR) */ + +#define TIMER_EGR_TG_BIT 6 +#define TIMER_EGR_CC4G_BIT 4 +#define TIMER_EGR_CC3G_BIT 3 +#define TIMER_EGR_CC2G_BIT 2 +#define TIMER_EGR_CC1G_BIT 1 +#define TIMER_EGR_UG_BIT 0 + +#define TIMER_EGR_TG BIT(TIMER_EGR_TG_BIT) +#define TIMER_EGR_CC4G BIT(TIMER_EGR_CC4G_BIT) +#define TIMER_EGR_CC3G BIT(TIMER_EGR_CC3G_BIT) +#define TIMER_EGR_CC2G BIT(TIMER_EGR_CC2G_BIT) +#define TIMER_EGR_CC1G BIT(TIMER_EGR_CC1G_BIT) +#define TIMER_EGR_UG BIT(TIMER_EGR_UG_BIT) + +/* Capture/compare mode registers, common values */ + +#define TIMER_CCMR_CCS_OUTPUT 0x0 +#define TIMER_CCMR_CCS_INPUT_TI1 0x1 +#define TIMER_CCMR_CCS_INPUT_TI2 0x2 +#define TIMER_CCMR_CCS_INPUT_TRC 0x3 + +/* Capture/compare mode register 1 (CCMR1) */ + +#define TIMER_CCMR1_OC2CE_BIT 15 +#define TIMER_CCMR1_OC2PE_BIT 11 +#define TIMER_CCMR1_OC2FE_BIT 10 +#define TIMER_CCMR1_OC1CE_BIT 7 +#define TIMER_CCMR1_OC1PE_BIT 3 +#define TIMER_CCMR1_OC1FE_BIT 2 + +#define TIMER_CCMR1_OC2CE BIT(TIMER_CCMR1_OC2CE_BIT) +#define TIMER_CCMR1_OC2M (0x3 << 12) +#define TIMER_CCMR1_IC2F (0xF << 12) +#define TIMER_CCMR1_OC2PE BIT(TIMER_CCMR1_OC2PE_BIT) +#define TIMER_CCMR1_OC2FE BIT(TIMER_CCMR1_OC2FE_BIT) +#define TIMER_CCMR1_IC2PSC (0x3 << 10) +#define TIMER_CCMR1_CC2S (0x3 << 8) +#define TIMER_CCMR1_CC2S_OUTPUT (TIMER_CCMR_CCS_OUTPUT << 8) +#define TIMER_CCMR1_CC2S_INPUT_TI1 (TIMER_CCMR_CCS_INPUT_TI1 << 8) +#define TIMER_CCMR1_CC2S_INPUT_TI2 (TIMER_CCMR_CCS_INPUT_TI2 << 8) +#define TIMER_CCMR1_CC2S_INPUT_TRC (TIMER_CCMR_CCS_INPUT_TRC << 8) +#define TIMER_CCMR1_OC1CE BIT(TIMER_CCMR1_OC1CE_BIT) +#define TIMER_CCMR1_OC1M (0x3 << 4) +#define TIMER_CCMR1_IC1F (0xF << 4) +#define TIMER_CCMR1_OC1PE BIT(TIMER_CCMR1_OC1PE_BIT) +#define TIMER_CCMR1_OC1FE BIT(TIMER_CCMR1_OC1FE_BIT) +#define TIMER_CCMR1_IC1PSC (0x3 << 2) +#define TIMER_CCMR1_CC1S 0x3 +#define TIMER_CCMR1_CC1S_OUTPUT TIMER_CCMR_CCS_OUTPUT +#define TIMER_CCMR1_CC1S_INPUT_TI1 TIMER_CCMR_CCS_INPUT_TI1 +#define TIMER_CCMR1_CC1S_INPUT_TI2 TIMER_CCMR_CCS_INPUT_TI2 +#define TIMER_CCMR1_CC1S_INPUT_TRC TIMER_CCMR_CCS_INPUT_TRC + +/* Capture/compare mode register 2 (CCMR2) */ + +#define TIMER_CCMR2_OC4CE_BIT 15 +#define TIMER_CCMR2_OC4PE_BIT 11 +#define TIMER_CCMR2_OC4FE_BIT 10 +#define TIMER_CCMR2_OC3CE_BIT 7 +#define TIMER_CCMR2_OC3PE_BIT 3 +#define TIMER_CCMR2_OC3FE_BIT 2 + +#define TIMER_CCMR2_OC4CE BIT(TIMER_CCMR2_OC4CE_BIT) +#define TIMER_CCMR2_OC4M (0x3 << 12) +#define TIMER_CCMR2_IC2F (0xF << 12) +#define TIMER_CCMR2_OC4PE BIT(TIMER_CCMR2_OC4PE_BIT) +#define TIMER_CCMR2_OC4FE BIT(TIMER_CCMR2_OC4FE_BIT) +#define TIMER_CCMR2_IC2PSC (0x3 << 10) +#define TIMER_CCMR2_CC4S (0x3 << 8) +#define TIMER_CCMR1_CC4S_OUTPUT (TIMER_CCMR_CCS_OUTPUT << 8) +#define TIMER_CCMR1_CC4S_INPUT_TI1 (TIMER_CCMR_CCS_INPUT_TI1 << 8) +#define TIMER_CCMR1_CC4S_INPUT_TI2 (TIMER_CCMR_CCS_INPUT_TI2 << 8) +#define TIMER_CCMR1_CC4S_INPUT_TRC (TIMER_CCMR_CCS_INPUT_TRC << 8) +#define TIMER_CCMR2_OC3CE BIT(TIMER_CCMR2_OC3CE_BIT) +#define TIMER_CCMR2_OC3M (0x3 << 4) +#define TIMER_CCMR2_IC1F (0xF << 4) +#define TIMER_CCMR2_OC3PE BIT(TIMER_CCMR2_OC3PE_BIT) +#define TIMER_CCMR2_OC3FE BIT(TIMER_CCMR2_OC3FE_BIT) +#define TIMER_CCMR2_IC1PSC (0x3 << 2) +#define TIMER_CCMR2_CC3S 0x3 +#define TIMER_CCMR1_CC3S_OUTPUT TIMER_CCMR_CCS_OUTPUT +#define TIMER_CCMR1_CC3S_INPUT_TI1 TIMER_CCMR_CCS_INPUT_TI1 +#define TIMER_CCMR1_CC3S_INPUT_TI2 TIMER_CCMR_CCS_INPUT_TI2 +#define TIMER_CCMR1_CC3S_INPUT_TRC TIMER_CCMR_CCS_INPUT_TRC + +/* Capture/compare enable register (CCER) */ + +#define TIMER_CCER_CC4P_BIT 13 +#define TIMER_CCER_CC4E_BIT 12 +#define TIMER_CCER_CC3P_BIT 9 +#define TIMER_CCER_CC3E_BIT 8 +#define TIMER_CCER_CC2P_BIT 5 +#define TIMER_CCER_CC2E_BIT 4 +#define TIMER_CCER_CC1P_BIT 1 +#define TIMER_CCER_CC1E_BIT 0 + +#define TIMER_CCER_CC4P BIT(TIMER_CCER_CC4P_BIT) +#define TIMER_CCER_CC4E BIT(TIMER_CCER_CC4E_BIT) +#define TIMER_CCER_CC3P BIT(TIMER_CCER_CC3P_BIT) +#define TIMER_CCER_CC3E BIT(TIMER_CCER_CC3E_BIT) +#define TIMER_CCER_CC2P BIT(TIMER_CCER_CC2P_BIT) +#define TIMER_CCER_CC2E BIT(TIMER_CCER_CC2E_BIT) +#define TIMER_CCER_CC1P BIT(TIMER_CCER_CC1P_BIT) +#define TIMER_CCER_CC1E BIT(TIMER_CCER_CC1E_BIT) + +/* Break and dead-time register (BDTR) */ + +#define TIMER_BDTR_MOE_BIT 15 +#define TIMER_BDTR_AOE_BIT 14 +#define TIMER_BDTR_BKP_BIT 13 +#define TIMER_BDTR_BKE_BIT 12 +#define TIMER_BDTR_OSSR_BIT 11 +#define TIMER_BDTR_OSSI_BIT 10 + +#define TIMER_BDTR_MOE BIT(TIMER_BDTR_MOE_BIT) +#define TIMER_BDTR_AOE BIT(TIMER_BDTR_AOE_BIT) +#define TIMER_BDTR_BKP BIT(TIMER_BDTR_BKP_BIT) +#define TIMER_BDTR_BKE BIT(TIMER_BDTR_BKE_BIT) +#define TIMER_BDTR_OSSR BIT(TIMER_BDTR_OSSR_BIT) +#define TIMER_BDTR_OSSI BIT(TIMER_BDTR_OSSI_BIT) +#define TIMER_BDTR_LOCK (0x3 << 8) +#define TIMER_BDTR_LOCK_OFF (0x0 << 8) +#define TIMER_BDTR_LOCK_LEVEL1 (0x1 << 8) +#define TIMER_BDTR_LOCK_LEVEL2 (0x2 << 8) +#define TIMER_BDTR_LOCK_LEVEL3 (0x3 << 8) +#define TIMER_BDTR_DTG 0xFF + +/* DMA control register (DCR) */ + +#define TIMER_DCR_DBL (0x1F << 8) +#define TIMER_DCR_DBL_1BYTE (0x0 << 8) +#define TIMER_DCR_DBL_2BYTE (0x1 << 8) +#define TIMER_DCR_DBL_3BYTE (0x2 << 8) +#define TIMER_DCR_DBL_4BYTE (0x3 << 8) +#define TIMER_DCR_DBL_5BYTE (0x4 << 8) +#define TIMER_DCR_DBL_6BYTE (0x5 << 8) +#define TIMER_DCR_DBL_7BYTE (0x6 << 8) +#define TIMER_DCR_DBL_8BYTE (0x7 << 8) +#define TIMER_DCR_DBL_9BYTE (0x8 << 8) +#define TIMER_DCR_DBL_10BYTE (0x9 << 8) +#define TIMER_DCR_DBL_11BYTE (0xA << 8) +#define TIMER_DCR_DBL_12BYTE (0xB << 8) +#define TIMER_DCR_DBL_13BYTE (0xC << 8) +#define TIMER_DCR_DBL_14BYTE (0xD << 8) +#define TIMER_DCR_DBL_15BYTE (0xE << 8) +#define TIMER_DCR_DBL_16BYTE (0xF << 8) +#define TIMER_DCR_DBL_17BYTE (0x10 << 8) +#define TIMER_DCR_DBL_18BYTE (0x11 << 8) +#define TIMER_DCR_DBA 0x1F +#define TIMER_DCR_DBA_CR1 0x0 +#define TIMER_DCR_DBA_CR2 0x1 +#define TIMER_DCR_DBA_SMCR 0x2 +#define TIMER_DCR_DBA_DIER 0x3 +#define TIMER_DCR_DBA_SR 0x4 +#define TIMER_DCR_DBA_EGR 0x5 +#define TIMER_DCR_DBA_CCMR1 0x6 +#define TIMER_DCR_DBA_CCMR2 0x7 +#define TIMER_DCR_DBA_CCER 0x8 +#define TIMER_DCR_DBA_CNT 0x9 +#define TIMER_DCR_DBA_PSC 0xA +#define TIMER_DCR_DBA_ARR 0xB +#define TIMER_DCR_DBA_RCR 0xC +#define TIMER_DCR_DBA_CCR1 0xD +#define TIMER_DCR_DBA_CCR2 0xE +#define TIMER_DCR_DBA_CCR3 0xF +#define TIMER_DCR_DBA_CCR4 0x10 +#define TIMER_DCR_DBA_BDTR 0x11 +#define TIMER_DCR_DBA_DCR 0x12 +#define TIMER_DCR_DBA_DMAR 0x13 + +/* + * Convenience routines + */ + +/** + * Used to configure the behavior of a timer channel. Note that not + * all timers can be configured in every mode. + */ +/* TODO TIMER_PWM_CENTER_ALIGNED, TIMER_INPUT_CAPTURE, TIMER_ONE_PULSE */ +typedef enum timer_mode { + TIMER_DISABLED, /**< In this mode, the timer stops counting, + channel interrupts are detached, and no state + changes are output. */ + TIMER_PWM, /**< PWM output mode. This is the default mode for pins + after initialization. */ + /* TIMER_PWM_CENTER_ALIGNED, /\**< Center-aligned PWM output mode. *\/ */ + TIMER_OUTPUT_COMPARE, /**< In this mode, the timer counts from 0 + to its reload value repeatedly; every + time the counter value reaches one of + the channel compare values, the + corresponding interrupt is fired. */ + /* TIMER_INPUT_CAPTURE, /\**< In this mode, the timer can measure the */ + /* pulse lengths of input signals. *\/ */ + /* TIMER_ONE_PULSE /\**< In this mode, the timer can generate a single */ + /* pulse on a GPIO pin for a specified amount of */ + /* time. *\/ */ +} timer_mode; + +/** Timer channel numbers */ +typedef enum timer_channel { + TIMER_CH1 = 1, /**< Channel 1 */ + TIMER_CH2 = 2, /**< Channel 2 */ + TIMER_CH3 = 3, /**< Channel 3 */ + TIMER_CH4 = 4 /**< Channel 4 */ +} timer_channel; + +/* + * Note: Don't require timer_channel arguments! We want to be able to say + * + * for (int channel = 1; channel <= 4; channel++) { + * ... + * } + * + * without the compiler yelling at us. + */ + +void timer_init(timer_dev *dev); +void timer_disable(timer_dev *dev); +void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode); +void timer_foreach(void (*fn)(timer_dev*)); + +/** + * @brief Timer interrupt number. + * + * Not all timers support all of these values; see the descriptions + * for each value. + */ +typedef enum timer_interrupt_id { + TIMER_UPDATE_INTERRUPT, /**< Update interrupt, available on all timers. */ + TIMER_CC1_INTERRUPT, /**< Capture/compare 1 interrupt, available + on general and advanced timers only. */ + TIMER_CC2_INTERRUPT, /**< Capture/compare 2 interrupt, general and + advanced timers only. */ + TIMER_CC3_INTERRUPT, /**< Capture/compare 3 interrupt, general and + advanced timers only. */ + TIMER_CC4_INTERRUPT, /**< Capture/compare 4 interrupt, general and + advanced timers only. */ + TIMER_COM_INTERRUPT, /**< COM interrupt, advanced timers only */ + TIMER_TRG_INTERRUPT, /**< Trigger interrupt, general and advanced + timers only */ + TIMER_BREAK_INTERRUPT /**< Break interrupt, advanced timers only. */ +} timer_interrupt_id; + +void timer_attach_interrupt(timer_dev *dev, + uint8 interrupt, + voidFuncPtr handler); +void timer_detach_interrupt(timer_dev *dev, uint8 interrupt); + +/** + * Initialize all timer devices on the chip. + */ +static inline void timer_init_all(void) { + timer_foreach(timer_init); +} + +/** + * Disables all timers on the device. + */ +static inline void timer_disable_all(void) { + timer_foreach(timer_disable); +} + +/** + * @brief Stop a timer's counter from changing. + * + * Does not affect the timer's mode or other settings. + * + * @param dev Device whose counter to pause. + */ +static inline void timer_pause(timer_dev *dev) { + *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 0; +} + +/** + * @brief Start a timer's counter. + * + * Does not affect the timer's mode or other settings. + * + * @param dev Device whose counter to resume + */ +static inline void timer_resume(timer_dev *dev) { + *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 1; +} + +/** + * @brief Returns the timer's counter value. + * + * This value is likely to be inaccurate if the counter is running + * with a low prescaler. + * + * @param dev Timer whose counter to return + */ +static inline uint16 timer_get_count(timer_dev *dev) { + return (uint16)(dev->regs).bas->CNT; +} + +/** + * @brief Sets the counter value for the given timer. + * @param dev Timer whose counter to set + * @param value New counter value + */ +static inline void timer_set_count(timer_dev *dev, uint16 value) { + (dev->regs).bas->CNT = value; +} + +/** + * @brief Returns the given timer's prescaler. + * + * Note that if the timer's prescaler is set (e.g. via + * timer_set_prescaler() or accessing a TIMx_PSC register), the value + * returned by this function will reflect the new setting, but the + * timer's counter will only reflect the new prescaler at the next + * update event. + * + * @param dev Timer whose prescaler to return + * @see timer_generate_update() + */ +static inline uint16 timer_get_prescaler(timer_dev *dev) { + return (uint16)(dev->regs).bas->PSC; +} + +/** + * @brief Set a timer's prescale value. + * + * Divides the input clock by (PSC+1). The new value will not take + * effect until the next update event. + * + * @param dev Timer whose prescaler to set + * @param psc New prescaler value + * @see timer_generate_update() + */ +static inline void timer_set_prescaler(timer_dev *dev, uint16 psc) { + (dev->regs).bas->PSC = psc; +} + +/** + * @brief Returns a timer's reload value. + * @param dev Timer whose reload value to return + */ +static inline uint16 timer_get_reload(timer_dev *dev) { + return (uint16)(dev->regs).bas->ARR; +} + +/** + * @brief Set a timer's reload value. + * @param dev Timer whose reload value to set + * @param arr New reload value to use. Takes effect at next update event. + * @see timer_generate_update() + */ +static inline void timer_set_reload(timer_dev *dev, uint16 arr) { + (dev->regs).bas->ARR = arr; +} + +/** + * @brief Get the compare value for the given timer channel. + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @param channel Channel whose compare value to get. + */ +static inline uint16 timer_get_compare(timer_dev *dev, uint8 channel) { + __io uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); + return *ccr; +} + +/** + * @brief Set the compare value for the given timer channel. + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @param channel Channel whose compare value to set. + * @param value New compare value. + */ +static inline void timer_set_compare(timer_dev *dev, + uint8 channel, + uint16 value) { + __io uint32 *ccr = &(dev->regs).gen->CCR1 + (channel - 1); + *ccr = value; +} + +/** + * @brief Generate an update event for the given timer. + * + * Normally, this will cause the prescaler and auto-reload values in + * the PSC and ARR registers to take immediate effect. However, this + * function will do nothing if the UDIS bit is set in the timer's CR1 + * register (UDIS is cleared by default). + * + * @param dev Timer device to generate an update for. + */ +static inline void timer_generate_update(timer_dev *dev) { + *bb_perip(&(dev->regs).bas->EGR, TIMER_EGR_UG_BIT) = 1; +} + +/** + * @brief Enable a timer's trigger DMA request + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL + */ +static inline void timer_dma_enable_trg_req(timer_dev *dev) { + *bb_perip(&(dev->regs).gen->DIER, TIMER_DIER_TDE_BIT) = 1; +} + +/** + * @brief Disable a timer's trigger DMA request + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL + */ +static inline void timer_dma_disable_trg_req(timer_dev *dev) { + *bb_perip(&(dev->regs).gen->DIER, TIMER_DIER_TDE_BIT) = 0; +} + +/** + * @brief Enable a timer channel's DMA request. + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL + * @param channel Channel whose DMA request to enable. + */ +static inline void timer_dma_enable_req(timer_dev *dev, uint8 channel) { + *bb_perip(&(dev->regs).gen->DIER, channel + 8) = 1; +} + +/** + * @brief Disable a timer channel's DMA request. + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @param channel Channel whose DMA request to disable. + */ +static inline void timer_dma_disable_req(timer_dev *dev, uint8 channel) { + *bb_perip(&(dev->regs).gen->DIER, channel + 8) = 0; +} + +/** + * @brief Enable a timer interrupt. + * @param dev Timer device. + * @param interrupt Interrupt number to enable; this may be any + * timer_interrupt_id value appropriate for the timer. + * @see timer_interrupt_id + * @see timer_channel + */ +static inline void timer_enable_irq(timer_dev *dev, uint8 interrupt) { + *bb_perip(&(dev->regs).adv->DIER, interrupt) = 1; +} + +/** + * @brief Disable a timer interrupt. + * @param dev Timer device. + * @param interrupt Interrupt number to disable; this may be any + * timer_interrupt_id value appropriate for the timer. + * @see timer_interrupt_id + * @see timer_channel + */ +static inline void timer_disable_irq(timer_dev *dev, uint8 interrupt) { + *bb_perip(&(dev->regs).adv->DIER, interrupt) = 0; +} + +/** + * @brief Enable a timer channel's capture/compare signal. + * + * If the channel is configured as output, the corresponding output + * compare signal will be output on the corresponding output pin. If + * the channel is configured as input, enables capture of the counter + * value into the input capture/compare register. + * + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @param channel Channel to enable, from 1 to 4. + */ +static inline void timer_cc_enable(timer_dev *dev, uint8 channel) { + *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1)) = 1; +} + +/** + * @brief Disable a timer channel's output compare or input capture signal. + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @param channel Channel to disable, from 1 to 4. + * @see timer_cc_enable() + */ +static inline void timer_cc_disable(timer_dev *dev, uint8 channel) { + *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1)) = 0; +} + +/** + * @brief Get a channel's capture/compare output polarity + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @param channel Channel whose capture/compare output polarity to get. + * @return Polarity, either 0 or 1. + * @see timer_cc_set_polarity() + */ +static inline uint8 timer_cc_get_pol(timer_dev *dev, uint8 channel) { + return *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1) + 1); +} + +/** + * @brief Set a timer channel's capture/compare output polarity. + * + * If the timer channel is configured as output: polarity == 0 means + * the output channel will be active high; polarity == 1 means active + * low. + * + * If the timer channel is configured as input: polarity == 0 means + * capture is done on the rising edge of ICn; when used as an external + * trigger, ICn is non-inverted. polarity == 1 means capture is done + * on the falling edge of ICn; when used as an external trigger, ICn + * is inverted. + * + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @param channel Channel whose capture/compare output polarity to set. + * @param pol New polarity, 0 or 1. + */ +static inline void timer_cc_set_pol(timer_dev *dev, uint8 channel, uint8 pol) { + *bb_perip(&(dev->regs).gen->CCER, 4 * (channel - 1) + 1) = pol; +} + +/** + * @brief Get a timer's DMA burst length. + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @return Number of bytes to be transferred per DMA request, from 1 to 18. + */ +static inline uint8 timer_dma_get_burst_len(timer_dev *dev) { + uint32 dbl = ((dev->regs).gen->DCR & TIMER_DCR_DBL) >> 8; + return dbl + 1; /* 0 means 1 byte, etc. */ +} + +/** + * @brief Set a timer's DMA burst length. + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @param length DMA burst length; i.e., number of bytes to transfer + * per DMA request, from 1 to 18. + */ +static inline void timer_dma_set_burst_len(timer_dev *dev, uint8 length) { + uint32 tmp = (dev->regs).gen->DCR; + tmp &= ~TIMER_DCR_DBL; + tmp |= (length - 1) << 8; + (dev->regs).gen->DCR = tmp; +} + +/** + * @brief Timer DMA base address. + * + * Defines the base address for DMA transfers. + */ +typedef enum timer_dma_base_addr { + TIMER_DMA_BASE_CR1 = TIMER_DCR_DBA_CR1, /**< Base is control register 1 */ + TIMER_DMA_BASE_CR2 = TIMER_DCR_DBA_CR2, /**< Base is control register 2 */ + TIMER_DMA_BASE_SMCR = TIMER_DCR_DBA_SMCR, /**< Base is slave mode + control register */ + TIMER_DMA_BASE_DIER = TIMER_DCR_DBA_DIER, /**< Base is DMA interrupt enable + register */ + TIMER_DMA_BASE_SR = TIMER_DCR_DBA_SR, /**< Base is status register */ + TIMER_DMA_BASE_EGR = TIMER_DCR_DBA_EGR, /**< Base is event generation + register */ + TIMER_DMA_BASE_CCMR1 = TIMER_DCR_DBA_CCMR1, /**< Base is capture/compare + mode register 1 */ + TIMER_DMA_BASE_CCMR2 = TIMER_DCR_DBA_CCMR2, /**< Base is capture/compare + mode register 2 */ + TIMER_DMA_BASE_CCER = TIMER_DCR_DBA_CCER, /**< Base is capture/compare + enable register */ + TIMER_DMA_BASE_CNT = TIMER_DCR_DBA_CNT, /**< Base is counter */ + TIMER_DMA_BASE_PSC = TIMER_DCR_DBA_PSC, /**< Base is prescaler */ + TIMER_DMA_BASE_ARR = TIMER_DCR_DBA_ARR, /**< Base is auto-reload + register */ + TIMER_DMA_BASE_RCR = TIMER_DCR_DBA_RCR, /**< Base is repetition + counter register */ + TIMER_DMA_BASE_CCR1 = TIMER_DCR_DBA_CCR1, /**< Base is capture/compare + register 1 */ + TIMER_DMA_BASE_CCR2 = TIMER_DCR_DBA_CCR2, /**< Base is capture/compare + register 2 */ + TIMER_DMA_BASE_CCR3 = TIMER_DCR_DBA_CCR3, /**< Base is capture/compare + register 3 */ + TIMER_DMA_BASE_CCR4 = TIMER_DCR_DBA_CCR4, /**< Base is capture/compare + register 4 */ + TIMER_DMA_BASE_BDTR = TIMER_DCR_DBA_BDTR, /**< Base is break and + dead-time register */ + TIMER_DMA_BASE_DCR = TIMER_DCR_DBA_DCR, /**< Base is DMA control + register */ + TIMER_DMA_BASE_DMAR = TIMER_DCR_DBA_DMAR /**< Base is DMA address for + full transfer */ +} timer_dma_base_addr; + +/** + * @brief Get the timer's DMA base address. + * + * Some restrictions apply; see ST RM0008. + * + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @return DMA base address + */ +static inline timer_dma_base_addr timer_dma_get_base_addr(timer_dev *dev) { + uint32 dcr = (dev->regs).gen->DCR; + return (timer_dma_base_addr)(dcr & TIMER_DCR_DBA); +} + +/** + * @brief Set the timer's DMA base address. + * + * Some restrictions apply; see ST RM0008. + * + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @param dma_base DMA base address. + */ +static inline void timer_dma_set_base_addr(timer_dev *dev, + timer_dma_base_addr dma_base) { + uint32 tmp = (dev->regs).gen->DCR; + tmp &= ~TIMER_DCR_DBA; + tmp |= dma_base; + (dev->regs).gen->DCR = tmp; +} + +/** + * Timer output compare modes. + */ +typedef enum timer_oc_mode { + TIMER_OC_MODE_FROZEN = 0 << 4, /**< Frozen: comparison between output + compare register and counter has no + effect on the outputs. */ + TIMER_OC_MODE_ACTIVE_ON_MATCH = 1 << 4, /**< OCxREF signal is forced + high when the count matches + the channel capture/compare + register. */ + TIMER_OC_MODE_INACTIVE_ON_MATCH = 2 << 4, /**< OCxREF signal is forced + low when the counter matches + the channel capture/compare + register. */ + TIMER_OC_MODE_TOGGLE = 3 << 4, /**< OCxREF toggles when counter + matches the cannel capture/compare + register. */ + TIMER_OC_MODE_FORCE_INACTIVE = 4 << 4, /**< OCxREF is forced low. */ + TIMER_OC_MODE_FORCE_ACTIVE = 5 << 4, /**< OCxREF is forced high. */ + TIMER_OC_MODE_PWM_1 = 6 << 4, /**< PWM mode 1. In upcounting, channel is + active as long as count is less than + channel capture/compare register, else + inactive. In downcounting, channel is + inactive as long as count exceeds + capture/compare register, else + active. */ + TIMER_OC_MODE_PWM_2 = 7 << 4 /**< PWM mode 2. In upcounting, channel is + inactive as long as count is less than + capture/compare register, else active. + In downcounting, channel is active as + long as count exceeds capture/compare + register, else inactive. */ +} timer_oc_mode; + +/** + * Timer output compare mode flags. + * @see timer_oc_set_mode() + */ +typedef enum timer_oc_mode_flags { + TIMER_OC_CE = BIT(7), /**< Output compare clear enable. */ + TIMER_OC_PE = BIT(3), /**< Output compare preload enable. */ + TIMER_OC_FE = BIT(2) /**< Output compare fast enable. */ +} timer_oc_mode_flags; + +/** + * @brief Configure a channel's output compare mode. + * + * @param dev Timer device, must have type TIMER_ADVANCED or TIMER_GENERAL. + * @param channel Channel to configure in output compare mode. + * @param mode Timer mode to set. + * @param flags OR of timer_oc_mode_flags. + * @see timer_oc_mode + * @see timer_oc_mode_flags + */ +static inline void timer_oc_set_mode(timer_dev *dev, + uint8 channel, + timer_oc_mode mode, + uint8 flags) { + uint8 bit0 = channel & 1; + //uint8 bit1 = (channel >> 1) & 1; // original + uint8 bit1 = ((channel-1) >> 1) & 1; // fixed + /* channel == 1,2 -> CCMR1; channel == 3,4 -> CCMR2 */ + __io uint32 *ccmr = &(dev->regs).gen->CCMR1 + bit1; + /* channel == 1,3 -> shift = 0, channel == 2,4 -> shift = 8 */ + uint8 shift = 8 * (1 - bit0); + + uint32 tmp = *ccmr; + tmp &= ~(0xFF << shift); + tmp |= (mode | flags | TIMER_CCMR_CCS_OUTPUT) << shift; + *ccmr = tmp; +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/usart.c b/Libmaple/libmaple/libmaple/usart.c index 47a08d13..48c0eabb 100644 --- a/Libmaple/libmaple/libmaple/usart.c +++ b/Libmaple/libmaple/libmaple/usart.c @@ -1,294 +1,294 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file usart.c - * @author Marti Bolivar , - * Perry Hung - * @brief USART control routines - */ - -#include "usart.h" -#define USART_TX_IRQ - -/* - * Devices - */ - -static usart_dev usart1 = { - .regs = USART1_BASE, - .max_baud = 4500000UL, - .clk_id = RCC_USART1, - .irq_num = NVIC_USART1 -}; -/** USART1 device */ -usart_dev *USART1 = &usart1; - -static usart_dev usart2 = { - .regs = USART2_BASE, - .max_baud = 2250000UL, - .clk_id = RCC_USART2, - .irq_num = NVIC_USART2 -}; -/** USART2 device */ -usart_dev *USART2 = &usart2; - -static usart_dev usart3 = { - .regs = USART3_BASE, - .max_baud = 2250000UL, - .clk_id = RCC_USART3, - .irq_num = NVIC_USART3 -}; -/** USART3 device */ -usart_dev *USART3 = &usart3; - -#ifdef STM32_HIGH_DENSITY -static usart_dev uart4 = { - .regs = UART4_BASE, - .max_baud = 2250000UL, - .clk_id = RCC_UART4, - .irq_num = NVIC_UART4 -}; -/** UART4 device */ -usart_dev *UART4 = &uart4; - -static usart_dev uart5 = { - .regs = UART5_BASE, - .max_baud = 2250000UL, - .clk_id = RCC_UART5, - .irq_num = NVIC_UART5 -}; -/** UART5 device */ -usart_dev *UART5 = &uart5; -#endif - -/** - * @brief Initialize a serial port. - * @param dev Serial port to be initialized - */ -void usart_init(usart_dev *dev) { - rb_init(&dev->rbRX, USART_RX_BUF_SIZE, dev->rx_buf); - rb_init(&dev->rbTX, USART_TX_BUF_SIZE, dev->tx_buf); - rcc_clk_enable(dev->clk_id); - nvic_irq_enable(dev->irq_num); -} - -/** - * @brief Configure a serial port's baud rate. - * - * @param dev Serial port to be configured - * @param clock_speed Clock speed, in megahertz. - * @param baud Baud rate for transmit/receive. - */ -void usart_set_baud_rate(usart_dev *dev, uint32 baud) { - uint32 integer_part; - uint32 fractional_part; - uint32 tmp; - - uint32 clock_speed = rcc_dev_clk_speed(dev->clk_id); - - /* See ST RM0008 for the details on configuring the baud rate register */ - integer_part = (25 * clock_speed) / (4 * baud); - tmp = (integer_part / 100) << 4; - fractional_part = integer_part - (100 * (tmp >> 4)); - tmp |= (((fractional_part * 16) + 50) / 100) & ((uint8)0x0F); - - dev->regs->BRR = (uint16)tmp; -} - -/** - * @brief Enable a serial port. - * - * USART is enabled in single buffer transmission mode, multibuffer - * receiver mode, 8n1. - * - * Serial port must have a baud rate configured to work properly. - * - * @param dev Serial port to enable. - * @see usart_set_baud_rate() - */ -void usart_enable(usart_dev *dev) { - usart_reg_map *regs = dev->regs; - regs->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE; - regs->CR1 |= USART_CR1_UE; -} - - -/** - * @brief Enable serial port tx interrupt. - * - * @param dev Serial port. - */ -void usart_tx_irq_enable(usart_dev *dev) { - bb_peri_set_bit(&dev->regs->CR1, USART_CR1_TXEIE_BIT, 1); -} - -/** - * @brief Disable serial port tx interrupt. - * - * @param dev Serial port. - */ -void usart_tx_irq_disable(usart_dev *dev) { - bb_peri_set_bit(&dev->regs->CR1, USART_CR1_TXEIE_BIT, 0); -} - -/** - * @brief Turn off a serial port. - * @param dev Serial port to be disabled - */ -void usart_disable(usart_dev *dev) { - /* FIXME this misbehaves if you try to use PWM on TX afterwards */ - usart_reg_map *regs = dev->regs; - - // flush output buffer - while(usart_data_pending(dev) > 0) - ; - - /* TC bit must be high before disabling the USART */ - while((regs->CR1 & USART_CR1_UE) && !(regs->SR & USART_SR_TC)) - ; - - /* Disable UE */ - regs->CR1 &= ~USART_CR1_UE; - - /* Clean up buffer */ - usart_reset_rx(dev); -} - -/** - * @brief Call a function on each USART. - * @param fn Function to call. - */ -void usart_foreach(void (*fn)(usart_dev*)) { - fn(USART1); - fn(USART2); - fn(USART3); -#ifdef STM32_HIGH_DENSITY - fn(UART4); - fn(UART5); -#endif -} - -/** - * @brief Nonblocking USART transmit - * @param dev Serial port to transmit over - * @param buf Buffer to transmit - * @param len Maximum number of bytes to transmit - * @return Number of bytes transmitted - */ -uint32 usart_tx(usart_dev *dev, const uint8 *buf, uint32 len) { - uint32 txed = 0; -#ifdef USART_TX_IRQ - while (txed < len && rb_safe_insert(&dev->rbTX, buf[txed])) { - usart_tx_irq_enable(dev); - txed++; - } - -#else - usart_reg_map *regs = dev->regs; - while ((regs->SR & USART_SR_TXE) && (txed < len)) { - regs->DR = buf[txed++]; - } -#endif - - return txed; -} - -/** - * @brief Transmit an unsigned integer to the specified serial port in - * decimal format. - * - * This function blocks until the integer's digits have been - * completely transmitted. - * - * @param dev Serial port to send on - * @param val Number to print - */ -void usart_putudec(usart_dev *dev, uint32 val) { - char digits[12]; - int i = 0; - - do { - digits[i++] = val % 10 + '0'; - val /= 10; - } while (val > 0); - - while (--i >= 0) { - usart_putc(dev, digits[i]); - } -} - -/* - * Interrupt handlers. - */ -static inline void usart_irq(usart_dev *dev) { - volatile int sr = dev->regs->SR; - if(sr & USART_SR_RXNE) { -#ifdef USART_SAFE_INSERT - /* If the buffer is full and the user defines USART_SAFE_INSERT, - * ignore new bytes. */ - rb_safe_insert(&dev->rbRX, (uint8)dev->regs->DR); -#else - /* By default, push bytes around in the ring buffer. */ - rb_push_insert(&dev->rbRX, (uint8)dev->regs->DR); -#endif - -#ifdef USART_TX_IRQ - } else if(sr & USART_SR_TXE) { - if(rb_full_count(&dev->rbTX) > 0) { - dev->regs->DR = rb_remove(&dev->rbTX); - } else { - usart_tx_irq_disable(dev); // disable tx irq - // nops needed to deactivate the irq before irq handler is left - asm volatile("nop"); - asm volatile("nop"); - } -#endif - - } -} - -void __irq_usart1(void) { - usart_irq(USART1); -} - -void __irq_usart2(void) { - usart_irq(USART2); -} - -void __irq_usart3(void) { - usart_irq(USART3); -} - -#ifdef STM32_HIGH_DENSITY -void __irq_uart4(void) { - usart_irq(UART4); -} - -void __irq_uart5(void) { - usart_irq(UART5); -} -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file usart.c + * @author Marti Bolivar , + * Perry Hung + * @brief USART control routines + */ + +#include "usart.h" +#define USART_TX_IRQ + +/* + * Devices + */ + +static usart_dev usart1 = { + .regs = USART1_BASE, + .max_baud = 4500000UL, + .clk_id = RCC_USART1, + .irq_num = NVIC_USART1 +}; +/** USART1 device */ +usart_dev *USART1 = &usart1; + +static usart_dev usart2 = { + .regs = USART2_BASE, + .max_baud = 2250000UL, + .clk_id = RCC_USART2, + .irq_num = NVIC_USART2 +}; +/** USART2 device */ +usart_dev *USART2 = &usart2; + +static usart_dev usart3 = { + .regs = USART3_BASE, + .max_baud = 2250000UL, + .clk_id = RCC_USART3, + .irq_num = NVIC_USART3 +}; +/** USART3 device */ +usart_dev *USART3 = &usart3; + +#ifdef STM32_HIGH_DENSITY +static usart_dev uart4 = { + .regs = UART4_BASE, + .max_baud = 2250000UL, + .clk_id = RCC_UART4, + .irq_num = NVIC_UART4 +}; +/** UART4 device */ +usart_dev *UART4 = &uart4; + +static usart_dev uart5 = { + .regs = UART5_BASE, + .max_baud = 2250000UL, + .clk_id = RCC_UART5, + .irq_num = NVIC_UART5 +}; +/** UART5 device */ +usart_dev *UART5 = &uart5; +#endif + +/** + * @brief Initialize a serial port. + * @param dev Serial port to be initialized + */ +void usart_init(usart_dev *dev) { + rb_init(&dev->rbRX, USART_RX_BUF_SIZE, dev->rx_buf); + rb_init(&dev->rbTX, USART_TX_BUF_SIZE, dev->tx_buf); + rcc_clk_enable(dev->clk_id); + nvic_irq_enable(dev->irq_num); +} + +/** + * @brief Configure a serial port's baud rate. + * + * @param dev Serial port to be configured + * @param clock_speed Clock speed, in megahertz. + * @param baud Baud rate for transmit/receive. + */ +void usart_set_baud_rate(usart_dev *dev, uint32 baud) { + uint32 integer_part; + uint32 fractional_part; + uint32 tmp; + + uint32 clock_speed = rcc_dev_clk_speed(dev->clk_id); + + /* See ST RM0008 for the details on configuring the baud rate register */ + integer_part = (25 * clock_speed) / (4 * baud); + tmp = (integer_part / 100) << 4; + fractional_part = integer_part - (100 * (tmp >> 4)); + tmp |= (((fractional_part * 16) + 50) / 100) & ((uint8)0x0F); + + dev->regs->BRR = (uint16)tmp; +} + +/** + * @brief Enable a serial port. + * + * USART is enabled in single buffer transmission mode, multibuffer + * receiver mode, 8n1. + * + * Serial port must have a baud rate configured to work properly. + * + * @param dev Serial port to enable. + * @see usart_set_baud_rate() + */ +void usart_enable(usart_dev *dev) { + usart_reg_map *regs = dev->regs; + regs->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE; + regs->CR1 |= USART_CR1_UE; +} + + +/** + * @brief Enable serial port tx interrupt. + * + * @param dev Serial port. + */ +void usart_tx_irq_enable(usart_dev *dev) { + bb_peri_set_bit(&dev->regs->CR1, USART_CR1_TXEIE_BIT, 1); +} + +/** + * @brief Disable serial port tx interrupt. + * + * @param dev Serial port. + */ +void usart_tx_irq_disable(usart_dev *dev) { + bb_peri_set_bit(&dev->regs->CR1, USART_CR1_TXEIE_BIT, 0); +} + +/** + * @brief Turn off a serial port. + * @param dev Serial port to be disabled + */ +void usart_disable(usart_dev *dev) { + /* FIXME this misbehaves if you try to use PWM on TX afterwards */ + usart_reg_map *regs = dev->regs; + + // flush output buffer + while(usart_data_pending(dev) > 0) + ; + + /* TC bit must be high before disabling the USART */ + while((regs->CR1 & USART_CR1_UE) && !(regs->SR & USART_SR_TC)) + ; + + /* Disable UE */ + regs->CR1 &= ~USART_CR1_UE; + + /* Clean up buffer */ + usart_reset_rx(dev); +} + +/** + * @brief Call a function on each USART. + * @param fn Function to call. + */ +void usart_foreach(void (*fn)(usart_dev*)) { + fn(USART1); + fn(USART2); + fn(USART3); +#ifdef STM32_HIGH_DENSITY + fn(UART4); + fn(UART5); +#endif +} + +/** + * @brief Nonblocking USART transmit + * @param dev Serial port to transmit over + * @param buf Buffer to transmit + * @param len Maximum number of bytes to transmit + * @return Number of bytes transmitted + */ +uint32 usart_tx(usart_dev *dev, const uint8 *buf, uint32 len) { + uint32 txed = 0; +#ifdef USART_TX_IRQ + while (txed < len && rb_safe_insert(&dev->rbTX, buf[txed])) { + usart_tx_irq_enable(dev); + txed++; + } + +#else + usart_reg_map *regs = dev->regs; + while ((regs->SR & USART_SR_TXE) && (txed < len)) { + regs->DR = buf[txed++]; + } +#endif + + return txed; +} + +/** + * @brief Transmit an unsigned integer to the specified serial port in + * decimal format. + * + * This function blocks until the integer's digits have been + * completely transmitted. + * + * @param dev Serial port to send on + * @param val Number to print + */ +void usart_putudec(usart_dev *dev, uint32 val) { + char digits[12]; + int i = 0; + + do { + digits[i++] = val % 10 + '0'; + val /= 10; + } while (val > 0); + + while (--i >= 0) { + usart_putc(dev, digits[i]); + } +} + +/* + * Interrupt handlers. + */ +static inline void usart_irq(usart_dev *dev) { + volatile int sr = dev->regs->SR; + if(sr & USART_SR_RXNE) { +#ifdef USART_SAFE_INSERT + /* If the buffer is full and the user defines USART_SAFE_INSERT, + * ignore new bytes. */ + rb_safe_insert(&dev->rbRX, (uint8)dev->regs->DR); +#else + /* By default, push bytes around in the ring buffer. */ + rb_push_insert(&dev->rbRX, (uint8)dev->regs->DR); +#endif + +#ifdef USART_TX_IRQ + } else if(sr & USART_SR_TXE) { + if(rb_full_count(&dev->rbTX) > 0) { + dev->regs->DR = rb_remove(&dev->rbTX); + } else { + usart_tx_irq_disable(dev); // disable tx irq + // nops needed to deactivate the irq before irq handler is left + asm volatile("nop"); + asm volatile("nop"); + } +#endif + + } +} + +void __irq_usart1(void) { + usart_irq(USART1); +} + +void __irq_usart2(void) { + usart_irq(USART2); +} + +void __irq_usart3(void) { + usart_irq(USART3); +} + +#ifdef STM32_HIGH_DENSITY +void __irq_uart4(void) { + usart_irq(UART4); +} + +void __irq_uart5(void) { + usart_irq(UART5); +} +#endif diff --git a/Libmaple/libmaple/libmaple/usart.h b/Libmaple/libmaple/libmaple/usart.h index 00fd997b..a3dfc31d 100644 --- a/Libmaple/libmaple/libmaple/usart.h +++ b/Libmaple/libmaple/libmaple/usart.h @@ -1,356 +1,356 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file usart.h - * @author Marti Bolivar , - * Perry Hung - * @brief USART definitions and prototypes - */ - -#ifndef _USART_H_ -#define _USART_H_ - -#include "libmaple_types.h" -#include "util.h" -#include "rcc.h" -#include "nvic.h" -#include "ring_buffer.h" -#include "bitband.h" - - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - * Register maps and devices - */ - -/** USART register map type */ -typedef struct usart_reg_map { - __io uint32 SR; /**< Status register */ - __io uint32 DR; /**< Data register */ - __io uint32 BRR; /**< Baud rate register */ - __io uint32 CR1; /**< Control register 1 */ - __io uint32 CR2; /**< Control register 2 */ - __io uint32 CR3; /**< Control register 3 */ - __io uint32 GTPR; /**< Guard time and prescaler register */ -} usart_reg_map; - -/** USART1 register map base pointer */ -#ifdef STM32F2 - #define USART1_BASE ((struct usart_reg_map*)0x40011000) -#else - #define USART1_BASE ((struct usart_reg_map*)0x40013800) -#endif -/** USART2 register map base pointer */ -#define USART2_BASE ((struct usart_reg_map*)0x40004400) -/** USART3 register map base pointer */ -#define USART3_BASE ((struct usart_reg_map*)0x40004800) -#ifdef STM32_HIGH_DENSITY -/** UART4 register map base pointer */ -#define UART4_BASE ((struct usart_reg_map*)0x40004C00) -/** UART5 register map base pointer */ -#define UART5_BASE ((struct usart_reg_map*)0x40005000) -#endif - -/* - * Register bit definitions - */ - -/* Status register */ - -#define USART_SR_CTS_BIT 9 -#define USART_SR_LBD_BIT 8 -#define USART_SR_TXE_BIT 7 -#define USART_SR_TC_BIT 6 -#define USART_SR_RXNE_BIT 5 -#define USART_SR_IDLE_BIT 4 -#define USART_SR_ORE_BIT 3 -#define USART_SR_NE_BIT 2 -#define USART_SR_FE_BIT 1 -#define USART_SR_PE_BIT 0 - -#define USART_SR_CTS BIT(USART_SR_CTS_BIT) -#define USART_SR_LBD BIT(USART_SR_LBD_BIT) -#define USART_SR_TXE BIT(USART_SR_TXE_BIT) -#define USART_SR_TC BIT(USART_SR_TC_BIT) -#define USART_SR_RXNE BIT(USART_SR_RXNE_BIT) -#define USART_SR_IDLE BIT(USART_SR_IDLE_BIT) -#define USART_SR_ORE BIT(USART_SR_ORE_BIT) -#define USART_SR_NE BIT(USART_SR_NE_BIT) -#define USART_SR_FE BIT(USART_SR_FE_BIT) -#define USART_SR_PE BIT(USART_SR_PE_BIT) - -/* Data register */ - -#define USART_DR_DR 0xFF - -/* Baud rate register */ - -#define USART_BRR_DIV_MANTISSA (0xFFF << 4) -#define USART_BRR_DIV_FRACTION 0xF - -/* Control register 1 */ - -#define USART_CR1_UE_BIT 13 -#define USART_CR1_M_BIT 12 -#define USART_CR1_WAKE_BIT 11 -#define USART_CR1_PCE_BIT 10 -#define USART_CR1_PS_BIT 9 -#define USART_CR1_PEIE_BIT 8 -#define USART_CR1_TXEIE_BIT 7 -#define USART_CR1_TCIE_BIT 6 -#define USART_CR1_RXNEIE_BIT 5 -#define USART_CR1_IDLEIE_BIT 4 -#define USART_CR1_TE_BIT 3 -#define USART_CR1_RE_BIT 2 -#define USART_CR1_RWU_BIT 1 -#define USART_CR1_SBK_BIT 0 - -#define USART_CR1_UE BIT(USART_CR1_UE_BIT) -#define USART_CR1_M BIT(USART_CR1_M_BIT) -#define USART_CR1_WAKE BIT(USART_CR1_WAKE_BIT) -#define USART_CR1_WAKE_IDLE (0 << USART_CR1_WAKE_BIT) -#define USART_CR1_WAKE_ADDR (1 << USART_CR1_WAKE_BIT) -#define USART_CR1_PCE BIT(USART_CR1_PCE_BIT) -#define USART_CR1_PS BIT(USART_CR1_PS_BIT) -#define USART_CR1_PS_EVEN (0 << USART_CR1_PS_BIT) -#define USART_CR1_PS_ODD (1 << USART_CR1_PS_BIT) -#define USART_CR1_PEIE BIT(USART_CR1_PEIE_BIT) -#define USART_CR1_TXEIE BIT(USART_CR1_TXEIE_BIT) -#define USART_CR1_TCIE BIT(USART_CR1_TCIE_BIT) -#define USART_CR1_RXNEIE BIT(USART_CR1_RXNEIE_BIT) -#define USART_CR1_IDLEIE BIT(USART_CR1_IDLEIE_BIT) -#define USART_CR1_TE BIT(USART_CR1_TE_BIT) -#define USART_CR1_RE BIT(USART_CR1_RE_BIT) -#define USART_CR1_RWU BIT(USART_CR1_RWU_BIT) -#define USART_CR1_RWU_ACTIVE (0 << USART_CR1_RWU_BIT) -#define USART_CR1_RWU_MUTE (1 << USART_CR1_RWU_BIT) -#define USART_CR1_SBK BIT(USART_CR1_SBK_BIT) - -/* Control register 2 */ - -#define USART_CR2_LINEN_BIT 14 -#define USART_CR2_CLKEN_BIT 11 -#define USART_CR2_CPOL_BIT 10 -#define USART_CR2_CPHA_BIT 9 -#define USART_CR2_LBCL_BIT 8 -#define USART_CR2_LBDIE_BIT 6 -#define USART_CR2_LBDL_BIT 5 - -#define USART_CR2_LINEN BIT(USART_CR2_LINEN_BIT) -#define USART_CR2_STOP (0x3 << 12) -#define USART_CR2_STOP_BITS_1 (0x0 << 12) -/* Not on UART4, UART5 */ -#define USART_CR2_STOP_BITS_POINT_5 (0x1 << 12) -/* Not on UART4, UART5 */ -#define USART_CR2_STOP_BITS_1_POINT_5 (0x3 << 12) -#define USART_CR2_STOP_BITS_2 (0x2 << 12) -#define USART_CR2_CLKEN BIT(USART_CR2_CLKEN_BIT) -/* Not on UART4, UART5 */ -#define USART_CR2_CPOL BIT(USART_CR2_CPOL_BIT) -#define USART_CR2_CPOL_LOW (0x0 << USART_CR2_CLKEN_BIT) -#define USART_CR2_CPOL_HIGH (0x1 << USART_CR2_CLKEN_BIT) -/* Not on UART4, UART5 */ -#define USART_CR2_CPHA BIT(USART_CR2_CPHA_BIT) -#define USART_CR2_CPHA_FIRST (0x0 << USART_CR2_CPHA_BIT) -#define USART_CR2_CPHA_SECOND (0x1 << USART_CR2_CPHA_BIT) -/* Not on UART4, UART5 */ -#define USART_CR2_LBCL BIT(USART_CR2_LBCL_BIT) -#define USART_CR2_LBDIE BIT(USART_CR2_LBDIE_BIT) -#define USART_CR2_LBDL BIT(USART_CR2_LBDL_BIT) -#define USART_CR2_LBDL_10_BIT (0 << USART_CR2_LBDL_BIT) -#define USART_CR2_LBDL_11_BIT (1 << USART_CR2_LBDL_BIT) -#define USART_CR2_ADD 0xF - -/* Control register 3 */ - -#define USART_CR3_CTSIE_BIT 10 -#define USART_CR3_CTSE_BIT 9 -#define USART_CR3_RTSE_BIT 8 -#define USART_CR3_DMAT_BIT 7 -#define USART_CR3_DMAR_BIT 6 -#define USART_CR3_SCEN_BIT 5 -#define USART_CR3_NACK_BIT 4 -#define USART_CR3_HDSEL_BIT 3 -#define USART_CR3_IRLP_BIT 2 -#define USART_CR3_IREN_BIT 1 -#define USART_CR3_EIE_BIT 0 - -/* Not on UART4, UART5 */ -#define USART_CR3_CTSIE BIT(USART_CR3_CTSIE_BIT) -/* Not on UART4, UART5 */ -#define USART_CR3_CTSE BIT(USART_CR3_CTSE_BIT) -/* Not on UART4, UART5 */ -#define USART_CR3_RTSE BIT(USART_CR3_RTSE_BIT) -/* Not on UART5 */ -#define USART_CR3_DMAT BIT(USART_CR3_DMAT_BIT) -/* Not on UART5 */ -#define USART_CR3_DMAR BIT(USART_CR3_DMAR_BIT) -/* Not on UART4, UART5 */ -#define USART_CR3_SCEN BIT(USART_CR3_SCEN_BIT) -/* Not on UART4, UART5 */ -#define USART_CR3_NACK BIT(USART_CR3_NACK_BIT) -#define USART_CR3_HDSEL BIT(USART_CR3_HDSEL_BIT) -#define USART_CR3_IRLP BIT(USART_CR3_IRLP_BIT) -#define USART_CR3_IRLP_NORMAL (0 << USART_CR3_IRLP_BIT) -#define USART_CR3_IRLP_LOW_POWER (1 << USART_CR3_IRLP_BIT) -#define USART_CR3_IREN BIT(USART_CR3_IREN_BIT) -#define USART_CR3_EIE BIT(USART_CR3_EIE_BIT) - -/* Guard time and prescaler register */ - -/* Not on UART4, UART5 */ -#define USART_GTPR_GT (0xFF << 8) -/* Not on UART4, UART5 */ -#define USART_GTPR_PSC 0xFF - -/* - * Devices - */ - -#ifndef USART_RX_BUF_SIZE -#define USART_RX_BUF_SIZE 256 -#endif - -#ifndef USART_TX_BUF_SIZE -#define USART_TX_BUF_SIZE 256 -#endif - -/** USART device type */ -typedef struct usart_dev { - usart_reg_map *regs; /**< Register map */ - ring_buffer rbRX; /**< RX ring buffer */ - ring_buffer rbTX; /**< RX ring buffer */ - uint32 max_baud; /**< Maximum baud */ - uint8 rx_buf[USART_RX_BUF_SIZE]; /**< @brief Deprecated. - * Actual RX buffer used by rb. - * This field will be removed in - * a future release. */ - uint8 tx_buf[USART_TX_BUF_SIZE]; - rcc_clk_id clk_id; /**< RCC clock information */ - nvic_irq_num irq_num; /**< USART NVIC interrupt */ -} usart_dev; - -extern usart_dev *USART1; -extern usart_dev *USART2; -extern usart_dev *USART3; -#ifdef STM32_HIGH_DENSITY -extern usart_dev *UART4; -extern usart_dev *UART5; -#endif - -void usart_init(usart_dev *dev); -void usart_set_baud_rate(usart_dev *dev, uint32 baud); -void usart_enable(usart_dev *dev); -void usart_disable(usart_dev *dev); -void usart_foreach(void (*fn)(usart_dev *dev)); -uint32 usart_tx(usart_dev *dev, const uint8 *buf, uint32 len); -void usart_putudec(usart_dev *dev, uint32 val); - -/** - * @brief Disable all serial ports. - */ -static inline void usart_disable_all(void) { - usart_foreach(usart_disable); -} - -/** - * @brief Transmit one character on a serial port. - * - * This function blocks until the character has been successfully - * transmitted. - * - * @param dev Serial port to send on. - * @param byte Byte to transmit. - */ -static inline void usart_putc(usart_dev* dev, uint8 byte) { - while (!usart_tx(dev, &byte, 1)) - ; -} - -/** - * @brief Transmit a character string on a serial port. - * - * This function blocks until str is completely transmitted. - * - * @param dev Serial port to send on - * @param str String to send - */ -static inline void usart_putstr(usart_dev *dev, const char* str) { - uint32 i = 0; - while (str[i] != '\0') { - usart_putc(dev, str[i++]); - } -} - -/** - * @brief Read one character from a serial port. - * - * It's not safe to call this function if the serial port has no data - * available. - * - * @param dev Serial port to read from - * @return byte read - * @see usart_data_available() - */ -static inline uint8 usart_getc(usart_dev *dev) { - return rb_remove(&dev->rbRX); -} - -/** - * @brief Return the amount of data available in a serial port's RX buffer. - * @param dev Serial port to check - * @return Number of bytes in dev's RX buffer. - */ -static inline uint32 usart_data_available(usart_dev *dev) { - return rb_full_count(&dev->rbRX); -} - -/** - * @brief Return the amount of data available in a serial port's TX buffer. - * @param dev Serial port to check - * @return Number of bytes in dev's TX buffer. - */ -static inline uint32 usart_data_pending(usart_dev *dev) { - return rb_full_count(&dev->rbTX); -} - -/** - * @brief Discard the contents of a serial port's RX buffer. - * @param dev Serial port whose buffer to empty. - */ -static inline void usart_reset_rx(usart_dev *dev) { - rb_reset(&dev->rbRX); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _USART_H_ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file usart.h + * @author Marti Bolivar , + * Perry Hung + * @brief USART definitions and prototypes + */ + +#ifndef _USART_H_ +#define _USART_H_ + +#include "libmaple_types.h" +#include "util.h" +#include "rcc.h" +#include "nvic.h" +#include "ring_buffer.h" +#include "bitband.h" + + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * Register maps and devices + */ + +/** USART register map type */ +typedef struct usart_reg_map { + __io uint32 SR; /**< Status register */ + __io uint32 DR; /**< Data register */ + __io uint32 BRR; /**< Baud rate register */ + __io uint32 CR1; /**< Control register 1 */ + __io uint32 CR2; /**< Control register 2 */ + __io uint32 CR3; /**< Control register 3 */ + __io uint32 GTPR; /**< Guard time and prescaler register */ +} usart_reg_map; + +/** USART1 register map base pointer */ +#ifdef STM32F2 + #define USART1_BASE ((struct usart_reg_map*)0x40011000) +#else + #define USART1_BASE ((struct usart_reg_map*)0x40013800) +#endif +/** USART2 register map base pointer */ +#define USART2_BASE ((struct usart_reg_map*)0x40004400) +/** USART3 register map base pointer */ +#define USART3_BASE ((struct usart_reg_map*)0x40004800) +#ifdef STM32_HIGH_DENSITY +/** UART4 register map base pointer */ +#define UART4_BASE ((struct usart_reg_map*)0x40004C00) +/** UART5 register map base pointer */ +#define UART5_BASE ((struct usart_reg_map*)0x40005000) +#endif + +/* + * Register bit definitions + */ + +/* Status register */ + +#define USART_SR_CTS_BIT 9 +#define USART_SR_LBD_BIT 8 +#define USART_SR_TXE_BIT 7 +#define USART_SR_TC_BIT 6 +#define USART_SR_RXNE_BIT 5 +#define USART_SR_IDLE_BIT 4 +#define USART_SR_ORE_BIT 3 +#define USART_SR_NE_BIT 2 +#define USART_SR_FE_BIT 1 +#define USART_SR_PE_BIT 0 + +#define USART_SR_CTS BIT(USART_SR_CTS_BIT) +#define USART_SR_LBD BIT(USART_SR_LBD_BIT) +#define USART_SR_TXE BIT(USART_SR_TXE_BIT) +#define USART_SR_TC BIT(USART_SR_TC_BIT) +#define USART_SR_RXNE BIT(USART_SR_RXNE_BIT) +#define USART_SR_IDLE BIT(USART_SR_IDLE_BIT) +#define USART_SR_ORE BIT(USART_SR_ORE_BIT) +#define USART_SR_NE BIT(USART_SR_NE_BIT) +#define USART_SR_FE BIT(USART_SR_FE_BIT) +#define USART_SR_PE BIT(USART_SR_PE_BIT) + +/* Data register */ + +#define USART_DR_DR 0xFF + +/* Baud rate register */ + +#define USART_BRR_DIV_MANTISSA (0xFFF << 4) +#define USART_BRR_DIV_FRACTION 0xF + +/* Control register 1 */ + +#define USART_CR1_UE_BIT 13 +#define USART_CR1_M_BIT 12 +#define USART_CR1_WAKE_BIT 11 +#define USART_CR1_PCE_BIT 10 +#define USART_CR1_PS_BIT 9 +#define USART_CR1_PEIE_BIT 8 +#define USART_CR1_TXEIE_BIT 7 +#define USART_CR1_TCIE_BIT 6 +#define USART_CR1_RXNEIE_BIT 5 +#define USART_CR1_IDLEIE_BIT 4 +#define USART_CR1_TE_BIT 3 +#define USART_CR1_RE_BIT 2 +#define USART_CR1_RWU_BIT 1 +#define USART_CR1_SBK_BIT 0 + +#define USART_CR1_UE BIT(USART_CR1_UE_BIT) +#define USART_CR1_M BIT(USART_CR1_M_BIT) +#define USART_CR1_WAKE BIT(USART_CR1_WAKE_BIT) +#define USART_CR1_WAKE_IDLE (0 << USART_CR1_WAKE_BIT) +#define USART_CR1_WAKE_ADDR (1 << USART_CR1_WAKE_BIT) +#define USART_CR1_PCE BIT(USART_CR1_PCE_BIT) +#define USART_CR1_PS BIT(USART_CR1_PS_BIT) +#define USART_CR1_PS_EVEN (0 << USART_CR1_PS_BIT) +#define USART_CR1_PS_ODD (1 << USART_CR1_PS_BIT) +#define USART_CR1_PEIE BIT(USART_CR1_PEIE_BIT) +#define USART_CR1_TXEIE BIT(USART_CR1_TXEIE_BIT) +#define USART_CR1_TCIE BIT(USART_CR1_TCIE_BIT) +#define USART_CR1_RXNEIE BIT(USART_CR1_RXNEIE_BIT) +#define USART_CR1_IDLEIE BIT(USART_CR1_IDLEIE_BIT) +#define USART_CR1_TE BIT(USART_CR1_TE_BIT) +#define USART_CR1_RE BIT(USART_CR1_RE_BIT) +#define USART_CR1_RWU BIT(USART_CR1_RWU_BIT) +#define USART_CR1_RWU_ACTIVE (0 << USART_CR1_RWU_BIT) +#define USART_CR1_RWU_MUTE (1 << USART_CR1_RWU_BIT) +#define USART_CR1_SBK BIT(USART_CR1_SBK_BIT) + +/* Control register 2 */ + +#define USART_CR2_LINEN_BIT 14 +#define USART_CR2_CLKEN_BIT 11 +#define USART_CR2_CPOL_BIT 10 +#define USART_CR2_CPHA_BIT 9 +#define USART_CR2_LBCL_BIT 8 +#define USART_CR2_LBDIE_BIT 6 +#define USART_CR2_LBDL_BIT 5 + +#define USART_CR2_LINEN BIT(USART_CR2_LINEN_BIT) +#define USART_CR2_STOP (0x3 << 12) +#define USART_CR2_STOP_BITS_1 (0x0 << 12) +/* Not on UART4, UART5 */ +#define USART_CR2_STOP_BITS_POINT_5 (0x1 << 12) +/* Not on UART4, UART5 */ +#define USART_CR2_STOP_BITS_1_POINT_5 (0x3 << 12) +#define USART_CR2_STOP_BITS_2 (0x2 << 12) +#define USART_CR2_CLKEN BIT(USART_CR2_CLKEN_BIT) +/* Not on UART4, UART5 */ +#define USART_CR2_CPOL BIT(USART_CR2_CPOL_BIT) +#define USART_CR2_CPOL_LOW (0x0 << USART_CR2_CLKEN_BIT) +#define USART_CR2_CPOL_HIGH (0x1 << USART_CR2_CLKEN_BIT) +/* Not on UART4, UART5 */ +#define USART_CR2_CPHA BIT(USART_CR2_CPHA_BIT) +#define USART_CR2_CPHA_FIRST (0x0 << USART_CR2_CPHA_BIT) +#define USART_CR2_CPHA_SECOND (0x1 << USART_CR2_CPHA_BIT) +/* Not on UART4, UART5 */ +#define USART_CR2_LBCL BIT(USART_CR2_LBCL_BIT) +#define USART_CR2_LBDIE BIT(USART_CR2_LBDIE_BIT) +#define USART_CR2_LBDL BIT(USART_CR2_LBDL_BIT) +#define USART_CR2_LBDL_10_BIT (0 << USART_CR2_LBDL_BIT) +#define USART_CR2_LBDL_11_BIT (1 << USART_CR2_LBDL_BIT) +#define USART_CR2_ADD 0xF + +/* Control register 3 */ + +#define USART_CR3_CTSIE_BIT 10 +#define USART_CR3_CTSE_BIT 9 +#define USART_CR3_RTSE_BIT 8 +#define USART_CR3_DMAT_BIT 7 +#define USART_CR3_DMAR_BIT 6 +#define USART_CR3_SCEN_BIT 5 +#define USART_CR3_NACK_BIT 4 +#define USART_CR3_HDSEL_BIT 3 +#define USART_CR3_IRLP_BIT 2 +#define USART_CR3_IREN_BIT 1 +#define USART_CR3_EIE_BIT 0 + +/* Not on UART4, UART5 */ +#define USART_CR3_CTSIE BIT(USART_CR3_CTSIE_BIT) +/* Not on UART4, UART5 */ +#define USART_CR3_CTSE BIT(USART_CR3_CTSE_BIT) +/* Not on UART4, UART5 */ +#define USART_CR3_RTSE BIT(USART_CR3_RTSE_BIT) +/* Not on UART5 */ +#define USART_CR3_DMAT BIT(USART_CR3_DMAT_BIT) +/* Not on UART5 */ +#define USART_CR3_DMAR BIT(USART_CR3_DMAR_BIT) +/* Not on UART4, UART5 */ +#define USART_CR3_SCEN BIT(USART_CR3_SCEN_BIT) +/* Not on UART4, UART5 */ +#define USART_CR3_NACK BIT(USART_CR3_NACK_BIT) +#define USART_CR3_HDSEL BIT(USART_CR3_HDSEL_BIT) +#define USART_CR3_IRLP BIT(USART_CR3_IRLP_BIT) +#define USART_CR3_IRLP_NORMAL (0 << USART_CR3_IRLP_BIT) +#define USART_CR3_IRLP_LOW_POWER (1 << USART_CR3_IRLP_BIT) +#define USART_CR3_IREN BIT(USART_CR3_IREN_BIT) +#define USART_CR3_EIE BIT(USART_CR3_EIE_BIT) + +/* Guard time and prescaler register */ + +/* Not on UART4, UART5 */ +#define USART_GTPR_GT (0xFF << 8) +/* Not on UART4, UART5 */ +#define USART_GTPR_PSC 0xFF + +/* + * Devices + */ + +#ifndef USART_RX_BUF_SIZE +#define USART_RX_BUF_SIZE 256 +#endif + +#ifndef USART_TX_BUF_SIZE +#define USART_TX_BUF_SIZE 256 +#endif + +/** USART device type */ +typedef struct usart_dev { + usart_reg_map *regs; /**< Register map */ + ring_buffer rbRX; /**< RX ring buffer */ + ring_buffer rbTX; /**< RX ring buffer */ + uint32 max_baud; /**< Maximum baud */ + uint8 rx_buf[USART_RX_BUF_SIZE]; /**< @brief Deprecated. + * Actual RX buffer used by rb. + * This field will be removed in + * a future release. */ + uint8 tx_buf[USART_TX_BUF_SIZE]; + rcc_clk_id clk_id; /**< RCC clock information */ + nvic_irq_num irq_num; /**< USART NVIC interrupt */ +} usart_dev; + +extern usart_dev *USART1; +extern usart_dev *USART2; +extern usart_dev *USART3; +#ifdef STM32_HIGH_DENSITY +extern usart_dev *UART4; +extern usart_dev *UART5; +#endif + +void usart_init(usart_dev *dev); +void usart_set_baud_rate(usart_dev *dev, uint32 baud); +void usart_enable(usart_dev *dev); +void usart_disable(usart_dev *dev); +void usart_foreach(void (*fn)(usart_dev *dev)); +uint32 usart_tx(usart_dev *dev, const uint8 *buf, uint32 len); +void usart_putudec(usart_dev *dev, uint32 val); + +/** + * @brief Disable all serial ports. + */ +static inline void usart_disable_all(void) { + usart_foreach(usart_disable); +} + +/** + * @brief Transmit one character on a serial port. + * + * This function blocks until the character has been successfully + * transmitted. + * + * @param dev Serial port to send on. + * @param byte Byte to transmit. + */ +static inline void usart_putc(usart_dev* dev, uint8 byte) { + while (!usart_tx(dev, &byte, 1)) + ; +} + +/** + * @brief Transmit a character string on a serial port. + * + * This function blocks until str is completely transmitted. + * + * @param dev Serial port to send on + * @param str String to send + */ +static inline void usart_putstr(usart_dev *dev, const char* str) { + uint32 i = 0; + while (str[i] != '\0') { + usart_putc(dev, str[i++]); + } +} + +/** + * @brief Read one character from a serial port. + * + * It's not safe to call this function if the serial port has no data + * available. + * + * @param dev Serial port to read from + * @return byte read + * @see usart_data_available() + */ +static inline uint8 usart_getc(usart_dev *dev) { + return rb_remove(&dev->rbRX); +} + +/** + * @brief Return the amount of data available in a serial port's RX buffer. + * @param dev Serial port to check + * @return Number of bytes in dev's RX buffer. + */ +static inline uint32 usart_data_available(usart_dev *dev) { + return rb_full_count(&dev->rbRX); +} + +/** + * @brief Return the amount of data available in a serial port's TX buffer. + * @param dev Serial port to check + * @return Number of bytes in dev's TX buffer. + */ +static inline uint32 usart_data_pending(usart_dev *dev) { + return rb_full_count(&dev->rbTX); +} + +/** + * @brief Discard the contents of a serial port's RX buffer. + * @param dev Serial port whose buffer to empty. + */ +static inline void usart_reset_rx(usart_dev *dev) { + rb_reset(&dev->rbRX); +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _USART_H_ diff --git a/Libmaple/libmaple/libmaple/usb/README b/Libmaple/libmaple/libmaple/usb/README index e41eeb53..540b1ea6 100644 --- a/Libmaple/libmaple/libmaple/usb/README +++ b/Libmaple/libmaple/libmaple/usb/README @@ -1,100 +1,100 @@ -The USB submodule of libmaple is responsible for: - - Initializing the USB peripheral, scaling the peripheral clocks - appropriately, enabling the interrupt channels to USB, defining - the USB isr, resetting the USB disc pin (used to tell the host - were alive). Additionally, the USB submodule defines the virtual - com port USB applications that is available to all user sketches - via SerialUSB.print() and others. - -To use it: - - [This section is out of date. Does SerialUSB.begin() do the same - thing as the old Usb.init()?] - - SerialUSB.print/ln, available(), read(), write() implement the same - interface as Serial1/2/3 - - -Current Status: - - Currently, the USB submodule relies on the low level core library - provided by ST to access the USB peripheral registers and - implement the USB transfer protocol for control endpoint - transfers. The high level virtual com port application is - unfortunately hard to untangle from this low level dependence, and - when a new USB core library is written (to nix ST dependence) - changes will likely have to be made to virtual com application - code. Ideally, the new core library should mimic the form of MyUSB - (LUFA), since this library (USB for AVR) is growing in popularity - and in example applications. Additionally, the USB lib here relies - on low level hardware functions that were just ripped out of the - bootloader code (for simplicity) but clearly this should be - replaced with direct accesses to functions provided elsewhere in - libmaple. - - The virtual com port serves two important purposes. - - 1) It allows serial data transfers between user sketches an a - host computer. - - 2) It allows the host machine to issue a system reset by - asserting the DTR signal. - - After reset, Maple will run the DFU bootloader for a few seconds, - during which the user can begin a DFU upload operation (uploads - application binary into RAM/FLASH). Thus, without this virtual com - port, it would be necessary to find an alternative means to reset - the chip in order to enable the bootloader. - - If you would like to develop your own USB application for whatever - reason (uses faster isochronous enpoints for streaming audio, or - implements the USB HID or Mass Storage specs for examples) then - ensure that you leave some hook for resetting Maple remotely in - order to spin up the DFU bootloader. Please make sure to give - yourself a unique vendor/product ID pair in your application, as - some operating systems will assign a host-side driver based on - these tags. - - It would be possible to build a compound USB device, that - implements endpoints for both the virtual COM port as well as some - other components (mass storage etc.). However, this turns out to - be a burden from the host driver side, as Windows and *nix handle - compound USB devices quite differently. - - Be mindful that enabling the USB peripheral isnt "free." The - device must respond to periodic bus activity (every few - milliseconds) by servicing an ISR. Therefore, the USB application - should be disabled inside of timing critical applications. In - order to disconnect the device from the host, the USB_DISC pin can - be asserted (on Maple this is GPIO C12). Alternatively, the NVIC - can be directly configured to disable the USB LP/HP IRQ's. - - This library should exposed through usb.h; do not include any - other files direcly in your application. - - The files inside of usb_lib were provided by ST and are subject to - their own license, all other files were written by the LeafLabs - team and fall under the MIT license. - -Integration with libmaple: - - The current USB lib is ported from the Maple bootloader code, - adapted to be a virtual com rather than a DFU device. That means - several functions are redefined locally that could have been - pulled from elsewhere in libmaple. Thus, ths USB module doesn't - have too many dependencies on libmaple. It even ensures that - clocks are configured correctly for its operation. However, over - time, some libmaple dependencies have crept in. - -Todo: - - - write custom low level USB stack to strip out any remaining - dependence on ST code - - remove dependence on hardware.c, since any functions here really - should have their own analogs elsewhere inside libmaple - - add a high level USB application library that would allow users - to make their own HID/Mass Storage/Audio/Video devices. - - implement a SerialUSB.link(SerialX) that forces a passthrough - the host computer virtual com to SerialX, and utilizes the - line_config commands correctly (sets baud etc) +The USB submodule of libmaple is responsible for: + + Initializing the USB peripheral, scaling the peripheral clocks + appropriately, enabling the interrupt channels to USB, defining + the USB isr, resetting the USB disc pin (used to tell the host + were alive). Additionally, the USB submodule defines the virtual + com port USB applications that is available to all user sketches + via SerialUSB.print() and others. + +To use it: + + [This section is out of date. Does SerialUSB.begin() do the same + thing as the old Usb.init()?] + + SerialUSB.print/ln, available(), read(), write() implement the same + interface as Serial1/2/3 + + +Current Status: + + Currently, the USB submodule relies on the low level core library + provided by ST to access the USB peripheral registers and + implement the USB transfer protocol for control endpoint + transfers. The high level virtual com port application is + unfortunately hard to untangle from this low level dependence, and + when a new USB core library is written (to nix ST dependence) + changes will likely have to be made to virtual com application + code. Ideally, the new core library should mimic the form of MyUSB + (LUFA), since this library (USB for AVR) is growing in popularity + and in example applications. Additionally, the USB lib here relies + on low level hardware functions that were just ripped out of the + bootloader code (for simplicity) but clearly this should be + replaced with direct accesses to functions provided elsewhere in + libmaple. + + The virtual com port serves two important purposes. + + 1) It allows serial data transfers between user sketches an a + host computer. + + 2) It allows the host machine to issue a system reset by + asserting the DTR signal. + + After reset, Maple will run the DFU bootloader for a few seconds, + during which the user can begin a DFU upload operation (uploads + application binary into RAM/FLASH). Thus, without this virtual com + port, it would be necessary to find an alternative means to reset + the chip in order to enable the bootloader. + + If you would like to develop your own USB application for whatever + reason (uses faster isochronous enpoints for streaming audio, or + implements the USB HID or Mass Storage specs for examples) then + ensure that you leave some hook for resetting Maple remotely in + order to spin up the DFU bootloader. Please make sure to give + yourself a unique vendor/product ID pair in your application, as + some operating systems will assign a host-side driver based on + these tags. + + It would be possible to build a compound USB device, that + implements endpoints for both the virtual COM port as well as some + other components (mass storage etc.). However, this turns out to + be a burden from the host driver side, as Windows and *nix handle + compound USB devices quite differently. + + Be mindful that enabling the USB peripheral isnt "free." The + device must respond to periodic bus activity (every few + milliseconds) by servicing an ISR. Therefore, the USB application + should be disabled inside of timing critical applications. In + order to disconnect the device from the host, the USB_DISC pin can + be asserted (on Maple this is GPIO C12). Alternatively, the NVIC + can be directly configured to disable the USB LP/HP IRQ's. + + This library should exposed through usb.h; do not include any + other files direcly in your application. + + The files inside of usb_lib were provided by ST and are subject to + their own license, all other files were written by the LeafLabs + team and fall under the MIT license. + +Integration with libmaple: + + The current USB lib is ported from the Maple bootloader code, + adapted to be a virtual com rather than a DFU device. That means + several functions are redefined locally that could have been + pulled from elsewhere in libmaple. Thus, ths USB module doesn't + have too many dependencies on libmaple. It even ensures that + clocks are configured correctly for its operation. However, over + time, some libmaple dependencies have crept in. + +Todo: + + - write custom low level USB stack to strip out any remaining + dependence on ST code + - remove dependence on hardware.c, since any functions here really + should have their own analogs elsewhere inside libmaple + - add a high level USB application library that would allow users + to make their own HID/Mass Storage/Audio/Video devices. + - implement a SerialUSB.link(SerialX) that forces a passthrough + the host computer virtual com to SerialX, and utilizes the + line_config commands correctly (sets baud etc) diff --git a/Libmaple/libmaple/libmaple/usb/descriptors.c b/Libmaple/libmaple/libmaple/usb/descriptors.c index e41ed016..8dd95212 100644 --- a/Libmaple/libmaple/libmaple/usb/descriptors.c +++ b/Libmaple/libmaple/libmaple/usb/descriptors.c @@ -1,199 +1,199 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include "descriptors.h" -#include "libmaple.h" -#include "usb_config.h" - -const USB_Descriptor_Device usbVcomDescriptor_Device = { - bLength: sizeof(USB_Descriptor_Device), - bDescriptorType: USB_DESCRIPTOR_TYPE_DEVICE, - bcdUSB: 0x0200, - bDeviceClass: USB_DEVICE_CLASS_CDC, - bDeviceSubClass: USB_DEVICE_SUBCLASS_CDC, - bDeviceProtocol: 0x00, - bMaxPacketSize0: 0x40, - idVendor: VCOM_ID_VENDOR, - idProduct: VCOM_ID_PRODUCT, - bcdDevice: 0x0200, - iManufacturer: 0x01, - iProduct: 0x02, - iSerialNumber: 0x00, - bNumConfigurations: 0x01 -}; - -const USB_Descriptor_Config usbVcomDescriptor_Config = { - bLength: 0x09,//sizeof(USB_Descriptor_Config_Header), - bDescriptorType: USB_DESCRIPTOR_TYPE_CONFIGURATION, - wTotalLength: 0x43,//sizeof(USB_Descriptor_Config), - bNumInterfaces: 0x02, - bConfigurationValue: 0x01, - iConfiguration: 0x00, - bmAttributes: (USB_CONFIG_ATTR_BUSPOWERED | - USB_CONFIG_ATTR_SELF_POWERED), - bMaxPower: USB_CONFIG_MAX_POWER, - - CCI_Interface: - { - bLength: 0x09,//sizeof(USB_Descriptor_Interface), - bDescriptorType: USB_DESCRIPTOR_TYPE_INTERFACE, - bInterfaceNumber: 0x00, - bAlternateSetting: 0x00, - bNumEndpoints: 0x01, - bInterfaceClass: 0x02, - bInterfaceSubClass: 0x02, - bInterfaceProtocol: 0x01, - iInterface: 0x00 - }, - - CDC_Functional_IntHeader: - { - bLength: 0x05,//sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), - bDescriptorType: 0x24, - SubType: 0x00, - Data: {0x01, 0x10} - }, - - CDC_Functional_CallManagement: - { - bLength: 0x05,//sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), - bDescriptorType: 0x24, - SubType: 0x01, - Data: {0x03, 0x01} - }, - - CDC_Functional_ACM: - { - bLength: 0x04,//sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), - bDescriptorType: 0x24, - SubType: 0x02, - Data: {0x06} - }, - - CDC_Functional_Union: - { - bLength: 0x05,//sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), - bDescriptorType: 0x24, - SubType: 0x06, - Data: {0x00, 0x01} - }, - - // ManagementEndpoint: - // { - EP1_bLength: 0x07,//sizeof(USB_Descriptor_Endpoint), - EP1_bDescriptorType: USB_DESCRIPTOR_TYPE_ENDPOINT, - EP1_bEndpointAddress: (USB_DESCRIPTOR_ENDPOINT_IN | VCOM_NOTIFICATION_EPNUM), - EP1_bmAttributes: EP_TYPE_INTERRUPT, - EP1_wMaxPacketSize0: VCOM_NOTIFICATION_EPSIZE, - EP1_wMaxPacketSize1: 0x00, - EP1_bInterval: 0xFF, - // }, - - // DCI_Interface: - // { - DCI_bLength: 0x09,//sizeof(USB_Descriptor_Interface), - DCI_bDescriptorType: USB_DESCRIPTOR_TYPE_INTERFACE, - DCI_bInterfaceNumber: 0x01, - DCI_bAlternateSetting: 0x00, - DCI_bNumEndpoints: 0x02, - DCI_bInterfaceClass: 0x0A, - DCI_bInterfaceSubClass: 0x00, - DCI_bInterfaceProtocol: 0x00, - DCI_iInterface: 0x00, - // }, - - //DataOutEndpoint: - // { - // }, - EP2_bLength: 0x07,//sizeof(USB_Descriptor_Endpoint), - EP2_bDescriptorType: USB_DESCRIPTOR_TYPE_ENDPOINT, - EP2_bEndpointAddress: (USB_DESCRIPTOR_ENDPOINT_OUT | VCOM_RX_EPNUM), - EP2_bmAttributes: EP_TYPE_BULK, - EP2_wMaxPacketSize0: VCOM_RX_EPSIZE, - EP2_wMaxPacketSize1: 0x00, - EP2_bInterval: 0x00, - - - // DataInEndpoint: - // { - EP3_bLength: 0x07,//sizeof(USB_Descriptor_Endpoint), - EP3_bDescriptorType: USB_DESCRIPTOR_TYPE_ENDPOINT, - EP3_bEndpointAddress: (USB_DESCRIPTOR_ENDPOINT_IN | VCOM_TX_EPNUM), - EP3_bmAttributes: EP_TYPE_BULK, - EP3_wMaxPacketSize0: VCOM_TX_EPSIZE, - EP3_wMaxPacketSize1: 0x00, - EP3_bInterval: 0x00 - - // } -}; - -/***************************************************************************** - ***************************************************************************** - *** - *** FIXME FIXME FIXME NOT THE RIGHT THING! MOVE ALL THIS INTO TO WIRISH! - *** - ***************************************************************************** - *****************************************************************************/ - -const uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)] = { - USB_DESCRIPTOR_STRING_LEN(1), - USB_DESCRIPTOR_TYPE_STRING, - 0x09, - 0x04 -}; - -const uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)] = { - USB_DESCRIPTOR_STRING_LEN(8), - USB_DESCRIPTOR_TYPE_STRING, - 'L', 0, 'e', 0, 'a', 0, 'f', 0, - 'L', 0, 'a', 0, 'b', 0, 's', 0 -}; - -/* - String Identifiers: - - we may choose to specify any or none of the following string - identifiers: - - iManufacturer: LeafLabs - iProduct: Maple R3 - iSerialNumber: NONE - iConfiguration: NONE - iInterface(CCI): NONE - iInterface(DCI): NONE - - additionally we must provide the unicode language identifier, - which is 0x0409 for US English -*/ -const uint8 usbVcomDescriptor_iProduct[USB_DESCRIPTOR_STRING_LEN(8)] = { - USB_DESCRIPTOR_STRING_LEN(8), - USB_DESCRIPTOR_TYPE_STRING, - 'M', 0, 'a', 0, 'p', 0, 'l', 0, - 'e', 0, ' ', 0, ' ', 0, ' ', 0 -}; - -/***************************************************************************** - *****************************************************************************/ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +#include "descriptors.h" +#include "libmaple.h" +#include "usb_config.h" + +const USB_Descriptor_Device usbVcomDescriptor_Device = { + bLength: sizeof(USB_Descriptor_Device), + bDescriptorType: USB_DESCRIPTOR_TYPE_DEVICE, + bcdUSB: 0x0200, + bDeviceClass: USB_DEVICE_CLASS_CDC, + bDeviceSubClass: USB_DEVICE_SUBCLASS_CDC, + bDeviceProtocol: 0x00, + bMaxPacketSize0: 0x40, + idVendor: VCOM_ID_VENDOR, + idProduct: VCOM_ID_PRODUCT, + bcdDevice: 0x0200, + iManufacturer: 0x01, + iProduct: 0x02, + iSerialNumber: 0x00, + bNumConfigurations: 0x01 +}; + +const USB_Descriptor_Config usbVcomDescriptor_Config = { + bLength: 0x09,//sizeof(USB_Descriptor_Config_Header), + bDescriptorType: USB_DESCRIPTOR_TYPE_CONFIGURATION, + wTotalLength: 0x43,//sizeof(USB_Descriptor_Config), + bNumInterfaces: 0x02, + bConfigurationValue: 0x01, + iConfiguration: 0x00, + bmAttributes: (USB_CONFIG_ATTR_BUSPOWERED | + USB_CONFIG_ATTR_SELF_POWERED), + bMaxPower: USB_CONFIG_MAX_POWER, + + CCI_Interface: + { + bLength: 0x09,//sizeof(USB_Descriptor_Interface), + bDescriptorType: USB_DESCRIPTOR_TYPE_INTERFACE, + bInterfaceNumber: 0x00, + bAlternateSetting: 0x00, + bNumEndpoints: 0x01, + bInterfaceClass: 0x02, + bInterfaceSubClass: 0x02, + bInterfaceProtocol: 0x01, + iInterface: 0x00 + }, + + CDC_Functional_IntHeader: + { + bLength: 0x05,//sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), + bDescriptorType: 0x24, + SubType: 0x00, + Data: {0x01, 0x10} + }, + + CDC_Functional_CallManagement: + { + bLength: 0x05,//sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), + bDescriptorType: 0x24, + SubType: 0x01, + Data: {0x03, 0x01} + }, + + CDC_Functional_ACM: + { + bLength: 0x04,//sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), + bDescriptorType: 0x24, + SubType: 0x02, + Data: {0x06} + }, + + CDC_Functional_Union: + { + bLength: 0x05,//sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), + bDescriptorType: 0x24, + SubType: 0x06, + Data: {0x00, 0x01} + }, + + // ManagementEndpoint: + // { + EP1_bLength: 0x07,//sizeof(USB_Descriptor_Endpoint), + EP1_bDescriptorType: USB_DESCRIPTOR_TYPE_ENDPOINT, + EP1_bEndpointAddress: (USB_DESCRIPTOR_ENDPOINT_IN | VCOM_NOTIFICATION_EPNUM), + EP1_bmAttributes: EP_TYPE_INTERRUPT, + EP1_wMaxPacketSize0: VCOM_NOTIFICATION_EPSIZE, + EP1_wMaxPacketSize1: 0x00, + EP1_bInterval: 0xFF, + // }, + + // DCI_Interface: + // { + DCI_bLength: 0x09,//sizeof(USB_Descriptor_Interface), + DCI_bDescriptorType: USB_DESCRIPTOR_TYPE_INTERFACE, + DCI_bInterfaceNumber: 0x01, + DCI_bAlternateSetting: 0x00, + DCI_bNumEndpoints: 0x02, + DCI_bInterfaceClass: 0x0A, + DCI_bInterfaceSubClass: 0x00, + DCI_bInterfaceProtocol: 0x00, + DCI_iInterface: 0x00, + // }, + + //DataOutEndpoint: + // { + // }, + EP2_bLength: 0x07,//sizeof(USB_Descriptor_Endpoint), + EP2_bDescriptorType: USB_DESCRIPTOR_TYPE_ENDPOINT, + EP2_bEndpointAddress: (USB_DESCRIPTOR_ENDPOINT_OUT | VCOM_RX_EPNUM), + EP2_bmAttributes: EP_TYPE_BULK, + EP2_wMaxPacketSize0: VCOM_RX_EPSIZE, + EP2_wMaxPacketSize1: 0x00, + EP2_bInterval: 0x00, + + + // DataInEndpoint: + // { + EP3_bLength: 0x07,//sizeof(USB_Descriptor_Endpoint), + EP3_bDescriptorType: USB_DESCRIPTOR_TYPE_ENDPOINT, + EP3_bEndpointAddress: (USB_DESCRIPTOR_ENDPOINT_IN | VCOM_TX_EPNUM), + EP3_bmAttributes: EP_TYPE_BULK, + EP3_wMaxPacketSize0: VCOM_TX_EPSIZE, + EP3_wMaxPacketSize1: 0x00, + EP3_bInterval: 0x00 + + // } +}; + +/***************************************************************************** + ***************************************************************************** + *** + *** FIXME FIXME FIXME NOT THE RIGHT THING! MOVE ALL THIS INTO TO WIRISH! + *** + ***************************************************************************** + *****************************************************************************/ + +const uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)] = { + USB_DESCRIPTOR_STRING_LEN(1), + USB_DESCRIPTOR_TYPE_STRING, + 0x09, + 0x04 +}; + +const uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)] = { + USB_DESCRIPTOR_STRING_LEN(8), + USB_DESCRIPTOR_TYPE_STRING, + 'L', 0, 'e', 0, 'a', 0, 'f', 0, + 'L', 0, 'a', 0, 'b', 0, 's', 0 +}; + +/* + String Identifiers: + + we may choose to specify any or none of the following string + identifiers: + + iManufacturer: LeafLabs + iProduct: Maple R3 + iSerialNumber: NONE + iConfiguration: NONE + iInterface(CCI): NONE + iInterface(DCI): NONE + + additionally we must provide the unicode language identifier, + which is 0x0409 for US English +*/ +const uint8 usbVcomDescriptor_iProduct[USB_DESCRIPTOR_STRING_LEN(8)] = { + USB_DESCRIPTOR_STRING_LEN(8), + USB_DESCRIPTOR_TYPE_STRING, + 'M', 0, 'a', 0, 'p', 0, 'l', 0, + 'e', 0, ' ', 0, ' ', 0, ' ', 0 +}; + +/***************************************************************************** + *****************************************************************************/ diff --git a/Libmaple/libmaple/libmaple/usb/descriptors.h b/Libmaple/libmaple/libmaple/usb/descriptors.h index 6207e1b9..460a88cd 100644 --- a/Libmaple/libmaple/libmaple/usb/descriptors.h +++ b/Libmaple/libmaple/libmaple/usb/descriptors.h @@ -1,225 +1,225 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -#ifndef __DESCRIPTORS_H -#define __DESCRIPTORS_H - - -#include "libmaple.h" -#include "usb_lib.h" - -#define USB_DESCRIPTOR_TYPE_DEVICE 0x01 -#define USB_DESCRIPTOR_TYPE_CONFIGURATION 0x02 -#define USB_DESCRIPTOR_TYPE_STRING 0x03 -#define USB_DESCRIPTOR_TYPE_INTERFACE 0x04 -#define USB_DESCRIPTOR_TYPE_ENDPOINT 0x05 - -#define USB_DEVICE_CLASS_CDC 0x02 -#define USB_DEVICE_SUBCLASS_CDC 0x00 - -#define USB_CONFIG_ATTR_BUSPOWERED 0b10000000 -#define USB_CONFIG_ATTR_SELF_POWERED 0b11000000 - -#define EP_TYPE_INTERRUPT 0x03 -#define EP_TYPE_BULK 0x02 - -#define USB_DESCRIPTOR_ENDPOINT_IN 0x80 -#define USB_DESCRIPTOR_ENDPOINT_OUT 0x00 - -#define USB_DESCRIPTOR_STRING_LEN(x) (2 + (x << 1)) - - -#if defined(__cplusplus) -extern "C" { -#endif - -#define USB_DESCRIPTOR_STRING(len) \ - struct { \ - uint8 bLength; \ - uint8 bDescriptorType; \ - uint16 bString[len]; \ - } - -#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \ - struct \ - { \ - uint8 bLength; \ - uint8 bDescriptorType; \ - uint8 SubType; \ - uint8 Data[DataSize]; \ - } - -typedef struct { - uint8 bLength; - uint8 bDescriptorType; - uint16 bcdUSB; - uint8 bDeviceClass; - uint8 bDeviceSubClass; - uint8 bDeviceProtocol; - uint8 bMaxPacketSize0; - uint16 idVendor; - uint16 idProduct; - uint16 bcdDevice; - uint8 iManufacturer; - uint8 iProduct; - uint8 iSerialNumber; - uint8 bNumConfigurations; -} USB_Descriptor_Device; - -typedef struct { - uint8 bLength; - uint8 bDescriptorType; - uint16 wTotalLength; - uint8 bNumInterfaces; - uint8 bConfigurationValue; - uint8 iConfiguration; - uint8 bmAttributes; - uint8 bMaxPower; -} USB_Descriptor_Config_Header; - -typedef struct { - uint8 bLength; - uint8 bDescriptorType; - uint8 bInterfaceNumber; - uint8 bAlternateSetting; - uint8 bNumEndpoints; - uint8 bInterfaceClass; - uint8 bInterfaceSubClass; - uint8 bInterfaceProtocol; - uint8 iInterface; -} USB_Descriptor_Interface; - -typedef struct { - uint8 bLength; - uint8 bDescriptorType; - uint8 bEndpointAddress; - uint8 bmAttributes; - uint16 wMaxPacketSize; - uint8 bInterval; -} USB_Descriptor_Endpoint; - -typedef struct { - /* config header */ - uint8 bLength; - uint8 bDescriptorType; - uint16 wTotalLength; - uint8 bNumInterfaces; - uint8 bConfigurationValue; - uint8 iConfiguration; - uint8 bmAttributes; - uint8 bMaxPower; - - USB_Descriptor_Interface CCI_Interface; - struct { - uint8 bLength; - uint8 bDescriptorType; - uint8 SubType; - uint8 Data[2]; - } CDC_Functional_IntHeader; - struct { - uint8 bLength; - uint8 bDescriptorType; - uint8 SubType; - uint8 Data[2]; - } CDC_Functional_CallManagement; - struct { - uint8 bLength; - uint8 bDescriptorType; - uint8 SubType; - uint8 Data[1]; - } CDC_Functional_ACM; - struct { - uint8 bLength; - uint8 bDescriptorType; - uint8 SubType; - uint8 Data[2]; - } CDC_Functional_Union; - - /* - USB_Descriptor_Endpoint ManagementEndpoint; - */ - uint8 EP1_bLength; - uint8 EP1_bDescriptorType; - uint8 EP1_bEndpointAddress; - uint8 EP1_bmAttributes; - uint8 EP1_wMaxPacketSize0; - uint8 EP1_wMaxPacketSize1; - uint8 EP1_bInterval; - - /* - USB_Descriptor_Interface DCI_Interface; - */ - - uint8 DCI_bLength; - uint8 DCI_bDescriptorType; - uint8 DCI_bInterfaceNumber; - uint8 DCI_bAlternateSetting; - uint8 DCI_bNumEndpoints; - uint8 DCI_bInterfaceClass; - uint8 DCI_bInterfaceSubClass; - uint8 DCI_bInterfaceProtocol; - uint8 DCI_iInterface; - - /* - USB_Descriptor_Endpoint DataOutEndpoint; - USB_Descriptor_Endpoint DataInEndpoint; - */ - - uint8 EP2_bLength; - uint8 EP2_bDescriptorType; - uint8 EP2_bEndpointAddress; - uint8 EP2_bmAttributes; - uint8 EP2_wMaxPacketSize0; - uint8 EP2_wMaxPacketSize1; - uint8 EP2_bInterval; - - uint8 EP3_bLength; - uint8 EP3_bDescriptorType; - uint8 EP3_bEndpointAddress; - uint8 EP3_bmAttributes; - uint8 EP3_wMaxPacketSize0; - uint8 EP3_wMaxPacketSize1; - uint8 EP3_bInterval; - - -}USB_Descriptor_Config; - - typedef struct { - uint8 bLength; - uint8 bDescriptorType; - uint16 bString[]; - } USB_Descriptor_String; - -extern const USB_Descriptor_Device usbVcomDescriptor_Device; -extern const USB_Descriptor_Config usbVcomDescriptor_Config; - -extern const uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)]; -extern const uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)]; -extern const uint8 usbVcomDescriptor_iProduct[USB_DESCRIPTOR_STRING_LEN(8)]; - -#if defined(__cplusplus) - } -#endif - -#endif // __DESCRIPTORS_H +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +#ifndef __DESCRIPTORS_H +#define __DESCRIPTORS_H + + +#include "libmaple.h" +#include "usb_lib.h" + +#define USB_DESCRIPTOR_TYPE_DEVICE 0x01 +#define USB_DESCRIPTOR_TYPE_CONFIGURATION 0x02 +#define USB_DESCRIPTOR_TYPE_STRING 0x03 +#define USB_DESCRIPTOR_TYPE_INTERFACE 0x04 +#define USB_DESCRIPTOR_TYPE_ENDPOINT 0x05 + +#define USB_DEVICE_CLASS_CDC 0x02 +#define USB_DEVICE_SUBCLASS_CDC 0x00 + +#define USB_CONFIG_ATTR_BUSPOWERED 0b10000000 +#define USB_CONFIG_ATTR_SELF_POWERED 0b11000000 + +#define EP_TYPE_INTERRUPT 0x03 +#define EP_TYPE_BULK 0x02 + +#define USB_DESCRIPTOR_ENDPOINT_IN 0x80 +#define USB_DESCRIPTOR_ENDPOINT_OUT 0x00 + +#define USB_DESCRIPTOR_STRING_LEN(x) (2 + (x << 1)) + + +#if defined(__cplusplus) +extern "C" { +#endif + +#define USB_DESCRIPTOR_STRING(len) \ + struct { \ + uint8 bLength; \ + uint8 bDescriptorType; \ + uint16 bString[len]; \ + } + +#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \ + struct \ + { \ + uint8 bLength; \ + uint8 bDescriptorType; \ + uint8 SubType; \ + uint8 Data[DataSize]; \ + } + +typedef struct { + uint8 bLength; + uint8 bDescriptorType; + uint16 bcdUSB; + uint8 bDeviceClass; + uint8 bDeviceSubClass; + uint8 bDeviceProtocol; + uint8 bMaxPacketSize0; + uint16 idVendor; + uint16 idProduct; + uint16 bcdDevice; + uint8 iManufacturer; + uint8 iProduct; + uint8 iSerialNumber; + uint8 bNumConfigurations; +} USB_Descriptor_Device; + +typedef struct { + uint8 bLength; + uint8 bDescriptorType; + uint16 wTotalLength; + uint8 bNumInterfaces; + uint8 bConfigurationValue; + uint8 iConfiguration; + uint8 bmAttributes; + uint8 bMaxPower; +} USB_Descriptor_Config_Header; + +typedef struct { + uint8 bLength; + uint8 bDescriptorType; + uint8 bInterfaceNumber; + uint8 bAlternateSetting; + uint8 bNumEndpoints; + uint8 bInterfaceClass; + uint8 bInterfaceSubClass; + uint8 bInterfaceProtocol; + uint8 iInterface; +} USB_Descriptor_Interface; + +typedef struct { + uint8 bLength; + uint8 bDescriptorType; + uint8 bEndpointAddress; + uint8 bmAttributes; + uint16 wMaxPacketSize; + uint8 bInterval; +} USB_Descriptor_Endpoint; + +typedef struct { + /* config header */ + uint8 bLength; + uint8 bDescriptorType; + uint16 wTotalLength; + uint8 bNumInterfaces; + uint8 bConfigurationValue; + uint8 iConfiguration; + uint8 bmAttributes; + uint8 bMaxPower; + + USB_Descriptor_Interface CCI_Interface; + struct { + uint8 bLength; + uint8 bDescriptorType; + uint8 SubType; + uint8 Data[2]; + } CDC_Functional_IntHeader; + struct { + uint8 bLength; + uint8 bDescriptorType; + uint8 SubType; + uint8 Data[2]; + } CDC_Functional_CallManagement; + struct { + uint8 bLength; + uint8 bDescriptorType; + uint8 SubType; + uint8 Data[1]; + } CDC_Functional_ACM; + struct { + uint8 bLength; + uint8 bDescriptorType; + uint8 SubType; + uint8 Data[2]; + } CDC_Functional_Union; + + /* + USB_Descriptor_Endpoint ManagementEndpoint; + */ + uint8 EP1_bLength; + uint8 EP1_bDescriptorType; + uint8 EP1_bEndpointAddress; + uint8 EP1_bmAttributes; + uint8 EP1_wMaxPacketSize0; + uint8 EP1_wMaxPacketSize1; + uint8 EP1_bInterval; + + /* + USB_Descriptor_Interface DCI_Interface; + */ + + uint8 DCI_bLength; + uint8 DCI_bDescriptorType; + uint8 DCI_bInterfaceNumber; + uint8 DCI_bAlternateSetting; + uint8 DCI_bNumEndpoints; + uint8 DCI_bInterfaceClass; + uint8 DCI_bInterfaceSubClass; + uint8 DCI_bInterfaceProtocol; + uint8 DCI_iInterface; + + /* + USB_Descriptor_Endpoint DataOutEndpoint; + USB_Descriptor_Endpoint DataInEndpoint; + */ + + uint8 EP2_bLength; + uint8 EP2_bDescriptorType; + uint8 EP2_bEndpointAddress; + uint8 EP2_bmAttributes; + uint8 EP2_wMaxPacketSize0; + uint8 EP2_wMaxPacketSize1; + uint8 EP2_bInterval; + + uint8 EP3_bLength; + uint8 EP3_bDescriptorType; + uint8 EP3_bEndpointAddress; + uint8 EP3_bmAttributes; + uint8 EP3_wMaxPacketSize0; + uint8 EP3_wMaxPacketSize1; + uint8 EP3_bInterval; + + +}USB_Descriptor_Config; + + typedef struct { + uint8 bLength; + uint8 bDescriptorType; + uint16 bString[]; + } USB_Descriptor_String; + +extern const USB_Descriptor_Device usbVcomDescriptor_Device; +extern const USB_Descriptor_Config usbVcomDescriptor_Config; + +extern const uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)]; +extern const uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)]; +extern const uint8 usbVcomDescriptor_iProduct[USB_DESCRIPTOR_STRING_LEN(8)]; + +#if defined(__cplusplus) + } +#endif + +#endif // __DESCRIPTORS_H diff --git a/Libmaple/libmaple/libmaple/usb/usb.c b/Libmaple/libmaple/libmaple/usb/usb.c index eb14eca4..ae21b062 100644 --- a/Libmaple/libmaple/libmaple/usb/usb.c +++ b/Libmaple/libmaple/libmaple/usb/usb.c @@ -1,488 +1,488 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief usb-specific hardware setup, NVIC, clocks, and usb activities - * in the pre-attached state. includes some of the lower level callbacks - * needed by the usb library, like suspend,resume,init,etc - */ -#ifdef DISABLEUSB -#include "usb_hardware.h" -#include "usb_regs.h" -void setupUSB (void) { -#if 0 - NVIC_InitTypeDef NVIC_InitStructure; - NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE; - nvicInit(&NVIC_InitStructure); - - pRCC->APB1ENR &= ~RCC_APB1ENR_USBEN_BIT; // disable USB - _SetCNTR(CNTR_FRES); - _SetISTR(0); - _SetCNTR(CNTR_FRES + CNTR_PDWN); -#endif -} -#else -#include "usb.h" -#include "libmaple.h" -#include "usb_lib.h" -#include "gpio.h" -#include "usb_hardware.h" -#include "delay.h" - -#include "usb_config.h" -#include "usb_callbacks.h" -#include "usb_lib.h" - -/* persistent usb structs */ - -volatile uint32 bDeviceState = UNCONNECTED; -volatile uint16 wIstr = 0; -volatile uint32 bIntPackSOF = 0; - -DEVICE Device_Table = - {NUM_ENDPTS, - 1}; - -DEVICE_PROP Device_Property = - {usbInit, - usbReset, - usbStatusIn, - usbStatusOut, - usbDataSetup, - usbNoDataSetup, - usbGetInterfaceSetting, - usbGetDeviceDescriptor, - usbGetConfigDescriptor, - usbGetStringDescriptor, - 0, - bMaxPacketSize}; - -USER_STANDARD_REQUESTS User_Standard_Requests = - {NOP_Process, - usbSetConfiguration, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process, - usbSetDeviceAddress}; - -void (*pEpInt_IN[7])(void) = - {vcomDataTxCb, - vcomManagementCb, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process}; - -void (*pEpInt_OUT[7])(void) = - {NOP_Process, - NOP_Process, - vcomDataRxCb, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process}; - -struct { - volatile RESUME_STATE eState; - volatile uint8 bESOFcnt; -} ResumeS; - -#if defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1) || defined(BOARD_aeroquad32mini) - -void setupUSB (void) { -#ifdef USB_DISC_OD - gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42 -#else - gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_PP); // ala42 for active pull-up on disconnect pin -#endif - - gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN,0); // ala42 - delay_us(200000); - - /* setup the apb1 clock for USB */ - pRCC->APB1ENR |= 0x00800000; - - /* initialize the usb application */ - gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 1); // ala42 // presents us to the host - USB_Init(); // low level init routine provided by the ST library -} - -void disableUSB (void) { - // These are just guesses about how to do this - // TODO: real disable function - usbDsbISR(); - gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 0); // ala42 -} - -#else - -void setupUSB (void) { - gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_PP); - - /* setup the apb1 clock for USB */ - pRCC->APB1ENR |= 0x00800000; - - /* initialize the usb application */ - gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 0); // presents us to the host - USB_Init(); // low level init routine provided by the ST library -} - -void disableUSB (void) { - // These are just guesses about how to do this - // TODO: real disable function - usbDsbISR(); - gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 1); -} - -#endif - - -void usbSuspend(void) { - u16 wCNTR; - wCNTR = _GetCNTR(); - wCNTR |= CNTR_FSUSP | CNTR_LPMODE; - _SetCNTR(wCNTR); - - /* run any power reduction handlers */ - bDeviceState = SUSPENDED; -} - -void usbResumeInit(void) { - u16 wCNTR; - - /* restart any clocks that had been stopped */ - - wCNTR = _GetCNTR(); - wCNTR &= (~CNTR_LPMODE); - _SetCNTR(wCNTR); - - /* undo power reduction handlers here */ - _SetCNTR(ISR_MSK); - -} - -void usbResume(RESUME_STATE eResumeSetVal) { - u16 wCNTR; - - if (eResumeSetVal != RESUME_ESOF) - ResumeS.eState = eResumeSetVal; - - switch (ResumeS.eState) - { - case RESUME_EXTERNAL: - usbResumeInit(); - ResumeS.eState = RESUME_OFF; - break; - case RESUME_INTERNAL: - usbResumeInit(); - ResumeS.eState = RESUME_START; - break; - case RESUME_LATER: - ResumeS.bESOFcnt = 2; - ResumeS.eState = RESUME_WAIT; - break; - case RESUME_WAIT: - ResumeS.bESOFcnt--; - if (ResumeS.bESOFcnt == 0) - ResumeS.eState = RESUME_START; - break; - case RESUME_START: - wCNTR = _GetCNTR(); - wCNTR |= CNTR_RESUME; - _SetCNTR(wCNTR); - ResumeS.eState = RESUME_ON; - ResumeS.bESOFcnt = 10; - break; - case RESUME_ON: - ResumeS.bESOFcnt--; - if (ResumeS.bESOFcnt == 0) { - wCNTR = _GetCNTR(); - wCNTR &= (~CNTR_RESUME); - _SetCNTR(wCNTR); - ResumeS.eState = RESUME_OFF; - } - break; - case RESUME_OFF: - case RESUME_ESOF: - default: - ResumeS.eState = RESUME_OFF; - break; - } -} - -RESULT usbPowerOn(void) { - u16 wRegVal; - - wRegVal = CNTR_FRES; - _SetCNTR(wRegVal); - - wInterrupt_Mask = 0; - _SetCNTR(wInterrupt_Mask); - _SetISTR(0); - wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM; // the bare minimum - _SetCNTR(wInterrupt_Mask); - - return USB_SUCCESS; -} - -RESULT usbPowerOff(void) { - _SetCNTR(CNTR_FRES); - _SetISTR(0); - _SetCNTR(CNTR_FRES + CNTR_PDWN); - - /* note that all weve done here is powerdown the - usb peripheral. we have no disabled the clocks, - pulled the usb_disc pin back up, or reset the - application state machines */ - - return USB_SUCCESS; -} - - -// These two functions (usbEnbISR/usbDsbISR) are implementented in ST style, -// and at least the DsbISR doesn't seem to work? -void usbEnbISR(void) { - NVIC_InitTypeDef NVIC_InitStructure; - NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE; - nvicInit(&NVIC_InitStructure); -} - -void usbDsbISR(void) { - NVIC_InitTypeDef NVIC_InitStructure; - NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE; - nvicInit(&NVIC_InitStructure); -} - -/* overloaded ISR routine, this is the main usb ISR */ -void __irq_usb_lp_can_rx0(void) { -wIstr = _GetISTR(); - -/* go nuts with the preproc switches since this is an ISTR and must be FAST */ -#if (ISR_MSK & ISTR_RESET) -if (wIstr & ISTR_RESET & wInterrupt_Mask) - { - _SetISTR((u16)CLR_RESET); - Device_Property.Reset(); - } -#endif - - -#if (ISR_MSK & ISTR_DOVR) -if (wIstr & ISTR_DOVR & wInterrupt_Mask) - { - _SetISTR((u16)CLR_DOVR); - } -#endif - - -#if (ISR_MSK & ISTR_ERR) -if (wIstr & ISTR_ERR & wInterrupt_Mask) - { - _SetISTR((u16)CLR_ERR); - } -#endif - - -#if (ISR_MSK & ISTR_WKUP) -if (wIstr & ISTR_WKUP & wInterrupt_Mask) { - _SetISTR((u16)CLR_WKUP); - usbResume(RESUME_EXTERNAL); -} -#endif - -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ -#if (ISR_MSK & ISTR_SUSP) -if (wIstr & ISTR_SUSP & wInterrupt_Mask) { - /* check if SUSPEND is possible */ - if (F_SUSPEND_ENABLED) { - usbSuspend(); - } else { - /* if not possible then resume after xx ms */ - usbResume(RESUME_LATER); - } - /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ - _SetISTR((u16)CLR_SUSP); -} -#endif - - -#if (ISR_MSK & ISTR_SOF) -if (wIstr & ISTR_SOF & wInterrupt_Mask) { - _SetISTR((u16)CLR_SOF); - bIntPackSOF++; - } -#endif - - -#if (ISR_MSK & ISTR_ESOF) -if (wIstr & ISTR_ESOF & wInterrupt_Mask) { - _SetISTR((u16)CLR_ESOF); - /* resume handling timing is made with ESOFs */ - usbResume(RESUME_ESOF); /* request without change of the machine state */ - } -#endif - -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ -#if (ISR_MSK & ISTR_CTR) -if (wIstr & ISTR_CTR & wInterrupt_Mask) { - /* servicing of the endpoint correct transfer interrupt */ - /* clear of the CTR flag into the sub */ - CTR_LP(); /* low priority ISR defined in the usb core lib */ - } -#endif - -} - -void usbWaitReset(void) { - delay_us(RESET_DELAY); - systemHardReset(); -} - -/* This low-level send bytes function is NON-BLOCKING; blocking behavior, with - * a timeout, is implemented in usercode (or in the Wirish C++ high level - * implementation). - * - * This function will quickly copy up to 64 bytes of data (out of an - * arbitrarily large buffer) into the USB peripheral TX buffer and return the - * number placed in that buffer. It is up to usercode to divide larger packets - * into 64-byte chunks to guarantee delivery. - * - * - */ -void usbBlockingSendByte(char ch) { - while (countTx); - UserToPMABufferCopy((uint8*)&ch,VCOM_TX_ADDR,1); - _SetEPTxCount(VCOM_TX_ENDP,1); - _SetEPTxValid(VCOM_TX_ENDP); - countTx = 1; - while (countTx); -} - -uint32 usbSendBytes(const uint8* sendBuf, uint32 len) { - /* Last transmission hasn't finished, abort */ - if (countTx) { - return 0; - } - - // We can only put VCOM_TX_EPSIZE bytes in the buffer - if (len > VCOM_TX_EPSIZE / 2) { - len = VCOM_TX_EPSIZE / 2; - } - - // Try to load some bytes if we can - if (len) { - UserToPMABufferCopy(sendBuf, VCOM_TX_ADDR, len); - _SetEPTxCount(VCOM_TX_ENDP, len); - countTx += len; - _SetEPTxValid(VCOM_TX_ENDP); - } - - return len; -} - -/* returns the number of available bytes are in the recv FIFO */ -uint32 usbBytesAvailable(void) { - return newBytes; -} - -/* copies len bytes from the local recieve FIFO (not - usb packet buffer) into recvBuf and deq's the fifo. - will only copy the minimum of len or the available - bytes. returns the number of bytes copied */ -uint32 usbReceiveBytes(uint8* recvBuf, uint32 len) { - static int offset = 0; - - if (len > newBytes) { - len = newBytes; - } - - int i; - for (i=0;iAPB1ENR &= ~RCC_APB1ENR_USBEN_BIT; // disable USB + _SetCNTR(CNTR_FRES); + _SetISTR(0); + _SetCNTR(CNTR_FRES + CNTR_PDWN); +#endif +} +#else +#include "usb.h" +#include "libmaple.h" +#include "usb_lib.h" +#include "gpio.h" +#include "usb_hardware.h" +#include "delay.h" + +#include "usb_config.h" +#include "usb_callbacks.h" +#include "usb_lib.h" + +/* persistent usb structs */ + +volatile uint32 bDeviceState = UNCONNECTED; +volatile uint16 wIstr = 0; +volatile uint32 bIntPackSOF = 0; + +DEVICE Device_Table = + {NUM_ENDPTS, + 1}; + +DEVICE_PROP Device_Property = + {usbInit, + usbReset, + usbStatusIn, + usbStatusOut, + usbDataSetup, + usbNoDataSetup, + usbGetInterfaceSetting, + usbGetDeviceDescriptor, + usbGetConfigDescriptor, + usbGetStringDescriptor, + 0, + bMaxPacketSize}; + +USER_STANDARD_REQUESTS User_Standard_Requests = + {NOP_Process, + usbSetConfiguration, + NOP_Process, + NOP_Process, + NOP_Process, + NOP_Process, + NOP_Process, + NOP_Process, + usbSetDeviceAddress}; + +void (*pEpInt_IN[7])(void) = + {vcomDataTxCb, + vcomManagementCb, + NOP_Process, + NOP_Process, + NOP_Process, + NOP_Process, + NOP_Process}; + +void (*pEpInt_OUT[7])(void) = + {NOP_Process, + NOP_Process, + vcomDataRxCb, + NOP_Process, + NOP_Process, + NOP_Process, + NOP_Process}; + +struct { + volatile RESUME_STATE eState; + volatile uint8 bESOFcnt; +} ResumeS; + +#if defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1) || defined(BOARD_aeroquad32mini) + +void setupUSB (void) { +#ifdef USB_DISC_OD + gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42 +#else + gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_PP); // ala42 for active pull-up on disconnect pin +#endif + + gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN,0); // ala42 + delay_us(200000); + + /* setup the apb1 clock for USB */ + pRCC->APB1ENR |= 0x00800000; + + /* initialize the usb application */ + gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 1); // ala42 // presents us to the host + USB_Init(); // low level init routine provided by the ST library +} + +void disableUSB (void) { + // These are just guesses about how to do this + // TODO: real disable function + usbDsbISR(); + gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 0); // ala42 +} + +#else + +void setupUSB (void) { + gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_PP); + + /* setup the apb1 clock for USB */ + pRCC->APB1ENR |= 0x00800000; + + /* initialize the usb application */ + gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 0); // presents us to the host + USB_Init(); // low level init routine provided by the ST library +} + +void disableUSB (void) { + // These are just guesses about how to do this + // TODO: real disable function + usbDsbISR(); + gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 1); +} + +#endif + + +void usbSuspend(void) { + u16 wCNTR; + wCNTR = _GetCNTR(); + wCNTR |= CNTR_FSUSP | CNTR_LPMODE; + _SetCNTR(wCNTR); + + /* run any power reduction handlers */ + bDeviceState = SUSPENDED; +} + +void usbResumeInit(void) { + u16 wCNTR; + + /* restart any clocks that had been stopped */ + + wCNTR = _GetCNTR(); + wCNTR &= (~CNTR_LPMODE); + _SetCNTR(wCNTR); + + /* undo power reduction handlers here */ + _SetCNTR(ISR_MSK); + +} + +void usbResume(RESUME_STATE eResumeSetVal) { + u16 wCNTR; + + if (eResumeSetVal != RESUME_ESOF) + ResumeS.eState = eResumeSetVal; + + switch (ResumeS.eState) + { + case RESUME_EXTERNAL: + usbResumeInit(); + ResumeS.eState = RESUME_OFF; + break; + case RESUME_INTERNAL: + usbResumeInit(); + ResumeS.eState = RESUME_START; + break; + case RESUME_LATER: + ResumeS.bESOFcnt = 2; + ResumeS.eState = RESUME_WAIT; + break; + case RESUME_WAIT: + ResumeS.bESOFcnt--; + if (ResumeS.bESOFcnt == 0) + ResumeS.eState = RESUME_START; + break; + case RESUME_START: + wCNTR = _GetCNTR(); + wCNTR |= CNTR_RESUME; + _SetCNTR(wCNTR); + ResumeS.eState = RESUME_ON; + ResumeS.bESOFcnt = 10; + break; + case RESUME_ON: + ResumeS.bESOFcnt--; + if (ResumeS.bESOFcnt == 0) { + wCNTR = _GetCNTR(); + wCNTR &= (~CNTR_RESUME); + _SetCNTR(wCNTR); + ResumeS.eState = RESUME_OFF; + } + break; + case RESUME_OFF: + case RESUME_ESOF: + default: + ResumeS.eState = RESUME_OFF; + break; + } +} + +RESULT usbPowerOn(void) { + u16 wRegVal; + + wRegVal = CNTR_FRES; + _SetCNTR(wRegVal); + + wInterrupt_Mask = 0; + _SetCNTR(wInterrupt_Mask); + _SetISTR(0); + wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM; // the bare minimum + _SetCNTR(wInterrupt_Mask); + + return USB_SUCCESS; +} + +RESULT usbPowerOff(void) { + _SetCNTR(CNTR_FRES); + _SetISTR(0); + _SetCNTR(CNTR_FRES + CNTR_PDWN); + + /* note that all weve done here is powerdown the + usb peripheral. we have no disabled the clocks, + pulled the usb_disc pin back up, or reset the + application state machines */ + + return USB_SUCCESS; +} + + +// These two functions (usbEnbISR/usbDsbISR) are implementented in ST style, +// and at least the DsbISR doesn't seem to work? +void usbEnbISR(void) { + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE; + nvicInit(&NVIC_InitStructure); +} + +void usbDsbISR(void) { + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE; + nvicInit(&NVIC_InitStructure); +} + +/* overloaded ISR routine, this is the main usb ISR */ +void __irq_usb_lp_can_rx0(void) { +wIstr = _GetISTR(); + +/* go nuts with the preproc switches since this is an ISTR and must be FAST */ +#if (ISR_MSK & ISTR_RESET) +if (wIstr & ISTR_RESET & wInterrupt_Mask) + { + _SetISTR((u16)CLR_RESET); + Device_Property.Reset(); + } +#endif + + +#if (ISR_MSK & ISTR_DOVR) +if (wIstr & ISTR_DOVR & wInterrupt_Mask) + { + _SetISTR((u16)CLR_DOVR); + } +#endif + + +#if (ISR_MSK & ISTR_ERR) +if (wIstr & ISTR_ERR & wInterrupt_Mask) + { + _SetISTR((u16)CLR_ERR); + } +#endif + + +#if (ISR_MSK & ISTR_WKUP) +if (wIstr & ISTR_WKUP & wInterrupt_Mask) { + _SetISTR((u16)CLR_WKUP); + usbResume(RESUME_EXTERNAL); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if (ISR_MSK & ISTR_SUSP) +if (wIstr & ISTR_SUSP & wInterrupt_Mask) { + /* check if SUSPEND is possible */ + if (F_SUSPEND_ENABLED) { + usbSuspend(); + } else { + /* if not possible then resume after xx ms */ + usbResume(RESUME_LATER); + } + /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ + _SetISTR((u16)CLR_SUSP); +} +#endif + + +#if (ISR_MSK & ISTR_SOF) +if (wIstr & ISTR_SOF & wInterrupt_Mask) { + _SetISTR((u16)CLR_SOF); + bIntPackSOF++; + } +#endif + + +#if (ISR_MSK & ISTR_ESOF) +if (wIstr & ISTR_ESOF & wInterrupt_Mask) { + _SetISTR((u16)CLR_ESOF); + /* resume handling timing is made with ESOFs */ + usbResume(RESUME_ESOF); /* request without change of the machine state */ + } +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if (ISR_MSK & ISTR_CTR) +if (wIstr & ISTR_CTR & wInterrupt_Mask) { + /* servicing of the endpoint correct transfer interrupt */ + /* clear of the CTR flag into the sub */ + CTR_LP(); /* low priority ISR defined in the usb core lib */ + } +#endif + +} + +void usbWaitReset(void) { + delay_us(RESET_DELAY); + systemHardReset(); +} + +/* This low-level send bytes function is NON-BLOCKING; blocking behavior, with + * a timeout, is implemented in usercode (or in the Wirish C++ high level + * implementation). + * + * This function will quickly copy up to 64 bytes of data (out of an + * arbitrarily large buffer) into the USB peripheral TX buffer and return the + * number placed in that buffer. It is up to usercode to divide larger packets + * into 64-byte chunks to guarantee delivery. + * + * + */ +void usbBlockingSendByte(char ch) { + while (countTx); + UserToPMABufferCopy((uint8*)&ch,VCOM_TX_ADDR,1); + _SetEPTxCount(VCOM_TX_ENDP,1); + _SetEPTxValid(VCOM_TX_ENDP); + countTx = 1; + while (countTx); +} + +uint32 usbSendBytes(const uint8* sendBuf, uint32 len) { + /* Last transmission hasn't finished, abort */ + if (countTx) { + return 0; + } + + // We can only put VCOM_TX_EPSIZE bytes in the buffer + if (len > VCOM_TX_EPSIZE / 2) { + len = VCOM_TX_EPSIZE / 2; + } + + // Try to load some bytes if we can + if (len) { + UserToPMABufferCopy(sendBuf, VCOM_TX_ADDR, len); + _SetEPTxCount(VCOM_TX_ENDP, len); + countTx += len; + _SetEPTxValid(VCOM_TX_ENDP); + } + + return len; +} + +/* returns the number of available bytes are in the recv FIFO */ +uint32 usbBytesAvailable(void) { + return newBytes; +} + +/* copies len bytes from the local recieve FIFO (not + usb packet buffer) into recvBuf and deq's the fifo. + will only copy the minimum of len or the available + bytes. returns the number of bytes copied */ +uint32 usbReceiveBytes(uint8* recvBuf, uint32 len) { + static int offset = 0; + + if (len > newBytes) { + len = newBytes; + } + + int i; + for (i=0;i= 4) { - unsigned int target = (unsigned int)usbWaitReset | 0x1; - - PMAToUserBufferCopy(chkBuf,VCOM_RX_ADDR,4); - - int i; - USB_Bool cmpMatch = TRUE; - for (i=0; i<4; i++) { - if (chkBuf[i] != cmpBuf[i]) { - cmpMatch = FALSE; - } - } - - if (cmpMatch) { - asm volatile("mov r0, %[stack_top] \n\t" // Reset the stack - "mov sp, r0 \n\t" - "mov r0, #1 \n\t" - "mov r1, %[target_addr] \n\t" - "mov r2, %[cpsr] \n\t" - "push {r2} \n\t" // Fake xPSR - "push {r1} \n\t" // Target address for PC - "push {r0} \n\t" // Fake LR - "push {r0} \n\t" // Fake R12 - "push {r0} \n\t" // Fake R3 - "push {r0} \n\t" // Fake R2 - "push {r0} \n\t" // Fake R1 - "push {r0} \n\t" // Fake R0 - "mov lr, %[exc_return] \n\t" - "bx lr" - : - : [stack_top] "r" (STACK_TOP), - [target_addr] "r" (target), - [exc_return] "r" (EXC_RETURN), - [cpsr] "r" (DEFAULT_CPSR) - : "r0", "r1", "r2"); - /* should never get here */ - } - } - } - - PMAToUserBufferCopy(&vcomBufferRx[0],VCOM_RX_ADDR,newBytes); -} - -void vcomManagementCb(void) { - /* unused. This enpoint would callback if we had sent a linestate - changed notification */ -} - -u8* vcomGetSetLineCoding(uint16 length) { - if (length == 0) { - pInformation->Ctrl_Info.Usb_wLength = sizeof(USB_Line_Coding); - } - return (uint8*)&line_coding; -} - -void vcomSetLineState(void) { -} - -void usbInit(void) { - pInformation->Current_Configuration = 0; - usbPowerOn(); - - _SetISTR(0); - wInterrupt_Mask = ISR_MSK; - _SetCNTR(wInterrupt_Mask); - - usbEnbISR(); - bDeviceState = UNCONNECTED; -} - -void usbReset(void) { - pInformation->Current_Configuration = 0; - - /* current feature is current bmAttributes */ - pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELF_POWERED); - - _SetBTABLE(USB_BTABLE_ADDRESS); - - /* setup control endpoint 0 */ - _SetEPType(ENDP0, EP_CONTROL); - _SetEPTxStatus(ENDP0, EP_TX_STALL); - _SetEPRxAddr(ENDP0,VCOM_CTRL_RX_ADDR); - _SetEPTxAddr(ENDP0,VCOM_CTRL_TX_ADDR); - Clear_Status_Out(ENDP0); - - SetEPRxCount(ENDP0, pProperty->MaxPacketSize); - SetEPRxValid(ENDP0); - - /* setup management endpoint 1 */ - SetEPType (VCOM_NOTIFICATION_ENDP, EP_INTERRUPT); - SetEPTxAddr (VCOM_NOTIFICATION_ENDP, VCOM_NOTIFICATION_ADDR); - SetEPTxStatus (VCOM_NOTIFICATION_ENDP, EP_TX_NAK); - SetEPRxStatus (VCOM_NOTIFICATION_ENDP, EP_RX_DIS); - - /* setup data endpoint OUT (rx) */ - /* SetEPType (VCOM_RX_ENDP, EP_BULK); */ - /* SetEPRxAddr (VCOM_RX_ENDP, VCOM_RX_ADDR); */ - /* SetEPRxCount (VCOM_RX_ENDP, VCOM_RX_EPSIZE); */ - /* // SetEPTxStatus (VCOM_RX_ENDP, EP_TX_DIS); */ - /* SetEPRxStatus (VCOM_RX_ENDP, EP_RX_VALID); */ - - SetEPType (3, EP_BULK); - SetEPRxAddr (3, 0x110); - SetEPRxCount (3,64); - // SetEPTxStatus (VCOM_RX_ENDP, EP_TX_DIS); - SetEPRxStatus (3, EP_RX_VALID); - - /* setup data endpoint IN (tx) */ - SetEPType (VCOM_TX_ENDP, EP_BULK); - SetEPTxAddr (VCOM_TX_ENDP, VCOM_TX_ADDR); - SetEPTxStatus (VCOM_TX_ENDP, EP_TX_NAK); - SetEPRxStatus (VCOM_TX_ENDP, EP_RX_DIS); - - bDeviceState = ATTACHED; - SetDeviceAddress(0); - - /* reset the rx fifo */ - recvBufIn = 0; - recvBufOut = 0; - maxNewBytes = VCOM_RX_EPSIZE; - countTx = 0; -} - - -void usbStatusIn(void) { - /* adjust the usart line coding - if we wish to couple the CDC line coding - with the real usart port */ -} - -void usbStatusOut(void) { -} - -RESULT usbDataSetup(uint8 request) { - uint8 *(*CopyRoutine)(uint16); - CopyRoutine = NULL; - - if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { - switch (request) { - case (GET_LINE_CODING): - CopyRoutine = vcomGetSetLineCoding; - last_request = GET_LINE_CODING; - break; - case (SET_LINE_CODING): - CopyRoutine = vcomGetSetLineCoding; - last_request = SET_LINE_CODING; - break; - default: break; - } - } - - if (CopyRoutine == NULL) { - return USB_UNSUPPORT; - } - - pInformation->Ctrl_Info.CopyData = CopyRoutine; - pInformation->Ctrl_Info.Usb_wOffset = 0; - (*CopyRoutine)(0); - return USB_SUCCESS; -} - -RESULT usbNoDataSetup(u8 request) { - uint8 new_signal; - - /* we support set com feature but dont handle it */ - if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { - - switch (request) { - case (SET_COMM_FEATURE): - return USB_SUCCESS; - case (SET_CONTROL_LINE_STATE): - /* to reset the board, pull both dtr and rts low - then pulse dtr by itself */ - new_signal = pInformation->USBwValues.bw.bb0 & (CONTROL_LINE_DTR | CONTROL_LINE_RTS); - line_dtr_rts = new_signal & 0x03; - - switch (reset_state) { - /* no default, covered enum */ - case DTR_UNSET: - if ((new_signal & CONTROL_LINE_DTR) == 0 ) { - reset_state = DTR_LOW; - } else { - reset_state = DTR_HIGH; - } - break; - - case DTR_HIGH: - if ((new_signal & CONTROL_LINE_DTR) == 0 ) { - reset_state = DTR_NEGEDGE; - } else { - reset_state = DTR_HIGH; - } - break; - - case DTR_NEGEDGE: - if ((new_signal & CONTROL_LINE_DTR) == 0 ) { - reset_state = DTR_LOW; - } else { - reset_state = DTR_HIGH; - } - break; - - case DTR_LOW: - if ((new_signal & CONTROL_LINE_DTR) == 0 ) { - reset_state = DTR_LOW; - } else { - reset_state = DTR_HIGH; - } - break; - } - - return USB_SUCCESS; - } - } - return USB_UNSUPPORT; -} - -RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) { - if (alt_setting > 0) { - return USB_UNSUPPORT; - } else if (interface > 1) { - return USB_UNSUPPORT; - } - - return USB_SUCCESS; -} - - -u8* usbGetDeviceDescriptor(u16 length) { - return Standard_GetDescriptorData(length, &Device_Descriptor); -} - -u8* usbGetConfigDescriptor(u16 length) { - return Standard_GetDescriptorData(length, &Config_Descriptor); -} - -u8* usbGetStringDescriptor(u16 length) { - uint8 wValue0 = pInformation->USBwValue0; - - if (wValue0 > 2) { - return NULL; - } - return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]); -} - -/* internal callbacks to respond to standard requests */ -void usbSetConfiguration(void) { - if (pInformation->Current_Configuration != 0) { - bDeviceState = CONFIGURED; - } -} - -void usbSetDeviceAddress(void) { - bDeviceState = ADDRESSED; -} - +/* insert license */ + +#include "usb_callbacks.h" +#include "usb_lib.h" +#include "descriptors.h" +#include "usb_config.h" +#include "usb.h" +#include "usb_hardware.h" + +ONE_DESCRIPTOR Device_Descriptor = { + (uint8*)&usbVcomDescriptor_Device, + sizeof(USB_Descriptor_Device) +}; + +ONE_DESCRIPTOR Config_Descriptor = { + (uint8*)&usbVcomDescriptor_Config, + 0x43//sizeof(USB_Descriptor_Config) +}; + +ONE_DESCRIPTOR String_Descriptor[3] = { + {(uint8*)&usbVcomDescriptor_LangID, USB_DESCRIPTOR_STRING_LEN(1)}, + {(uint8*)&usbVcomDescriptor_iManufacturer,USB_DESCRIPTOR_STRING_LEN(8)}, + {(uint8*)&usbVcomDescriptor_iProduct, USB_DESCRIPTOR_STRING_LEN(8)} +}; + +uint8 last_request = 0; + +USB_Line_Coding line_coding = { + bitrate: 115200, + format: 0x00, /* stop bits-1 */ + paritytype: 0x00, + datatype: 0x08 +}; + +uint8 vcomBufferRx[VCOM_RX_BUFLEN]; +volatile uint32 countTx = 0; +volatile uint32 recvBufIn = 0; +volatile uint32 recvBufOut = 0; +volatile uint32 maxNewBytes = VCOM_RX_BUFLEN; +volatile uint32 newBytes = 0; +RESET_STATE reset_state = DTR_UNSET; +uint8 line_dtr_rts = 0; + +void vcomDataTxCb(void) { + /* do whatever after data has been sent to host */ + + /* allows usbSendBytes to stop blocking */ + + /* assumes tx transactions are atomic 64 bytes (nearly certain they are) */ + countTx = 0; +} + +/* we could get arbitrarily complicated here for speed purposes + however, the simple scheme here is to implement a receive fifo + and always set the maximum to new bytes to the space remaining + in the fifo. this number will be reincremented after calls + to usbReceiveBytes */ +void vcomDataRxCb(void) { + /* do whatever after data has been received from host */ + + /* setEPRxCount on the previous cycle should garuntee + we havnt received more bytes than we can fit */ + newBytes = GetEPRxCount(VCOM_RX_ENDP); + SetEPRxStatus(VCOM_RX_ENDP,EP_RX_NAK); + + /* todo, not checking very carefully for edge cases. USUALLY, + if we emit the reset pulse and send 4 bytes, then newBytes + should be 4. But its POSSIBLE that this would be violated + in some cases */ + + /* magic number, {0x31, 0x45, 0x41, 0x46} is "1EAF" */ + uint8 chkBuf[4]; + uint8 cmpBuf[4] = {0x31, 0x45, 0x41, 0x46}; + if (reset_state == DTR_NEGEDGE) { + reset_state = DTR_LOW; + + if (newBytes >= 4) { + unsigned int target = (unsigned int)usbWaitReset | 0x1; + + PMAToUserBufferCopy(chkBuf,VCOM_RX_ADDR,4); + + int i; + USB_Bool cmpMatch = TRUE; + for (i=0; i<4; i++) { + if (chkBuf[i] != cmpBuf[i]) { + cmpMatch = FALSE; + } + } + + if (cmpMatch) { + asm volatile("mov r0, %[stack_top] \n\t" // Reset the stack + "mov sp, r0 \n\t" + "mov r0, #1 \n\t" + "mov r1, %[target_addr] \n\t" + "mov r2, %[cpsr] \n\t" + "push {r2} \n\t" // Fake xPSR + "push {r1} \n\t" // Target address for PC + "push {r0} \n\t" // Fake LR + "push {r0} \n\t" // Fake R12 + "push {r0} \n\t" // Fake R3 + "push {r0} \n\t" // Fake R2 + "push {r0} \n\t" // Fake R1 + "push {r0} \n\t" // Fake R0 + "mov lr, %[exc_return] \n\t" + "bx lr" + : + : [stack_top] "r" (STACK_TOP), + [target_addr] "r" (target), + [exc_return] "r" (EXC_RETURN), + [cpsr] "r" (DEFAULT_CPSR) + : "r0", "r1", "r2"); + /* should never get here */ + } + } + } + + PMAToUserBufferCopy(&vcomBufferRx[0],VCOM_RX_ADDR,newBytes); +} + +void vcomManagementCb(void) { + /* unused. This enpoint would callback if we had sent a linestate + changed notification */ +} + +u8* vcomGetSetLineCoding(uint16 length) { + if (length == 0) { + pInformation->Ctrl_Info.Usb_wLength = sizeof(USB_Line_Coding); + } + return (uint8*)&line_coding; +} + +void vcomSetLineState(void) { +} + +void usbInit(void) { + pInformation->Current_Configuration = 0; + usbPowerOn(); + + _SetISTR(0); + wInterrupt_Mask = ISR_MSK; + _SetCNTR(wInterrupt_Mask); + + usbEnbISR(); + bDeviceState = UNCONNECTED; +} + +void usbReset(void) { + pInformation->Current_Configuration = 0; + + /* current feature is current bmAttributes */ + pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELF_POWERED); + + _SetBTABLE(USB_BTABLE_ADDRESS); + + /* setup control endpoint 0 */ + _SetEPType(ENDP0, EP_CONTROL); + _SetEPTxStatus(ENDP0, EP_TX_STALL); + _SetEPRxAddr(ENDP0,VCOM_CTRL_RX_ADDR); + _SetEPTxAddr(ENDP0,VCOM_CTRL_TX_ADDR); + Clear_Status_Out(ENDP0); + + SetEPRxCount(ENDP0, pProperty->MaxPacketSize); + SetEPRxValid(ENDP0); + + /* setup management endpoint 1 */ + SetEPType (VCOM_NOTIFICATION_ENDP, EP_INTERRUPT); + SetEPTxAddr (VCOM_NOTIFICATION_ENDP, VCOM_NOTIFICATION_ADDR); + SetEPTxStatus (VCOM_NOTIFICATION_ENDP, EP_TX_NAK); + SetEPRxStatus (VCOM_NOTIFICATION_ENDP, EP_RX_DIS); + + /* setup data endpoint OUT (rx) */ + /* SetEPType (VCOM_RX_ENDP, EP_BULK); */ + /* SetEPRxAddr (VCOM_RX_ENDP, VCOM_RX_ADDR); */ + /* SetEPRxCount (VCOM_RX_ENDP, VCOM_RX_EPSIZE); */ + /* // SetEPTxStatus (VCOM_RX_ENDP, EP_TX_DIS); */ + /* SetEPRxStatus (VCOM_RX_ENDP, EP_RX_VALID); */ + + SetEPType (3, EP_BULK); + SetEPRxAddr (3, 0x110); + SetEPRxCount (3,64); + // SetEPTxStatus (VCOM_RX_ENDP, EP_TX_DIS); + SetEPRxStatus (3, EP_RX_VALID); + + /* setup data endpoint IN (tx) */ + SetEPType (VCOM_TX_ENDP, EP_BULK); + SetEPTxAddr (VCOM_TX_ENDP, VCOM_TX_ADDR); + SetEPTxStatus (VCOM_TX_ENDP, EP_TX_NAK); + SetEPRxStatus (VCOM_TX_ENDP, EP_RX_DIS); + + bDeviceState = ATTACHED; + SetDeviceAddress(0); + + /* reset the rx fifo */ + recvBufIn = 0; + recvBufOut = 0; + maxNewBytes = VCOM_RX_EPSIZE; + countTx = 0; +} + + +void usbStatusIn(void) { + /* adjust the usart line coding + if we wish to couple the CDC line coding + with the real usart port */ +} + +void usbStatusOut(void) { +} + +RESULT usbDataSetup(uint8 request) { + uint8 *(*CopyRoutine)(uint16); + CopyRoutine = NULL; + + if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { + switch (request) { + case (GET_LINE_CODING): + CopyRoutine = vcomGetSetLineCoding; + last_request = GET_LINE_CODING; + break; + case (SET_LINE_CODING): + CopyRoutine = vcomGetSetLineCoding; + last_request = SET_LINE_CODING; + break; + default: break; + } + } + + if (CopyRoutine == NULL) { + return USB_UNSUPPORT; + } + + pInformation->Ctrl_Info.CopyData = CopyRoutine; + pInformation->Ctrl_Info.Usb_wOffset = 0; + (*CopyRoutine)(0); + return USB_SUCCESS; +} + +RESULT usbNoDataSetup(u8 request) { + uint8 new_signal; + + /* we support set com feature but dont handle it */ + if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { + + switch (request) { + case (SET_COMM_FEATURE): + return USB_SUCCESS; + case (SET_CONTROL_LINE_STATE): + /* to reset the board, pull both dtr and rts low + then pulse dtr by itself */ + new_signal = pInformation->USBwValues.bw.bb0 & (CONTROL_LINE_DTR | CONTROL_LINE_RTS); + line_dtr_rts = new_signal & 0x03; + + switch (reset_state) { + /* no default, covered enum */ + case DTR_UNSET: + if ((new_signal & CONTROL_LINE_DTR) == 0 ) { + reset_state = DTR_LOW; + } else { + reset_state = DTR_HIGH; + } + break; + + case DTR_HIGH: + if ((new_signal & CONTROL_LINE_DTR) == 0 ) { + reset_state = DTR_NEGEDGE; + } else { + reset_state = DTR_HIGH; + } + break; + + case DTR_NEGEDGE: + if ((new_signal & CONTROL_LINE_DTR) == 0 ) { + reset_state = DTR_LOW; + } else { + reset_state = DTR_HIGH; + } + break; + + case DTR_LOW: + if ((new_signal & CONTROL_LINE_DTR) == 0 ) { + reset_state = DTR_LOW; + } else { + reset_state = DTR_HIGH; + } + break; + } + + return USB_SUCCESS; + } + } + return USB_UNSUPPORT; +} + +RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) { + if (alt_setting > 0) { + return USB_UNSUPPORT; + } else if (interface > 1) { + return USB_UNSUPPORT; + } + + return USB_SUCCESS; +} + + +u8* usbGetDeviceDescriptor(u16 length) { + return Standard_GetDescriptorData(length, &Device_Descriptor); +} + +u8* usbGetConfigDescriptor(u16 length) { + return Standard_GetDescriptorData(length, &Config_Descriptor); +} + +u8* usbGetStringDescriptor(u16 length) { + uint8 wValue0 = pInformation->USBwValue0; + + if (wValue0 > 2) { + return NULL; + } + return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]); +} + +/* internal callbacks to respond to standard requests */ +void usbSetConfiguration(void) { + if (pInformation->Current_Configuration != 0) { + bDeviceState = CONFIGURED; + } +} + +void usbSetDeviceAddress(void) { + bDeviceState = ADDRESSED; +} + diff --git a/Libmaple/libmaple/libmaple/usb/usb_callbacks.h b/Libmaple/libmaple/libmaple/usb/usb_callbacks.h index 5d86d42d..20d2c13f 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_callbacks.h +++ b/Libmaple/libmaple/libmaple/usb/usb_callbacks.h @@ -1,75 +1,75 @@ -/* insert license */ - -#ifndef __USB_CALLBACKS -#define __USB_CALLBACKS - -#include "libmaple.h" -#include "usb_lib.h" -#include "usb_config.h" - -#define SET_LINE_CODING 0x20 -#define GET_LINE_CODING 0x21 -#define SET_COMM_FEATURE 0x02 -#define SET_CONTROL_LINE_STATE 0x22 -#define CONTROL_LINE_DTR (0x01) -#define CONTROL_LINE_RTS (0x02) - -#if defined(__cplusplus) -extern "C" { -#endif - -typedef struct { - uint32 bitrate; - uint8 format; - uint8 paritytype; - uint8 datatype; -} USB_Line_Coding; - -typedef enum { - DTR_UNSET, - DTR_HIGH, - DTR_NEGEDGE, - DTR_LOW -} RESET_STATE; - -extern RESET_STATE reset_state; /* tracks DTR/RTS */ -extern uint8 line_dtr_rts; -extern volatile uint32 countTx; -extern uint8 vcomBufferRx[VCOM_RX_BUFLEN]; /* no reason this has to be VCOM_RX_EPSIZE, could be bigger */ -extern volatile uint32 recvBufIn; /* the FIFO in index to the recvbuffer */ -extern volatile uint32 recvBufOut; /* the FIFO out index to the recvbuffer */ -extern volatile uint32 maxNewBytes; -extern volatile uint32 newBytes; - -void vcomDataTxCb(void); -void vcomDataRxCb(void); -void vcomManagementCb(void); - -uint8* vcomGetSetLineCoding(uint16 length); -void vcomSetLineSate(void); - -void usbInit(void); -/* internal functions (as per the usb_core pProperty structure) */ -void usbInit(void); -void usbReset(void); -void usbStatusIn(void); -void usbStatusOut(void); - -RESULT usbDataSetup(uint8 request); -RESULT usbNoDataSetup(uint8 request); -RESULT usbGetInterfaceSetting(uint8,uint8); - -uint8* usbGetDeviceDescriptor(uint16 length); -uint8* usbGetConfigDescriptor(uint16 length); -uint8* usbGetStringDescriptor(uint16 length); - -/* internal callbacks to respond to standard requests */ -void usbSetConfiguration(void); -void usbSetDeviceAddress(void); - -#if defined(__cplusplus) -} -#endif - - -#endif +/* insert license */ + +#ifndef __USB_CALLBACKS +#define __USB_CALLBACKS + +#include "libmaple.h" +#include "usb_lib.h" +#include "usb_config.h" + +#define SET_LINE_CODING 0x20 +#define GET_LINE_CODING 0x21 +#define SET_COMM_FEATURE 0x02 +#define SET_CONTROL_LINE_STATE 0x22 +#define CONTROL_LINE_DTR (0x01) +#define CONTROL_LINE_RTS (0x02) + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef struct { + uint32 bitrate; + uint8 format; + uint8 paritytype; + uint8 datatype; +} USB_Line_Coding; + +typedef enum { + DTR_UNSET, + DTR_HIGH, + DTR_NEGEDGE, + DTR_LOW +} RESET_STATE; + +extern RESET_STATE reset_state; /* tracks DTR/RTS */ +extern uint8 line_dtr_rts; +extern volatile uint32 countTx; +extern uint8 vcomBufferRx[VCOM_RX_BUFLEN]; /* no reason this has to be VCOM_RX_EPSIZE, could be bigger */ +extern volatile uint32 recvBufIn; /* the FIFO in index to the recvbuffer */ +extern volatile uint32 recvBufOut; /* the FIFO out index to the recvbuffer */ +extern volatile uint32 maxNewBytes; +extern volatile uint32 newBytes; + +void vcomDataTxCb(void); +void vcomDataRxCb(void); +void vcomManagementCb(void); + +uint8* vcomGetSetLineCoding(uint16 length); +void vcomSetLineSate(void); + +void usbInit(void); +/* internal functions (as per the usb_core pProperty structure) */ +void usbInit(void); +void usbReset(void); +void usbStatusIn(void); +void usbStatusOut(void); + +RESULT usbDataSetup(uint8 request); +RESULT usbNoDataSetup(uint8 request); +RESULT usbGetInterfaceSetting(uint8,uint8); + +uint8* usbGetDeviceDescriptor(uint16 length); +uint8* usbGetConfigDescriptor(uint16 length); +uint8* usbGetStringDescriptor(uint16 length); + +/* internal callbacks to respond to standard requests */ +void usbSetConfiguration(void); +void usbSetDeviceAddress(void); + +#if defined(__cplusplus) +} +#endif + + +#endif diff --git a/Libmaple/libmaple/libmaple/usb/usb_config.h b/Libmaple/libmaple/libmaple/usb/usb_config.h index d1fdccc5..09841d71 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_config.h +++ b/Libmaple/libmaple/libmaple/usb/usb_config.h @@ -1,133 +1,133 @@ -/* insert license */ - -#ifndef __USB_CONFIG_H -#define __USB_CONFIG_H - -#include "usb_lib.h" -#include "gpio.h" - -/****************************************************************************** - ****************************************************************************** - *** - *** HACK ALERT - *** - *** FIXME FIXME FIXME FIXME - *** - *** A bunch of board-specific #defines that are only used by the - *** USB routines got put into libmaple.h for what appear to be - *** historical reasons. I'm [mbolivar] putting them in here for - *** now, so that we can treat the usb/ directory as a black box, - *** freeing the rest of libmaple/ to be implemented as a - *** general-purpose STM32 library. All of this REALLY needs to get - *** moved into wirish when we get a chance to redo the USB stack. - *** - ****************************************************************************** - *****************************************************************************/ - -#define VCOM_ID_VENDOR 0x1EAF -#define RESET_DELAY (100000) -#define USB_CONFIG_MAX_POWER (100 >> 1) - -#if defined(BOARD_maple) || defined(BOARD_maple_RET6) - - /* USB Identifier numbers */ - #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_DEV GPIOC - #define USB_DISC_PIN 12 - -#elif defined(BOARD_maple_mini) - - #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_DEV GPIOB - #define USB_DISC_PIN 9 - -#elif defined(BOARD_maple_native) - - #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_DEV GPIOB - #define USB_DISC_PIN 8 - -#elif defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1) - - #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_DEV GPIOD - #define USB_DISC_PIN 11 - -#elif defined(BOARD_aeroquad32mini) - - #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_DEV GPIOA - #define USB_DISC_PIN 8 - -#elif defined(BOARD_discovery_f4) - - #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_DEV GPIOD - #define USB_DISC_PIN 11 - -#elif defined(BOARD_freeflight) - // dummy entry, USB is disabled - #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_DEV GPIOA - #define USB_DISC_PIN 8 - -#else - -#error ("Sorry! the USB stack relies on LeafLabs board-specific " \ - "configuration right now. If you want, you can pretend you're one " \ - "of our boards; i.e., #define BOARD_maple, BOARD_maple_mini, or " \ - "BOARD_maple_native according to what matches your MCU best. " \ - "You should also take a look at libmaple/usb/descriptors.c; we make " \ - "some assumptions there that you probably won't like.") - -#endif - -/****************************************************************************** - ****************************************************************************** - *** - *** END HACK - *** - ****************************************************************************** - *****************************************************************************/ - - -/* choose addresses to give endpoints the max 64 byte buffers */ -#define USB_BTABLE_ADDRESS 0x00 -#define VCOM_CTRL_EPNUM 0x00 -#define VCOM_CTRL_RX_ADDR 0x40 -#define VCOM_CTRL_TX_ADDR 0x80 -#define VCOM_CTRL_EPSIZE 0x40 - -#define VCOM_TX_ENDP ENDP1 -#define VCOM_TX_EPNUM 0x01 -#define VCOM_TX_ADDR 0xC0 -#define VCOM_TX_EPSIZE 0x40 - -#define VCOM_NOTIFICATION_ENDP ENDP2 -#define VCOM_NOTIFICATION_EPNUM 0x02 -#define VCOM_NOTIFICATION_ADDR 0x100 -#define VCOM_NOTIFICATION_EPSIZE 0x40 - -#define VCOM_RX_ENDP ENDP3 -#define VCOM_RX_EPNUM 0x03 -#define VCOM_RX_ADDR 0x110 -#define VCOM_RX_EPSIZE 0x40 -#define VCOM_RX_BUFLEN (VCOM_RX_EPSIZE*3) - -#define bMaxPacketSize 0x40 /* 64B, maximum for USB FS Devices */ - -#define NUM_ENDPTS 0x04 - -/* handle all usb interrupts */ -#define ISR_MSK (CNTR_CTRM | \ - CNTR_WKUPM | \ - CNTR_SUSPM | \ - CNTR_ERRM | \ - CNTR_SOFM | \ - CNTR_ESOFM | \ - CNTR_RESETM) - -#define F_SUSPEND_ENABLED 1 - - -#endif +/* insert license */ + +#ifndef __USB_CONFIG_H +#define __USB_CONFIG_H + +#include "usb_lib.h" +#include "gpio.h" + +/****************************************************************************** + ****************************************************************************** + *** + *** HACK ALERT + *** + *** FIXME FIXME FIXME FIXME + *** + *** A bunch of board-specific #defines that are only used by the + *** USB routines got put into libmaple.h for what appear to be + *** historical reasons. I'm [mbolivar] putting them in here for + *** now, so that we can treat the usb/ directory as a black box, + *** freeing the rest of libmaple/ to be implemented as a + *** general-purpose STM32 library. All of this REALLY needs to get + *** moved into wirish when we get a chance to redo the USB stack. + *** + ****************************************************************************** + *****************************************************************************/ + +#define VCOM_ID_VENDOR 0x1EAF +#define RESET_DELAY (100000) +#define USB_CONFIG_MAX_POWER (100 >> 1) + +#if defined(BOARD_maple) || defined(BOARD_maple_RET6) + + /* USB Identifier numbers */ + #define VCOM_ID_PRODUCT 0x0004 + #define USB_DISC_DEV GPIOC + #define USB_DISC_PIN 12 + +#elif defined(BOARD_maple_mini) + + #define VCOM_ID_PRODUCT 0x0004 + #define USB_DISC_DEV GPIOB + #define USB_DISC_PIN 9 + +#elif defined(BOARD_maple_native) + + #define VCOM_ID_PRODUCT 0x0004 + #define USB_DISC_DEV GPIOB + #define USB_DISC_PIN 8 + +#elif defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1) + + #define VCOM_ID_PRODUCT 0x0004 + #define USB_DISC_DEV GPIOD + #define USB_DISC_PIN 11 + +#elif defined(BOARD_aeroquad32mini) + + #define VCOM_ID_PRODUCT 0x0004 + #define USB_DISC_DEV GPIOA + #define USB_DISC_PIN 8 + +#elif defined(BOARD_discovery_f4) + + #define VCOM_ID_PRODUCT 0x0004 + #define USB_DISC_DEV GPIOD + #define USB_DISC_PIN 11 + +#elif defined(BOARD_freeflight) + // dummy entry, USB is disabled + #define VCOM_ID_PRODUCT 0x0004 + #define USB_DISC_DEV GPIOA + #define USB_DISC_PIN 8 + +#else + +#error ("Sorry! the USB stack relies on LeafLabs board-specific " \ + "configuration right now. If you want, you can pretend you're one " \ + "of our boards; i.e., #define BOARD_maple, BOARD_maple_mini, or " \ + "BOARD_maple_native according to what matches your MCU best. " \ + "You should also take a look at libmaple/usb/descriptors.c; we make " \ + "some assumptions there that you probably won't like.") + +#endif + +/****************************************************************************** + ****************************************************************************** + *** + *** END HACK + *** + ****************************************************************************** + *****************************************************************************/ + + +/* choose addresses to give endpoints the max 64 byte buffers */ +#define USB_BTABLE_ADDRESS 0x00 +#define VCOM_CTRL_EPNUM 0x00 +#define VCOM_CTRL_RX_ADDR 0x40 +#define VCOM_CTRL_TX_ADDR 0x80 +#define VCOM_CTRL_EPSIZE 0x40 + +#define VCOM_TX_ENDP ENDP1 +#define VCOM_TX_EPNUM 0x01 +#define VCOM_TX_ADDR 0xC0 +#define VCOM_TX_EPSIZE 0x40 + +#define VCOM_NOTIFICATION_ENDP ENDP2 +#define VCOM_NOTIFICATION_EPNUM 0x02 +#define VCOM_NOTIFICATION_ADDR 0x100 +#define VCOM_NOTIFICATION_EPSIZE 0x40 + +#define VCOM_RX_ENDP ENDP3 +#define VCOM_RX_EPNUM 0x03 +#define VCOM_RX_ADDR 0x110 +#define VCOM_RX_EPSIZE 0x40 +#define VCOM_RX_BUFLEN (VCOM_RX_EPSIZE*3) + +#define bMaxPacketSize 0x40 /* 64B, maximum for USB FS Devices */ + +#define NUM_ENDPTS 0x04 + +/* handle all usb interrupts */ +#define ISR_MSK (CNTR_CTRM | \ + CNTR_WKUPM | \ + CNTR_SUSPM | \ + CNTR_ERRM | \ + CNTR_SOFM | \ + CNTR_ESOFM | \ + CNTR_RESETM) + +#define F_SUSPEND_ENABLED 1 + + +#endif diff --git a/Libmaple/libmaple/libmaple/usb/usb_hardware.c b/Libmaple/libmaple/libmaple/usb/usb_hardware.c index ea395350..9a7d12ca 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_hardware.c +++ b/Libmaple/libmaple/libmaple/usb/usb_hardware.c @@ -1,99 +1,99 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file usb_hardware.c - * - * @brief init routines to setup clocks and interrupts for usb. - * - */ - -#include "usb_hardware.h" - -void nvicInit(NVIC_InitTypeDef* NVIC_InitStruct) { - u32 tmppriority = 0x00; - u32 tmpreg = 0x00; - u32 tmpmask = 0x00; - u32 tmppre = 0; - u32 tmpsub = 0x0F; - - SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE; - NVIC_TypeDef* rNVIC = (NVIC_TypeDef *) NVIC_BASE; - - - /* Compute the Corresponding IRQ Priority -------------------------------*/ - tmppriority = (0x700 - (rSCB->AIRCR & (u32)0x700))>> 0x08; - tmppre = (0x4 - tmppriority); - tmpsub = tmpsub >> tmppriority; - - tmppriority = (u32)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << - tmppre; - tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub; - - tmppriority = tmppriority << 0x04; - tmppriority = ((u32)tmppriority) << - ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08); - - tmpreg = rNVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)]; - tmpmask = (u32)0xFF << - ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08); - tmpreg &= ~tmpmask; - tmppriority &= tmpmask; - tmpreg |= tmppriority; - - rNVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)] = tmpreg; - - /* Enable the Selected IRQ Channels -------------------------------------*/ - rNVIC->ISER[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] = - (u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F); -} - -void nvicDisableInterrupts() { - NVIC_TypeDef* rNVIC = (NVIC_TypeDef *) NVIC_BASE; - rNVIC->ICER[0] = 0xFFFFFFFF; - rNVIC->ICER[1] = 0xFFFFFFFF; - rNVIC->ICPR[0] = 0xFFFFFFFF; - rNVIC->ICPR[1] = 0xFFFFFFFF; - - /* Disable the systick timer, which operates separately from NVIC */ - SET_REG(STK_CTRL,0x04); -} - -void systemHardReset(void) { - SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE; - typedef void (*funcPtr)(void); - - /* Reset */ - rSCB->AIRCR = (u32)AIRCR_RESET_REQ; - - /* Should never get here */ - while (1) { - asm volatile("nop"); - } -} - - - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file usb_hardware.c + * + * @brief init routines to setup clocks and interrupts for usb. + * + */ + +#include "usb_hardware.h" + +void nvicInit(NVIC_InitTypeDef* NVIC_InitStruct) { + u32 tmppriority = 0x00; + u32 tmpreg = 0x00; + u32 tmpmask = 0x00; + u32 tmppre = 0; + u32 tmpsub = 0x0F; + + SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE; + NVIC_TypeDef* rNVIC = (NVIC_TypeDef *) NVIC_BASE; + + + /* Compute the Corresponding IRQ Priority -------------------------------*/ + tmppriority = (0x700 - (rSCB->AIRCR & (u32)0x700))>> 0x08; + tmppre = (0x4 - tmppriority); + tmpsub = tmpsub >> tmppriority; + + tmppriority = (u32)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << + tmppre; + tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub; + + tmppriority = tmppriority << 0x04; + tmppriority = ((u32)tmppriority) << + ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08); + + tmpreg = rNVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)]; + tmpmask = (u32)0xFF << + ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08); + tmpreg &= ~tmpmask; + tmppriority &= tmpmask; + tmpreg |= tmppriority; + + rNVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)] = tmpreg; + + /* Enable the Selected IRQ Channels -------------------------------------*/ + rNVIC->ISER[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] = + (u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F); +} + +void nvicDisableInterrupts() { + NVIC_TypeDef* rNVIC = (NVIC_TypeDef *) NVIC_BASE; + rNVIC->ICER[0] = 0xFFFFFFFF; + rNVIC->ICER[1] = 0xFFFFFFFF; + rNVIC->ICPR[0] = 0xFFFFFFFF; + rNVIC->ICPR[1] = 0xFFFFFFFF; + + /* Disable the systick timer, which operates separately from NVIC */ + SET_REG(STK_CTRL,0x04); +} + +void systemHardReset(void) { + SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE; + typedef void (*funcPtr)(void); + + /* Reset */ + rSCB->AIRCR = (u32)AIRCR_RESET_REQ; + + /* Should never get here */ + while (1) { + asm volatile("nop"); + } +} + + + diff --git a/Libmaple/libmaple/libmaple/usb/usb_hardware.h b/Libmaple/libmaple/libmaple/usb/usb_hardware.h index e31bc4c3..cfead1ae 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_hardware.h +++ b/Libmaple/libmaple/libmaple/usb/usb_hardware.h @@ -1,136 +1,136 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -#include "rcc.h" -#include "usb_type.h" - -#ifndef _USB_HARDWARE_H_ -#define _USB_HARDWARE_H_ - -/* macro'd register and peripheral definitions */ -#define EXC_RETURN 0xFFFFFFF9 -#define DEFAULT_CPSR 0x61000000 - -#define FLASH ((u32)0x40022000) - -#define USB_PACKET_BUFFER ((u32)0x40006000) - -#define SCS_BASE ((u32)0xE000E000) -#define NVIC_BASE (SCS_BASE + 0x0100) -#define SCB_BASE (SCS_BASE + 0x0D00) - -#define SCS 0xE000E000 -#define NVIC (SCS+0x100) -#define SCB (SCS+0xD00) -#define STK (SCS+0x10) - -#define SCB_VTOR (SCB+0x08) -#define STK_CTRL (STK+0x00) - -#define USB_HP_IRQ ((u8)0x13) -#define USB_LP_IRQ ((u8)0x14) - -/* AIRCR */ -#define AIRCR_RESET 0x05FA0000 -#define AIRCR_RESET_REQ (AIRCR_RESET | (u32)0x04); - -/* temporary copyage of example from kiel */ -#define __VAL(__TIMCLK, __PERIOD) ((__TIMCLK/1000000UL)*__PERIOD) -#define __PSC(__TIMCLK, __PERIOD) (((__VAL(__TIMCLK, __PERIOD)+49999UL)/50000UL) - 1) -#define __ARR(__TIMCLK, __PERIOD) ((__VAL(__TIMCLK, __PERIOD)/(__PSC(__TIMCLK, __PERIOD)+1)) - 1) - -#define SET_REG(addr,val) do { *(vu32*)(addr)=val; } while (0) -#define GET_REG(addr) do { *(vu32*)(addr); } while (0) - -#if defined(__cplusplus) -extern "C" { -#endif - -/* todo: there must be some major misunderstanding in how we access regs. The direct access approach (GET_REG) - causes the usb init to fail upon trying to activate RCC_APB1 |= 0x00800000. However, using the struct approach - from ST, it works fine...temporarily switching to that approach */ -typedef struct -{ - vu32 CR; - vu32 CFGR; - vu32 CIR; - vu32 APB2RSTR; - vu32 APB1RSTR; - vu32 AHBENR; - vu32 APB2ENR; - vu32 APB1ENR; - vu32 BDCR; - vu32 CSR; -} RCC_RegStruct; -#define pRCC ((RCC_RegStruct *) RCC_BASE) - -typedef struct { - vu32 ISER[2]; - u32 RESERVED0[30]; - vu32 ICER[2]; - u32 RSERVED1[30]; - vu32 ISPR[2]; - u32 RESERVED2[30]; - vu32 ICPR[2]; - u32 RESERVED3[30]; - vu32 IABR[2]; - u32 RESERVED4[62]; - vu32 IPR[15]; -} NVIC_TypeDef; - -typedef struct { - u8 NVIC_IRQChannel; - u8 NVIC_IRQChannelPreemptionPriority; - u8 NVIC_IRQChannelSubPriority; - USB_Bool NVIC_IRQChannelCmd; /* TRUE for enable */ -} NVIC_InitTypeDef; - -typedef struct { - vuc32 CPUID; - vu32 ICSR; - vu32 VTOR; - vu32 AIRCR; - vu32 SCR; - vu32 CCR; - vu32 SHPR[3]; - vu32 SHCSR; - vu32 CFSR; - vu32 HFSR; - vu32 DFSR; - vu32 MMFAR; - vu32 BFAR; - vu32 AFSR; -} SCB_TypeDef; - - -void systemHardReset(void); - -void nvicInit (NVIC_InitTypeDef*); -void nvicDisableInterrupts(void); - -#if defined(__cplusplus) -} -#endif - -#endif +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +#include "rcc.h" +#include "usb_type.h" + +#ifndef _USB_HARDWARE_H_ +#define _USB_HARDWARE_H_ + +/* macro'd register and peripheral definitions */ +#define EXC_RETURN 0xFFFFFFF9 +#define DEFAULT_CPSR 0x61000000 + +#define FLASH ((u32)0x40022000) + +#define USB_PACKET_BUFFER ((u32)0x40006000) + +#define SCS_BASE ((u32)0xE000E000) +#define NVIC_BASE (SCS_BASE + 0x0100) +#define SCB_BASE (SCS_BASE + 0x0D00) + +#define SCS 0xE000E000 +#define NVIC (SCS+0x100) +#define SCB (SCS+0xD00) +#define STK (SCS+0x10) + +#define SCB_VTOR (SCB+0x08) +#define STK_CTRL (STK+0x00) + +#define USB_HP_IRQ ((u8)0x13) +#define USB_LP_IRQ ((u8)0x14) + +/* AIRCR */ +#define AIRCR_RESET 0x05FA0000 +#define AIRCR_RESET_REQ (AIRCR_RESET | (u32)0x04); + +/* temporary copyage of example from kiel */ +#define __VAL(__TIMCLK, __PERIOD) ((__TIMCLK/1000000UL)*__PERIOD) +#define __PSC(__TIMCLK, __PERIOD) (((__VAL(__TIMCLK, __PERIOD)+49999UL)/50000UL) - 1) +#define __ARR(__TIMCLK, __PERIOD) ((__VAL(__TIMCLK, __PERIOD)/(__PSC(__TIMCLK, __PERIOD)+1)) - 1) + +#define SET_REG(addr,val) do { *(vu32*)(addr)=val; } while (0) +#define GET_REG(addr) do { *(vu32*)(addr); } while (0) + +#if defined(__cplusplus) +extern "C" { +#endif + +/* todo: there must be some major misunderstanding in how we access regs. The direct access approach (GET_REG) + causes the usb init to fail upon trying to activate RCC_APB1 |= 0x00800000. However, using the struct approach + from ST, it works fine...temporarily switching to that approach */ +typedef struct +{ + vu32 CR; + vu32 CFGR; + vu32 CIR; + vu32 APB2RSTR; + vu32 APB1RSTR; + vu32 AHBENR; + vu32 APB2ENR; + vu32 APB1ENR; + vu32 BDCR; + vu32 CSR; +} RCC_RegStruct; +#define pRCC ((RCC_RegStruct *) RCC_BASE) + +typedef struct { + vu32 ISER[2]; + u32 RESERVED0[30]; + vu32 ICER[2]; + u32 RSERVED1[30]; + vu32 ISPR[2]; + u32 RESERVED2[30]; + vu32 ICPR[2]; + u32 RESERVED3[30]; + vu32 IABR[2]; + u32 RESERVED4[62]; + vu32 IPR[15]; +} NVIC_TypeDef; + +typedef struct { + u8 NVIC_IRQChannel; + u8 NVIC_IRQChannelPreemptionPriority; + u8 NVIC_IRQChannelSubPriority; + USB_Bool NVIC_IRQChannelCmd; /* TRUE for enable */ +} NVIC_InitTypeDef; + +typedef struct { + vuc32 CPUID; + vu32 ICSR; + vu32 VTOR; + vu32 AIRCR; + vu32 SCR; + vu32 CCR; + vu32 SHPR[3]; + vu32 SHCSR; + vu32 CFSR; + vu32 HFSR; + vu32 DFSR; + vu32 MMFAR; + vu32 BFAR; + vu32 AFSR; +} SCB_TypeDef; + + +void systemHardReset(void); + +void nvicInit (NVIC_InitTypeDef*); +void nvicDisableInterrupts(void); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_core.c b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_core.c index afe8798e..5cf9e874 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_core.c +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_core.c @@ -1,1013 +1,1013 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_core.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Standard protocol processing (USB v2.0) -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define ValBit(VAR,Place) (VAR & (1 << Place)) -#define SetBit(VAR,Place) (VAR |= (1 << Place)) -#define ClrBit(VAR,Place) (VAR &= ((1 << Place) ^ 255)) - -#define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \ - vSetEPTxStatus(EP_TX_VALID); \ - } - -#define vSetEPRxStatus(st) (SaveRState = st) -#define vSetEPTxStatus(st) (SaveTState = st) - -#define USB_StatusIn() Send0LengthData() -#define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID) - -#define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */ -#define StatusInfo1 StatusInfo.bw.bb0 - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -u16_u8 StatusInfo; -USB_Bool Data_Mul_MaxPacketSize = FALSE; -/* Private function prototypes -----------------------------------------------*/ -static void DataStageOut(void); -static void DataStageIn(void); -static void NoData_Setup0(void); -static void Data_Setup0(void); -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : Standard_GetConfiguration. -* Description : Return the current configuration variable address. -* Input : Length - How many bytes are needed. -* Output : None. -* Return : Return 1 , if the request is invalid when "Length" is 0. -* Return "Buffer" if the "Length" is not 0. -*******************************************************************************/ -u8 *Standard_GetConfiguration(u16 Length) -{ - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = - sizeof(pInformation->Current_Configuration); - return 0; - } - pUser_Standard_Requests->User_GetConfiguration(); - return (u8 *)&pInformation->Current_Configuration; -} - -/******************************************************************************* -* Function Name : Standard_SetConfiguration. -* Description : This routine is called to set the configuration value -* Then each class should configure device themself. -* Input : None. -* Output : None. -* Return : Return USB_SUCCESS, if the request is performed. -* Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetConfiguration(void) -{ - - if ((pInformation->USBwValue0 <= - Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0) - && (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/ - { - pInformation->Current_Configuration = pInformation->USBwValue0; - pUser_Standard_Requests->User_SetConfiguration(); - return USB_SUCCESS; - } - else - { - return USB_UNSUPPORT; - } -} - -/******************************************************************************* -* Function Name : Standard_GetInterface. -* Description : Return the Alternate Setting of the current interface. -* Input : Length - How many bytes are needed. -* Output : None. -* Return : Return 0, if the request is invalid when "Length" is 0. -* Return "Buffer" if the "Length" is not 0. -*******************************************************************************/ -u8 *Standard_GetInterface(u16 Length) -{ - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = - sizeof(pInformation->Current_AlternateSetting); - return 0; - } - pUser_Standard_Requests->User_GetInterface(); - return (u8 *)&pInformation->Current_AlternateSetting; -} - -/******************************************************************************* -* Function Name : Standard_SetInterface. -* Description : This routine is called to set the interface. -* Then each class should configure the interface them self. -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetInterface(void) -{ - RESULT Re; - /*Test if the specified Interface and Alternate Setting are supported by - the application Firmware*/ - Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0); - - if (pInformation->Current_Configuration != 0) - { - if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0) - || (pInformation->USBwValue1 != 0)) - { - return USB_UNSUPPORT; - } - else if (Re == USB_SUCCESS) - { - pUser_Standard_Requests->User_SetInterface(); - pInformation->Current_Interface = pInformation->USBwIndex0; - pInformation->Current_AlternateSetting = pInformation->USBwValue0; - return USB_SUCCESS; - } - - } - - return USB_UNSUPPORT; -} - -/******************************************************************************* -* Function Name : Standard_GetStatus. -* Description : Copy the device request data to "StatusInfo buffer". -* Input : - Length - How many bytes are needed. -* Output : None. -* Return : Return 0, if the request is at end of data block, -* or is invalid when "Length" is 0. -*******************************************************************************/ -u8 *Standard_GetStatus(u16 Length) -{ - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = 2; - return 0; - } - - StatusInfo.w = 0; - /* Reset Status Information */ - - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - /*Get Device Status */ - u8 Feature = pInformation->Current_Feature; - - /* Remote Wakeup enabled */ - if (ValBit(Feature, 5)) - { - SetBit(StatusInfo0, 1); - } - - /* Bus-powered */ - if (ValBit(Feature, 6)) - { - ClrBit(StatusInfo0, 0); - } - else /* Self-powered */ - { - SetBit(StatusInfo0, 0); - } - } - /*Interface Status*/ - else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - { - return (u8 *)&StatusInfo; - } - /*Get EndPoint Status*/ - else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - { - u8 Related_Endpoint; - u8 wIndex0 = pInformation->USBwIndex0; - - Related_Endpoint = (wIndex0 & 0x0f); - if (ValBit(wIndex0, 7)) - { - /* IN endpoint */ - if (_GetTxStallStatus(Related_Endpoint)) - { - SetBit(StatusInfo0, 0); /* IN Endpoint stalled */ - } - } - else - { - /* OUT endpoint */ - if (_GetRxStallStatus(Related_Endpoint)) - { - SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */ - } - } - - } - else - { - return NULL; - } - pUser_Standard_Requests->User_GetStatus(); - return (u8 *)&StatusInfo; -} - -/******************************************************************************* -* Function Name : Standard_ClearFeature. -* Description : Clear or disable a specific feature. -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_ClearFeature(void) -{ - u32 Type_Rec = Type_Recipient; - u32 Status; - - - if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - {/*Device Clear Feature*/ - ClrBit(pInformation->Current_Feature, 5); - return USB_SUCCESS; - } - else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - {/*EndPoint Clear Feature*/ - DEVICE* pDev; - u32 Related_Endpoint; - u32 wIndex0; - u32 rEP; - - if ((pInformation->USBwValue != ENDPOINT_STALL) - || (pInformation->USBwIndex1 != 0)) - { - return USB_UNSUPPORT; - } - - pDev = &Device_Table; - wIndex0 = pInformation->USBwIndex0; - rEP = wIndex0 & ~0x80; - Related_Endpoint = ENDP0 + rEP; - - if (ValBit(pInformation->USBwIndex0, 7)) - { - /*Get Status of endpoint & stall the request if the related_ENdpoint - is Disabled*/ - Status = _GetEPTxStatus(Related_Endpoint); - } - else - { - Status = _GetEPRxStatus(Related_Endpoint); - } - - if ((rEP >= pDev->Total_Endpoint) || (Status == 0) - || (pInformation->Current_Configuration == 0)) - { - return USB_UNSUPPORT; - } - - - if (wIndex0 & 0x80) - { - /* IN endpoint */ - if (_GetTxStallStatus(Related_Endpoint )) - { - ClearDTOG_TX(Related_Endpoint); - SetEPTxStatus(Related_Endpoint, EP_TX_VALID); - } - } - else - { - /* OUT endpoint */ - if (_GetRxStallStatus(Related_Endpoint)) - { - if (Related_Endpoint == ENDP0) - { - /* After clear the STALL, enable the default endpoint receiver */ - SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize); - _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); - } - else - { - ClearDTOG_RX(Related_Endpoint); - _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); - } - } - } - pUser_Standard_Requests->User_ClearFeature(); - return USB_SUCCESS; - } - - return USB_UNSUPPORT; -} - -/******************************************************************************* -* Function Name : Standard_SetEndPointFeature -* Description : Set or enable a specific feature of EndPoint -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetEndPointFeature(void) -{ - u32 wIndex0; - u32 Related_Endpoint; - u32 rEP; - u32 Status; - - wIndex0 = pInformation->USBwIndex0; - rEP = wIndex0 & ~0x80; - Related_Endpoint = ENDP0 + rEP; - - if (ValBit(pInformation->USBwIndex0, 7)) - { - /* get Status of endpoint & stall the request if the related_ENdpoint - is Disabled*/ - Status = _GetEPTxStatus(Related_Endpoint); - } - else - { - Status = _GetEPRxStatus(Related_Endpoint); - } - - if (Related_Endpoint >= Device_Table.Total_Endpoint - || pInformation->USBwValue != 0 || Status == 0 - || pInformation->Current_Configuration == 0) - { - return USB_UNSUPPORT; - } - else - { - if (wIndex0 & 0x80) - { - /* IN endpoint */ - _SetEPTxStatus(Related_Endpoint, EP_TX_STALL); - } - - else - { - /* OUT endpoint */ - _SetEPRxStatus(Related_Endpoint, EP_RX_STALL); - } - } - pUser_Standard_Requests->User_SetEndPointFeature(); - return USB_SUCCESS; -} - -/******************************************************************************* -* Function Name : Standard_SetDeviceFeature. -* Description : Set or enable a specific feature of Device. -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetDeviceFeature(void) -{ - SetBit(pInformation->Current_Feature, 5); - pUser_Standard_Requests->User_SetDeviceFeature(); - return USB_SUCCESS; -} - -/******************************************************************************* -* Function Name : Standard_GetDescriptorData. -* Description : Standard_GetDescriptorData is used for descriptors transfer. -* : This routine is used for the descriptors resident in Flash -* or RAM -* pDesc can be in either Flash or RAM -* The purpose of this routine is to have a versatile way to -* response descriptors request. It allows user to generate -* certain descriptors with software or read descriptors from -* external storage part by part. -* Input : - Length - Length of the data in this transfer. -* - pDesc - A pointer points to descriptor struct. -* The structure gives the initial address of the descriptor and -* its original size. -* Output : None. -* Return : Address of a part of the descriptor pointed by the Usb_ -* wOffset The buffer pointed by this address contains at least -* Length bytes. -*******************************************************************************/ -u8 *Standard_GetDescriptorData(u16 Length, ONE_DESCRIPTOR *pDesc) -{ - u32 wOffset; - - wOffset = pInformation->Ctrl_Info.Usb_wOffset; - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset; - return 0; - } - - return pDesc->Descriptor + wOffset; -} - -/******************************************************************************* -* Function Name : DataStageOut. -* Description : Data stage of a Control Write Transfer. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void DataStageOut(void) -{ - ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; - u32 save_rLength; - - save_rLength = pEPinfo->Usb_rLength; - - if (pEPinfo->CopyData && save_rLength) - { - u8 *Buffer; - u32 Length; - - Length = pEPinfo->PacketSize; - if (Length > save_rLength) - { - Length = save_rLength; - } - - Buffer = (*pEPinfo->CopyData)(Length); - pEPinfo->Usb_rLength -= Length; - pEPinfo->Usb_rOffset += Length; - - PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); - } - - if (pEPinfo->Usb_rLength != 0) - { - vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */ - SetEPTxCount(ENDP0, 0); - vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */ - } - /* Set the next State*/ - if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) - { - pInformation->ControlState = OUT_DATA; - } - else - { - if (pEPinfo->Usb_rLength > 0) - { - pInformation->ControlState = LAST_OUT_DATA; - } - else if (pEPinfo->Usb_rLength == 0) - { - pInformation->ControlState = WAIT_STATUS_IN; - USB_StatusIn(); - } - } -} - -/******************************************************************************* -* Function Name : DataStageIn. -* Description : Data stage of a Control Read Transfer. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void DataStageIn(void) -{ - ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; - u32 save_wLength = pEPinfo->Usb_wLength; - u32 ControlState = pInformation->ControlState; - - u8 *DataBuffer; - u32 Length; - - if ((save_wLength == 0) && (ControlState == LAST_IN_DATA)) - { - if(Data_Mul_MaxPacketSize == TRUE) - { - /* No more data to send and empty packet */ - Send0LengthData(); - ControlState = LAST_IN_DATA; - Data_Mul_MaxPacketSize = FALSE; - } - else - { - /* No more data to send so STALL the TX Status*/ - ControlState = WAIT_STATUS_OUT; - vSetEPTxStatus(EP_TX_STALL); - } - - goto Expect_Status_Out; - } - - Length = pEPinfo->PacketSize; - ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA; - - if (Length > save_wLength) - { - Length = save_wLength; - } - - DataBuffer = (*pEPinfo->CopyData)(Length); - - UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length); - - SetEPTxCount(ENDP0, Length); - - pEPinfo->Usb_wLength -= Length; - pEPinfo->Usb_wOffset += Length; - vSetEPTxStatus(EP_TX_VALID); - - USB_StatusOut();/* Expect the host to abort the data IN stage */ - -Expect_Status_Out: - pInformation->ControlState = ControlState; -} - -/******************************************************************************* -* Function Name : NoData_Setup0. -* Description : Proceed the processing of setup request without data stage. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void NoData_Setup0(void) -{ - RESULT Result = USB_UNSUPPORT; - u32 RequestNo = pInformation->USBbRequest; - u32 ControlState; - - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - /* Device Request*/ - /* SET_CONFIGURATION*/ - if (RequestNo == SET_CONFIGURATION) - { - Result = Standard_SetConfiguration(); - } - - /*SET ADDRESS*/ - else if (RequestNo == SET_ADDRESS) - { - if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0) - || (pInformation->USBwIndex != 0) - || (pInformation->Current_Configuration != 0)) - /* Device Address should be 127 or less*/ - { - ControlState = STALLED; - goto exit_NoData_Setup0; - } - else - { - Result = USB_SUCCESS; - } - } - /*SET FEATURE for Device*/ - else if (RequestNo == SET_FEATURE) - { - if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP) - && (pInformation->USBwIndex == 0) - && (ValBit(pInformation->Current_Feature, 5))) - { - Result = Standard_SetDeviceFeature(); - } - else - { - Result = USB_UNSUPPORT; - } - } - /*Clear FEATURE for Device */ - else if (RequestNo == CLEAR_FEATURE) - { - if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP - && pInformation->USBwIndex == 0 - && ValBit(pInformation->Current_Feature, 5)) - { - Result = Standard_ClearFeature(); - } - else - { - Result = USB_UNSUPPORT; - } - } - - } - - /* Interface Request*/ - else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - { - /*SET INTERFACE*/ - if (RequestNo == SET_INTERFACE) - { - Result = Standard_SetInterface(); - } - } - - /* EndPoint Request*/ - else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - { - /*CLEAR FEATURE for EndPoint*/ - if (RequestNo == CLEAR_FEATURE) - { - Result = Standard_ClearFeature(); - } - /* SET FEATURE for EndPoint*/ - else if (RequestNo == SET_FEATURE) - { - Result = Standard_SetEndPointFeature(); - } - } - else - { - Result = USB_UNSUPPORT; - } - - - if (Result != USB_SUCCESS) - { - Result = (*pProperty->Class_NoData_Setup)(RequestNo); - if (Result == USB_NOT_READY) - { - ControlState = PAUSE; - goto exit_NoData_Setup0; - } - } - - if (Result != USB_SUCCESS) - { - ControlState = STALLED; - goto exit_NoData_Setup0; - } - - ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */ - - USB_StatusIn(); - -exit_NoData_Setup0: - pInformation->ControlState = ControlState; - return; -} - -/******************************************************************************* -* Function Name : Data_Setup0. -* Description : Proceed the processing of setup request with data stage. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void Data_Setup0(void) -{ - u8 *(*CopyRoutine)(u16); - RESULT Result; - u32 Request_No = pInformation->USBbRequest; - - u32 Related_Endpoint, Reserved; - u32 wOffset, Status; - - - - CopyRoutine = NULL; - wOffset = 0; - - if (Request_No == GET_DESCRIPTOR) - { - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - u8 wValue1 = pInformation->USBwValue1; - if (wValue1 == DEVICE_DESCRIPTOR) - { - CopyRoutine = pProperty->GetDeviceDescriptor; - } - else if (wValue1 == CONFIG_DESCRIPTOR) - { - CopyRoutine = pProperty->GetConfigDescriptor; - } - else if (wValue1 == STRING_DESCRIPTOR) - { - CopyRoutine = pProperty->GetStringDescriptor; - } /* End of GET_DESCRIPTOR */ - } - } - - /*GET STATUS*/ - else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0) - && (pInformation->USBwLength == 0x0002) - && (pInformation->USBwIndex1 == 0)) - { - /* GET STATUS for Device*/ - if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - && (pInformation->USBwIndex == 0)) - { - CopyRoutine = Standard_GetStatus; - } - - /* GET STATUS for Interface*/ - else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - { - if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS) - && (pInformation->Current_Configuration != 0)) - { - CopyRoutine = Standard_GetStatus; - } - } - - /* GET STATUS for EndPoint*/ - else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - { - Related_Endpoint = (pInformation->USBwIndex0 & 0x0f); - Reserved = pInformation->USBwIndex0 & 0x70; - - if (ValBit(pInformation->USBwIndex0, 7)) - { - /*Get Status of endpoint & stall the request if the related_ENdpoint - is Disabled*/ - Status = _GetEPTxStatus(Related_Endpoint); - } - else - { - Status = _GetEPRxStatus(Related_Endpoint); - } - - if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0) - && (Status != 0)) - { - CopyRoutine = Standard_GetStatus; - } - } - - } - - /*GET CONFIGURATION*/ - else if (Request_No == GET_CONFIGURATION) - { - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - CopyRoutine = Standard_GetConfiguration; - } - } - /*GET INTERFACE*/ - else if (Request_No == GET_INTERFACE) - { - if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0) - && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001) - && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)) - { - CopyRoutine = Standard_GetInterface; - } - - } - - if (CopyRoutine) - { - pInformation->Ctrl_Info.Usb_wOffset = wOffset; - pInformation->Ctrl_Info.CopyData = CopyRoutine; - /* sb in the original the cast to word was directly */ - /* now the cast is made step by step */ - (*CopyRoutine)(0); - Result = USB_SUCCESS; - } - else - { - Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest); - if (Result == USB_NOT_READY) - { - pInformation->ControlState = PAUSE; - return; - } - } - - if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF) - { - /* Data is not ready, wait it */ - pInformation->ControlState = PAUSE; - return; - } - if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0)) - { - /* Unsupported request */ - pInformation->ControlState = STALLED; - return; - } - - - if (ValBit(pInformation->USBbmRequestType, 7)) - { - /* Device ==> Host */ - vu32 wLength = pInformation->USBwLength; - - /* Restrict the data length to be the one host asks */ - if (pInformation->Ctrl_Info.Usb_wLength > wLength) - { - pInformation->Ctrl_Info.Usb_wLength = wLength; - } - - else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength) - { - if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize) - { - Data_Mul_MaxPacketSize = FALSE; - } - else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0) - { - Data_Mul_MaxPacketSize = TRUE; - } - } - - pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize; - DataStageIn(); - } - else - { - pInformation->ControlState = OUT_DATA; - vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */ - } - - return; -} - -/******************************************************************************* -* Function Name : Setup0_Process -* Description : Get the device request data and dispatch to individual process. -* Input : None. -* Output : None. -* Return : Post0_Process. -*******************************************************************************/ -u8 Setup0_Process(void) -{ - - union - { - u8* b; - u16* w; - } pBuf; - - pBuf.b = PMAAddr + (u8 *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */ - - if (pInformation->ControlState != PAUSE) - { - pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */ - pInformation->USBbRequest = *pBuf.b++; /* bRequest */ - pBuf.w++; /* word not accessed because of 32 bits addressing */ - pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */ - pBuf.w++; /* word not accessed because of 32 bits addressing */ - pInformation->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */ - pBuf.w++; /* word not accessed because of 32 bits addressing */ - pInformation->USBwLength = *pBuf.w; /* wLength */ - } - - pInformation->ControlState = SETTING_UP; - if (pInformation->USBwLength == 0) - { - /* Setup with no data stage */ - NoData_Setup0(); - } - else - { - /* Setup with data stage */ - Data_Setup0(); - } - return Post0_Process(); -} - -/******************************************************************************* -* Function Name : In0_Process -* Description : Process the IN token on all default endpoint. -* Input : None. -* Output : None. -* Return : Post0_Process. -*******************************************************************************/ -u8 In0_Process(void) -{ - u32 ControlState = pInformation->ControlState; - - if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) - { - DataStageIn(); - /* ControlState may be changed outside the function */ - ControlState = pInformation->ControlState; - } - - else if (ControlState == WAIT_STATUS_IN) - { - if ((pInformation->USBbRequest == SET_ADDRESS) && - (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))) - { - SetDeviceAddress(pInformation->USBwValue0); - pUser_Standard_Requests->User_SetDeviceAddress(); - } - (*pProperty->Process_Status_IN)(); - ControlState = STALLED; - } - - else - { - ControlState = STALLED; - } - - pInformation->ControlState = ControlState; - - return Post0_Process(); -} - -/******************************************************************************* -* Function Name : Out0_Process -* Description : Process the OUT token on all default endpoint. -* Input : None. -* Output : None. -* Return : Post0_Process. -*******************************************************************************/ -u8 Out0_Process(void) -{ - u32 ControlState = pInformation->ControlState; - - if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA)) - { - DataStageOut(); - ControlState = pInformation->ControlState; /* may be changed outside the function */ - } - - else if (ControlState == WAIT_STATUS_OUT) - { - (*pProperty->Process_Status_OUT)(); - ControlState = STALLED; - } - - else if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) - { - /* host aborts the transfer before finish */ - ControlState = STALLED; - } - - /* Unexpect state, STALL the endpoint */ - else - { - ControlState = STALLED; - } - - pInformation->ControlState = ControlState; - - return Post0_Process(); -} - -/******************************************************************************* -* Function Name : Post0_Process -* Description : Stall the Endpoint 0 in case of error. -* Input : None. -* Output : None. -* Return : - 0 if the control State is in PAUSE -* - 1 if not. -*******************************************************************************/ -u8 Post0_Process(void) -{ - SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); - - if (pInformation->ControlState == STALLED) - { - vSetEPRxStatus(EP_RX_STALL); - vSetEPTxStatus(EP_TX_STALL); - } - - return (pInformation->ControlState == PAUSE); -} - -/******************************************************************************* -* Function Name : SetDeviceAddress. -* Description : Set the device and all the used Endpoints addresses. -* Input : - Val: device adress. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetDeviceAddress(u8 Val) -{ - u32 i; - u32 nEP = Device_Table.Total_Endpoint; - - /* set address in every used endpoint */ - for (i = 0; i < nEP; i++) - { - _SetEPAddress((u8)i, (u8)i); - } /* for */ - _SetDADDR(Val | DADDR_EF); /* set device address and enable function */ -} - -/******************************************************************************* -* Function Name : NOP_Process -* Description : No operation function. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void NOP_Process(void) -{ -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_core.c +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Standard protocol processing (USB v2.0) +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_lib.h" +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define ValBit(VAR,Place) (VAR & (1 << Place)) +#define SetBit(VAR,Place) (VAR |= (1 << Place)) +#define ClrBit(VAR,Place) (VAR &= ((1 << Place) ^ 255)) + +#define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \ + vSetEPTxStatus(EP_TX_VALID); \ + } + +#define vSetEPRxStatus(st) (SaveRState = st) +#define vSetEPTxStatus(st) (SaveTState = st) + +#define USB_StatusIn() Send0LengthData() +#define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID) + +#define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */ +#define StatusInfo1 StatusInfo.bw.bb0 + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +u16_u8 StatusInfo; +USB_Bool Data_Mul_MaxPacketSize = FALSE; +/* Private function prototypes -----------------------------------------------*/ +static void DataStageOut(void); +static void DataStageIn(void); +static void NoData_Setup0(void); +static void Data_Setup0(void); +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : Standard_GetConfiguration. +* Description : Return the current configuration variable address. +* Input : Length - How many bytes are needed. +* Output : None. +* Return : Return 1 , if the request is invalid when "Length" is 0. +* Return "Buffer" if the "Length" is not 0. +*******************************************************************************/ +u8 *Standard_GetConfiguration(u16 Length) +{ + if (Length == 0) + { + pInformation->Ctrl_Info.Usb_wLength = + sizeof(pInformation->Current_Configuration); + return 0; + } + pUser_Standard_Requests->User_GetConfiguration(); + return (u8 *)&pInformation->Current_Configuration; +} + +/******************************************************************************* +* Function Name : Standard_SetConfiguration. +* Description : This routine is called to set the configuration value +* Then each class should configure device themself. +* Input : None. +* Output : None. +* Return : Return USB_SUCCESS, if the request is performed. +* Return USB_UNSUPPORT, if the request is invalid. +*******************************************************************************/ +RESULT Standard_SetConfiguration(void) +{ + + if ((pInformation->USBwValue0 <= + Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0) + && (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/ + { + pInformation->Current_Configuration = pInformation->USBwValue0; + pUser_Standard_Requests->User_SetConfiguration(); + return USB_SUCCESS; + } + else + { + return USB_UNSUPPORT; + } +} + +/******************************************************************************* +* Function Name : Standard_GetInterface. +* Description : Return the Alternate Setting of the current interface. +* Input : Length - How many bytes are needed. +* Output : None. +* Return : Return 0, if the request is invalid when "Length" is 0. +* Return "Buffer" if the "Length" is not 0. +*******************************************************************************/ +u8 *Standard_GetInterface(u16 Length) +{ + if (Length == 0) + { + pInformation->Ctrl_Info.Usb_wLength = + sizeof(pInformation->Current_AlternateSetting); + return 0; + } + pUser_Standard_Requests->User_GetInterface(); + return (u8 *)&pInformation->Current_AlternateSetting; +} + +/******************************************************************************* +* Function Name : Standard_SetInterface. +* Description : This routine is called to set the interface. +* Then each class should configure the interface them self. +* Input : None. +* Output : None. +* Return : - Return USB_SUCCESS, if the request is performed. +* - Return USB_UNSUPPORT, if the request is invalid. +*******************************************************************************/ +RESULT Standard_SetInterface(void) +{ + RESULT Re; + /*Test if the specified Interface and Alternate Setting are supported by + the application Firmware*/ + Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0); + + if (pInformation->Current_Configuration != 0) + { + if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0) + || (pInformation->USBwValue1 != 0)) + { + return USB_UNSUPPORT; + } + else if (Re == USB_SUCCESS) + { + pUser_Standard_Requests->User_SetInterface(); + pInformation->Current_Interface = pInformation->USBwIndex0; + pInformation->Current_AlternateSetting = pInformation->USBwValue0; + return USB_SUCCESS; + } + + } + + return USB_UNSUPPORT; +} + +/******************************************************************************* +* Function Name : Standard_GetStatus. +* Description : Copy the device request data to "StatusInfo buffer". +* Input : - Length - How many bytes are needed. +* Output : None. +* Return : Return 0, if the request is at end of data block, +* or is invalid when "Length" is 0. +*******************************************************************************/ +u8 *Standard_GetStatus(u16 Length) +{ + if (Length == 0) + { + pInformation->Ctrl_Info.Usb_wLength = 2; + return 0; + } + + StatusInfo.w = 0; + /* Reset Status Information */ + + if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + { + /*Get Device Status */ + u8 Feature = pInformation->Current_Feature; + + /* Remote Wakeup enabled */ + if (ValBit(Feature, 5)) + { + SetBit(StatusInfo0, 1); + } + + /* Bus-powered */ + if (ValBit(Feature, 6)) + { + ClrBit(StatusInfo0, 0); + } + else /* Self-powered */ + { + SetBit(StatusInfo0, 0); + } + } + /*Interface Status*/ + else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) + { + return (u8 *)&StatusInfo; + } + /*Get EndPoint Status*/ + else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) + { + u8 Related_Endpoint; + u8 wIndex0 = pInformation->USBwIndex0; + + Related_Endpoint = (wIndex0 & 0x0f); + if (ValBit(wIndex0, 7)) + { + /* IN endpoint */ + if (_GetTxStallStatus(Related_Endpoint)) + { + SetBit(StatusInfo0, 0); /* IN Endpoint stalled */ + } + } + else + { + /* OUT endpoint */ + if (_GetRxStallStatus(Related_Endpoint)) + { + SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */ + } + } + + } + else + { + return NULL; + } + pUser_Standard_Requests->User_GetStatus(); + return (u8 *)&StatusInfo; +} + +/******************************************************************************* +* Function Name : Standard_ClearFeature. +* Description : Clear or disable a specific feature. +* Input : None. +* Output : None. +* Return : - Return USB_SUCCESS, if the request is performed. +* - Return USB_UNSUPPORT, if the request is invalid. +*******************************************************************************/ +RESULT Standard_ClearFeature(void) +{ + u32 Type_Rec = Type_Recipient; + u32 Status; + + + if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + {/*Device Clear Feature*/ + ClrBit(pInformation->Current_Feature, 5); + return USB_SUCCESS; + } + else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) + {/*EndPoint Clear Feature*/ + DEVICE* pDev; + u32 Related_Endpoint; + u32 wIndex0; + u32 rEP; + + if ((pInformation->USBwValue != ENDPOINT_STALL) + || (pInformation->USBwIndex1 != 0)) + { + return USB_UNSUPPORT; + } + + pDev = &Device_Table; + wIndex0 = pInformation->USBwIndex0; + rEP = wIndex0 & ~0x80; + Related_Endpoint = ENDP0 + rEP; + + if (ValBit(pInformation->USBwIndex0, 7)) + { + /*Get Status of endpoint & stall the request if the related_ENdpoint + is Disabled*/ + Status = _GetEPTxStatus(Related_Endpoint); + } + else + { + Status = _GetEPRxStatus(Related_Endpoint); + } + + if ((rEP >= pDev->Total_Endpoint) || (Status == 0) + || (pInformation->Current_Configuration == 0)) + { + return USB_UNSUPPORT; + } + + + if (wIndex0 & 0x80) + { + /* IN endpoint */ + if (_GetTxStallStatus(Related_Endpoint )) + { + ClearDTOG_TX(Related_Endpoint); + SetEPTxStatus(Related_Endpoint, EP_TX_VALID); + } + } + else + { + /* OUT endpoint */ + if (_GetRxStallStatus(Related_Endpoint)) + { + if (Related_Endpoint == ENDP0) + { + /* After clear the STALL, enable the default endpoint receiver */ + SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize); + _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); + } + else + { + ClearDTOG_RX(Related_Endpoint); + _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); + } + } + } + pUser_Standard_Requests->User_ClearFeature(); + return USB_SUCCESS; + } + + return USB_UNSUPPORT; +} + +/******************************************************************************* +* Function Name : Standard_SetEndPointFeature +* Description : Set or enable a specific feature of EndPoint +* Input : None. +* Output : None. +* Return : - Return USB_SUCCESS, if the request is performed. +* - Return USB_UNSUPPORT, if the request is invalid. +*******************************************************************************/ +RESULT Standard_SetEndPointFeature(void) +{ + u32 wIndex0; + u32 Related_Endpoint; + u32 rEP; + u32 Status; + + wIndex0 = pInformation->USBwIndex0; + rEP = wIndex0 & ~0x80; + Related_Endpoint = ENDP0 + rEP; + + if (ValBit(pInformation->USBwIndex0, 7)) + { + /* get Status of endpoint & stall the request if the related_ENdpoint + is Disabled*/ + Status = _GetEPTxStatus(Related_Endpoint); + } + else + { + Status = _GetEPRxStatus(Related_Endpoint); + } + + if (Related_Endpoint >= Device_Table.Total_Endpoint + || pInformation->USBwValue != 0 || Status == 0 + || pInformation->Current_Configuration == 0) + { + return USB_UNSUPPORT; + } + else + { + if (wIndex0 & 0x80) + { + /* IN endpoint */ + _SetEPTxStatus(Related_Endpoint, EP_TX_STALL); + } + + else + { + /* OUT endpoint */ + _SetEPRxStatus(Related_Endpoint, EP_RX_STALL); + } + } + pUser_Standard_Requests->User_SetEndPointFeature(); + return USB_SUCCESS; +} + +/******************************************************************************* +* Function Name : Standard_SetDeviceFeature. +* Description : Set or enable a specific feature of Device. +* Input : None. +* Output : None. +* Return : - Return USB_SUCCESS, if the request is performed. +* - Return USB_UNSUPPORT, if the request is invalid. +*******************************************************************************/ +RESULT Standard_SetDeviceFeature(void) +{ + SetBit(pInformation->Current_Feature, 5); + pUser_Standard_Requests->User_SetDeviceFeature(); + return USB_SUCCESS; +} + +/******************************************************************************* +* Function Name : Standard_GetDescriptorData. +* Description : Standard_GetDescriptorData is used for descriptors transfer. +* : This routine is used for the descriptors resident in Flash +* or RAM +* pDesc can be in either Flash or RAM +* The purpose of this routine is to have a versatile way to +* response descriptors request. It allows user to generate +* certain descriptors with software or read descriptors from +* external storage part by part. +* Input : - Length - Length of the data in this transfer. +* - pDesc - A pointer points to descriptor struct. +* The structure gives the initial address of the descriptor and +* its original size. +* Output : None. +* Return : Address of a part of the descriptor pointed by the Usb_ +* wOffset The buffer pointed by this address contains at least +* Length bytes. +*******************************************************************************/ +u8 *Standard_GetDescriptorData(u16 Length, ONE_DESCRIPTOR *pDesc) +{ + u32 wOffset; + + wOffset = pInformation->Ctrl_Info.Usb_wOffset; + if (Length == 0) + { + pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset; + return 0; + } + + return pDesc->Descriptor + wOffset; +} + +/******************************************************************************* +* Function Name : DataStageOut. +* Description : Data stage of a Control Write Transfer. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void DataStageOut(void) +{ + ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; + u32 save_rLength; + + save_rLength = pEPinfo->Usb_rLength; + + if (pEPinfo->CopyData && save_rLength) + { + u8 *Buffer; + u32 Length; + + Length = pEPinfo->PacketSize; + if (Length > save_rLength) + { + Length = save_rLength; + } + + Buffer = (*pEPinfo->CopyData)(Length); + pEPinfo->Usb_rLength -= Length; + pEPinfo->Usb_rOffset += Length; + + PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); + } + + if (pEPinfo->Usb_rLength != 0) + { + vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */ + SetEPTxCount(ENDP0, 0); + vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */ + } + /* Set the next State*/ + if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) + { + pInformation->ControlState = OUT_DATA; + } + else + { + if (pEPinfo->Usb_rLength > 0) + { + pInformation->ControlState = LAST_OUT_DATA; + } + else if (pEPinfo->Usb_rLength == 0) + { + pInformation->ControlState = WAIT_STATUS_IN; + USB_StatusIn(); + } + } +} + +/******************************************************************************* +* Function Name : DataStageIn. +* Description : Data stage of a Control Read Transfer. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void DataStageIn(void) +{ + ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; + u32 save_wLength = pEPinfo->Usb_wLength; + u32 ControlState = pInformation->ControlState; + + u8 *DataBuffer; + u32 Length; + + if ((save_wLength == 0) && (ControlState == LAST_IN_DATA)) + { + if(Data_Mul_MaxPacketSize == TRUE) + { + /* No more data to send and empty packet */ + Send0LengthData(); + ControlState = LAST_IN_DATA; + Data_Mul_MaxPacketSize = FALSE; + } + else + { + /* No more data to send so STALL the TX Status*/ + ControlState = WAIT_STATUS_OUT; + vSetEPTxStatus(EP_TX_STALL); + } + + goto Expect_Status_Out; + } + + Length = pEPinfo->PacketSize; + ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA; + + if (Length > save_wLength) + { + Length = save_wLength; + } + + DataBuffer = (*pEPinfo->CopyData)(Length); + + UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length); + + SetEPTxCount(ENDP0, Length); + + pEPinfo->Usb_wLength -= Length; + pEPinfo->Usb_wOffset += Length; + vSetEPTxStatus(EP_TX_VALID); + + USB_StatusOut();/* Expect the host to abort the data IN stage */ + +Expect_Status_Out: + pInformation->ControlState = ControlState; +} + +/******************************************************************************* +* Function Name : NoData_Setup0. +* Description : Proceed the processing of setup request without data stage. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void NoData_Setup0(void) +{ + RESULT Result = USB_UNSUPPORT; + u32 RequestNo = pInformation->USBbRequest; + u32 ControlState; + + if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + { + /* Device Request*/ + /* SET_CONFIGURATION*/ + if (RequestNo == SET_CONFIGURATION) + { + Result = Standard_SetConfiguration(); + } + + /*SET ADDRESS*/ + else if (RequestNo == SET_ADDRESS) + { + if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0) + || (pInformation->USBwIndex != 0) + || (pInformation->Current_Configuration != 0)) + /* Device Address should be 127 or less*/ + { + ControlState = STALLED; + goto exit_NoData_Setup0; + } + else + { + Result = USB_SUCCESS; + } + } + /*SET FEATURE for Device*/ + else if (RequestNo == SET_FEATURE) + { + if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP) + && (pInformation->USBwIndex == 0) + && (ValBit(pInformation->Current_Feature, 5))) + { + Result = Standard_SetDeviceFeature(); + } + else + { + Result = USB_UNSUPPORT; + } + } + /*Clear FEATURE for Device */ + else if (RequestNo == CLEAR_FEATURE) + { + if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP + && pInformation->USBwIndex == 0 + && ValBit(pInformation->Current_Feature, 5)) + { + Result = Standard_ClearFeature(); + } + else + { + Result = USB_UNSUPPORT; + } + } + + } + + /* Interface Request*/ + else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) + { + /*SET INTERFACE*/ + if (RequestNo == SET_INTERFACE) + { + Result = Standard_SetInterface(); + } + } + + /* EndPoint Request*/ + else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) + { + /*CLEAR FEATURE for EndPoint*/ + if (RequestNo == CLEAR_FEATURE) + { + Result = Standard_ClearFeature(); + } + /* SET FEATURE for EndPoint*/ + else if (RequestNo == SET_FEATURE) + { + Result = Standard_SetEndPointFeature(); + } + } + else + { + Result = USB_UNSUPPORT; + } + + + if (Result != USB_SUCCESS) + { + Result = (*pProperty->Class_NoData_Setup)(RequestNo); + if (Result == USB_NOT_READY) + { + ControlState = PAUSE; + goto exit_NoData_Setup0; + } + } + + if (Result != USB_SUCCESS) + { + ControlState = STALLED; + goto exit_NoData_Setup0; + } + + ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */ + + USB_StatusIn(); + +exit_NoData_Setup0: + pInformation->ControlState = ControlState; + return; +} + +/******************************************************************************* +* Function Name : Data_Setup0. +* Description : Proceed the processing of setup request with data stage. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void Data_Setup0(void) +{ + u8 *(*CopyRoutine)(u16); + RESULT Result; + u32 Request_No = pInformation->USBbRequest; + + u32 Related_Endpoint, Reserved; + u32 wOffset, Status; + + + + CopyRoutine = NULL; + wOffset = 0; + + if (Request_No == GET_DESCRIPTOR) + { + if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + { + u8 wValue1 = pInformation->USBwValue1; + if (wValue1 == DEVICE_DESCRIPTOR) + { + CopyRoutine = pProperty->GetDeviceDescriptor; + } + else if (wValue1 == CONFIG_DESCRIPTOR) + { + CopyRoutine = pProperty->GetConfigDescriptor; + } + else if (wValue1 == STRING_DESCRIPTOR) + { + CopyRoutine = pProperty->GetStringDescriptor; + } /* End of GET_DESCRIPTOR */ + } + } + + /*GET STATUS*/ + else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0) + && (pInformation->USBwLength == 0x0002) + && (pInformation->USBwIndex1 == 0)) + { + /* GET STATUS for Device*/ + if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + && (pInformation->USBwIndex == 0)) + { + CopyRoutine = Standard_GetStatus; + } + + /* GET STATUS for Interface*/ + else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) + { + if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS) + && (pInformation->Current_Configuration != 0)) + { + CopyRoutine = Standard_GetStatus; + } + } + + /* GET STATUS for EndPoint*/ + else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) + { + Related_Endpoint = (pInformation->USBwIndex0 & 0x0f); + Reserved = pInformation->USBwIndex0 & 0x70; + + if (ValBit(pInformation->USBwIndex0, 7)) + { + /*Get Status of endpoint & stall the request if the related_ENdpoint + is Disabled*/ + Status = _GetEPTxStatus(Related_Endpoint); + } + else + { + Status = _GetEPRxStatus(Related_Endpoint); + } + + if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0) + && (Status != 0)) + { + CopyRoutine = Standard_GetStatus; + } + } + + } + + /*GET CONFIGURATION*/ + else if (Request_No == GET_CONFIGURATION) + { + if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + { + CopyRoutine = Standard_GetConfiguration; + } + } + /*GET INTERFACE*/ + else if (Request_No == GET_INTERFACE) + { + if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) + && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0) + && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001) + && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)) + { + CopyRoutine = Standard_GetInterface; + } + + } + + if (CopyRoutine) + { + pInformation->Ctrl_Info.Usb_wOffset = wOffset; + pInformation->Ctrl_Info.CopyData = CopyRoutine; + /* sb in the original the cast to word was directly */ + /* now the cast is made step by step */ + (*CopyRoutine)(0); + Result = USB_SUCCESS; + } + else + { + Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest); + if (Result == USB_NOT_READY) + { + pInformation->ControlState = PAUSE; + return; + } + } + + if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF) + { + /* Data is not ready, wait it */ + pInformation->ControlState = PAUSE; + return; + } + if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0)) + { + /* Unsupported request */ + pInformation->ControlState = STALLED; + return; + } + + + if (ValBit(pInformation->USBbmRequestType, 7)) + { + /* Device ==> Host */ + vu32 wLength = pInformation->USBwLength; + + /* Restrict the data length to be the one host asks */ + if (pInformation->Ctrl_Info.Usb_wLength > wLength) + { + pInformation->Ctrl_Info.Usb_wLength = wLength; + } + + else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength) + { + if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize) + { + Data_Mul_MaxPacketSize = FALSE; + } + else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0) + { + Data_Mul_MaxPacketSize = TRUE; + } + } + + pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize; + DataStageIn(); + } + else + { + pInformation->ControlState = OUT_DATA; + vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */ + } + + return; +} + +/******************************************************************************* +* Function Name : Setup0_Process +* Description : Get the device request data and dispatch to individual process. +* Input : None. +* Output : None. +* Return : Post0_Process. +*******************************************************************************/ +u8 Setup0_Process(void) +{ + + union + { + u8* b; + u16* w; + } pBuf; + + pBuf.b = PMAAddr + (u8 *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */ + + if (pInformation->ControlState != PAUSE) + { + pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */ + pInformation->USBbRequest = *pBuf.b++; /* bRequest */ + pBuf.w++; /* word not accessed because of 32 bits addressing */ + pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */ + pBuf.w++; /* word not accessed because of 32 bits addressing */ + pInformation->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */ + pBuf.w++; /* word not accessed because of 32 bits addressing */ + pInformation->USBwLength = *pBuf.w; /* wLength */ + } + + pInformation->ControlState = SETTING_UP; + if (pInformation->USBwLength == 0) + { + /* Setup with no data stage */ + NoData_Setup0(); + } + else + { + /* Setup with data stage */ + Data_Setup0(); + } + return Post0_Process(); +} + +/******************************************************************************* +* Function Name : In0_Process +* Description : Process the IN token on all default endpoint. +* Input : None. +* Output : None. +* Return : Post0_Process. +*******************************************************************************/ +u8 In0_Process(void) +{ + u32 ControlState = pInformation->ControlState; + + if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) + { + DataStageIn(); + /* ControlState may be changed outside the function */ + ControlState = pInformation->ControlState; + } + + else if (ControlState == WAIT_STATUS_IN) + { + if ((pInformation->USBbRequest == SET_ADDRESS) && + (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))) + { + SetDeviceAddress(pInformation->USBwValue0); + pUser_Standard_Requests->User_SetDeviceAddress(); + } + (*pProperty->Process_Status_IN)(); + ControlState = STALLED; + } + + else + { + ControlState = STALLED; + } + + pInformation->ControlState = ControlState; + + return Post0_Process(); +} + +/******************************************************************************* +* Function Name : Out0_Process +* Description : Process the OUT token on all default endpoint. +* Input : None. +* Output : None. +* Return : Post0_Process. +*******************************************************************************/ +u8 Out0_Process(void) +{ + u32 ControlState = pInformation->ControlState; + + if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA)) + { + DataStageOut(); + ControlState = pInformation->ControlState; /* may be changed outside the function */ + } + + else if (ControlState == WAIT_STATUS_OUT) + { + (*pProperty->Process_Status_OUT)(); + ControlState = STALLED; + } + + else if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) + { + /* host aborts the transfer before finish */ + ControlState = STALLED; + } + + /* Unexpect state, STALL the endpoint */ + else + { + ControlState = STALLED; + } + + pInformation->ControlState = ControlState; + + return Post0_Process(); +} + +/******************************************************************************* +* Function Name : Post0_Process +* Description : Stall the Endpoint 0 in case of error. +* Input : None. +* Output : None. +* Return : - 0 if the control State is in PAUSE +* - 1 if not. +*******************************************************************************/ +u8 Post0_Process(void) +{ + SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); + + if (pInformation->ControlState == STALLED) + { + vSetEPRxStatus(EP_RX_STALL); + vSetEPTxStatus(EP_TX_STALL); + } + + return (pInformation->ControlState == PAUSE); +} + +/******************************************************************************* +* Function Name : SetDeviceAddress. +* Description : Set the device and all the used Endpoints addresses. +* Input : - Val: device adress. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetDeviceAddress(u8 Val) +{ + u32 i; + u32 nEP = Device_Table.Total_Endpoint; + + /* set address in every used endpoint */ + for (i = 0; i < nEP; i++) + { + _SetEPAddress((u8)i, (u8)i); + } /* for */ + _SetDADDR(Val | DADDR_EF); /* set device address and enable function */ +} + +/******************************************************************************* +* Function Name : NOP_Process +* Description : No operation function. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void NOP_Process(void) +{ +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_core.h b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_core.h index d8c099fc..fa29a183 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_core.h +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_core.h @@ -1,251 +1,251 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_core.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Standard protocol processing functions prototypes -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CORE_H -#define __USB_CORE_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -typedef enum _CONTROL_STATE -{ - WAIT_SETUP, /* 0 */ - SETTING_UP, /* 1 */ - IN_DATA, /* 2 */ - OUT_DATA, /* 3 */ - LAST_IN_DATA, /* 4 */ - LAST_OUT_DATA, /* 5 */ - WAIT_STATUS_IN, /* 7 */ - WAIT_STATUS_OUT, /* 8 */ - STALLED, /* 9 */ - PAUSE /* 10 */ -} CONTROL_STATE; /* The state machine states of a control pipe */ - -typedef struct OneDescriptor -{ - u8 *Descriptor; - u16 Descriptor_Size; -} -ONE_DESCRIPTOR, *PONE_DESCRIPTOR; -/* All the request process routines return a value of this type - If the return value is not SUCCESS or NOT_READY, - the software will STALL the correspond endpoint */ -typedef enum _RESULT -{ - USB_SUCCESS = 0, /* Process sucessfully */ - USB_ERROR, - USB_UNSUPPORT, - USB_NOT_READY /* The process has not been finished, endpoint will be - NAK to further rquest */ -} RESULT; - - -/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/ -typedef struct _ENDPOINT_INFO -{ - /* When send data out of the device, - CopyData() is used to get data buffer 'Length' bytes data - if Length is 0, - CopyData() returns the total length of the data - if the request is not supported, returns 0 - (NEW Feature ) - if CopyData() returns -1, the calling routine should not proceed - further and will resume the SETUP process by the class device - if Length is not 0, - CopyData() returns a pointer to indicate the data location - Usb_wLength is the data remain to be sent, - Usb_wOffset is the Offset of original data - When receive data from the host, - CopyData() is used to get user data buffer which is capable - of Length bytes data to copy data from the endpoint buffer. - if Length is 0, - CopyData() returns the available data length, - if Length is not 0, - CopyData() returns user buffer address - Usb_rLength is the data remain to be received, - Usb_rPointer is the Offset of data buffer - */ - u16 Usb_wLength; - u16 Usb_wOffset; - u16 PacketSize; - u8 *(*CopyData)(u16 Length); -}ENDPOINT_INFO; - -/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/ - -typedef struct _DEVICE -{ - u8 Total_Endpoint; /* Number of endpoints that are used */ - u8 Total_Configuration;/* Number of configuration available */ -} -DEVICE; - -typedef union -{ - u16 w; - struct BW - { - u8 bb1; - u8 bb0; - } - bw; -} u16_u8; - -typedef struct _DEVICE_INFO -{ - u8 USBbmRequestType; /* bmRequestType */ - u8 USBbRequest; /* bRequest */ - u16_u8 USBwValues; /* wValue */ - u16_u8 USBwIndexs; /* wIndex */ - u16_u8 USBwLengths; /* wLength */ - - u8 ControlState; /* of type CONTROL_STATE */ - u8 Current_Feature; - u8 Current_Configuration; /* Selected configuration */ - u8 Current_Interface; /* Selected interface of current configuration */ - u8 Current_AlternateSetting;/* Selected Alternate Setting of current - interface*/ - - ENDPOINT_INFO Ctrl_Info; -}DEVICE_INFO; - -typedef struct _DEVICE_PROP -{ - void (*Init)(void); /* Initialize the device */ - void (*Reset)(void); /* Reset routine of this device */ - - /* Device dependent process after the status stage */ - void (*Process_Status_IN)(void); - void (*Process_Status_OUT)(void); - - /* Procedure of process on setup stage of a class specified request with data stage */ - /* All class specified requests with data stage are processed in Class_Data_Setup - Class_Data_Setup() - responses to check all special requests and fills ENDPOINT_INFO - according to the request - If IN tokens are expected, then wLength & wOffset will be filled - with the total transferring bytes and the starting position - If OUT tokens are expected, then rLength & rOffset will be filled - with the total expected bytes and the starting position in the buffer - - If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT - - CAUTION: - Since GET_CONFIGURATION & GET_INTERFACE are highly related to - the individual classes, they will be checked and processed here. - */ - RESULT (*Class_Data_Setup)(u8 RequestNo); - - /* Procedure of process on setup stage of a class specified request without data stage */ - /* All class specified requests without data stage are processed in Class_NoData_Setup - Class_NoData_Setup - responses to check all special requests and perform the request - - CAUTION: - Since SET_CONFIGURATION & SET_INTERFACE are highly related to - the individual classes, they will be checked and processed here. - */ - RESULT (*Class_NoData_Setup)(u8 RequestNo); - - /*Class_Get_Interface_Setting - This function is used by the file usb_core.c to test if the selected Interface - and Alternate Setting (u8 Interface, u8 AlternateSetting) are supported by - the application. - This function is writing by user. It should return "SUCCESS" if the Interface - and Alternate Setting are supported by the application or "UNSUPPORT" if they - are not supported. */ - - RESULT (*Class_Get_Interface_Setting)(u8 Interface, u8 AlternateSetting); - - u8* (*GetDeviceDescriptor)(u16 Length); - u8* (*GetConfigDescriptor)(u16 Length); - u8* (*GetStringDescriptor)(u16 Length); - - u8* RxEP_buffer; - u8 MaxPacketSize; - -}DEVICE_PROP; - -typedef struct _USER_STANDARD_REQUESTS -{ - void (*User_GetConfiguration)(void); /* Get Configuration */ - void (*User_SetConfiguration)(void); /* Set Configuration */ - void (*User_GetInterface)(void); /* Get Interface */ - void (*User_SetInterface)(void); /* Set Interface */ - void (*User_GetStatus)(void); /* Get Status */ - void (*User_ClearFeature)(void); /* Clear Feature */ - void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */ - void (*User_SetDeviceFeature)(void); /* Set Device Feature */ - void (*User_SetDeviceAddress)(void); /* Set Device Address */ -} -USER_STANDARD_REQUESTS; - -/* Exported constants --------------------------------------------------------*/ -#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) - -#define Usb_rLength Usb_wLength -#define Usb_rOffset Usb_wOffset - -#define USBwValue USBwValues.w -#define USBwValue0 USBwValues.bw.bb0 -#define USBwValue1 USBwValues.bw.bb1 -#define USBwIndex USBwIndexs.w -#define USBwIndex0 USBwIndexs.bw.bb0 -#define USBwIndex1 USBwIndexs.bw.bb1 -#define USBwLength USBwLengths.w -#define USBwLength0 USBwLengths.bw.bb0 -#define USBwLength1 USBwLengths.bw.bb1 - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -u8 Setup0_Process(void); -u8 Post0_Process(void); -u8 Out0_Process(void); -u8 In0_Process(void); - -RESULT Standard_SetEndPointFeature(void); -RESULT Standard_SetDeviceFeature(void); - -u8 *Standard_GetConfiguration(u16 Length); -RESULT Standard_SetConfiguration(void); -u8 *Standard_GetInterface(u16 Length); -RESULT Standard_SetInterface(void); -u8 *Standard_GetDescriptorData(u16 Length, PONE_DESCRIPTOR pDesc); - -u8 *Standard_GetStatus(u16 Length); -RESULT Standard_ClearFeature(void); -void SetDeviceAddress(u8); -void NOP_Process(void); - -extern DEVICE_PROP Device_Property; -extern USER_STANDARD_REQUESTS User_Standard_Requests; -extern DEVICE Device_Table; -extern DEVICE_INFO Device_Info; - -/* cells saving status during interrupt servicing */ -extern u16 SaveRState; -extern u16 SaveTState; - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_CORE_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_core.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Standard protocol processing functions prototypes +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CORE_H +#define __USB_CORE_H + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +typedef enum _CONTROL_STATE +{ + WAIT_SETUP, /* 0 */ + SETTING_UP, /* 1 */ + IN_DATA, /* 2 */ + OUT_DATA, /* 3 */ + LAST_IN_DATA, /* 4 */ + LAST_OUT_DATA, /* 5 */ + WAIT_STATUS_IN, /* 7 */ + WAIT_STATUS_OUT, /* 8 */ + STALLED, /* 9 */ + PAUSE /* 10 */ +} CONTROL_STATE; /* The state machine states of a control pipe */ + +typedef struct OneDescriptor +{ + u8 *Descriptor; + u16 Descriptor_Size; +} +ONE_DESCRIPTOR, *PONE_DESCRIPTOR; +/* All the request process routines return a value of this type + If the return value is not SUCCESS or NOT_READY, + the software will STALL the correspond endpoint */ +typedef enum _RESULT +{ + USB_SUCCESS = 0, /* Process sucessfully */ + USB_ERROR, + USB_UNSUPPORT, + USB_NOT_READY /* The process has not been finished, endpoint will be + NAK to further rquest */ +} RESULT; + + +/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _ENDPOINT_INFO +{ + /* When send data out of the device, + CopyData() is used to get data buffer 'Length' bytes data + if Length is 0, + CopyData() returns the total length of the data + if the request is not supported, returns 0 + (NEW Feature ) + if CopyData() returns -1, the calling routine should not proceed + further and will resume the SETUP process by the class device + if Length is not 0, + CopyData() returns a pointer to indicate the data location + Usb_wLength is the data remain to be sent, + Usb_wOffset is the Offset of original data + When receive data from the host, + CopyData() is used to get user data buffer which is capable + of Length bytes data to copy data from the endpoint buffer. + if Length is 0, + CopyData() returns the available data length, + if Length is not 0, + CopyData() returns user buffer address + Usb_rLength is the data remain to be received, + Usb_rPointer is the Offset of data buffer + */ + u16 Usb_wLength; + u16 Usb_wOffset; + u16 PacketSize; + u8 *(*CopyData)(u16 Length); +}ENDPOINT_INFO; + +/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/ + +typedef struct _DEVICE +{ + u8 Total_Endpoint; /* Number of endpoints that are used */ + u8 Total_Configuration;/* Number of configuration available */ +} +DEVICE; + +typedef union +{ + u16 w; + struct BW + { + u8 bb1; + u8 bb0; + } + bw; +} u16_u8; + +typedef struct _DEVICE_INFO +{ + u8 USBbmRequestType; /* bmRequestType */ + u8 USBbRequest; /* bRequest */ + u16_u8 USBwValues; /* wValue */ + u16_u8 USBwIndexs; /* wIndex */ + u16_u8 USBwLengths; /* wLength */ + + u8 ControlState; /* of type CONTROL_STATE */ + u8 Current_Feature; + u8 Current_Configuration; /* Selected configuration */ + u8 Current_Interface; /* Selected interface of current configuration */ + u8 Current_AlternateSetting;/* Selected Alternate Setting of current + interface*/ + + ENDPOINT_INFO Ctrl_Info; +}DEVICE_INFO; + +typedef struct _DEVICE_PROP +{ + void (*Init)(void); /* Initialize the device */ + void (*Reset)(void); /* Reset routine of this device */ + + /* Device dependent process after the status stage */ + void (*Process_Status_IN)(void); + void (*Process_Status_OUT)(void); + + /* Procedure of process on setup stage of a class specified request with data stage */ + /* All class specified requests with data stage are processed in Class_Data_Setup + Class_Data_Setup() + responses to check all special requests and fills ENDPOINT_INFO + according to the request + If IN tokens are expected, then wLength & wOffset will be filled + with the total transferring bytes and the starting position + If OUT tokens are expected, then rLength & rOffset will be filled + with the total expected bytes and the starting position in the buffer + + If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT + + CAUTION: + Since GET_CONFIGURATION & GET_INTERFACE are highly related to + the individual classes, they will be checked and processed here. + */ + RESULT (*Class_Data_Setup)(u8 RequestNo); + + /* Procedure of process on setup stage of a class specified request without data stage */ + /* All class specified requests without data stage are processed in Class_NoData_Setup + Class_NoData_Setup + responses to check all special requests and perform the request + + CAUTION: + Since SET_CONFIGURATION & SET_INTERFACE are highly related to + the individual classes, they will be checked and processed here. + */ + RESULT (*Class_NoData_Setup)(u8 RequestNo); + + /*Class_Get_Interface_Setting + This function is used by the file usb_core.c to test if the selected Interface + and Alternate Setting (u8 Interface, u8 AlternateSetting) are supported by + the application. + This function is writing by user. It should return "SUCCESS" if the Interface + and Alternate Setting are supported by the application or "UNSUPPORT" if they + are not supported. */ + + RESULT (*Class_Get_Interface_Setting)(u8 Interface, u8 AlternateSetting); + + u8* (*GetDeviceDescriptor)(u16 Length); + u8* (*GetConfigDescriptor)(u16 Length); + u8* (*GetStringDescriptor)(u16 Length); + + u8* RxEP_buffer; + u8 MaxPacketSize; + +}DEVICE_PROP; + +typedef struct _USER_STANDARD_REQUESTS +{ + void (*User_GetConfiguration)(void); /* Get Configuration */ + void (*User_SetConfiguration)(void); /* Set Configuration */ + void (*User_GetInterface)(void); /* Get Interface */ + void (*User_SetInterface)(void); /* Set Interface */ + void (*User_GetStatus)(void); /* Get Status */ + void (*User_ClearFeature)(void); /* Clear Feature */ + void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */ + void (*User_SetDeviceFeature)(void); /* Set Device Feature */ + void (*User_SetDeviceAddress)(void); /* Set Device Address */ +} +USER_STANDARD_REQUESTS; + +/* Exported constants --------------------------------------------------------*/ +#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) + +#define Usb_rLength Usb_wLength +#define Usb_rOffset Usb_wOffset + +#define USBwValue USBwValues.w +#define USBwValue0 USBwValues.bw.bb0 +#define USBwValue1 USBwValues.bw.bb1 +#define USBwIndex USBwIndexs.w +#define USBwIndex0 USBwIndexs.bw.bb0 +#define USBwIndex1 USBwIndexs.bw.bb1 +#define USBwLength USBwLengths.w +#define USBwLength0 USBwLengths.bw.bb0 +#define USBwLength1 USBwLengths.bw.bb1 + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +u8 Setup0_Process(void); +u8 Post0_Process(void); +u8 Out0_Process(void); +u8 In0_Process(void); + +RESULT Standard_SetEndPointFeature(void); +RESULT Standard_SetDeviceFeature(void); + +u8 *Standard_GetConfiguration(u16 Length); +RESULT Standard_SetConfiguration(void); +u8 *Standard_GetInterface(u16 Length); +RESULT Standard_SetInterface(void); +u8 *Standard_GetDescriptorData(u16 Length, PONE_DESCRIPTOR pDesc); + +u8 *Standard_GetStatus(u16 Length); +RESULT Standard_ClearFeature(void); +void SetDeviceAddress(u8); +void NOP_Process(void); + +extern DEVICE_PROP Device_Property; +extern USER_STANDARD_REQUESTS User_Standard_Requests; +extern DEVICE Device_Table; +extern DEVICE_INFO Device_Info; + +/* cells saving status during interrupt servicing */ +extern u16 SaveRState; +extern u16 SaveTState; + +#if defined(__cplusplus) +} +#endif + +#endif /* __USB_CORE_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_def.h b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_def.h index aa6bcba8..80aa3038 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_def.h +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_def.h @@ -1,88 +1,88 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_def.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Definitions related to USB Core -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_DEF_H -#define __USB_DEF_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -typedef enum _RECIPIENT_TYPE -{ - DEVICE_RECIPIENT, /* Recipient device */ - INTERFACE_RECIPIENT, /* Recipient interface */ - ENDPOINT_RECIPIENT, /* Recipient endpoint */ - OTHER_RECIPIENT -} RECIPIENT_TYPE; - - -typedef enum _STANDARD_REQUESTS -{ - GET_STATUS = 0, - CLEAR_FEATURE, - RESERVED1, - SET_FEATURE, - RESERVED2, - SET_ADDRESS, - GET_DESCRIPTOR, - SET_DESCRIPTOR, - GET_CONFIGURATION, - SET_CONFIGURATION, - GET_INTERFACE, - SET_INTERFACE, - TOTAL_sREQUEST, /* Total number of Standard request */ - SYNCH_FRAME = 12 -} STANDARD_REQUESTS; - -/* Definition of "USBwValue" */ -typedef enum _DESCRIPTOR_TYPE -{ - DEVICE_DESCRIPTOR = 1, - CONFIG_DESCRIPTOR, - STRING_DESCRIPTOR, - INTERFACE_DESCRIPTOR, - ENDPOINT_DESCRIPTOR -} DESCRIPTOR_TYPE; - -/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */ -typedef enum _FEATURE_SELECTOR -{ - ENDPOINT_STALL, - DEVICE_REMOTE_WAKEUP -} FEATURE_SELECTOR; - -/* Exported constants --------------------------------------------------------*/ -/* Definition of "USBbmRequestType" */ -#define REQUEST_TYPE 0x60 /* Mask to get request type */ -#define STANDARD_REQUEST 0x00 /* Standard request */ -#define CLASS_REQUEST 0x20 /* Class request */ -#define VENDOR_REQUEST 0x40 /* Vendor request */ - -#define RECIPIENT 0x1F /* Mask to get recipient */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_DEF_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_def.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Definitions related to USB Core +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_DEF_H +#define __USB_DEF_H + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +typedef enum _RECIPIENT_TYPE +{ + DEVICE_RECIPIENT, /* Recipient device */ + INTERFACE_RECIPIENT, /* Recipient interface */ + ENDPOINT_RECIPIENT, /* Recipient endpoint */ + OTHER_RECIPIENT +} RECIPIENT_TYPE; + + +typedef enum _STANDARD_REQUESTS +{ + GET_STATUS = 0, + CLEAR_FEATURE, + RESERVED1, + SET_FEATURE, + RESERVED2, + SET_ADDRESS, + GET_DESCRIPTOR, + SET_DESCRIPTOR, + GET_CONFIGURATION, + SET_CONFIGURATION, + GET_INTERFACE, + SET_INTERFACE, + TOTAL_sREQUEST, /* Total number of Standard request */ + SYNCH_FRAME = 12 +} STANDARD_REQUESTS; + +/* Definition of "USBwValue" */ +typedef enum _DESCRIPTOR_TYPE +{ + DEVICE_DESCRIPTOR = 1, + CONFIG_DESCRIPTOR, + STRING_DESCRIPTOR, + INTERFACE_DESCRIPTOR, + ENDPOINT_DESCRIPTOR +} DESCRIPTOR_TYPE; + +/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */ +typedef enum _FEATURE_SELECTOR +{ + ENDPOINT_STALL, + DEVICE_REMOTE_WAKEUP +} FEATURE_SELECTOR; + +/* Exported constants --------------------------------------------------------*/ +/* Definition of "USBbmRequestType" */ +#define REQUEST_TYPE 0x60 /* Mask to get request type */ +#define STANDARD_REQUEST 0x00 /* Standard request */ +#define CLASS_REQUEST 0x20 /* Class request */ +#define VENDOR_REQUEST 0x40 /* Vendor request */ + +#define RECIPIENT 0x1F /* Mask to get recipient */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#if defined(__cplusplus) +} +#endif + +#endif /* __USB_DEF_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_init.c b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_init.c index 58621455..94f3a836 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_init.c +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_init.c @@ -1,64 +1,64 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_init.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Initialization routines & global variables -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* The number of current endpoint, it will be used to specify an endpoint */ - u8 EPindex; -/* The number of current device, it is an index to the Device_Table */ -/* u8 Device_no; */ -/* Points to the DEVICE_INFO structure of current device */ -/* The purpose of this register is to speed up the execution */ -DEVICE_INFO *pInformation; -/* Points to the DEVICE_PROP structure of current device */ -/* The purpose of this register is to speed up the execution */ -DEVICE_PROP *pProperty; -/* Temporary save the state of Rx & Tx status. */ -/* Whenever the Rx or Tx state is changed, its value is saved */ -/* in this variable first and will be set to the EPRB or EPRA */ -/* at the end of interrupt process */ -u16 SaveState ; -u16 wInterrupt_Mask; -DEVICE_INFO Device_Info; -USER_STANDARD_REQUESTS *pUser_Standard_Requests; - -/* Extern variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : USB_Init -* Description : USB system initialization -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void USB_Init(void) -{ - pInformation = &Device_Info; - pInformation->ControlState = 2; - pProperty = &Device_Property; - pUser_Standard_Requests = &User_Standard_Requests; - /* Initialize devices one by one */ - - pProperty->Init(); -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_init.c +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Initialization routines & global variables +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_lib.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* The number of current endpoint, it will be used to specify an endpoint */ + u8 EPindex; +/* The number of current device, it is an index to the Device_Table */ +/* u8 Device_no; */ +/* Points to the DEVICE_INFO structure of current device */ +/* The purpose of this register is to speed up the execution */ +DEVICE_INFO *pInformation; +/* Points to the DEVICE_PROP structure of current device */ +/* The purpose of this register is to speed up the execution */ +DEVICE_PROP *pProperty; +/* Temporary save the state of Rx & Tx status. */ +/* Whenever the Rx or Tx state is changed, its value is saved */ +/* in this variable first and will be set to the EPRB or EPRA */ +/* at the end of interrupt process */ +u16 SaveState ; +u16 wInterrupt_Mask; +DEVICE_INFO Device_Info; +USER_STANDARD_REQUESTS *pUser_Standard_Requests; + +/* Extern variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : USB_Init +* Description : USB system initialization +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void USB_Init(void) +{ + pInformation = &Device_Info; + pInformation->ControlState = 2; + pProperty = &Device_Property; + pUser_Standard_Requests = &User_Standard_Requests; + /* Initialize devices one by one */ + + pProperty->Init(); +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_init.h b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_init.h index 1091ce5c..80ee2fb3 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_init.h +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_init.h @@ -1,57 +1,57 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_init.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Initialization routines & global variables -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_INIT_H -#define __USB_INIT_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -void USB_Init(void); - -/* External variables --------------------------------------------------------*/ -/* The number of current endpoint, it will be used to specify an endpoint */ -extern u8 EPindex; -/* The number of current device, it is an index to the Device_Table */ -/*extern u8 Device_no; */ -/* Points to the DEVICE_INFO structure of current device */ -/* The purpose of this register is to speed up the execution */ -extern DEVICE_INFO* pInformation; -/* Points to the DEVICE_PROP structure of current device */ -/* The purpose of this register is to speed up the execution */ -extern DEVICE_PROP* pProperty; -/* Temporary save the state of Rx & Tx status. */ -/* Whenever the Rx or Tx state is changed, its value is saved */ -/* in this variable first and will be set to the EPRB or EPRA */ -/* at the end of interrupt process */ -extern USER_STANDARD_REQUESTS *pUser_Standard_Requests; - -extern u16 SaveState ; -extern u16 wInterrupt_Mask; - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_INIT_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_init.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Initialization routines & global variables +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_INIT_H +#define __USB_INIT_H + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +void USB_Init(void); + +/* External variables --------------------------------------------------------*/ +/* The number of current endpoint, it will be used to specify an endpoint */ +extern u8 EPindex; +/* The number of current device, it is an index to the Device_Table */ +/*extern u8 Device_no; */ +/* Points to the DEVICE_INFO structure of current device */ +/* The purpose of this register is to speed up the execution */ +extern DEVICE_INFO* pInformation; +/* Points to the DEVICE_PROP structure of current device */ +/* The purpose of this register is to speed up the execution */ +extern DEVICE_PROP* pProperty; +/* Temporary save the state of Rx & Tx status. */ +/* Whenever the Rx or Tx state is changed, its value is saved */ +/* in this variable first and will be set to the EPRB or EPRA */ +/* at the end of interrupt process */ +extern USER_STANDARD_REQUESTS *pUser_Standard_Requests; + +extern u16 SaveState ; +extern u16 wInterrupt_Mask; + +#if defined(__cplusplus) +} +#endif + +#endif /* __USB_INIT_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_int.c b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_int.c index f1d82be7..61a989bf 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_int.c +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_int.c @@ -1,192 +1,192 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_int.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Endpoint CTR (Low and High) interrupt's service routines -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -u16 SaveRState; -u16 SaveTState; - -/* Extern variables ----------------------------------------------------------*/ -extern void (*pEpInt_IN[7])(void); /* Handles IN interrupts */ -extern void (*pEpInt_OUT[7])(void); /* Handles OUT interrupts */ - -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : CTR_LP. -* Description : Low priority Endpoint Correct Transfer interrupt's service -* routine. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void CTR_LP(void) -{ - u32 wEPVal = 0; - /* stay in loop while pending ints */ - while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) - { - _SetISTR((u16)CLR_CTR); /* clear CTR flag */ - /* extract highest priority endpoint number */ - EPindex = (u8)(wIstr & ISTR_EP_ID); - if (EPindex == 0) - { - /* Decode and service control endpoint interrupt */ - /* calling related service routine */ - /* (Setup0_Process, In0_Process, Out0_Process) */ - - /* save RX & TX status */ - /* and set both to NAK */ - SaveRState = _GetEPRxStatus(ENDP0); - SaveTState = _GetEPTxStatus(ENDP0); - _SetEPRxStatus(ENDP0, EP_RX_NAK); - _SetEPTxStatus(ENDP0, EP_TX_NAK); - - - /* DIR bit = origin of the interrupt */ - - if ((wIstr & ISTR_DIR) == 0) - { - /* DIR = 0 */ - - /* DIR = 0 => IN int */ - /* DIR = 0 implies that (EP_CTR_TX = 1) always */ - - - _ClearEP_CTR_TX(ENDP0); - In0_Process(); - - /* before terminate set Tx & Rx status */ - _SetEPRxStatus(ENDP0, SaveRState); - _SetEPTxStatus(ENDP0, SaveTState); - return; - } - else - { - /* DIR = 1 */ - - /* DIR = 1 & CTR_RX => SETUP or OUT int */ - /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ - - wEPVal = _GetENDPOINT(ENDP0); - if ((wEPVal & EP_CTR_TX) != 0) - { - _ClearEP_CTR_TX(ENDP0); - In0_Process(); - /* before terminate set Tx & Rx status */ - _SetEPRxStatus(ENDP0, SaveRState); - _SetEPTxStatus(ENDP0, SaveTState); - return; - } - else if ((wEPVal &EP_SETUP) != 0) - { - _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */ - Setup0_Process(); - /* before terminate set Tx & Rx status */ - _SetEPRxStatus(ENDP0, SaveRState); - _SetEPTxStatus(ENDP0, SaveTState); - return; - } - - else if ((wEPVal & EP_CTR_RX) != 0) - { - _ClearEP_CTR_RX(ENDP0); - Out0_Process(); - /* before terminate set Tx & Rx status */ - _SetEPRxStatus(ENDP0, SaveRState); - _SetEPTxStatus(ENDP0, SaveTState); - return; - } - } - }/* if(EPindex == 0) */ - else - { - /* Decode and service non control endpoints interrupt */ - - /* process related endpoint register */ - wEPVal = _GetENDPOINT(EPindex); - if ((wEPVal & EP_CTR_RX) != 0) - { - /* clear int flag */ - _ClearEP_CTR_RX(EPindex); - - /* call OUT service function */ - (*pEpInt_OUT[EPindex-1])(); - - } /* if((wEPVal & EP_CTR_RX) */ - - if ((wEPVal & EP_CTR_TX) != 0) - { - /* clear int flag */ - _ClearEP_CTR_TX(EPindex); - - /* call IN service function */ - (*pEpInt_IN[EPindex-1])(); - } /* if((wEPVal & EP_CTR_TX) != 0) */ - - }/* if(EPindex == 0) else */ - - }/* while(...) */ -} - -/******************************************************************************* -* Function Name : CTR_HP. -* Description : High Priority Endpoint Correct Transfer interrupt's service -* routine. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void CTR_HP(void) -{ - u32 wEPVal = 0; - - while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) - { - _SetISTR((u16)CLR_CTR); /* clear CTR flag */ - /* extract highest priority endpoint number */ - EPindex = (u8)(wIstr & ISTR_EP_ID); - /* process related endpoint register */ - wEPVal = _GetENDPOINT(EPindex); - if ((wEPVal & EP_CTR_RX) != 0) - { - /* clear int flag */ - _ClearEP_CTR_RX(EPindex); - - /* call OUT service function */ - (*pEpInt_OUT[EPindex-1])(); - - } /* if((wEPVal & EP_CTR_RX) */ - else if ((wEPVal & EP_CTR_TX) != 0) - { - /* clear int flag */ - _ClearEP_CTR_TX(EPindex); - - /* call IN service function */ - (*pEpInt_IN[EPindex-1])(); - - - } /* if((wEPVal & EP_CTR_TX) != 0) */ - - }/* while(...) */ -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_int.c +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Endpoint CTR (Low and High) interrupt's service routines +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_lib.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +u16 SaveRState; +u16 SaveTState; + +/* Extern variables ----------------------------------------------------------*/ +extern void (*pEpInt_IN[7])(void); /* Handles IN interrupts */ +extern void (*pEpInt_OUT[7])(void); /* Handles OUT interrupts */ + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : CTR_LP. +* Description : Low priority Endpoint Correct Transfer interrupt's service +* routine. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void CTR_LP(void) +{ + u32 wEPVal = 0; + /* stay in loop while pending ints */ + while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) + { + _SetISTR((u16)CLR_CTR); /* clear CTR flag */ + /* extract highest priority endpoint number */ + EPindex = (u8)(wIstr & ISTR_EP_ID); + if (EPindex == 0) + { + /* Decode and service control endpoint interrupt */ + /* calling related service routine */ + /* (Setup0_Process, In0_Process, Out0_Process) */ + + /* save RX & TX status */ + /* and set both to NAK */ + SaveRState = _GetEPRxStatus(ENDP0); + SaveTState = _GetEPTxStatus(ENDP0); + _SetEPRxStatus(ENDP0, EP_RX_NAK); + _SetEPTxStatus(ENDP0, EP_TX_NAK); + + + /* DIR bit = origin of the interrupt */ + + if ((wIstr & ISTR_DIR) == 0) + { + /* DIR = 0 */ + + /* DIR = 0 => IN int */ + /* DIR = 0 implies that (EP_CTR_TX = 1) always */ + + + _ClearEP_CTR_TX(ENDP0); + In0_Process(); + + /* before terminate set Tx & Rx status */ + _SetEPRxStatus(ENDP0, SaveRState); + _SetEPTxStatus(ENDP0, SaveTState); + return; + } + else + { + /* DIR = 1 */ + + /* DIR = 1 & CTR_RX => SETUP or OUT int */ + /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ + + wEPVal = _GetENDPOINT(ENDP0); + if ((wEPVal & EP_CTR_TX) != 0) + { + _ClearEP_CTR_TX(ENDP0); + In0_Process(); + /* before terminate set Tx & Rx status */ + _SetEPRxStatus(ENDP0, SaveRState); + _SetEPTxStatus(ENDP0, SaveTState); + return; + } + else if ((wEPVal &EP_SETUP) != 0) + { + _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */ + Setup0_Process(); + /* before terminate set Tx & Rx status */ + _SetEPRxStatus(ENDP0, SaveRState); + _SetEPTxStatus(ENDP0, SaveTState); + return; + } + + else if ((wEPVal & EP_CTR_RX) != 0) + { + _ClearEP_CTR_RX(ENDP0); + Out0_Process(); + /* before terminate set Tx & Rx status */ + _SetEPRxStatus(ENDP0, SaveRState); + _SetEPTxStatus(ENDP0, SaveTState); + return; + } + } + }/* if(EPindex == 0) */ + else + { + /* Decode and service non control endpoints interrupt */ + + /* process related endpoint register */ + wEPVal = _GetENDPOINT(EPindex); + if ((wEPVal & EP_CTR_RX) != 0) + { + /* clear int flag */ + _ClearEP_CTR_RX(EPindex); + + /* call OUT service function */ + (*pEpInt_OUT[EPindex-1])(); + + } /* if((wEPVal & EP_CTR_RX) */ + + if ((wEPVal & EP_CTR_TX) != 0) + { + /* clear int flag */ + _ClearEP_CTR_TX(EPindex); + + /* call IN service function */ + (*pEpInt_IN[EPindex-1])(); + } /* if((wEPVal & EP_CTR_TX) != 0) */ + + }/* if(EPindex == 0) else */ + + }/* while(...) */ +} + +/******************************************************************************* +* Function Name : CTR_HP. +* Description : High Priority Endpoint Correct Transfer interrupt's service +* routine. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void CTR_HP(void) +{ + u32 wEPVal = 0; + + while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) + { + _SetISTR((u16)CLR_CTR); /* clear CTR flag */ + /* extract highest priority endpoint number */ + EPindex = (u8)(wIstr & ISTR_EP_ID); + /* process related endpoint register */ + wEPVal = _GetENDPOINT(EPindex); + if ((wEPVal & EP_CTR_RX) != 0) + { + /* clear int flag */ + _ClearEP_CTR_RX(EPindex); + + /* call OUT service function */ + (*pEpInt_OUT[EPindex-1])(); + + } /* if((wEPVal & EP_CTR_RX) */ + else if ((wEPVal & EP_CTR_TX) != 0) + { + /* clear int flag */ + _ClearEP_CTR_TX(EPindex); + + /* call IN service function */ + (*pEpInt_IN[EPindex-1])(); + + + } /* if((wEPVal & EP_CTR_TX) != 0) */ + + }/* while(...) */ +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_int.h b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_int.h index 10a33fb9..5c14711a 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_int.h +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_int.h @@ -1,41 +1,41 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_int.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Endpoint CTR (Low and High) interrupt's service routines -* prototypes -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_INT_H -#define __USB_INT_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -#if defined(__cplusplus) -extern "C" { -#endif - -void CTR_LP(void); -void CTR_HP(void); - -/* External variables --------------------------------------------------------*/ - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_INT_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_int.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Endpoint CTR (Low and High) interrupt's service routines +* prototypes +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_INT_H +#define __USB_INT_H + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +#if defined(__cplusplus) +extern "C" { +#endif + +void CTR_LP(void); +void CTR_HP(void); + +/* External variables --------------------------------------------------------*/ + +#if defined(__cplusplus) +} +#endif + +#endif /* __USB_INT_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_lib.h b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_lib.h index 5d14b5af..4437b8dd 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_lib.h +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_lib.h @@ -1,37 +1,37 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_lib.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : USB library include files -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_LIB_H -#define __USB_LIB_H - -/* Includes ------------------------------------------------------------------*/ -#include "usb_type.h" -#include "usb_regs.h" -#include "usb_def.h" -#include "usb_core.h" -#include "usb_init.h" -#include "usb_mem.h" -#include "usb_int.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -/* External variables --------------------------------------------------------*/ - -#endif /* __USB_LIB_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_lib.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : USB library include files +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_LIB_H +#define __USB_LIB_H + +/* Includes ------------------------------------------------------------------*/ +#include "usb_type.h" +#include "usb_regs.h" +#include "usb_def.h" +#include "usb_core.h" +#include "usb_init.h" +#include "usb_mem.h" +#include "usb_int.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* External variables --------------------------------------------------------*/ + +#endif /* __USB_LIB_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_mem.c b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_mem.c index 90ffc628..ad9740a1 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_mem.c +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_mem.c @@ -1,73 +1,73 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_mem.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Utility functions for memory transfers to/from PMA -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Extern variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ -/******************************************************************************* -* Function Name : UserToPMABufferCopy -* Description : Copy a buffer from user memory area to packet memory area (PMA) -* Input : - pbUsrBuf: pointer to user memory area. -* - wPMABufAddr: address into PMA. -* - wNBytes: no. of bytes to be copied. -* Output : None. -* Return : None . -*******************************************************************************/ -void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) -{ - u32 n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */ - u32 i, temp1, temp2; - u16 *pdwVal; - pdwVal = (u16 *)(wPMABufAddr * 2 + PMAAddr); - for (i = n; i != 0; i--) - { - temp1 = (u16) * pbUsrBuf; - pbUsrBuf++; - temp2 = temp1 | (u16) * pbUsrBuf << 8; - *pdwVal++ = temp2; - pdwVal++; - pbUsrBuf++; - } -} -/******************************************************************************* -* Function Name : PMAToUserBufferCopy -* Description : Copy a buffer from user memory area to packet memory area (PMA) -* Input : - pbUsrBuf = pointer to user memory area. -* - wPMABufAddr = address into PMA. -* - wNBytes = no. of bytes to be copied. -* Output : None. -* Return : None. -*******************************************************************************/ -void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) -{ - u32 n = (wNBytes + 1) >> 1;/* /2*/ - u32 i; - u32 *pdwVal; - pdwVal = (u32 *)(wPMABufAddr * 2 + PMAAddr); - for (i = n; i != 0; i--) - { - *(u16*)pbUsrBuf++ = *pdwVal++; - pbUsrBuf++; - } -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_mem.c +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Utility functions for memory transfers to/from PMA +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_lib.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Extern variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/******************************************************************************* +* Function Name : UserToPMABufferCopy +* Description : Copy a buffer from user memory area to packet memory area (PMA) +* Input : - pbUsrBuf: pointer to user memory area. +* - wPMABufAddr: address into PMA. +* - wNBytes: no. of bytes to be copied. +* Output : None. +* Return : None . +*******************************************************************************/ +void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) +{ + u32 n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */ + u32 i, temp1, temp2; + u16 *pdwVal; + pdwVal = (u16 *)(wPMABufAddr * 2 + PMAAddr); + for (i = n; i != 0; i--) + { + temp1 = (u16) * pbUsrBuf; + pbUsrBuf++; + temp2 = temp1 | (u16) * pbUsrBuf << 8; + *pdwVal++ = temp2; + pdwVal++; + pbUsrBuf++; + } +} +/******************************************************************************* +* Function Name : PMAToUserBufferCopy +* Description : Copy a buffer from user memory area to packet memory area (PMA) +* Input : - pbUsrBuf = pointer to user memory area. +* - wPMABufAddr = address into PMA. +* - wNBytes = no. of bytes to be copied. +* Output : None. +* Return : None. +*******************************************************************************/ +void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) +{ + u32 n = (wNBytes + 1) >> 1;/* /2*/ + u32 i; + u32 *pdwVal; + pdwVal = (u32 *)(wPMABufAddr * 2 + PMAAddr); + for (i = n; i != 0; i--) + { + *(u16*)pbUsrBuf++ = *pdwVal++; + pbUsrBuf++; + } +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_mem.h b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_mem.h index 60ff9f16..b0e0474a 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_mem.h +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_mem.h @@ -1,40 +1,40 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_mem.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Utility prototypes functions for memory/PMA transfers -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_MEM_H -#define __USB_MEM_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -#if defined(__cplusplus) -extern "C" { -#endif - -void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); -void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); - -#if defined(__cplusplus) -} -#endif - -/* External variables --------------------------------------------------------*/ - -#endif /*__USB_MEM_H*/ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_mem.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Utility prototypes functions for memory/PMA transfers +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_MEM_H +#define __USB_MEM_H + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +#if defined(__cplusplus) +extern "C" { +#endif + +void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); +void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); + +#if defined(__cplusplus) +} +#endif + +/* External variables --------------------------------------------------------*/ + +#endif /*__USB_MEM_H*/ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_regs.c b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_regs.c index c28ef5a7..c7e0276f 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_regs.c +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_regs.c @@ -1,748 +1,748 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_regs.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Interface functions to USB cell registers -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Extern variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : SetCNTR. -* Description : Set the CNTR register value. -* Input : wRegValue: new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetCNTR(u16 wRegValue) -{ - _SetCNTR(wRegValue); -} - -/******************************************************************************* -* Function Name : GetCNTR. -* Description : returns the CNTR register value. -* Input : None. -* Output : None. -* Return : CNTR register Value. -*******************************************************************************/ -u16 GetCNTR(void) -{ - return(_GetCNTR()); -} - -/******************************************************************************* -* Function Name : SetISTR. -* Description : Set the ISTR register value. -* Input : wRegValue: new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetISTR(u16 wRegValue) -{ - _SetISTR(wRegValue); -} - -/******************************************************************************* -* Function Name : GetISTR -* Description : Returns the ISTR register value. -* Input : None. -* Output : None. -* Return : ISTR register Value -*******************************************************************************/ -u16 GetISTR(void) -{ - return(_GetISTR()); -} - -/******************************************************************************* -* Function Name : GetFNR -* Description : Returns the FNR register value. -* Input : None. -* Output : None. -* Return : FNR register Value -*******************************************************************************/ -u16 GetFNR(void) -{ - return(_GetFNR()); -} - -/******************************************************************************* -* Function Name : SetDADDR -* Description : Set the DADDR register value. -* Input : wRegValue: new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetDADDR(u16 wRegValue) -{ - _SetDADDR(wRegValue); -} - -/******************************************************************************* -* Function Name : GetDADDR -* Description : Returns the DADDR register value. -* Input : None. -* Output : None. -* Return : DADDR register Value -*******************************************************************************/ -u16 GetDADDR(void) -{ - return(_GetDADDR()); -} - -/******************************************************************************* -* Function Name : SetBTABLE -* Description : Set the BTABLE. -* Input : wRegValue: New register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetBTABLE(u16 wRegValue) -{ - _SetBTABLE(wRegValue); -} - -/******************************************************************************* -* Function Name : GetBTABLE. -* Description : Returns the BTABLE register value. -* Input : None. -* Output : None. -* Return : BTABLE address. -*******************************************************************************/ -u16 GetBTABLE(void) -{ - return(_GetBTABLE()); -} - -/******************************************************************************* -* Function Name : SetENDPOINT -* Description : Setthe Endpoint register value. -* Input : bEpNum: Endpoint Number. -* wRegValue. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetENDPOINT(u8 bEpNum, u16 wRegValue) -{ - _SetENDPOINT(bEpNum, wRegValue); -} - -/******************************************************************************* -* Function Name : GetENDPOINT -* Description : Return the Endpoint register value. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint register value. -*******************************************************************************/ -u16 GetENDPOINT(u8 bEpNum) -{ - return(_GetENDPOINT(bEpNum)); -} - -/******************************************************************************* -* Function Name : SetEPType -* Description : sets the type in the endpoint register. -* Input : bEpNum: Endpoint Number. -* wType: type definition. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPType(u8 bEpNum, u16 wType) -{ - _SetEPType(bEpNum, wType); -} - -/******************************************************************************* -* Function Name : GetEPType -* Description : Returns the endpoint type. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Type -*******************************************************************************/ -u16 GetEPType(u8 bEpNum) -{ - return(_GetEPType(bEpNum)); -} - -/******************************************************************************* -* Function Name : SetEPTxStatus -* Description : Set the status of Tx endpoint. -* Input : bEpNum: Endpoint Number. -* wState: new state. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxStatus(u8 bEpNum, u16 wState) -{ - _SetEPTxStatus(bEpNum, wState); -} - -/******************************************************************************* -* Function Name : SetEPRxStatus -* Description : Set the status of Rx endpoint. -* Input : bEpNum: Endpoint Number. -* wState: new state. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxStatus(u8 bEpNum, u16 wState) -{ - _SetEPRxStatus(bEpNum, wState); -} - -/******************************************************************************* -* Function Name : SetDouBleBuffEPStall -* Description : sets the status for Double Buffer Endpoint to STALL -* Input : bEpNum: Endpoint Number. -* bDir: Endpoint direction. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetDouBleBuffEPStall(u8 bEpNum, u8 bDir) -{ - u16 Endpoint_DTOG_Status; - Endpoint_DTOG_Status = GetENDPOINT(bEpNum); - if (bDir == EP_DBUF_OUT) - { /* OUT double buffered endpoint */ - _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1); - } - else if (bDir == EP_DBUF_IN) - { /* IN double buffered endpoint */ - _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1); - } -} - -/******************************************************************************* -* Function Name : GetEPTxStatus -* Description : Returns the endpoint Tx status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint TX Status -*******************************************************************************/ -u16 GetEPTxStatus(u8 bEpNum) -{ - return(_GetEPTxStatus(bEpNum)); -} - -/******************************************************************************* -* Function Name : GetEPRxStatus -* Description : Returns the endpoint Rx status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint RX Status -*******************************************************************************/ -u16 GetEPRxStatus(u8 bEpNum) -{ - return(_GetEPRxStatus(bEpNum)); -} - -/******************************************************************************* -* Function Name : SetEPTxValid -* Description : Valid the endpoint Tx Status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxValid(u8 bEpNum) -{ - _SetEPTxStatus(bEpNum, EP_TX_VALID); -} - -/******************************************************************************* -* Function Name : SetEPRxValid -* Description : Valid the endpoint Rx Status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxValid(u8 bEpNum) -{ - _SetEPRxStatus(bEpNum, EP_RX_VALID); -} - -/******************************************************************************* -* Function Name : SetEP_KIND -* Description : Clear the EP_KIND bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEP_KIND(u8 bEpNum) -{ - _SetEP_KIND(bEpNum); -} - -/******************************************************************************* -* Function Name : ClearEP_KIND -* Description : set the EP_KIND bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEP_KIND(u8 bEpNum) -{ - _ClearEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : Clear_Status_Out -* Description : Clear the Status Out of the related Endpoint -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void Clear_Status_Out(u8 bEpNum) -{ - _ClearEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : Set_Status_Out -* Description : Set the Status Out of the related Endpoint -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void Set_Status_Out(u8 bEpNum) -{ - _SetEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : SetEPDoubleBuff -* Description : Enable the double buffer feature for the endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDoubleBuff(u8 bEpNum) -{ - _SetEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : ClearEPDoubleBuff -* Description : Disable the double buffer feature for the endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEPDoubleBuff(u8 bEpNum) -{ - _ClearEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : GetTxStallStatus -* Description : Returns the Stall status of the Tx endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Tx Stall status. -*******************************************************************************/ -u16 GetTxStallStatus(u8 bEpNum) -{ - return(_GetTxStallStatus(bEpNum)); -} -/******************************************************************************* -* Function Name : GetRxStallStatus -* Description : Returns the Stall status of the Rx endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx Stall status. -*******************************************************************************/ -u16 GetRxStallStatus(u8 bEpNum) -{ - return(_GetRxStallStatus(bEpNum)); -} -/******************************************************************************* -* Function Name : ClearEP_CTR_RX -* Description : Clear the CTR_RX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEP_CTR_RX(u8 bEpNum) -{ - _ClearEP_CTR_RX(bEpNum); -} -/******************************************************************************* -* Function Name : ClearEP_CTR_TX -* Description : Clear the CTR_TX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEP_CTR_TX(u8 bEpNum) -{ - _ClearEP_CTR_TX(bEpNum); -} -/******************************************************************************* -* Function Name : ToggleDTOG_RX -* Description : Toggle the DTOG_RX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ToggleDTOG_RX(u8 bEpNum) -{ - _ToggleDTOG_RX(bEpNum); -} -/******************************************************************************* -* Function Name : ToggleDTOG_TX -* Description : Toggle the DTOG_TX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ToggleDTOG_TX(u8 bEpNum) -{ - _ToggleDTOG_TX(bEpNum); -} -/******************************************************************************* -* Function Name : ClearDTOG_RX. -* Description : Clear the DTOG_RX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearDTOG_RX(u8 bEpNum) -{ - _ClearDTOG_RX(bEpNum); -} -/******************************************************************************* -* Function Name : ClearDTOG_TX. -* Description : Clear the DTOG_TX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearDTOG_TX(u8 bEpNum) -{ - _ClearDTOG_TX(bEpNum); -} -/******************************************************************************* -* Function Name : SetEPAddress -* Description : Set the endpoint address. -* Input : bEpNum: Endpoint Number. -* bAddr: New endpoint address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPAddress(u8 bEpNum, u8 bAddr) -{ - _SetEPAddress(bEpNum, bAddr); -} -/******************************************************************************* -* Function Name : GetEPAddress -* Description : Get the endpoint address. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint address. -*******************************************************************************/ -u8 GetEPAddress(u8 bEpNum) -{ - return(_GetEPAddress(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPTxAddr -* Description : Set the endpoint Tx buffer address. -* Input : bEpNum: Endpoint Number. -* wAddr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxAddr(u8 bEpNum, u16 wAddr) -{ - _SetEPTxAddr(bEpNum, wAddr); -} -/******************************************************************************* -* Function Name : SetEPRxAddr -* Description : Set the endpoint Rx buffer address. -* Input : bEpNum: Endpoint Number. -* wAddr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxAddr(u8 bEpNum, u16 wAddr) -{ - _SetEPRxAddr(bEpNum, wAddr); -} -/******************************************************************************* -* Function Name : GetEPTxAddr -* Description : Returns the endpoint Tx buffer address. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx buffer address. -*******************************************************************************/ -u16 GetEPTxAddr(u8 bEpNum) -{ - return(_GetEPTxAddr(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPRxAddr. -* Description : Returns the endpoint Rx buffer address. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx buffer address. -*******************************************************************************/ -u16 GetEPRxAddr(u8 bEpNum) -{ - return(_GetEPRxAddr(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPTxCount. -* Description : Set the Tx count. -* Input : bEpNum: Endpoint Number. -* wCount: new count value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxCount(u8 bEpNum, u16 wCount) -{ - _SetEPTxCount(bEpNum, wCount); -} -/******************************************************************************* -* Function Name : SetEPCountRxReg. -* Description : Set the Count Rx Register value. -* Input : *pdwReg: point to the register. -* wCount: the new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPCountRxReg(u32 *pdwReg, u16 wCount) -{ - _SetEPCountRxReg(dwReg, wCount); -} -/******************************************************************************* -* Function Name : SetEPRxCount -* Description : Set the Rx count. -* Input : bEpNum: Endpoint Number. -* wCount: the new count value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxCount(u8 bEpNum, u16 wCount) -{ - _SetEPRxCount(bEpNum, wCount); -} -/******************************************************************************* -* Function Name : GetEPTxCount -* Description : Get the Tx count. -* Input : bEpNum: Endpoint Number. -* Output : None -* Return : Tx count value. -*******************************************************************************/ -u16 GetEPTxCount(u8 bEpNum) -{ - return(_GetEPTxCount(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPRxCount -* Description : Get the Rx count. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx count value. -*******************************************************************************/ -u16 GetEPRxCount(u8 bEpNum) -{ - return(_GetEPRxCount(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPDblBuffAddr -* Description : Set the addresses of the buffer 0 and 1. -* Input : bEpNum: Endpoint Number. -* wBuf0Addr: new address of buffer 0. -* wBuf1Addr: new address of buffer 1. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuffAddr(u8 bEpNum, u16 wBuf0Addr, u16 wBuf1Addr) -{ - _SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr); -} -/******************************************************************************* -* Function Name : SetEPDblBuf0Addr -* Description : Set the Buffer 1 address. -* Input : bEpNum: Endpoint Number -* wBuf0Addr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf0Addr(u8 bEpNum, u16 wBuf0Addr) -{ - _SetEPDblBuf0Addr(bEpNum, wBuf0Addr); -} -/******************************************************************************* -* Function Name : SetEPDblBuf1Addr -* Description : Set the Buffer 1 address. -* Input : bEpNum: Endpoint Number -* wBuf1Addr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf1Addr(u8 bEpNum, u16 wBuf1Addr) -{ - _SetEPDblBuf1Addr(bEpNum, wBuf1Addr); -} -/******************************************************************************* -* Function Name : GetEPDblBuf0Addr -* Description : Returns the address of the Buffer 0. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -u16 GetEPDblBuf0Addr(u8 bEpNum) -{ - return(_GetEPDblBuf0Addr(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPDblBuf1Addr -* Description : Returns the address of the Buffer 1. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Address of the Buffer 1. -*******************************************************************************/ -u16 GetEPDblBuf1Addr(u8 bEpNum) -{ - return(_GetEPDblBuf1Addr(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPDblBuffCount -* Description : Set the number of bytes for a double Buffer -* endpoint. -* Input : bEpNum,bDir, wCount -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuffCount(u8 bEpNum, u8 bDir, u16 wCount) -{ - _SetEPDblBuffCount(bEpNum, bDir, wCount); -} -/******************************************************************************* -* Function Name : SetEPDblBuf0Count -* Description : Set the number of bytes in the buffer 0 of a double Buffer -* endpoint. -* Input : bEpNum, bDir, wCount -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf0Count(u8 bEpNum, u8 bDir, u16 wCount) -{ - _SetEPDblBuf0Count(bEpNum, bDir, wCount); -} -/******************************************************************************* -* Function Name : SetEPDblBuf1Count -* Description : Set the number of bytes in the buffer 0 of a double Buffer -* endpoint. -* Input : bEpNum, bDir, wCount -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf1Count(u8 bEpNum, u8 bDir, u16 wCount) -{ - _SetEPDblBuf1Count(bEpNum, bDir, wCount); -} -/******************************************************************************* -* Function Name : GetEPDblBuf0Count -* Description : Returns the number of byte received in the buffer 0 of a double -* Buffer endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Buffer 0 count -*******************************************************************************/ -u16 GetEPDblBuf0Count(u8 bEpNum) -{ - return(_GetEPDblBuf0Count(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPDblBuf1Count -* Description : Returns the number of data received in the buffer 1 of a double -* Buffer endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Buffer 1 count. -*******************************************************************************/ -u16 GetEPDblBuf1Count(u8 bEpNum) -{ - return(_GetEPDblBuf1Count(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPDblBufDir -* Description : gets direction of the double buffered endpoint -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : EP_DBUF_OUT, EP_DBUF_IN, -* EP_DBUF_ERR if the endpoint counter not yet programmed. -*******************************************************************************/ -EP_DBUF_DIR GetEPDblBufDir(u8 bEpNum) -{ - if ((u16)(*_pEPRxCount(bEpNum) & 0xFC00) != 0) - return(EP_DBUF_OUT); - else if (((u16)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0) - return(EP_DBUF_IN); - else - return(EP_DBUF_ERR); -} -/******************************************************************************* -* Function Name : FreeUserBuffer -* Description : free buffer used from the application realizing it to the line - toggles bit SW_BUF in the double buffered endpoint register -* Input : bEpNum, bDir -* Output : None. -* Return : None. -*******************************************************************************/ -void FreeUserBuffer(u8 bEpNum, u8 bDir) -{ - if (bDir == EP_DBUF_OUT) - { /* OUT double buffered endpoint */ - _ToggleDTOG_TX(bEpNum); - } - else if (bDir == EP_DBUF_IN) - { /* IN double buffered endpoint */ - _ToggleDTOG_RX(bEpNum); - } -} - -/******************************************************************************* -* Function Name : ToWord -* Description : merge two byte in a word. -* Input : bh: byte high, bl: bytes low. -* Output : None. -* Return : resulted word. -*******************************************************************************/ -u16 ToWord(u8 bh, u8 bl) -{ - u16 wRet; - wRet = (u16)bl | ((u16)bh << 8); - return(wRet); -} -/******************************************************************************* -* Function Name : ByteSwap -* Description : Swap two byte in a word. -* Input : wSwW: word to Swap. -* Output : None. -* Return : resulted word. -*******************************************************************************/ -u16 ByteSwap(u16 wSwW) -{ - u8 bTemp; - u16 wRet; - bTemp = (u8)(wSwW & 0xff); - wRet = (wSwW >> 8) | ((u16)bTemp << 8); - return(wRet); -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_regs.c +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Interface functions to USB cell registers +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_lib.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Extern variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : SetCNTR. +* Description : Set the CNTR register value. +* Input : wRegValue: new register value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetCNTR(u16 wRegValue) +{ + _SetCNTR(wRegValue); +} + +/******************************************************************************* +* Function Name : GetCNTR. +* Description : returns the CNTR register value. +* Input : None. +* Output : None. +* Return : CNTR register Value. +*******************************************************************************/ +u16 GetCNTR(void) +{ + return(_GetCNTR()); +} + +/******************************************************************************* +* Function Name : SetISTR. +* Description : Set the ISTR register value. +* Input : wRegValue: new register value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetISTR(u16 wRegValue) +{ + _SetISTR(wRegValue); +} + +/******************************************************************************* +* Function Name : GetISTR +* Description : Returns the ISTR register value. +* Input : None. +* Output : None. +* Return : ISTR register Value +*******************************************************************************/ +u16 GetISTR(void) +{ + return(_GetISTR()); +} + +/******************************************************************************* +* Function Name : GetFNR +* Description : Returns the FNR register value. +* Input : None. +* Output : None. +* Return : FNR register Value +*******************************************************************************/ +u16 GetFNR(void) +{ + return(_GetFNR()); +} + +/******************************************************************************* +* Function Name : SetDADDR +* Description : Set the DADDR register value. +* Input : wRegValue: new register value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetDADDR(u16 wRegValue) +{ + _SetDADDR(wRegValue); +} + +/******************************************************************************* +* Function Name : GetDADDR +* Description : Returns the DADDR register value. +* Input : None. +* Output : None. +* Return : DADDR register Value +*******************************************************************************/ +u16 GetDADDR(void) +{ + return(_GetDADDR()); +} + +/******************************************************************************* +* Function Name : SetBTABLE +* Description : Set the BTABLE. +* Input : wRegValue: New register value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetBTABLE(u16 wRegValue) +{ + _SetBTABLE(wRegValue); +} + +/******************************************************************************* +* Function Name : GetBTABLE. +* Description : Returns the BTABLE register value. +* Input : None. +* Output : None. +* Return : BTABLE address. +*******************************************************************************/ +u16 GetBTABLE(void) +{ + return(_GetBTABLE()); +} + +/******************************************************************************* +* Function Name : SetENDPOINT +* Description : Setthe Endpoint register value. +* Input : bEpNum: Endpoint Number. +* wRegValue. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetENDPOINT(u8 bEpNum, u16 wRegValue) +{ + _SetENDPOINT(bEpNum, wRegValue); +} + +/******************************************************************************* +* Function Name : GetENDPOINT +* Description : Return the Endpoint register value. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint register value. +*******************************************************************************/ +u16 GetENDPOINT(u8 bEpNum) +{ + return(_GetENDPOINT(bEpNum)); +} + +/******************************************************************************* +* Function Name : SetEPType +* Description : sets the type in the endpoint register. +* Input : bEpNum: Endpoint Number. +* wType: type definition. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPType(u8 bEpNum, u16 wType) +{ + _SetEPType(bEpNum, wType); +} + +/******************************************************************************* +* Function Name : GetEPType +* Description : Returns the endpoint type. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint Type +*******************************************************************************/ +u16 GetEPType(u8 bEpNum) +{ + return(_GetEPType(bEpNum)); +} + +/******************************************************************************* +* Function Name : SetEPTxStatus +* Description : Set the status of Tx endpoint. +* Input : bEpNum: Endpoint Number. +* wState: new state. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPTxStatus(u8 bEpNum, u16 wState) +{ + _SetEPTxStatus(bEpNum, wState); +} + +/******************************************************************************* +* Function Name : SetEPRxStatus +* Description : Set the status of Rx endpoint. +* Input : bEpNum: Endpoint Number. +* wState: new state. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPRxStatus(u8 bEpNum, u16 wState) +{ + _SetEPRxStatus(bEpNum, wState); +} + +/******************************************************************************* +* Function Name : SetDouBleBuffEPStall +* Description : sets the status for Double Buffer Endpoint to STALL +* Input : bEpNum: Endpoint Number. +* bDir: Endpoint direction. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetDouBleBuffEPStall(u8 bEpNum, u8 bDir) +{ + u16 Endpoint_DTOG_Status; + Endpoint_DTOG_Status = GetENDPOINT(bEpNum); + if (bDir == EP_DBUF_OUT) + { /* OUT double buffered endpoint */ + _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1); + } + else if (bDir == EP_DBUF_IN) + { /* IN double buffered endpoint */ + _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1); + } +} + +/******************************************************************************* +* Function Name : GetEPTxStatus +* Description : Returns the endpoint Tx status. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint TX Status +*******************************************************************************/ +u16 GetEPTxStatus(u8 bEpNum) +{ + return(_GetEPTxStatus(bEpNum)); +} + +/******************************************************************************* +* Function Name : GetEPRxStatus +* Description : Returns the endpoint Rx status. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint RX Status +*******************************************************************************/ +u16 GetEPRxStatus(u8 bEpNum) +{ + return(_GetEPRxStatus(bEpNum)); +} + +/******************************************************************************* +* Function Name : SetEPTxValid +* Description : Valid the endpoint Tx Status. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPTxValid(u8 bEpNum) +{ + _SetEPTxStatus(bEpNum, EP_TX_VALID); +} + +/******************************************************************************* +* Function Name : SetEPRxValid +* Description : Valid the endpoint Rx Status. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPRxValid(u8 bEpNum) +{ + _SetEPRxStatus(bEpNum, EP_RX_VALID); +} + +/******************************************************************************* +* Function Name : SetEP_KIND +* Description : Clear the EP_KIND bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEP_KIND(u8 bEpNum) +{ + _SetEP_KIND(bEpNum); +} + +/******************************************************************************* +* Function Name : ClearEP_KIND +* Description : set the EP_KIND bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearEP_KIND(u8 bEpNum) +{ + _ClearEP_KIND(bEpNum); +} +/******************************************************************************* +* Function Name : Clear_Status_Out +* Description : Clear the Status Out of the related Endpoint +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void Clear_Status_Out(u8 bEpNum) +{ + _ClearEP_KIND(bEpNum); +} +/******************************************************************************* +* Function Name : Set_Status_Out +* Description : Set the Status Out of the related Endpoint +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void Set_Status_Out(u8 bEpNum) +{ + _SetEP_KIND(bEpNum); +} +/******************************************************************************* +* Function Name : SetEPDoubleBuff +* Description : Enable the double buffer feature for the endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDoubleBuff(u8 bEpNum) +{ + _SetEP_KIND(bEpNum); +} +/******************************************************************************* +* Function Name : ClearEPDoubleBuff +* Description : Disable the double buffer feature for the endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearEPDoubleBuff(u8 bEpNum) +{ + _ClearEP_KIND(bEpNum); +} +/******************************************************************************* +* Function Name : GetTxStallStatus +* Description : Returns the Stall status of the Tx endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Tx Stall status. +*******************************************************************************/ +u16 GetTxStallStatus(u8 bEpNum) +{ + return(_GetTxStallStatus(bEpNum)); +} +/******************************************************************************* +* Function Name : GetRxStallStatus +* Description : Returns the Stall status of the Rx endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Rx Stall status. +*******************************************************************************/ +u16 GetRxStallStatus(u8 bEpNum) +{ + return(_GetRxStallStatus(bEpNum)); +} +/******************************************************************************* +* Function Name : ClearEP_CTR_RX +* Description : Clear the CTR_RX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearEP_CTR_RX(u8 bEpNum) +{ + _ClearEP_CTR_RX(bEpNum); +} +/******************************************************************************* +* Function Name : ClearEP_CTR_TX +* Description : Clear the CTR_TX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearEP_CTR_TX(u8 bEpNum) +{ + _ClearEP_CTR_TX(bEpNum); +} +/******************************************************************************* +* Function Name : ToggleDTOG_RX +* Description : Toggle the DTOG_RX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ToggleDTOG_RX(u8 bEpNum) +{ + _ToggleDTOG_RX(bEpNum); +} +/******************************************************************************* +* Function Name : ToggleDTOG_TX +* Description : Toggle the DTOG_TX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ToggleDTOG_TX(u8 bEpNum) +{ + _ToggleDTOG_TX(bEpNum); +} +/******************************************************************************* +* Function Name : ClearDTOG_RX. +* Description : Clear the DTOG_RX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearDTOG_RX(u8 bEpNum) +{ + _ClearDTOG_RX(bEpNum); +} +/******************************************************************************* +* Function Name : ClearDTOG_TX. +* Description : Clear the DTOG_TX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearDTOG_TX(u8 bEpNum) +{ + _ClearDTOG_TX(bEpNum); +} +/******************************************************************************* +* Function Name : SetEPAddress +* Description : Set the endpoint address. +* Input : bEpNum: Endpoint Number. +* bAddr: New endpoint address. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPAddress(u8 bEpNum, u8 bAddr) +{ + _SetEPAddress(bEpNum, bAddr); +} +/******************************************************************************* +* Function Name : GetEPAddress +* Description : Get the endpoint address. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint address. +*******************************************************************************/ +u8 GetEPAddress(u8 bEpNum) +{ + return(_GetEPAddress(bEpNum)); +} +/******************************************************************************* +* Function Name : SetEPTxAddr +* Description : Set the endpoint Tx buffer address. +* Input : bEpNum: Endpoint Number. +* wAddr: new address. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPTxAddr(u8 bEpNum, u16 wAddr) +{ + _SetEPTxAddr(bEpNum, wAddr); +} +/******************************************************************************* +* Function Name : SetEPRxAddr +* Description : Set the endpoint Rx buffer address. +* Input : bEpNum: Endpoint Number. +* wAddr: new address. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPRxAddr(u8 bEpNum, u16 wAddr) +{ + _SetEPRxAddr(bEpNum, wAddr); +} +/******************************************************************************* +* Function Name : GetEPTxAddr +* Description : Returns the endpoint Tx buffer address. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Rx buffer address. +*******************************************************************************/ +u16 GetEPTxAddr(u8 bEpNum) +{ + return(_GetEPTxAddr(bEpNum)); +} +/******************************************************************************* +* Function Name : GetEPRxAddr. +* Description : Returns the endpoint Rx buffer address. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Rx buffer address. +*******************************************************************************/ +u16 GetEPRxAddr(u8 bEpNum) +{ + return(_GetEPRxAddr(bEpNum)); +} +/******************************************************************************* +* Function Name : SetEPTxCount. +* Description : Set the Tx count. +* Input : bEpNum: Endpoint Number. +* wCount: new count value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPTxCount(u8 bEpNum, u16 wCount) +{ + _SetEPTxCount(bEpNum, wCount); +} +/******************************************************************************* +* Function Name : SetEPCountRxReg. +* Description : Set the Count Rx Register value. +* Input : *pdwReg: point to the register. +* wCount: the new register value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPCountRxReg(u32 *pdwReg, u16 wCount) +{ + _SetEPCountRxReg(dwReg, wCount); +} +/******************************************************************************* +* Function Name : SetEPRxCount +* Description : Set the Rx count. +* Input : bEpNum: Endpoint Number. +* wCount: the new count value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPRxCount(u8 bEpNum, u16 wCount) +{ + _SetEPRxCount(bEpNum, wCount); +} +/******************************************************************************* +* Function Name : GetEPTxCount +* Description : Get the Tx count. +* Input : bEpNum: Endpoint Number. +* Output : None +* Return : Tx count value. +*******************************************************************************/ +u16 GetEPTxCount(u8 bEpNum) +{ + return(_GetEPTxCount(bEpNum)); +} +/******************************************************************************* +* Function Name : GetEPRxCount +* Description : Get the Rx count. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Rx count value. +*******************************************************************************/ +u16 GetEPRxCount(u8 bEpNum) +{ + return(_GetEPRxCount(bEpNum)); +} +/******************************************************************************* +* Function Name : SetEPDblBuffAddr +* Description : Set the addresses of the buffer 0 and 1. +* Input : bEpNum: Endpoint Number. +* wBuf0Addr: new address of buffer 0. +* wBuf1Addr: new address of buffer 1. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuffAddr(u8 bEpNum, u16 wBuf0Addr, u16 wBuf1Addr) +{ + _SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr); +} +/******************************************************************************* +* Function Name : SetEPDblBuf0Addr +* Description : Set the Buffer 1 address. +* Input : bEpNum: Endpoint Number +* wBuf0Addr: new address. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuf0Addr(u8 bEpNum, u16 wBuf0Addr) +{ + _SetEPDblBuf0Addr(bEpNum, wBuf0Addr); +} +/******************************************************************************* +* Function Name : SetEPDblBuf1Addr +* Description : Set the Buffer 1 address. +* Input : bEpNum: Endpoint Number +* wBuf1Addr: new address. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuf1Addr(u8 bEpNum, u16 wBuf1Addr) +{ + _SetEPDblBuf1Addr(bEpNum, wBuf1Addr); +} +/******************************************************************************* +* Function Name : GetEPDblBuf0Addr +* Description : Returns the address of the Buffer 0. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +u16 GetEPDblBuf0Addr(u8 bEpNum) +{ + return(_GetEPDblBuf0Addr(bEpNum)); +} +/******************************************************************************* +* Function Name : GetEPDblBuf1Addr +* Description : Returns the address of the Buffer 1. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Address of the Buffer 1. +*******************************************************************************/ +u16 GetEPDblBuf1Addr(u8 bEpNum) +{ + return(_GetEPDblBuf1Addr(bEpNum)); +} +/******************************************************************************* +* Function Name : SetEPDblBuffCount +* Description : Set the number of bytes for a double Buffer +* endpoint. +* Input : bEpNum,bDir, wCount +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuffCount(u8 bEpNum, u8 bDir, u16 wCount) +{ + _SetEPDblBuffCount(bEpNum, bDir, wCount); +} +/******************************************************************************* +* Function Name : SetEPDblBuf0Count +* Description : Set the number of bytes in the buffer 0 of a double Buffer +* endpoint. +* Input : bEpNum, bDir, wCount +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuf0Count(u8 bEpNum, u8 bDir, u16 wCount) +{ + _SetEPDblBuf0Count(bEpNum, bDir, wCount); +} +/******************************************************************************* +* Function Name : SetEPDblBuf1Count +* Description : Set the number of bytes in the buffer 0 of a double Buffer +* endpoint. +* Input : bEpNum, bDir, wCount +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuf1Count(u8 bEpNum, u8 bDir, u16 wCount) +{ + _SetEPDblBuf1Count(bEpNum, bDir, wCount); +} +/******************************************************************************* +* Function Name : GetEPDblBuf0Count +* Description : Returns the number of byte received in the buffer 0 of a double +* Buffer endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint Buffer 0 count +*******************************************************************************/ +u16 GetEPDblBuf0Count(u8 bEpNum) +{ + return(_GetEPDblBuf0Count(bEpNum)); +} +/******************************************************************************* +* Function Name : GetEPDblBuf1Count +* Description : Returns the number of data received in the buffer 1 of a double +* Buffer endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint Buffer 1 count. +*******************************************************************************/ +u16 GetEPDblBuf1Count(u8 bEpNum) +{ + return(_GetEPDblBuf1Count(bEpNum)); +} +/******************************************************************************* +* Function Name : GetEPDblBufDir +* Description : gets direction of the double buffered endpoint +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : EP_DBUF_OUT, EP_DBUF_IN, +* EP_DBUF_ERR if the endpoint counter not yet programmed. +*******************************************************************************/ +EP_DBUF_DIR GetEPDblBufDir(u8 bEpNum) +{ + if ((u16)(*_pEPRxCount(bEpNum) & 0xFC00) != 0) + return(EP_DBUF_OUT); + else if (((u16)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0) + return(EP_DBUF_IN); + else + return(EP_DBUF_ERR); +} +/******************************************************************************* +* Function Name : FreeUserBuffer +* Description : free buffer used from the application realizing it to the line + toggles bit SW_BUF in the double buffered endpoint register +* Input : bEpNum, bDir +* Output : None. +* Return : None. +*******************************************************************************/ +void FreeUserBuffer(u8 bEpNum, u8 bDir) +{ + if (bDir == EP_DBUF_OUT) + { /* OUT double buffered endpoint */ + _ToggleDTOG_TX(bEpNum); + } + else if (bDir == EP_DBUF_IN) + { /* IN double buffered endpoint */ + _ToggleDTOG_RX(bEpNum); + } +} + +/******************************************************************************* +* Function Name : ToWord +* Description : merge two byte in a word. +* Input : bh: byte high, bl: bytes low. +* Output : None. +* Return : resulted word. +*******************************************************************************/ +u16 ToWord(u8 bh, u8 bl) +{ + u16 wRet; + wRet = (u16)bl | ((u16)bh << 8); + return(wRet); +} +/******************************************************************************* +* Function Name : ByteSwap +* Description : Swap two byte in a word. +* Input : wSwW: word to Swap. +* Output : None. +* Return : resulted word. +*******************************************************************************/ +u16 ByteSwap(u16 wSwW) +{ + u8 bTemp; + u16 wRet; + bTemp = (u8)(wSwW & 0xff); + wRet = (wSwW >> 8) | ((u16)bTemp << 8); + return(wRet); +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_regs.h b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_regs.h index ddd3b7a6..b63cc5fd 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_regs.h +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_regs.h @@ -1,627 +1,627 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_regs.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Interface prototype functions to USB cell registers -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_REGS_H -#define __USB_REGS_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -#if defined(__cplusplus) -extern "C" { -#endif - -typedef enum _EP_DBUF_DIR -{ - /* double buffered endpoint direction */ - EP_DBUF_ERR, - EP_DBUF_OUT, - EP_DBUF_IN -}EP_DBUF_DIR; - -/* endpoint buffer number */ -enum EP_BUF_NUM -{ - EP_NOBUF, - EP_BUF0, - EP_BUF1 -}; - -/* Exported constants --------------------------------------------------------*/ -#define RegBase (0x40005C00L) /* USB_IP Peripheral Registers base address */ -#define PMAAddr (0x40006000L) /* USB_IP Packet Memory Area base address */ - -/******************************************************************************/ -/* General registers */ -/******************************************************************************/ - -/* Control register */ -#define CNTR ((volatile unsigned *)(RegBase + 0x40)) -/* Interrupt status register */ -#define ISTR ((volatile unsigned *)(RegBase + 0x44)) -/* Frame number register */ -#define FNR ((volatile unsigned *)(RegBase + 0x48)) -/* Device address register */ -#define DADDR ((volatile unsigned *)(RegBase + 0x4C)) -/* Buffer Table address register */ -#define BTABLE ((volatile unsigned *)(RegBase + 0x50)) -/******************************************************************************/ -/* Endpoint registers */ -/******************************************************************************/ -#define EP0REG ((volatile unsigned *)(RegBase)) /* endpoint 0 register address */ - -/* endpoints enumeration */ -#define ENDP0 ((u8)0) -#define ENDP1 ((u8)1) -#define ENDP2 ((u8)2) -#define ENDP3 ((u8)3) -#define ENDP4 ((u8)4) -#define ENDP5 ((u8)5) -#define ENDP6 ((u8)6) -#define ENDP7 ((u8)7) -/******************************************************************************/ -/* ISTR interrupt events */ -/******************************************************************************/ -#define ISTR_CTR (0x8000) /* Correct TRansfer (clear-only bit) */ -#define ISTR_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */ -#define ISTR_ERR (0x2000) /* ERRor (clear-only bit) */ -#define ISTR_WKUP (0x1000) /* WaKe UP (clear-only bit) */ -#define ISTR_SUSP (0x0800) /* SUSPend (clear-only bit) */ -#define ISTR_RESET (0x0400) /* RESET (clear-only bit) */ -#define ISTR_SOF (0x0200) /* Start Of Frame (clear-only bit) */ -#define ISTR_ESOF (0x0100) /* Expected Start Of Frame (clear-only bit) */ - - -#define ISTR_DIR (0x0010) /* DIRection of transaction (read-only bit) */ -#define ISTR_EP_ID (0x000F) /* EndPoint IDentifier (read-only bit) */ - -#define CLR_CTR (~ISTR_CTR) /* clear Correct TRansfer bit */ -#define CLR_DOVR (~ISTR_DOVR) /* clear DMA OVeR/underrun bit*/ -#define CLR_ERR (~ISTR_ERR) /* clear ERRor bit */ -#define CLR_WKUP (~ISTR_WKUP) /* clear WaKe UP bit */ -#define CLR_SUSP (~ISTR_SUSP) /* clear SUSPend bit */ -#define CLR_RESET (~ISTR_RESET) /* clear RESET bit */ -#define CLR_SOF (~ISTR_SOF) /* clear Start Of Frame bit */ -#define CLR_ESOF (~ISTR_ESOF) /* clear Expected Start Of Frame bit */ - -/******************************************************************************/ -/* CNTR control register bits definitions */ -/******************************************************************************/ -#define CNTR_CTRM (0x8000) /* Correct TRansfer Mask */ -#define CNTR_DOVRM (0x4000) /* DMA OVeR/underrun Mask */ -#define CNTR_ERRM (0x2000) /* ERRor Mask */ -#define CNTR_WKUPM (0x1000) /* WaKe UP Mask */ -#define CNTR_SUSPM (0x0800) /* SUSPend Mask */ -#define CNTR_RESETM (0x0400) /* RESET Mask */ -#define CNTR_SOFM (0x0200) /* Start Of Frame Mask */ -#define CNTR_ESOFM (0x0100) /* Expected Start Of Frame Mask */ - - -#define CNTR_RESUME (0x0010) /* RESUME request */ -#define CNTR_FSUSP (0x0008) /* Force SUSPend */ -#define CNTR_LPMODE (0x0004) /* Low-power MODE */ -#define CNTR_PDWN (0x0002) /* Power DoWN */ -#define CNTR_FRES (0x0001) /* Force USB RESet */ - -/******************************************************************************/ -/* FNR Frame Number Register bit definitions */ -/******************************************************************************/ -#define FNR_RXDP (0x8000) /* status of D+ data line */ -#define FNR_RXDM (0x4000) /* status of D- data line */ -#define FNR_LCK (0x2000) /* LoCKed */ -#define FNR_LSOF (0x1800) /* Lost SOF */ -#define FNR_FN (0x07FF) /* Frame Number */ -/******************************************************************************/ -/* DADDR Device ADDRess bit definitions */ -/******************************************************************************/ -#define DADDR_EF (0x80) -#define DADDR_ADD (0x7F) -/******************************************************************************/ -/* Endpoint register */ -/******************************************************************************/ -/* bit positions */ -#define EP_CTR_RX (0x8000) /* EndPoint Correct TRansfer RX */ -#define EP_DTOG_RX (0x4000) /* EndPoint Data TOGGLE RX */ -#define EPRX_STAT (0x3000) /* EndPoint RX STATus bit field */ -#define EP_SETUP (0x0800) /* EndPoint SETUP */ -#define EP_T_FIELD (0x0600) /* EndPoint TYPE */ -#define EP_KIND (0x0100) /* EndPoint KIND */ -#define EP_CTR_TX (0x0080) /* EndPoint Correct TRansfer TX */ -#define EP_DTOG_TX (0x0040) /* EndPoint Data TOGGLE TX */ -#define EPTX_STAT (0x0030) /* EndPoint TX STATus bit field */ -#define EPADDR_FIELD (0x000F) /* EndPoint ADDRess FIELD */ - -/* EndPoint REGister MASK (no toggle fields) */ -#define EPREG_MASK (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD) - -/* EP_TYPE[1:0] EndPoint TYPE */ -#define EP_TYPE_MASK (0x0600) /* EndPoint TYPE Mask */ -#define EP_BULK (0x0000) /* EndPoint BULK */ -#define EP_CONTROL (0x0200) /* EndPoint CONTROL */ -#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */ -#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */ -#define EP_T_MASK (~EP_T_FIELD & EPREG_MASK) - - -/* EP_KIND EndPoint KIND */ -#define EPKIND_MASK (~EP_KIND & EPREG_MASK) - -/* STAT_TX[1:0] STATus for TX transfer */ -#define EP_TX_DIS (0x0000) /* EndPoint TX DISabled */ -#define EP_TX_STALL (0x0010) /* EndPoint TX STALLed */ -#define EP_TX_NAK (0x0020) /* EndPoint TX NAKed */ -#define EP_TX_VALID (0x0030) /* EndPoint TX VALID */ -#define EPTX_DTOG1 (0x0010) /* EndPoint TX Data TOGgle bit1 */ -#define EPTX_DTOG2 (0x0020) /* EndPoint TX Data TOGgle bit2 */ -#define EPTX_DTOGMASK (EPTX_STAT|EPREG_MASK) - -/* STAT_RX[1:0] STATus for RX transfer */ -#define EP_RX_DIS (0x0000) /* EndPoint RX DISabled */ -#define EP_RX_STALL (0x1000) /* EndPoint RX STALLed */ -#define EP_RX_NAK (0x2000) /* EndPoint RX NAKed */ -#define EP_RX_VALID (0x3000) /* EndPoint RX VALID */ -#define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */ -#define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */ -#define EPRX_DTOGMASK (EPRX_STAT|EPREG_MASK) -/* Exported macro ------------------------------------------------------------*/ -/* SetCNTR */ -#define _SetCNTR(wRegValue) (*CNTR = (u16)wRegValue) - -/* SetISTR */ -#define _SetISTR(wRegValue) (*ISTR = (u16)wRegValue) - -/* SetDADDR */ -#define _SetDADDR(wRegValue) (*DADDR = (u16)wRegValue) - -/* SetBTABLE */ -#define _SetBTABLE(wRegValue)(*BTABLE = (u16)(wRegValue & 0xFFF8)) - -/* GetCNTR */ -#define _GetCNTR() ((u16) *CNTR) - -/* GetISTR */ -#define _GetISTR() ((u16) *ISTR) - -/* GetFNR */ -#define _GetFNR() ((u16) *FNR) - -/* GetDADDR */ -#define _GetDADDR() ((u16) *DADDR) - -/* GetBTABLE */ -#define _GetBTABLE() ((u16) *BTABLE) - -/* SetENDPOINT */ -#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \ - (u16)wRegValue) - -/* GetENDPOINT */ -#define _GetENDPOINT(bEpNum) ((u16)(*(EP0REG + bEpNum))) - -/******************************************************************************* -* Macro Name : SetEPType -* Description : sets the type in the endpoint register(bits EP_TYPE[1:0]) -* Input : bEpNum: Endpoint Number. -* wType -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\ - ((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType))) - -/******************************************************************************* -* Macro Name : GetEPType -* Description : gets the type in the endpoint register(bits EP_TYPE[1:0]) -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Type -*******************************************************************************/ -#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD) - -/******************************************************************************* -* Macro Name : SetEPTxStatus -* Description : sets the status for tx transfer (bits STAT_TX[1:0]). -* Input : bEpNum: Endpoint Number. -* wState: new state -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxStatus(bEpNum,wState) {\ - register u16 _wRegVal; \ - _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\ - /* toggle first bit ? */ \ - if((EPTX_DTOG1 & wState)!= 0) \ - _wRegVal ^= EPTX_DTOG1; \ - /* toggle second bit ? */ \ - if((EPTX_DTOG2 & wState)!= 0) \ - _wRegVal ^= EPTX_DTOG2; \ - _SetENDPOINT(bEpNum, _wRegVal); \ - } /* _SetEPTxStatus */ - -/******************************************************************************* -* Macro Name : SetEPRxStatus -* Description : sets the status for rx transfer (bits STAT_TX[1:0]) -* Input : bEpNum: Endpoint Number. -* wState: new state. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPRxStatus(bEpNum,wState) {\ - register u16 _wRegVal; \ - \ - _wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\ - /* toggle first bit ? */ \ - if((EPRX_DTOG1 & wState)!= 0) \ - _wRegVal ^= EPRX_DTOG1; \ - /* toggle second bit ? */ \ - if((EPRX_DTOG2 & wState)!= 0) \ - _wRegVal ^= EPRX_DTOG2; \ - _SetENDPOINT(bEpNum, _wRegVal); \ - } /* _SetEPRxStatus */ -/******************************************************************************* -* Macro Name : GetEPTxStatus / GetEPRxStatus -* Description : gets the status for tx/rx transfer (bits STAT_TX[1:0] -* /STAT_RX[1:0]) -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : status . -*******************************************************************************/ -#define _GetEPTxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPTX_STAT) - -#define _GetEPRxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPRX_STAT) - -/******************************************************************************* -* Macro Name : SetEPTxValid / SetEPRxValid -* Description : sets directly the VALID tx/rx-status into the enpoint register -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxValid(bEpNum) (_SetEPTxStatus(bEpNum, EP_TX_VALID)) - -#define _SetEPRxValid(bEpNum) (_SetEPRxStatus(bEpNum, EP_RX_VALID)) - -/******************************************************************************* -* Macro Name : GetTxStallStatus / GetRxStallStatus. -* Description : checks stall condition in an endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : TRUE = endpoint in stall condition. -*******************************************************************************/ -#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \ - == EP_TX_STALL) -#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \ - == EP_RX_STALL) - -/******************************************************************************* -* Macro Name : SetEP_KIND / ClearEP_KIND. -* Description : set & clear EP_KIND bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \ - (_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK)) -#define _ClearEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \ - (_GetENDPOINT(bEpNum) & EPKIND_MASK))) - -/******************************************************************************* -* Macro Name : Set_Status_Out / Clear_Status_Out. -* Description : Sets/clears directly STATUS_OUT bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _Set_Status_Out(bEpNum) _SetEP_KIND(bEpNum) -#define _Clear_Status_Out(bEpNum) _ClearEP_KIND(bEpNum) - -/******************************************************************************* -* Macro Name : SetEPDoubleBuff / ClearEPDoubleBuff. -* Description : Sets/clears directly EP_KIND bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDoubleBuff(bEpNum) _SetEP_KIND(bEpNum) -#define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum) - -/******************************************************************************* -* Macro Name : ClearEP_CTR_RX / ClearEP_CTR_TX. -* Description : Clears bit CTR_RX / CTR_TX in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _ClearEP_CTR_RX(bEpNum) (_SetENDPOINT(bEpNum,\ - _GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK)) -#define _ClearEP_CTR_TX(bEpNum) (_SetENDPOINT(bEpNum,\ - _GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK)) - -/******************************************************************************* -* Macro Name : ToggleDTOG_RX / ToggleDTOG_TX . -* Description : Toggles DTOG_RX / DTOG_TX bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _ToggleDTOG_RX(bEpNum) (_SetENDPOINT(bEpNum, \ - EP_DTOG_RX | (_GetENDPOINT(bEpNum) & EPREG_MASK))) -#define _ToggleDTOG_TX(bEpNum) (_SetENDPOINT(bEpNum, \ - EP_DTOG_TX | (_GetENDPOINT(bEpNum) & EPREG_MASK))) - -/******************************************************************************* -* Macro Name : ClearDTOG_RX / ClearDTOG_TX. -* Description : Clears DTOG_RX / DTOG_TX bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _ClearDTOG_RX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\ - _ToggleDTOG_RX(bEpNum) -#define _ClearDTOG_TX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\ - _ToggleDTOG_TX(bEpNum) -/******************************************************************************* -* Macro Name : SetEPAddress. -* Description : Sets address in an endpoint register. -* Input : bEpNum: Endpoint Number. -* bAddr: Address. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\ - (_GetENDPOINT(bEpNum) & EPREG_MASK) | bAddr) - -/******************************************************************************* -* Macro Name : GetEPAddress. -* Description : Gets address in an endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _GetEPAddress(bEpNum) ((u8)(_GetENDPOINT(bEpNum) & EPADDR_FIELD)) - -#define _pEPTxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8 )*2 + PMAAddr)) -#define _pEPTxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr)) -#define _pEPRxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr)) -#define _pEPRxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr)) - -/******************************************************************************* -* Macro Name : SetEPTxAddr / SetEPRxAddr. -* Description : sets address of the tx/rx buffer. -* Input : bEpNum: Endpoint Number. -* wAddr: address to be set (must be word aligned). -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1)) -#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1)) - -/******************************************************************************* -* Macro Name : GetEPTxAddr / GetEPRxAddr. -* Description : Gets address of the tx/rx buffer. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : address of the buffer. -*******************************************************************************/ -#define _GetEPTxAddr(bEpNum) ((u16)*_pEPTxAddr(bEpNum)) -#define _GetEPRxAddr(bEpNum) ((u16)*_pEPRxAddr(bEpNum)) - -/******************************************************************************* -* Macro Name : SetEPCountRxReg. -* Description : Sets counter of rx buffer with no. of blocks. -* Input : pdwReg: pointer to counter. -* wCount: Counter. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _BlocksOf32(dwReg,wCount,wNBlocks) {\ - wNBlocks = wCount >> 5;\ - if((wCount & 0x1f) == 0)\ - wNBlocks--;\ - *pdwReg = (u32)((wNBlocks << 10) | 0x8000);\ - }/* _BlocksOf32 */ - -#define _BlocksOf2(dwReg,wCount,wNBlocks) {\ - wNBlocks = wCount >> 1;\ - if((wCount & 0x1) != 0)\ - wNBlocks++;\ - *pdwReg = (u32)(wNBlocks << 10);\ - }/* _BlocksOf2 */ - -#define _SetEPCountRxReg(dwReg,wCount) {\ - u16 wNBlocks;\ - if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\ - else {_BlocksOf2(dwReg,wCount,wNBlocks);}\ - }/* _SetEPCountRxReg */ - - - -#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\ - u32 *pdwReg = _pEPTxCount(bEpNum); \ - _SetEPCountRxReg(pdwReg, wCount);\ - } -/******************************************************************************* -* Macro Name : SetEPTxCount / SetEPRxCount. -* Description : sets counter for the tx/rx buffer. -* Input : bEpNum: endpoint number. -* wCount: Counter value. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount) -#define _SetEPRxCount(bEpNum,wCount) {\ - u32 *pdwReg = _pEPRxCount(bEpNum); \ - _SetEPCountRxReg(pdwReg, wCount);\ - } -/******************************************************************************* -* Macro Name : GetEPTxCount / GetEPRxCount. -* Description : gets counter of the tx buffer. -* Input : bEpNum: endpoint number. -* Output : None. -* Return : Counter value. -*******************************************************************************/ -#define _GetEPTxCount(bEpNum)((u16)(*_pEPTxCount(bEpNum)) & 0x3ff) -#define _GetEPRxCount(bEpNum)((u16)(*_pEPRxCount(bEpNum)) & 0x3ff) - -/******************************************************************************* -* Macro Name : SetEPDblBuf0Addr / SetEPDblBuf1Addr. -* Description : Sets buffer 0/1 address in a double buffer endpoint. -* Input : bEpNum: endpoint number. -* : wBuf0Addr: buffer 0 address. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);} -#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);} - -/******************************************************************************* -* Macro Name : SetEPDblBuffAddr. -* Description : Sets addresses in a double buffer endpoint. -* Input : bEpNum: endpoint number. -* : wBuf0Addr: buffer 0 address. -* : wBuf1Addr = buffer 1 address. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \ - _SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\ - _SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\ - } /* _SetEPDblBuffAddr */ - -/******************************************************************************* -* Macro Name : GetEPDblBuf0Addr / GetEPDblBuf1Addr. -* Description : Gets buffer 0/1 address of a double buffer endpoint. -* Input : bEpNum: endpoint number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum)) -#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum)) - -/******************************************************************************* -* Macro Name : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count. -* Description : Gets buffer 0/1 address of a double buffer endpoint. -* Input : bEpNum: endpoint number. -* : bDir: endpoint dir EP_DBUF_OUT = OUT -* EP_DBUF_IN = IN -* : wCount: Counter value -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDblBuf0Count(bEpNum, bDir, wCount) { \ - if(bDir == EP_DBUF_OUT)\ - /* OUT endpoint */ \ - {_SetEPRxDblBuf0Count(bEpNum,wCount);} \ - else if(bDir == EP_DBUF_IN)\ - /* IN endpoint */ \ - *_pEPTxCount(bEpNum) = (u32)wCount; \ - } /* SetEPDblBuf0Count*/ - -#define _SetEPDblBuf1Count(bEpNum, bDir, wCount) { \ - if(bDir == EP_DBUF_OUT)\ - /* OUT endpoint */ \ - {_SetEPRxCount(bEpNum,wCount);}\ - else if(bDir == EP_DBUF_IN)\ - /* IN endpoint */\ - *_pEPRxCount(bEpNum) = (u32)wCount; \ - } /* SetEPDblBuf1Count */ - -#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\ - _SetEPDblBuf0Count(bEpNum, bDir, wCount); \ - _SetEPDblBuf1Count(bEpNum, bDir, wCount); \ - } /* _SetEPDblBuffCount */ - -/******************************************************************************* -* Macro Name : GetEPDblBuf0Count / GetEPDblBuf1Count. -* Description : Gets buffer 0/1 rx/tx counter for double buffering. -* Input : bEpNum: endpoint number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum)) -#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum)) - - -/* External variables --------------------------------------------------------*/ -extern volatile u16 wIstr; /* ISTR register last read value */ - -/* Exported functions ------------------------------------------------------- */ -void SetCNTR(u16 /*wRegValue*/); -void SetISTR(u16 /*wRegValue*/); -void SetDADDR(u16 /*wRegValue*/); -void SetBTABLE(u16 /*wRegValue*/); -u16 GetCNTR(void); -u16 GetISTR(void); -u16 GetFNR(void); -u16 GetDADDR(void); -u16 GetBTABLE(void); -void SetENDPOINT(u8 /*bEpNum*/, u16 /*wRegValue*/); -u16 GetENDPOINT(u8 /*bEpNum*/); -void SetEPType(u8 /*bEpNum*/, u16 /*wType*/); -u16 GetEPType(u8 /*bEpNum*/); -void SetEPTxStatus(u8 /*bEpNum*/, u16 /*wState*/); -void SetEPRxStatus(u8 /*bEpNum*/, u16 /*wState*/); -void SetDouBleBuffEPStall(u8 /*bEpNum*/, u8 bDir); -u16 GetEPTxStatus(u8 /*bEpNum*/); -u16 GetEPRxStatus(u8 /*bEpNum*/); -void SetEPTxValid(u8 /*bEpNum*/); -void SetEPRxValid(u8 /*bEpNum*/); -u16 GetTxStallStatus(u8 /*bEpNum*/); -u16 GetRxStallStatus(u8 /*bEpNum*/); -void SetEP_KIND(u8 /*bEpNum*/); -void ClearEP_KIND(u8 /*bEpNum*/); -void Set_Status_Out(u8 /*bEpNum*/); -void Clear_Status_Out(u8 /*bEpNum*/); -void SetEPDoubleBuff(u8 /*bEpNum*/); -void ClearEPDoubleBuff(u8 /*bEpNum*/); -void ClearEP_CTR_RX(u8 /*bEpNum*/); -void ClearEP_CTR_TX(u8 /*bEpNum*/); -void ToggleDTOG_RX(u8 /*bEpNum*/); -void ToggleDTOG_TX(u8 /*bEpNum*/); -void ClearDTOG_RX(u8 /*bEpNum*/); -void ClearDTOG_TX(u8 /*bEpNum*/); -void SetEPAddress(u8 /*bEpNum*/, u8 /*bAddr*/); -u8 GetEPAddress(u8 /*bEpNum*/); -void SetEPTxAddr(u8 /*bEpNum*/, u16 /*wAddr*/); -void SetEPRxAddr(u8 /*bEpNum*/, u16 /*wAddr*/); -u16 GetEPTxAddr(u8 /*bEpNum*/); -u16 GetEPRxAddr(u8 /*bEpNum*/); -void SetEPCountRxReg(u32 * /*pdwReg*/, u16 /*wCount*/); -void SetEPTxCount(u8 /*bEpNum*/, u16 /*wCount*/); -void SetEPRxCount(u8 /*bEpNum*/, u16 /*wCount*/); -u16 GetEPTxCount(u8 /*bEpNum*/); -u16 GetEPRxCount(u8 /*bEpNum*/); -void SetEPDblBuf0Addr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/); -void SetEPDblBuf1Addr(u8 /*bEpNum*/, u16 /*wBuf1Addr*/); -void SetEPDblBuffAddr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/, u16 /*wBuf1Addr*/); -u16 GetEPDblBuf0Addr(u8 /*bEpNum*/); -u16 GetEPDblBuf1Addr(u8 /*bEpNum*/); -void SetEPDblBuffCount(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); -void SetEPDblBuf0Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); -void SetEPDblBuf1Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); -u16 GetEPDblBuf0Count(u8 /*bEpNum*/); -u16 GetEPDblBuf1Count(u8 /*bEpNum*/); -EP_DBUF_DIR GetEPDblBufDir(u8 /*bEpNum*/); -void FreeUserBuffer(u8 bEpNum/*bEpNum*/, u8 bDir); -u16 ToWord(u8, u8); -u16 ByteSwap(u16); - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_REGS_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_regs.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Interface prototype functions to USB cell registers +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_REGS_H +#define __USB_REGS_H + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +#if defined(__cplusplus) +extern "C" { +#endif + +typedef enum _EP_DBUF_DIR +{ + /* double buffered endpoint direction */ + EP_DBUF_ERR, + EP_DBUF_OUT, + EP_DBUF_IN +}EP_DBUF_DIR; + +/* endpoint buffer number */ +enum EP_BUF_NUM +{ + EP_NOBUF, + EP_BUF0, + EP_BUF1 +}; + +/* Exported constants --------------------------------------------------------*/ +#define RegBase (0x40005C00L) /* USB_IP Peripheral Registers base address */ +#define PMAAddr (0x40006000L) /* USB_IP Packet Memory Area base address */ + +/******************************************************************************/ +/* General registers */ +/******************************************************************************/ + +/* Control register */ +#define CNTR ((volatile unsigned *)(RegBase + 0x40)) +/* Interrupt status register */ +#define ISTR ((volatile unsigned *)(RegBase + 0x44)) +/* Frame number register */ +#define FNR ((volatile unsigned *)(RegBase + 0x48)) +/* Device address register */ +#define DADDR ((volatile unsigned *)(RegBase + 0x4C)) +/* Buffer Table address register */ +#define BTABLE ((volatile unsigned *)(RegBase + 0x50)) +/******************************************************************************/ +/* Endpoint registers */ +/******************************************************************************/ +#define EP0REG ((volatile unsigned *)(RegBase)) /* endpoint 0 register address */ + +/* endpoints enumeration */ +#define ENDP0 ((u8)0) +#define ENDP1 ((u8)1) +#define ENDP2 ((u8)2) +#define ENDP3 ((u8)3) +#define ENDP4 ((u8)4) +#define ENDP5 ((u8)5) +#define ENDP6 ((u8)6) +#define ENDP7 ((u8)7) +/******************************************************************************/ +/* ISTR interrupt events */ +/******************************************************************************/ +#define ISTR_CTR (0x8000) /* Correct TRansfer (clear-only bit) */ +#define ISTR_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */ +#define ISTR_ERR (0x2000) /* ERRor (clear-only bit) */ +#define ISTR_WKUP (0x1000) /* WaKe UP (clear-only bit) */ +#define ISTR_SUSP (0x0800) /* SUSPend (clear-only bit) */ +#define ISTR_RESET (0x0400) /* RESET (clear-only bit) */ +#define ISTR_SOF (0x0200) /* Start Of Frame (clear-only bit) */ +#define ISTR_ESOF (0x0100) /* Expected Start Of Frame (clear-only bit) */ + + +#define ISTR_DIR (0x0010) /* DIRection of transaction (read-only bit) */ +#define ISTR_EP_ID (0x000F) /* EndPoint IDentifier (read-only bit) */ + +#define CLR_CTR (~ISTR_CTR) /* clear Correct TRansfer bit */ +#define CLR_DOVR (~ISTR_DOVR) /* clear DMA OVeR/underrun bit*/ +#define CLR_ERR (~ISTR_ERR) /* clear ERRor bit */ +#define CLR_WKUP (~ISTR_WKUP) /* clear WaKe UP bit */ +#define CLR_SUSP (~ISTR_SUSP) /* clear SUSPend bit */ +#define CLR_RESET (~ISTR_RESET) /* clear RESET bit */ +#define CLR_SOF (~ISTR_SOF) /* clear Start Of Frame bit */ +#define CLR_ESOF (~ISTR_ESOF) /* clear Expected Start Of Frame bit */ + +/******************************************************************************/ +/* CNTR control register bits definitions */ +/******************************************************************************/ +#define CNTR_CTRM (0x8000) /* Correct TRansfer Mask */ +#define CNTR_DOVRM (0x4000) /* DMA OVeR/underrun Mask */ +#define CNTR_ERRM (0x2000) /* ERRor Mask */ +#define CNTR_WKUPM (0x1000) /* WaKe UP Mask */ +#define CNTR_SUSPM (0x0800) /* SUSPend Mask */ +#define CNTR_RESETM (0x0400) /* RESET Mask */ +#define CNTR_SOFM (0x0200) /* Start Of Frame Mask */ +#define CNTR_ESOFM (0x0100) /* Expected Start Of Frame Mask */ + + +#define CNTR_RESUME (0x0010) /* RESUME request */ +#define CNTR_FSUSP (0x0008) /* Force SUSPend */ +#define CNTR_LPMODE (0x0004) /* Low-power MODE */ +#define CNTR_PDWN (0x0002) /* Power DoWN */ +#define CNTR_FRES (0x0001) /* Force USB RESet */ + +/******************************************************************************/ +/* FNR Frame Number Register bit definitions */ +/******************************************************************************/ +#define FNR_RXDP (0x8000) /* status of D+ data line */ +#define FNR_RXDM (0x4000) /* status of D- data line */ +#define FNR_LCK (0x2000) /* LoCKed */ +#define FNR_LSOF (0x1800) /* Lost SOF */ +#define FNR_FN (0x07FF) /* Frame Number */ +/******************************************************************************/ +/* DADDR Device ADDRess bit definitions */ +/******************************************************************************/ +#define DADDR_EF (0x80) +#define DADDR_ADD (0x7F) +/******************************************************************************/ +/* Endpoint register */ +/******************************************************************************/ +/* bit positions */ +#define EP_CTR_RX (0x8000) /* EndPoint Correct TRansfer RX */ +#define EP_DTOG_RX (0x4000) /* EndPoint Data TOGGLE RX */ +#define EPRX_STAT (0x3000) /* EndPoint RX STATus bit field */ +#define EP_SETUP (0x0800) /* EndPoint SETUP */ +#define EP_T_FIELD (0x0600) /* EndPoint TYPE */ +#define EP_KIND (0x0100) /* EndPoint KIND */ +#define EP_CTR_TX (0x0080) /* EndPoint Correct TRansfer TX */ +#define EP_DTOG_TX (0x0040) /* EndPoint Data TOGGLE TX */ +#define EPTX_STAT (0x0030) /* EndPoint TX STATus bit field */ +#define EPADDR_FIELD (0x000F) /* EndPoint ADDRess FIELD */ + +/* EndPoint REGister MASK (no toggle fields) */ +#define EPREG_MASK (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD) + +/* EP_TYPE[1:0] EndPoint TYPE */ +#define EP_TYPE_MASK (0x0600) /* EndPoint TYPE Mask */ +#define EP_BULK (0x0000) /* EndPoint BULK */ +#define EP_CONTROL (0x0200) /* EndPoint CONTROL */ +#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */ +#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */ +#define EP_T_MASK (~EP_T_FIELD & EPREG_MASK) + + +/* EP_KIND EndPoint KIND */ +#define EPKIND_MASK (~EP_KIND & EPREG_MASK) + +/* STAT_TX[1:0] STATus for TX transfer */ +#define EP_TX_DIS (0x0000) /* EndPoint TX DISabled */ +#define EP_TX_STALL (0x0010) /* EndPoint TX STALLed */ +#define EP_TX_NAK (0x0020) /* EndPoint TX NAKed */ +#define EP_TX_VALID (0x0030) /* EndPoint TX VALID */ +#define EPTX_DTOG1 (0x0010) /* EndPoint TX Data TOGgle bit1 */ +#define EPTX_DTOG2 (0x0020) /* EndPoint TX Data TOGgle bit2 */ +#define EPTX_DTOGMASK (EPTX_STAT|EPREG_MASK) + +/* STAT_RX[1:0] STATus for RX transfer */ +#define EP_RX_DIS (0x0000) /* EndPoint RX DISabled */ +#define EP_RX_STALL (0x1000) /* EndPoint RX STALLed */ +#define EP_RX_NAK (0x2000) /* EndPoint RX NAKed */ +#define EP_RX_VALID (0x3000) /* EndPoint RX VALID */ +#define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */ +#define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */ +#define EPRX_DTOGMASK (EPRX_STAT|EPREG_MASK) +/* Exported macro ------------------------------------------------------------*/ +/* SetCNTR */ +#define _SetCNTR(wRegValue) (*CNTR = (u16)wRegValue) + +/* SetISTR */ +#define _SetISTR(wRegValue) (*ISTR = (u16)wRegValue) + +/* SetDADDR */ +#define _SetDADDR(wRegValue) (*DADDR = (u16)wRegValue) + +/* SetBTABLE */ +#define _SetBTABLE(wRegValue)(*BTABLE = (u16)(wRegValue & 0xFFF8)) + +/* GetCNTR */ +#define _GetCNTR() ((u16) *CNTR) + +/* GetISTR */ +#define _GetISTR() ((u16) *ISTR) + +/* GetFNR */ +#define _GetFNR() ((u16) *FNR) + +/* GetDADDR */ +#define _GetDADDR() ((u16) *DADDR) + +/* GetBTABLE */ +#define _GetBTABLE() ((u16) *BTABLE) + +/* SetENDPOINT */ +#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \ + (u16)wRegValue) + +/* GetENDPOINT */ +#define _GetENDPOINT(bEpNum) ((u16)(*(EP0REG + bEpNum))) + +/******************************************************************************* +* Macro Name : SetEPType +* Description : sets the type in the endpoint register(bits EP_TYPE[1:0]) +* Input : bEpNum: Endpoint Number. +* wType +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\ + ((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType))) + +/******************************************************************************* +* Macro Name : GetEPType +* Description : gets the type in the endpoint register(bits EP_TYPE[1:0]) +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint Type +*******************************************************************************/ +#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD) + +/******************************************************************************* +* Macro Name : SetEPTxStatus +* Description : sets the status for tx transfer (bits STAT_TX[1:0]). +* Input : bEpNum: Endpoint Number. +* wState: new state +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPTxStatus(bEpNum,wState) {\ + register u16 _wRegVal; \ + _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\ + /* toggle first bit ? */ \ + if((EPTX_DTOG1 & wState)!= 0) \ + _wRegVal ^= EPTX_DTOG1; \ + /* toggle second bit ? */ \ + if((EPTX_DTOG2 & wState)!= 0) \ + _wRegVal ^= EPTX_DTOG2; \ + _SetENDPOINT(bEpNum, _wRegVal); \ + } /* _SetEPTxStatus */ + +/******************************************************************************* +* Macro Name : SetEPRxStatus +* Description : sets the status for rx transfer (bits STAT_TX[1:0]) +* Input : bEpNum: Endpoint Number. +* wState: new state. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPRxStatus(bEpNum,wState) {\ + register u16 _wRegVal; \ + \ + _wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\ + /* toggle first bit ? */ \ + if((EPRX_DTOG1 & wState)!= 0) \ + _wRegVal ^= EPRX_DTOG1; \ + /* toggle second bit ? */ \ + if((EPRX_DTOG2 & wState)!= 0) \ + _wRegVal ^= EPRX_DTOG2; \ + _SetENDPOINT(bEpNum, _wRegVal); \ + } /* _SetEPRxStatus */ +/******************************************************************************* +* Macro Name : GetEPTxStatus / GetEPRxStatus +* Description : gets the status for tx/rx transfer (bits STAT_TX[1:0] +* /STAT_RX[1:0]) +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : status . +*******************************************************************************/ +#define _GetEPTxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPTX_STAT) + +#define _GetEPRxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPRX_STAT) + +/******************************************************************************* +* Macro Name : SetEPTxValid / SetEPRxValid +* Description : sets directly the VALID tx/rx-status into the enpoint register +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPTxValid(bEpNum) (_SetEPTxStatus(bEpNum, EP_TX_VALID)) + +#define _SetEPRxValid(bEpNum) (_SetEPRxStatus(bEpNum, EP_RX_VALID)) + +/******************************************************************************* +* Macro Name : GetTxStallStatus / GetRxStallStatus. +* Description : checks stall condition in an endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : TRUE = endpoint in stall condition. +*******************************************************************************/ +#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \ + == EP_TX_STALL) +#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \ + == EP_RX_STALL) + +/******************************************************************************* +* Macro Name : SetEP_KIND / ClearEP_KIND. +* Description : set & clear EP_KIND bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \ + (_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK)) +#define _ClearEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \ + (_GetENDPOINT(bEpNum) & EPKIND_MASK))) + +/******************************************************************************* +* Macro Name : Set_Status_Out / Clear_Status_Out. +* Description : Sets/clears directly STATUS_OUT bit in the endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _Set_Status_Out(bEpNum) _SetEP_KIND(bEpNum) +#define _Clear_Status_Out(bEpNum) _ClearEP_KIND(bEpNum) + +/******************************************************************************* +* Macro Name : SetEPDoubleBuff / ClearEPDoubleBuff. +* Description : Sets/clears directly EP_KIND bit in the endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPDoubleBuff(bEpNum) _SetEP_KIND(bEpNum) +#define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum) + +/******************************************************************************* +* Macro Name : ClearEP_CTR_RX / ClearEP_CTR_TX. +* Description : Clears bit CTR_RX / CTR_TX in the endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _ClearEP_CTR_RX(bEpNum) (_SetENDPOINT(bEpNum,\ + _GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK)) +#define _ClearEP_CTR_TX(bEpNum) (_SetENDPOINT(bEpNum,\ + _GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK)) + +/******************************************************************************* +* Macro Name : ToggleDTOG_RX / ToggleDTOG_TX . +* Description : Toggles DTOG_RX / DTOG_TX bit in the endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _ToggleDTOG_RX(bEpNum) (_SetENDPOINT(bEpNum, \ + EP_DTOG_RX | (_GetENDPOINT(bEpNum) & EPREG_MASK))) +#define _ToggleDTOG_TX(bEpNum) (_SetENDPOINT(bEpNum, \ + EP_DTOG_TX | (_GetENDPOINT(bEpNum) & EPREG_MASK))) + +/******************************************************************************* +* Macro Name : ClearDTOG_RX / ClearDTOG_TX. +* Description : Clears DTOG_RX / DTOG_TX bit in the endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _ClearDTOG_RX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\ + _ToggleDTOG_RX(bEpNum) +#define _ClearDTOG_TX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\ + _ToggleDTOG_TX(bEpNum) +/******************************************************************************* +* Macro Name : SetEPAddress. +* Description : Sets address in an endpoint register. +* Input : bEpNum: Endpoint Number. +* bAddr: Address. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\ + (_GetENDPOINT(bEpNum) & EPREG_MASK) | bAddr) + +/******************************************************************************* +* Macro Name : GetEPAddress. +* Description : Gets address in an endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _GetEPAddress(bEpNum) ((u8)(_GetENDPOINT(bEpNum) & EPADDR_FIELD)) + +#define _pEPTxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8 )*2 + PMAAddr)) +#define _pEPTxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr)) +#define _pEPRxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr)) +#define _pEPRxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr)) + +/******************************************************************************* +* Macro Name : SetEPTxAddr / SetEPRxAddr. +* Description : sets address of the tx/rx buffer. +* Input : bEpNum: Endpoint Number. +* wAddr: address to be set (must be word aligned). +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1)) +#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1)) + +/******************************************************************************* +* Macro Name : GetEPTxAddr / GetEPRxAddr. +* Description : Gets address of the tx/rx buffer. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : address of the buffer. +*******************************************************************************/ +#define _GetEPTxAddr(bEpNum) ((u16)*_pEPTxAddr(bEpNum)) +#define _GetEPRxAddr(bEpNum) ((u16)*_pEPRxAddr(bEpNum)) + +/******************************************************************************* +* Macro Name : SetEPCountRxReg. +* Description : Sets counter of rx buffer with no. of blocks. +* Input : pdwReg: pointer to counter. +* wCount: Counter. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _BlocksOf32(dwReg,wCount,wNBlocks) {\ + wNBlocks = wCount >> 5;\ + if((wCount & 0x1f) == 0)\ + wNBlocks--;\ + *pdwReg = (u32)((wNBlocks << 10) | 0x8000);\ + }/* _BlocksOf32 */ + +#define _BlocksOf2(dwReg,wCount,wNBlocks) {\ + wNBlocks = wCount >> 1;\ + if((wCount & 0x1) != 0)\ + wNBlocks++;\ + *pdwReg = (u32)(wNBlocks << 10);\ + }/* _BlocksOf2 */ + +#define _SetEPCountRxReg(dwReg,wCount) {\ + u16 wNBlocks;\ + if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\ + else {_BlocksOf2(dwReg,wCount,wNBlocks);}\ + }/* _SetEPCountRxReg */ + + + +#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\ + u32 *pdwReg = _pEPTxCount(bEpNum); \ + _SetEPCountRxReg(pdwReg, wCount);\ + } +/******************************************************************************* +* Macro Name : SetEPTxCount / SetEPRxCount. +* Description : sets counter for the tx/rx buffer. +* Input : bEpNum: endpoint number. +* wCount: Counter value. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount) +#define _SetEPRxCount(bEpNum,wCount) {\ + u32 *pdwReg = _pEPRxCount(bEpNum); \ + _SetEPCountRxReg(pdwReg, wCount);\ + } +/******************************************************************************* +* Macro Name : GetEPTxCount / GetEPRxCount. +* Description : gets counter of the tx buffer. +* Input : bEpNum: endpoint number. +* Output : None. +* Return : Counter value. +*******************************************************************************/ +#define _GetEPTxCount(bEpNum)((u16)(*_pEPTxCount(bEpNum)) & 0x3ff) +#define _GetEPRxCount(bEpNum)((u16)(*_pEPRxCount(bEpNum)) & 0x3ff) + +/******************************************************************************* +* Macro Name : SetEPDblBuf0Addr / SetEPDblBuf1Addr. +* Description : Sets buffer 0/1 address in a double buffer endpoint. +* Input : bEpNum: endpoint number. +* : wBuf0Addr: buffer 0 address. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);} +#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);} + +/******************************************************************************* +* Macro Name : SetEPDblBuffAddr. +* Description : Sets addresses in a double buffer endpoint. +* Input : bEpNum: endpoint number. +* : wBuf0Addr: buffer 0 address. +* : wBuf1Addr = buffer 1 address. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \ + _SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\ + _SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\ + } /* _SetEPDblBuffAddr */ + +/******************************************************************************* +* Macro Name : GetEPDblBuf0Addr / GetEPDblBuf1Addr. +* Description : Gets buffer 0/1 address of a double buffer endpoint. +* Input : bEpNum: endpoint number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum)) +#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum)) + +/******************************************************************************* +* Macro Name : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count. +* Description : Gets buffer 0/1 address of a double buffer endpoint. +* Input : bEpNum: endpoint number. +* : bDir: endpoint dir EP_DBUF_OUT = OUT +* EP_DBUF_IN = IN +* : wCount: Counter value +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPDblBuf0Count(bEpNum, bDir, wCount) { \ + if(bDir == EP_DBUF_OUT)\ + /* OUT endpoint */ \ + {_SetEPRxDblBuf0Count(bEpNum,wCount);} \ + else if(bDir == EP_DBUF_IN)\ + /* IN endpoint */ \ + *_pEPTxCount(bEpNum) = (u32)wCount; \ + } /* SetEPDblBuf0Count*/ + +#define _SetEPDblBuf1Count(bEpNum, bDir, wCount) { \ + if(bDir == EP_DBUF_OUT)\ + /* OUT endpoint */ \ + {_SetEPRxCount(bEpNum,wCount);}\ + else if(bDir == EP_DBUF_IN)\ + /* IN endpoint */\ + *_pEPRxCount(bEpNum) = (u32)wCount; \ + } /* SetEPDblBuf1Count */ + +#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\ + _SetEPDblBuf0Count(bEpNum, bDir, wCount); \ + _SetEPDblBuf1Count(bEpNum, bDir, wCount); \ + } /* _SetEPDblBuffCount */ + +/******************************************************************************* +* Macro Name : GetEPDblBuf0Count / GetEPDblBuf1Count. +* Description : Gets buffer 0/1 rx/tx counter for double buffering. +* Input : bEpNum: endpoint number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum)) +#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum)) + + +/* External variables --------------------------------------------------------*/ +extern volatile u16 wIstr; /* ISTR register last read value */ + +/* Exported functions ------------------------------------------------------- */ +void SetCNTR(u16 /*wRegValue*/); +void SetISTR(u16 /*wRegValue*/); +void SetDADDR(u16 /*wRegValue*/); +void SetBTABLE(u16 /*wRegValue*/); +u16 GetCNTR(void); +u16 GetISTR(void); +u16 GetFNR(void); +u16 GetDADDR(void); +u16 GetBTABLE(void); +void SetENDPOINT(u8 /*bEpNum*/, u16 /*wRegValue*/); +u16 GetENDPOINT(u8 /*bEpNum*/); +void SetEPType(u8 /*bEpNum*/, u16 /*wType*/); +u16 GetEPType(u8 /*bEpNum*/); +void SetEPTxStatus(u8 /*bEpNum*/, u16 /*wState*/); +void SetEPRxStatus(u8 /*bEpNum*/, u16 /*wState*/); +void SetDouBleBuffEPStall(u8 /*bEpNum*/, u8 bDir); +u16 GetEPTxStatus(u8 /*bEpNum*/); +u16 GetEPRxStatus(u8 /*bEpNum*/); +void SetEPTxValid(u8 /*bEpNum*/); +void SetEPRxValid(u8 /*bEpNum*/); +u16 GetTxStallStatus(u8 /*bEpNum*/); +u16 GetRxStallStatus(u8 /*bEpNum*/); +void SetEP_KIND(u8 /*bEpNum*/); +void ClearEP_KIND(u8 /*bEpNum*/); +void Set_Status_Out(u8 /*bEpNum*/); +void Clear_Status_Out(u8 /*bEpNum*/); +void SetEPDoubleBuff(u8 /*bEpNum*/); +void ClearEPDoubleBuff(u8 /*bEpNum*/); +void ClearEP_CTR_RX(u8 /*bEpNum*/); +void ClearEP_CTR_TX(u8 /*bEpNum*/); +void ToggleDTOG_RX(u8 /*bEpNum*/); +void ToggleDTOG_TX(u8 /*bEpNum*/); +void ClearDTOG_RX(u8 /*bEpNum*/); +void ClearDTOG_TX(u8 /*bEpNum*/); +void SetEPAddress(u8 /*bEpNum*/, u8 /*bAddr*/); +u8 GetEPAddress(u8 /*bEpNum*/); +void SetEPTxAddr(u8 /*bEpNum*/, u16 /*wAddr*/); +void SetEPRxAddr(u8 /*bEpNum*/, u16 /*wAddr*/); +u16 GetEPTxAddr(u8 /*bEpNum*/); +u16 GetEPRxAddr(u8 /*bEpNum*/); +void SetEPCountRxReg(u32 * /*pdwReg*/, u16 /*wCount*/); +void SetEPTxCount(u8 /*bEpNum*/, u16 /*wCount*/); +void SetEPRxCount(u8 /*bEpNum*/, u16 /*wCount*/); +u16 GetEPTxCount(u8 /*bEpNum*/); +u16 GetEPRxCount(u8 /*bEpNum*/); +void SetEPDblBuf0Addr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/); +void SetEPDblBuf1Addr(u8 /*bEpNum*/, u16 /*wBuf1Addr*/); +void SetEPDblBuffAddr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/, u16 /*wBuf1Addr*/); +u16 GetEPDblBuf0Addr(u8 /*bEpNum*/); +u16 GetEPDblBuf1Addr(u8 /*bEpNum*/); +void SetEPDblBuffCount(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); +void SetEPDblBuf0Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); +void SetEPDblBuf1Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); +u16 GetEPDblBuf0Count(u8 /*bEpNum*/); +u16 GetEPDblBuf1Count(u8 /*bEpNum*/); +EP_DBUF_DIR GetEPDblBufDir(u8 /*bEpNum*/); +void FreeUserBuffer(u8 bEpNum/*bEpNum*/, u8 bDir); +u16 ToWord(u8, u8); +u16 ByteSwap(u16); + +#if defined(__cplusplus) +} +#endif + +#endif /* __USB_REGS_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_type.h b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_type.h index 11067862..34b3bf5b 100644 --- a/Libmaple/libmaple/libmaple/usb/usb_lib/usb_type.h +++ b/Libmaple/libmaple/libmaple/usb/usb_lib/usb_type.h @@ -1,77 +1,77 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_type.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Type definitions used by the USB Library -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_TYPE_H -#define __USB_TYPE_H - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -#ifndef NULL -#define NULL ((void *)0) -#endif - -typedef signed long s32; -typedef signed short s16; -typedef signed char s8; - -typedef volatile signed long vs32; -typedef volatile signed short vs16; -typedef volatile signed char vs8; - -typedef unsigned long u32; -typedef unsigned short u16; -typedef unsigned char u8; - -typedef unsigned long const uc32; /* Read Only */ -typedef unsigned short const uc16; /* Read Only */ -typedef unsigned char const uc8; /* Read Only */ - -typedef volatile unsigned long vu32; -typedef volatile unsigned short vu16; -typedef volatile unsigned char vu8; - -typedef volatile unsigned long const vuc32; /* Read Only */ -typedef volatile unsigned short const vuc16; /* Read Only */ -typedef volatile unsigned char const vuc8; /* Read Only */ - - -typedef enum -{ - FALSE = 0, TRUE = !FALSE -} -USB_Bool; - -typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus; - -typedef enum { DISABLE = 0, ENABLE = !DISABLE} FunctionalState; - -typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus; - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -/* External variables --------------------------------------------------------*/ - -#if defined(__cplusplus) -} -#endif - -#endif /* __USB_TYPE_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_type.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Type definitions used by the USB Library +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_TYPE_H +#define __USB_TYPE_H + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +#ifndef NULL +#define NULL ((void *)0) +#endif + +typedef signed long s32; +typedef signed short s16; +typedef signed char s8; + +typedef volatile signed long vs32; +typedef volatile signed short vs16; +typedef volatile signed char vs8; + +typedef unsigned long u32; +typedef unsigned short u16; +typedef unsigned char u8; + +typedef unsigned long const uc32; /* Read Only */ +typedef unsigned short const uc16; /* Read Only */ +typedef unsigned char const uc8; /* Read Only */ + +typedef volatile unsigned long vu32; +typedef volatile unsigned short vu16; +typedef volatile unsigned char vu8; + +typedef volatile unsigned long const vuc32; /* Read Only */ +typedef volatile unsigned short const vuc16; /* Read Only */ +typedef volatile unsigned char const vuc8; /* Read Only */ + + +typedef enum +{ + FALSE = 0, TRUE = !FALSE +} +USB_Bool; + +typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus; + +typedef enum { DISABLE = 0, ENABLE = !DISABLE} FunctionalState; + +typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* External variables --------------------------------------------------------*/ + +#if defined(__cplusplus) +} +#endif + +#endif /* __USB_TYPE_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h index 6892c1d8..f58ff060 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h @@ -1,158 +1,158 @@ -/** - ****************************************************************************** - * @file usbd_audio_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_audio_core.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_AUDIO_CORE_H_ -#define __USB_AUDIO_CORE_H_ - -#include "usbd_ioreq.h" -#include "usbd_req.h" -#include "usbd_desc.h" - - - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup usbd_audio - * @brief This file is the Header file for USBD_audio.c - * @{ - */ - - -/** @defgroup usbd_audio_Exported_Defines - * @{ - */ - -/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */ -#define AUDIO_OUT_PACKET (uint32_t)(((USBD_AUDIO_FREQ * 2 * 2) /1000)) - -/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure - that it is an even number and higher than 3 */ -#define OUT_PACKET_NUM 4 -/* Total size of the audio transfer buffer */ -#define TOTAL_OUT_BUF_SIZE ((uint32_t)(AUDIO_OUT_PACKET * OUT_PACKET_NUM)) - -#define AUDIO_CONFIG_DESC_SIZE 109 -#define AUDIO_INTERFACE_DESC_SIZE 9 -#define USB_AUDIO_DESC_SIZ 0x09 -#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09 -#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07 - -#define AUDIO_DESCRIPTOR_TYPE 0x21 -#define USB_DEVICE_CLASS_AUDIO 0x01 -#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01 -#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 -#define AUDIO_PROTOCOL_UNDEFINED 0x00 -#define AUDIO_STREAMING_GENERAL 0x01 -#define AUDIO_STREAMING_FORMAT_TYPE 0x02 - -/* Audio Descriptor Types */ -#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24 -#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25 - -/* Audio Control Interface Descriptor Subtypes */ -#define AUDIO_CONTROL_HEADER 0x01 -#define AUDIO_CONTROL_INPUT_TERMINAL 0x02 -#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03 -#define AUDIO_CONTROL_FEATURE_UNIT 0x06 - -#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C -#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09 -#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07 - -#define AUDIO_CONTROL_MUTE 0x0001 - -#define AUDIO_FORMAT_TYPE_I 0x01 -#define AUDIO_FORMAT_TYPE_III 0x03 - -#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 -#define AUDIO_ENDPOINT_GENERAL 0x01 - -#define AUDIO_REQ_GET_CUR 0x81 -#define AUDIO_REQ_SET_CUR 0x01 - -#define AUDIO_OUT_STREAMING_CTRL 0x02 - -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ -typedef struct _Audio_Fops -{ - uint8_t (*Init) (uint32_t AudioFreq, uint32_t Volume, uint32_t options); - uint8_t (*DeInit) (uint32_t options); - uint8_t (*AudioCmd) (uint8_t* pbuf, uint32_t size, uint8_t cmd); - uint8_t (*VolumeCtl) (uint8_t vol); - uint8_t (*MuteCtl) (uint8_t cmd); - uint8_t (*PeriodicTC) (uint8_t cmd); - uint8_t (*GetState) (void); -}AUDIO_FOPS_TypeDef; -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ -#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \ - (uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF) -#define SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -extern USBD_Class_cb_TypeDef AUDIO_cb; - -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Functions - * @{ - */ -/** - * @} - */ - -#endif // __USB_AUDIO_CORE_H_ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_audio_core.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header file for the usbd_audio_core.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#ifndef __USB_AUDIO_CORE_H_ +#define __USB_AUDIO_CORE_H_ + +#include "usbd_ioreq.h" +#include "usbd_req.h" +#include "usbd_desc.h" + + + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_audio + * @brief This file is the Header file for USBD_audio.c + * @{ + */ + + +/** @defgroup usbd_audio_Exported_Defines + * @{ + */ + +/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */ +#define AUDIO_OUT_PACKET (uint32_t)(((USBD_AUDIO_FREQ * 2 * 2) /1000)) + +/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure + that it is an even number and higher than 3 */ +#define OUT_PACKET_NUM 4 +/* Total size of the audio transfer buffer */ +#define TOTAL_OUT_BUF_SIZE ((uint32_t)(AUDIO_OUT_PACKET * OUT_PACKET_NUM)) + +#define AUDIO_CONFIG_DESC_SIZE 109 +#define AUDIO_INTERFACE_DESC_SIZE 9 +#define USB_AUDIO_DESC_SIZ 0x09 +#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09 +#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07 + +#define AUDIO_DESCRIPTOR_TYPE 0x21 +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01 +#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 +#define AUDIO_PROTOCOL_UNDEFINED 0x00 +#define AUDIO_STREAMING_GENERAL 0x01 +#define AUDIO_STREAMING_FORMAT_TYPE 0x02 + +/* Audio Descriptor Types */ +#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24 +#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25 + +/* Audio Control Interface Descriptor Subtypes */ +#define AUDIO_CONTROL_HEADER 0x01 +#define AUDIO_CONTROL_INPUT_TERMINAL 0x02 +#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03 +#define AUDIO_CONTROL_FEATURE_UNIT 0x06 + +#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C +#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09 +#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07 + +#define AUDIO_CONTROL_MUTE 0x0001 + +#define AUDIO_FORMAT_TYPE_I 0x01 +#define AUDIO_FORMAT_TYPE_III 0x03 + +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define AUDIO_ENDPOINT_GENERAL 0x01 + +#define AUDIO_REQ_GET_CUR 0x81 +#define AUDIO_REQ_SET_CUR 0x01 + +#define AUDIO_OUT_STREAMING_CTRL 0x02 + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ +typedef struct _Audio_Fops +{ + uint8_t (*Init) (uint32_t AudioFreq, uint32_t Volume, uint32_t options); + uint8_t (*DeInit) (uint32_t options); + uint8_t (*AudioCmd) (uint8_t* pbuf, uint32_t size, uint8_t cmd); + uint8_t (*VolumeCtl) (uint8_t vol); + uint8_t (*MuteCtl) (uint8_t cmd); + uint8_t (*PeriodicTC) (uint8_t cmd); + uint8_t (*GetState) (void); +}AUDIO_FOPS_TypeDef; +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ +#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \ + (uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF) +#define SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_Class_cb_TypeDef AUDIO_cb; + +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +/** + * @} + */ + +#endif // __USB_AUDIO_CORE_H_ +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h index 36db4155..a6b53fa8 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h @@ -1,117 +1,117 @@ -/** - ****************************************************************************** - * @file usbd_audio_out_if.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_audio_out_if.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_AUDIO_OUT_IF_H_ -#define __USB_AUDIO_OUT_IF_H_ - -#ifdef STM32F2XX - #include "stm322xg_usb_audio_codec.h" -#elif defined(STM32F10X_CL) - #include "stm3210c_usb_audio_codec.h" -#endif /* STM32F2XX */ - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup usbd_audio - * @brief This file is the Header file for USBD_audio.c - * @{ - */ - - -/** @defgroup usbd_audio_Exported_Defines - * @{ - */ -/* Audio Commands enmueration */ -typedef enum -{ - AUDIO_CMD_PLAY = 1, - AUDIO_CMD_PAUSE, - AUDIO_CMD_STOP, -}AUDIO_CMD_TypeDef; - -/* Mute commands */ -#define AUDIO_MUTE 0x01 -#define AUDIO_UNMUTE 0x00 - -/* Functions return value */ -#define AUDIO_OK 0x00 -#define AUDIO_FAIL 0xFF - -/* Audio Machine States */ -#define AUDIO_STATE_INACTIVE 0x00 -#define AUDIO_STATE_ACTIVE 0x01 -#define AUDIO_STATE_PLAYING 0x02 -#define AUDIO_STATE_PAUSED 0x03 -#define AUDIO_STATE_STOPPED 0x04 -#define AUDIO_STATE_ERROR 0x05 - -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -extern AUDIO_FOPS_TypeDef AUDIO_OUT_fops; - -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Functions - * @{ - */ -/** - * @} - */ - -#endif /* __USB_AUDIO_OUT_IF_H_ */ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_audio_out_if.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header file for the usbd_audio_out_if.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#ifndef __USB_AUDIO_OUT_IF_H_ +#define __USB_AUDIO_OUT_IF_H_ + +#ifdef STM32F2XX + #include "stm322xg_usb_audio_codec.h" +#elif defined(STM32F10X_CL) + #include "stm3210c_usb_audio_codec.h" +#endif /* STM32F2XX */ + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_audio + * @brief This file is the Header file for USBD_audio.c + * @{ + */ + + +/** @defgroup usbd_audio_Exported_Defines + * @{ + */ +/* Audio Commands enmueration */ +typedef enum +{ + AUDIO_CMD_PLAY = 1, + AUDIO_CMD_PAUSE, + AUDIO_CMD_STOP, +}AUDIO_CMD_TypeDef; + +/* Mute commands */ +#define AUDIO_MUTE 0x01 +#define AUDIO_UNMUTE 0x00 + +/* Functions return value */ +#define AUDIO_OK 0x00 +#define AUDIO_FAIL 0xFF + +/* Audio Machine States */ +#define AUDIO_STATE_INACTIVE 0x00 +#define AUDIO_STATE_ACTIVE 0x01 +#define AUDIO_STATE_PLAYING 0x02 +#define AUDIO_STATE_PAUSED 0x03 +#define AUDIO_STATE_STOPPED 0x04 +#define AUDIO_STATE_ERROR 0x05 + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern AUDIO_FOPS_TypeDef AUDIO_OUT_fops; + +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +/** + * @} + */ + +#endif /* __USB_AUDIO_OUT_IF_H_ */ +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c index 6b73d295..b26f574a 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c @@ -1,665 +1,665 @@ -/** - ****************************************************************************** - * @file usbd_audio_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the high layer firmware functions to manage the - * following functionalities of the USB Audio Class: - * - Initialization and Configuration of high and low layer - * - Enumeration as Audio Streaming Device - * - Audio Streaming data transfer - * - AudioControl requests management - * - Error management - * - * @verbatim - * - * =================================================================== - * Audio Class Driver Description - * =================================================================== - * This driver manages the Audio Class 1.0 following the "USB Device Class Definition for - * Audio Devices V1.0 Mar 18, 98". - * This driver implements the following aspects of the specification: - * - Device descriptor management - * - Configuration descriptor management - * - Standard AC Interface Descriptor management - * - 1 Audio Streaming Interface (with single channel, PCM, Stereo mode) - * - 1 Audio Streaming Endpoint - * - 1 Audio Terminal Input (1 channel) - * - Audio Class-Specific AC Interfaces - * - Audio Class-Specific AS Interfaces - * - AudioControl Requests: only SET_CUR and GET_CUR requests are supported (for Mute) - * - Audio Feature Unit (limited to Mute control) - * - Audio Synchronization type: Asynchronous - * - Single fixed audio sampling rate (configurable in usbd_conf.h file) - * - * @note - * The Audio Class 1.0 is based on USB Specification 1.0 and thus supports only - * Low and Full speed modes and does not allow High Speed transfers. - * Please refer to "USB Device Class Definition for Audio Devices V1.0 Mar 18, 98" - * for more details. - * - * These aspects may be enriched or modified for a specific user application. - * - * This driver doesn't implement the following aspects of the specification - * (but it is possible to manage these features with some modifications on this driver): - * - AudioControl Endpoint management - * - AudioControl requsests other than SET_CUR and GET_CUR - * - Abstraction layer for AudioControl requests (only Mute functionality is managed) - * - Audio Synchronization type: Adaptive - * - Audio Compression modules and interfaces - * - MIDI interfaces and modules - * - Mixer/Selector/Processing/Extension Units (Feature unit is limited to Mute control) - * - Any other application-specific modules - * - Multiple and Variable audio sampling rates - * - Out Streaming Endpoint/Interface (microphone) - * - * @endverbatim - * - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#include "usbd_audio_core.h" -#include "usbd_audio_out_if.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup usbd_audio - * @brief usbd core module - * @{ - */ - -/** @defgroup usbd_audio_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_Private_FunctionPrototypes - * @{ - */ - -/********************************************* - AUDIO Device library callbacks - *********************************************/ -static uint8_t usbd_audio_Init (void *pdev, uint8_t cfgidx); -static uint8_t usbd_audio_DeInit (void *pdev, uint8_t cfgidx); -static uint8_t usbd_audio_Setup (void *pdev, USB_SETUP_REQ *req); -static uint8_t usbd_audio_EP0_RxReady(void *pdev); -static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum); -static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum); -static uint8_t usbd_audio_SOF (void *pdev); -static uint8_t usbd_audio_OUT_Incplt (void *pdev); - -/********************************************* - AUDIO Requests management functions - *********************************************/ -static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req); -static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req); -static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length); -/** - * @} - */ - -/** @defgroup usbd_audio_Private_Variables - * @{ - */ -/* Main Buffer for Audio Data Out transfers and its relative pointers */ -uint8_t IsocOutBuff [TOTAL_OUT_BUF_SIZE * 2]; -uint8_t* IsocOutWrPtr = IsocOutBuff; -uint8_t* IsocOutRdPtr = IsocOutBuff; - -/* Main Buffer for Audio Control Rrequests transfers and its relative variables */ -uint8_t AudioCtl[64]; -uint8_t AudioCtlCmd = 0; -uint32_t AudioCtlLen = 0; -uint8_t AudioCtlUnit = 0; - -static uint32_t PlayFlag = 0; - -static __IO uint32_t usbd_audio_AltSet = 0; -static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE]; - -/* AUDIO interface class callbacks structure */ -USBD_Class_cb_TypeDef AUDIO_cb = -{ - usbd_audio_Init, - usbd_audio_DeInit, - usbd_audio_Setup, - NULL, /* EP0_TxSent */ - usbd_audio_EP0_RxReady, - usbd_audio_DataIn, - usbd_audio_DataOut, - usbd_audio_SOF, - NULL, - usbd_audio_OUT_Incplt, - USBD_audio_GetCfgDesc, -#ifdef USB_OTG_HS_CORE - USBD_audio_GetCfgDesc, /* use same config as per FS */ -#endif -}; - -/* USB AUDIO device Configuration Descriptor */ -static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] = -{ - /* Configuration 1 */ - 0x09, /* bLength */ - USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ - LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength 109 bytes*/ - HIBYTE(AUDIO_CONFIG_DESC_SIZE), - 0x02, /* bNumInterfaces */ - 0x01, /* bConfigurationValue */ - 0x00, /* iConfiguration */ - 0xC0, /* bmAttributes BUS Powred*/ - 0x32, /* bMaxPower = 100 mA*/ - /* 09 byte*/ - - /* USB Speaker Standard interface descriptor */ - AUDIO_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x00, /* bInterfaceNumber */ - 0x00, /* bAlternateSetting */ - 0x00, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - /* 09 byte*/ - - /* USB Speaker Class-specific AC Interface Descriptor */ - AUDIO_INTERFACE_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */ - 0x00, /* 1.00 */ /* bcdADC */ - 0x01, - 0x27, /* wTotalLength = 39*/ - 0x00, - 0x01, /* bInCollection */ - 0x01, /* baInterfaceNr */ - /* 09 byte*/ - - /* USB Speaker Input Terminal Descriptor */ - AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */ - 0x01, /* bTerminalID */ - 0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */ - 0x01, - 0x00, /* bAssocTerminal */ - 0x01, /* bNrChannels */ - 0x00, /* wChannelConfig 0x0000 Mono */ - 0x00, - 0x00, /* iChannelNames */ - 0x00, /* iTerminal */ - /* 12 byte*/ - - /* USB Speaker Audio Feature Unit Descriptor */ - 0x09, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */ - AUDIO_OUT_STREAMING_CTRL, /* bUnitID */ - 0x01, /* bSourceID */ - 0x01, /* bControlSize */ - AUDIO_CONTROL_MUTE, /* bmaControls(0) */ - 0x00, /* bmaControls(1) */ - 0x00, /* iTerminal */ - /* 09 byte*/ - - /*USB Speaker Output Terminal Descriptor */ - 0x09, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */ - 0x03, /* bTerminalID */ - 0x01, /* wTerminalType 0x0301*/ - 0x03, - 0x00, /* bAssocTerminal */ - 0x02, /* bSourceID */ - 0x00, /* iTerminal */ - /* 09 byte*/ - - /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */ - /* Interface 1, Alternate Setting 0 */ - AUDIO_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x01, /* bInterfaceNumber */ - 0x00, /* bAlternateSetting */ - 0x00, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - /* 09 byte*/ - - /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */ - /* Interface 1, Alternate Setting 1 */ - AUDIO_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x01, /* bInterfaceNumber */ - 0x01, /* bAlternateSetting */ - 0x01, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - /* 09 byte*/ - - /* USB Speaker Audio Streaming Interface Descriptor */ - AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ - 0x01, /* bTerminalLink */ - 0x01, /* bDelay */ - 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/ - 0x00, - /* 07 byte*/ - - /* USB Speaker Audio Type III Format Interface Descriptor */ - 0x0B, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ - AUDIO_FORMAT_TYPE_III, /* bFormatType */ - 0x02, /* bNrChannels */ - 0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */ - 16, /* bBitResolution (16-bits per sample) */ - 0x01, /* bSamFreqType only one frequency supported */ - SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */ - /* 11 byte*/ - - /* Endpoint 1 - Standard Descriptor */ - AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/ - USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */ - AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */ - 0x01, /* bInterval */ - 0x00, /* bRefresh */ - 0x00, /* bSynchAddress */ - /* 09 byte*/ - - /* Endpoint - Audio Streaming Descriptor*/ - AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */ - AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ - 0x00, /* bmAttributes */ - 0x00, /* bLockDelayUnits */ - 0x00, /* wLockDelay */ - 0x00, - /* 07 byte*/ -} ; - -/** - * @} - */ - -/** @defgroup usbd_audio_Private_Functions - * @{ - */ - -/** -* @brief usbd_audio_Init -* Initilaizes the AUDIO interface. -* @param pdev: device instance -* @param cfgidx: Configuration index -* @retval status -*/ -static uint8_t usbd_audio_Init (void *pdev, - uint8_t cfgidx) -{ - /* Open EP OUT */ - DCD_EP_Open(pdev, - AUDIO_OUT_EP, - AUDIO_OUT_PACKET, - USB_OTG_EP_ISOC); - - /* Initialize the Audio output Hardware layer */ - if (AUDIO_OUT_fops.Init(USBD_AUDIO_FREQ, DEFAULT_VOLUME, 0) != USBD_OK) - { - return USBD_FAIL; - } - - /* Prepare Out endpoint to receive audio data */ - DCD_EP_PrepareRx(pdev, - AUDIO_OUT_EP, - (uint8_t*)IsocOutBuff, - AUDIO_OUT_PACKET); - - return USBD_OK; -} - -/** -* @brief usbd_audio_Init -* DeInitializes the AUDIO layer. -* @param pdev: device instance -* @param cfgidx: Configuration index -* @retval status -*/ -static uint8_t usbd_audio_DeInit (void *pdev, - uint8_t cfgidx) -{ - DCD_EP_Close (pdev , AUDIO_OUT_EP); - - /* DeInitialize the Audio output Hardware layer */ - if (AUDIO_OUT_fops.DeInit(0) != USBD_OK) - { - return USBD_FAIL; - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_Setup - * Handles the Audio control request parsing. - * @param pdev: instance - * @param req: usb requests - * @retval status - */ -static uint8_t usbd_audio_Setup (void *pdev, - USB_SETUP_REQ *req) -{ - uint16_t len; - uint8_t *pbuf; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - /* AUDIO Class Requests -------------------------------*/ - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case AUDIO_REQ_GET_CUR: - AUDIO_Req_GetCurrent(pdev, req); - break; - - case AUDIO_REQ_SET_CUR: - AUDIO_Req_SetCurrent(pdev, req); - break; - - default: - USBD_CtlError (pdev, req); - return USBD_FAIL; - } - break; - - /* Standard Requests -------------------------------*/ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if( (req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE) - { -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - pbuf = usbd_audio_Desc; -#else - pbuf = usbd_audio_CfgDesc + 18; -#endif - len = MIN(USB_AUDIO_DESC_SIZ , req->wLength); - } - - USBD_CtlSendData (pdev, - pbuf, - len); - break; - - case USB_REQ_GET_INTERFACE : - USBD_CtlSendData (pdev, - (uint8_t *)&usbd_audio_AltSet, - 1); - break; - - case USB_REQ_SET_INTERFACE : - if ((uint8_t)(req->wValue) < AUDIO_TOTAL_IF_NUM) - { - usbd_audio_AltSet = (uint8_t)(req->wValue); - } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - break; - } - } - return USBD_OK; -} - -/** - * @brief usbd_audio_EP0_RxReady - * Handles audio control requests data. - * @param pdev: device device instance - * @retval status - */ -static uint8_t usbd_audio_EP0_RxReady (void *pdev) -{ - /* Check if an AudioControl request has been issued */ - if (AudioCtlCmd == AUDIO_REQ_SET_CUR) - {/* In this driver, to simplify code, only SET_CUR request is managed */ - /* Check for which addressed unit the AudioControl request has been issued */ - if (AudioCtlUnit == AUDIO_OUT_STREAMING_CTRL) - {/* In this driver, to simplify code, only one unit is manage */ - /* Call the audio interface mute function */ - AUDIO_OUT_fops.MuteCtl(AudioCtl[0]); - - /* Reset the AudioCtlCmd variable to prevent re-entering this function */ - AudioCtlCmd = 0; - AudioCtlLen = 0; - } - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_DataIn - * Handles the audio IN data stage. - * @param pdev: instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum) -{ - return USBD_OK; -} - -/** - * @brief usbd_audio_DataOut - * Handles the Audio Out data stage. - * @param pdev: instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum) -{ - if (epnum == AUDIO_OUT_EP) - { - /* Increment the Buffer pointer or roll it back when all buffers are full */ - if (IsocOutWrPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM))) - {/* All buffers are full: roll back */ - IsocOutWrPtr = IsocOutBuff; - } - else - {/* Increment the buffer pointer */ - IsocOutWrPtr += AUDIO_OUT_PACKET; - } - - /* Toggle the frame index */ - ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame = - (((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame)? 0:1; - - /* Prepare Out endpoint to receive next audio packet */ - DCD_EP_PrepareRx(pdev, - AUDIO_OUT_EP, - (uint8_t*)(IsocOutWrPtr), - AUDIO_OUT_PACKET); - - /* Trigger the start of streaming only when half buffer is full */ - if ((PlayFlag == 0) && (IsocOutWrPtr >= (IsocOutBuff + ((AUDIO_OUT_PACKET * OUT_PACKET_NUM) / 2)))) - { - /* Enable start of Streaming */ - PlayFlag = 1; - } - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_SOF - * Handles the SOF event (data buffer update and synchronization). - * @param pdev: instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_audio_SOF (void *pdev) -{ - /* Check if there are available data in stream buffer. - In this function, a single variable (PlayFlag) is used to avoid software delays. - The play operation must be executed as soon as possible after the SOF detection. */ - if (PlayFlag) - { - /* Start playing received packet */ - AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutRdPtr), /* Samples buffer pointer */ - AUDIO_OUT_PACKET, /* Number of samples in Bytes */ - AUDIO_CMD_PLAY); /* Command to be processed */ - - /* Increment the Buffer pointer or roll it back when all buffers all full */ - if (IsocOutRdPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM))) - {/* Roll back to the start of buffer */ - IsocOutRdPtr = IsocOutBuff; - } - else - {/* Increment to the next sub-buffer */ - IsocOutRdPtr += AUDIO_OUT_PACKET; - } - - /* If all available buffers have been consumed, stop playing */ - if (IsocOutRdPtr == IsocOutWrPtr) - { - /* Pause the audio stream */ - AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutBuff), /* Samples buffer pointer */ - AUDIO_OUT_PACKET, /* Number of samples in Bytes */ - AUDIO_CMD_PAUSE); /* Command to be processed */ - - /* Stop entering play loop */ - PlayFlag = 0; - - /* Reset buffer pointers */ - IsocOutRdPtr = IsocOutBuff; - IsocOutWrPtr = IsocOutBuff; - } - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_OUT_Incplt - * Handles the iso out incomplete event. - * @param pdev: instance - * @retval status - */ -static uint8_t usbd_audio_OUT_Incplt (void *pdev) -{ - return USBD_OK; -} - -/****************************************************************************** - AUDIO Class requests management -******************************************************************************/ -/** - * @brief AUDIO_Req_GetCurrent - * Handles the GET_CUR Audio control request. - * @param pdev: instance - * @param req: setup class request - * @retval status - */ -static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req) -{ - /* Send the current mute state */ - USBD_CtlSendData (pdev, - AudioCtl, - req->wLength); -} - -/** - * @brief AUDIO_Req_SetCurrent - * Handles the SET_CUR Audio control request. - * @param pdev: instance - * @param req: setup class request - * @retval status - */ -static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req) -{ - if (req->wLength) - { - /* Prepare the reception of the buffer over EP0 */ - USBD_CtlPrepareRx (pdev, - AudioCtl, - req->wLength); - - /* Set the global variables indicating current request and its length - to the function usbd_audio_EP0_RxReady() which will process the request */ - AudioCtlCmd = AUDIO_REQ_SET_CUR; /* Set the request value */ - AudioCtlLen = req->wLength; /* Set the request data length */ - AudioCtlUnit = HIBYTE(req->wIndex); /* Set the request target unit */ - } -} - -/** - * @brief USBD_audio_GetCfgDesc - * Returns configuration descriptor. - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (usbd_audio_CfgDesc); - return usbd_audio_CfgDesc; -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_audio_core.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB Audio Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as Audio Streaming Device + * - Audio Streaming data transfer + * - AudioControl requests management + * - Error management + * + * @verbatim + * + * =================================================================== + * Audio Class Driver Description + * =================================================================== + * This driver manages the Audio Class 1.0 following the "USB Device Class Definition for + * Audio Devices V1.0 Mar 18, 98". + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Standard AC Interface Descriptor management + * - 1 Audio Streaming Interface (with single channel, PCM, Stereo mode) + * - 1 Audio Streaming Endpoint + * - 1 Audio Terminal Input (1 channel) + * - Audio Class-Specific AC Interfaces + * - Audio Class-Specific AS Interfaces + * - AudioControl Requests: only SET_CUR and GET_CUR requests are supported (for Mute) + * - Audio Feature Unit (limited to Mute control) + * - Audio Synchronization type: Asynchronous + * - Single fixed audio sampling rate (configurable in usbd_conf.h file) + * + * @note + * The Audio Class 1.0 is based on USB Specification 1.0 and thus supports only + * Low and Full speed modes and does not allow High Speed transfers. + * Please refer to "USB Device Class Definition for Audio Devices V1.0 Mar 18, 98" + * for more details. + * + * These aspects may be enriched or modified for a specific user application. + * + * This driver doesn't implement the following aspects of the specification + * (but it is possible to manage these features with some modifications on this driver): + * - AudioControl Endpoint management + * - AudioControl requsests other than SET_CUR and GET_CUR + * - Abstraction layer for AudioControl requests (only Mute functionality is managed) + * - Audio Synchronization type: Adaptive + * - Audio Compression modules and interfaces + * - MIDI interfaces and modules + * - Mixer/Selector/Processing/Extension Units (Feature unit is limited to Mute control) + * - Any other application-specific modules + * - Multiple and Variable audio sampling rates + * - Out Streaming Endpoint/Interface (microphone) + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#include "usbd_audio_core.h" +#include "usbd_audio_out_if.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup usbd_audio + * @brief usbd core module + * @{ + */ + +/** @defgroup usbd_audio_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_audio_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_audio_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_audio_Private_FunctionPrototypes + * @{ + */ + +/********************************************* + AUDIO Device library callbacks + *********************************************/ +static uint8_t usbd_audio_Init (void *pdev, uint8_t cfgidx); +static uint8_t usbd_audio_DeInit (void *pdev, uint8_t cfgidx); +static uint8_t usbd_audio_Setup (void *pdev, USB_SETUP_REQ *req); +static uint8_t usbd_audio_EP0_RxReady(void *pdev); +static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum); +static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum); +static uint8_t usbd_audio_SOF (void *pdev); +static uint8_t usbd_audio_OUT_Incplt (void *pdev); + +/********************************************* + AUDIO Requests management functions + *********************************************/ +static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req); +static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req); +static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length); +/** + * @} + */ + +/** @defgroup usbd_audio_Private_Variables + * @{ + */ +/* Main Buffer for Audio Data Out transfers and its relative pointers */ +uint8_t IsocOutBuff [TOTAL_OUT_BUF_SIZE * 2]; +uint8_t* IsocOutWrPtr = IsocOutBuff; +uint8_t* IsocOutRdPtr = IsocOutBuff; + +/* Main Buffer for Audio Control Rrequests transfers and its relative variables */ +uint8_t AudioCtl[64]; +uint8_t AudioCtlCmd = 0; +uint32_t AudioCtlLen = 0; +uint8_t AudioCtlUnit = 0; + +static uint32_t PlayFlag = 0; + +static __IO uint32_t usbd_audio_AltSet = 0; +static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE]; + +/* AUDIO interface class callbacks structure */ +USBD_Class_cb_TypeDef AUDIO_cb = +{ + usbd_audio_Init, + usbd_audio_DeInit, + usbd_audio_Setup, + NULL, /* EP0_TxSent */ + usbd_audio_EP0_RxReady, + usbd_audio_DataIn, + usbd_audio_DataOut, + usbd_audio_SOF, + NULL, + usbd_audio_OUT_Incplt, + USBD_audio_GetCfgDesc, +#ifdef USB_OTG_HS_CORE + USBD_audio_GetCfgDesc, /* use same config as per FS */ +#endif +}; + +/* USB AUDIO device Configuration Descriptor */ +static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] = +{ + /* Configuration 1 */ + 0x09, /* bLength */ + USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ + LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength 109 bytes*/ + HIBYTE(AUDIO_CONFIG_DESC_SIZE), + 0x02, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x00, /* iConfiguration */ + 0xC0, /* bmAttributes BUS Powred*/ + 0x32, /* bMaxPower = 100 mA*/ + /* 09 byte*/ + + /* USB Speaker Standard interface descriptor */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x00, /* bNumEndpoints */ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ + AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + /* 09 byte*/ + + /* USB Speaker Class-specific AC Interface Descriptor */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */ + 0x00, /* 1.00 */ /* bcdADC */ + 0x01, + 0x27, /* wTotalLength = 39*/ + 0x00, + 0x01, /* bInCollection */ + 0x01, /* baInterfaceNr */ + /* 09 byte*/ + + /* USB Speaker Input Terminal Descriptor */ + AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */ + 0x01, /* bTerminalID */ + 0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */ + 0x01, + 0x00, /* bAssocTerminal */ + 0x01, /* bNrChannels */ + 0x00, /* wChannelConfig 0x0000 Mono */ + 0x00, + 0x00, /* iChannelNames */ + 0x00, /* iTerminal */ + /* 12 byte*/ + + /* USB Speaker Audio Feature Unit Descriptor */ + 0x09, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */ + AUDIO_OUT_STREAMING_CTRL, /* bUnitID */ + 0x01, /* bSourceID */ + 0x01, /* bControlSize */ + AUDIO_CONTROL_MUTE, /* bmaControls(0) */ + 0x00, /* bmaControls(1) */ + 0x00, /* iTerminal */ + /* 09 byte*/ + + /*USB Speaker Output Terminal Descriptor */ + 0x09, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */ + 0x03, /* bTerminalID */ + 0x01, /* wTerminalType 0x0301*/ + 0x03, + 0x00, /* bAssocTerminal */ + 0x02, /* bSourceID */ + 0x00, /* iTerminal */ + /* 09 byte*/ + + /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */ + /* Interface 1, Alternate Setting 0 */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + 0x01, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x00, /* bNumEndpoints */ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ + AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + /* 09 byte*/ + + /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */ + /* Interface 1, Alternate Setting 1 */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + 0x01, /* bInterfaceNumber */ + 0x01, /* bAlternateSetting */ + 0x01, /* bNumEndpoints */ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ + AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + /* 09 byte*/ + + /* USB Speaker Audio Streaming Interface Descriptor */ + AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ + 0x01, /* bTerminalLink */ + 0x01, /* bDelay */ + 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/ + 0x00, + /* 07 byte*/ + + /* USB Speaker Audio Type III Format Interface Descriptor */ + 0x0B, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ + AUDIO_FORMAT_TYPE_III, /* bFormatType */ + 0x02, /* bNrChannels */ + 0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */ + 16, /* bBitResolution (16-bits per sample) */ + 0x01, /* bSamFreqType only one frequency supported */ + SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */ + /* 11 byte*/ + + /* Endpoint 1 - Standard Descriptor */ + AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/ + USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */ + AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */ + 0x01, /* bInterval */ + 0x00, /* bRefresh */ + 0x00, /* bSynchAddress */ + /* 09 byte*/ + + /* Endpoint - Audio Streaming Descriptor*/ + AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */ + AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ + 0x00, /* bmAttributes */ + 0x00, /* bLockDelayUnits */ + 0x00, /* wLockDelay */ + 0x00, + /* 07 byte*/ +} ; + +/** + * @} + */ + +/** @defgroup usbd_audio_Private_Functions + * @{ + */ + +/** +* @brief usbd_audio_Init +* Initilaizes the AUDIO interface. +* @param pdev: device instance +* @param cfgidx: Configuration index +* @retval status +*/ +static uint8_t usbd_audio_Init (void *pdev, + uint8_t cfgidx) +{ + /* Open EP OUT */ + DCD_EP_Open(pdev, + AUDIO_OUT_EP, + AUDIO_OUT_PACKET, + USB_OTG_EP_ISOC); + + /* Initialize the Audio output Hardware layer */ + if (AUDIO_OUT_fops.Init(USBD_AUDIO_FREQ, DEFAULT_VOLUME, 0) != USBD_OK) + { + return USBD_FAIL; + } + + /* Prepare Out endpoint to receive audio data */ + DCD_EP_PrepareRx(pdev, + AUDIO_OUT_EP, + (uint8_t*)IsocOutBuff, + AUDIO_OUT_PACKET); + + return USBD_OK; +} + +/** +* @brief usbd_audio_Init +* DeInitializes the AUDIO layer. +* @param pdev: device instance +* @param cfgidx: Configuration index +* @retval status +*/ +static uint8_t usbd_audio_DeInit (void *pdev, + uint8_t cfgidx) +{ + DCD_EP_Close (pdev , AUDIO_OUT_EP); + + /* DeInitialize the Audio output Hardware layer */ + if (AUDIO_OUT_fops.DeInit(0) != USBD_OK) + { + return USBD_FAIL; + } + + return USBD_OK; +} + +/** + * @brief usbd_audio_Setup + * Handles the Audio control request parsing. + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t usbd_audio_Setup (void *pdev, + USB_SETUP_REQ *req) +{ + uint16_t len; + uint8_t *pbuf; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + /* AUDIO Class Requests -------------------------------*/ + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + case AUDIO_REQ_GET_CUR: + AUDIO_Req_GetCurrent(pdev, req); + break; + + case AUDIO_REQ_SET_CUR: + AUDIO_Req_SetCurrent(pdev, req); + break; + + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + } + break; + + /* Standard Requests -------------------------------*/ + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( (req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE) + { +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + pbuf = usbd_audio_Desc; +#else + pbuf = usbd_audio_CfgDesc + 18; +#endif + len = MIN(USB_AUDIO_DESC_SIZ , req->wLength); + } + + USBD_CtlSendData (pdev, + pbuf, + len); + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&usbd_audio_AltSet, + 1); + break; + + case USB_REQ_SET_INTERFACE : + if ((uint8_t)(req->wValue) < AUDIO_TOTAL_IF_NUM) + { + usbd_audio_AltSet = (uint8_t)(req->wValue); + } + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + break; + } + } + return USBD_OK; +} + +/** + * @brief usbd_audio_EP0_RxReady + * Handles audio control requests data. + * @param pdev: device device instance + * @retval status + */ +static uint8_t usbd_audio_EP0_RxReady (void *pdev) +{ + /* Check if an AudioControl request has been issued */ + if (AudioCtlCmd == AUDIO_REQ_SET_CUR) + {/* In this driver, to simplify code, only SET_CUR request is managed */ + /* Check for which addressed unit the AudioControl request has been issued */ + if (AudioCtlUnit == AUDIO_OUT_STREAMING_CTRL) + {/* In this driver, to simplify code, only one unit is manage */ + /* Call the audio interface mute function */ + AUDIO_OUT_fops.MuteCtl(AudioCtl[0]); + + /* Reset the AudioCtlCmd variable to prevent re-entering this function */ + AudioCtlCmd = 0; + AudioCtlLen = 0; + } + } + + return USBD_OK; +} + +/** + * @brief usbd_audio_DataIn + * Handles the audio IN data stage. + * @param pdev: instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum) +{ + return USBD_OK; +} + +/** + * @brief usbd_audio_DataOut + * Handles the Audio Out data stage. + * @param pdev: instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum) +{ + if (epnum == AUDIO_OUT_EP) + { + /* Increment the Buffer pointer or roll it back when all buffers are full */ + if (IsocOutWrPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM))) + {/* All buffers are full: roll back */ + IsocOutWrPtr = IsocOutBuff; + } + else + {/* Increment the buffer pointer */ + IsocOutWrPtr += AUDIO_OUT_PACKET; + } + + /* Toggle the frame index */ + ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame = + (((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame)? 0:1; + + /* Prepare Out endpoint to receive next audio packet */ + DCD_EP_PrepareRx(pdev, + AUDIO_OUT_EP, + (uint8_t*)(IsocOutWrPtr), + AUDIO_OUT_PACKET); + + /* Trigger the start of streaming only when half buffer is full */ + if ((PlayFlag == 0) && (IsocOutWrPtr >= (IsocOutBuff + ((AUDIO_OUT_PACKET * OUT_PACKET_NUM) / 2)))) + { + /* Enable start of Streaming */ + PlayFlag = 1; + } + } + + return USBD_OK; +} + +/** + * @brief usbd_audio_SOF + * Handles the SOF event (data buffer update and synchronization). + * @param pdev: instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t usbd_audio_SOF (void *pdev) +{ + /* Check if there are available data in stream buffer. + In this function, a single variable (PlayFlag) is used to avoid software delays. + The play operation must be executed as soon as possible after the SOF detection. */ + if (PlayFlag) + { + /* Start playing received packet */ + AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutRdPtr), /* Samples buffer pointer */ + AUDIO_OUT_PACKET, /* Number of samples in Bytes */ + AUDIO_CMD_PLAY); /* Command to be processed */ + + /* Increment the Buffer pointer or roll it back when all buffers all full */ + if (IsocOutRdPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM))) + {/* Roll back to the start of buffer */ + IsocOutRdPtr = IsocOutBuff; + } + else + {/* Increment to the next sub-buffer */ + IsocOutRdPtr += AUDIO_OUT_PACKET; + } + + /* If all available buffers have been consumed, stop playing */ + if (IsocOutRdPtr == IsocOutWrPtr) + { + /* Pause the audio stream */ + AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutBuff), /* Samples buffer pointer */ + AUDIO_OUT_PACKET, /* Number of samples in Bytes */ + AUDIO_CMD_PAUSE); /* Command to be processed */ + + /* Stop entering play loop */ + PlayFlag = 0; + + /* Reset buffer pointers */ + IsocOutRdPtr = IsocOutBuff; + IsocOutWrPtr = IsocOutBuff; + } + } + + return USBD_OK; +} + +/** + * @brief usbd_audio_OUT_Incplt + * Handles the iso out incomplete event. + * @param pdev: instance + * @retval status + */ +static uint8_t usbd_audio_OUT_Incplt (void *pdev) +{ + return USBD_OK; +} + +/****************************************************************************** + AUDIO Class requests management +******************************************************************************/ +/** + * @brief AUDIO_Req_GetCurrent + * Handles the GET_CUR Audio control request. + * @param pdev: instance + * @param req: setup class request + * @retval status + */ +static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req) +{ + /* Send the current mute state */ + USBD_CtlSendData (pdev, + AudioCtl, + req->wLength); +} + +/** + * @brief AUDIO_Req_SetCurrent + * Handles the SET_CUR Audio control request. + * @param pdev: instance + * @param req: setup class request + * @retval status + */ +static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req) +{ + if (req->wLength) + { + /* Prepare the reception of the buffer over EP0 */ + USBD_CtlPrepareRx (pdev, + AudioCtl, + req->wLength); + + /* Set the global variables indicating current request and its length + to the function usbd_audio_EP0_RxReady() which will process the request */ + AudioCtlCmd = AUDIO_REQ_SET_CUR; /* Set the request value */ + AudioCtlLen = req->wLength; /* Set the request data length */ + AudioCtlUnit = HIBYTE(req->wIndex); /* Set the request target unit */ + } +} + +/** + * @brief USBD_audio_GetCfgDesc + * Returns configuration descriptor. + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length) +{ + *length = sizeof (usbd_audio_CfgDesc); + return usbd_audio_CfgDesc; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c index 37bff57d..21d98394 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c @@ -1,318 +1,318 @@ -/** - ****************************************************************************** - * @file usbd_audio_out_if.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the Audio Out (palyback) interface API. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_audio_core.h" -#include "usbd_audio_out_if.h" - - - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup usbd_audio_out_if - * @brief usbd out interface module - * @{ - */ - -/** @defgroup usbd_audio_out_if_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_out_if_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_out_if_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_out_if_Private_FunctionPrototypes - * @{ - */ -static uint8_t Init (uint32_t AudioFreq, uint32_t Volume, uint32_t options); -static uint8_t DeInit (uint32_t options); -static uint8_t AudioCmd (uint8_t* pbuf, uint32_t size, uint8_t cmd); -static uint8_t VolumeCtl (uint8_t vol); -static uint8_t MuteCtl (uint8_t cmd); -static uint8_t PeriodicTC (uint8_t cmd); -static uint8_t GetState (void); - -/** - * @} - */ - -/** @defgroup usbd_audio_out_if_Private_Variables - * @{ - */ -AUDIO_FOPS_TypeDef AUDIO_OUT_fops = -{ - Init, - DeInit, - AudioCmd, - VolumeCtl, - MuteCtl, - PeriodicTC, - GetState -}; - -static uint8_t AudioState = AUDIO_STATE_INACTIVE; - -/** - * @} - */ - -/** @defgroup usbd_audio_out_if_Private_Functions - * @{ - */ - -/** - * @brief Init - * Initialize and configures all required resources for audio play function. - * @param AudioFreq: Statrtup audio frequency. - * @param Volume: Startup volume to be set. - * @param options: specific options passed to low layer function. - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t Init (uint32_t AudioFreq, - uint32_t Volume, - uint32_t options) -{ - static uint32_t Initialized = 0; - - /* Check if the low layer has already been initialized */ - if (Initialized == 0) - { - /* Call low layer function */ - if (EVAL_AUDIO_Init(OUTPUT_DEVICE_AUTO, Volume, AudioFreq) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - - /* Set the Initialization flag to prevent reinitializing the interface again */ - Initialized = 1; - } - - /* Update the Audio state machine */ - AudioState = AUDIO_STATE_ACTIVE; - - return AUDIO_OK; -} - -/** - * @brief DeInit - * Free all resources used by low layer and stops audio-play function. - * @param options: options passed to low layer function. - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t DeInit (uint32_t options) -{ - /* Update the Audio state machine */ - AudioState = AUDIO_STATE_INACTIVE; - - return AUDIO_OK; -} - -/** - * @brief AudioCmd - * Play, Stop, Pause or Resume current file. - * @param pbuf: address from which file shoud be played. - * @param size: size of the current buffer/file. - * @param cmd: command to be executed, can be AUDIO_CMD_PLAY , AUDIO_CMD_PAUSE, - * AUDIO_CMD_RESUME or AUDIO_CMD_STOP. - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t AudioCmd(uint8_t* pbuf, - uint32_t size, - uint8_t cmd) -{ - /* Check the current state */ - if ((AudioState == AUDIO_STATE_INACTIVE) || (AudioState == AUDIO_STATE_ERROR)) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - - switch (cmd) - { - /* Process the PLAY command ----------------------------*/ - case AUDIO_CMD_PLAY: - /* If current state is Active or Stopped */ - if ((AudioState == AUDIO_STATE_ACTIVE) || \ - (AudioState == AUDIO_STATE_STOPPED) || \ - (AudioState == AUDIO_STATE_PLAYING)) - { - Audio_MAL_Play((uint32_t)pbuf, (size/2)); - AudioState = AUDIO_STATE_PLAYING; - return AUDIO_OK; - } - /* If current state is Paused */ - else if (AudioState == AUDIO_STATE_PAUSED) - { - if (EVAL_AUDIO_PauseResume(AUDIO_RESUME, (uint32_t)pbuf, (size/2)) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - else - { - AudioState = AUDIO_STATE_PLAYING; - return AUDIO_OK; - } - } - else /* Not allowed command */ - { - return AUDIO_FAIL; - } - - /* Process the STOP command ----------------------------*/ - case AUDIO_CMD_STOP: - if (AudioState != AUDIO_STATE_PLAYING) - { - /* Unsupported command */ - return AUDIO_FAIL; - } - else if (EVAL_AUDIO_Stop(CODEC_PDWN_SW) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - else - { - AudioState = AUDIO_STATE_STOPPED; - return AUDIO_OK; - } - - /* Process the PAUSE command ---------------------------*/ - case AUDIO_CMD_PAUSE: - if (AudioState != AUDIO_STATE_PLAYING) - { - /* Unsupported command */ - return AUDIO_FAIL; - } - else if (EVAL_AUDIO_PauseResume(AUDIO_PAUSE, (uint32_t)pbuf, (size/2)) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - else - { - AudioState = AUDIO_STATE_PAUSED; - return AUDIO_OK; - } - - /* Unsupported command ---------------------------------*/ - default: - return AUDIO_FAIL; - } -} - -/** - * @brief VolumeCtl - * Set the volume level in % - * @param vol: volume level to be set in % (from 0% to 100%) - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t VolumeCtl (uint8_t vol) -{ - /* Call low layer volume setting function */ - if (EVAL_AUDIO_VolumeCtl(vol) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - - return AUDIO_OK; -} - -/** - * @brief MuteCtl - * Mute or Unmute the audio current output - * @param cmd: can be 0 to unmute, or 1 to mute. - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t MuteCtl (uint8_t cmd) -{ - /* Call low layer mute setting function */ - if (EVAL_AUDIO_Mute(cmd) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - - return AUDIO_OK; -} - -/** - * @brief - * - * @param - * @param - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t PeriodicTC (uint8_t cmd) -{ - - - return AUDIO_OK; -} - - -/** - * @brief GetState - * Return the current state of the audio machine - * @param None - * @retval Current State. - */ -static uint8_t GetState (void) -{ - return AudioState; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_audio_out_if.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides the Audio Out (palyback) interface API. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_audio_core.h" +#include "usbd_audio_out_if.h" + + + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup usbd_audio_out_if + * @brief usbd out interface module + * @{ + */ + +/** @defgroup usbd_audio_out_if_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_audio_out_if_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_audio_out_if_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_audio_out_if_Private_FunctionPrototypes + * @{ + */ +static uint8_t Init (uint32_t AudioFreq, uint32_t Volume, uint32_t options); +static uint8_t DeInit (uint32_t options); +static uint8_t AudioCmd (uint8_t* pbuf, uint32_t size, uint8_t cmd); +static uint8_t VolumeCtl (uint8_t vol); +static uint8_t MuteCtl (uint8_t cmd); +static uint8_t PeriodicTC (uint8_t cmd); +static uint8_t GetState (void); + +/** + * @} + */ + +/** @defgroup usbd_audio_out_if_Private_Variables + * @{ + */ +AUDIO_FOPS_TypeDef AUDIO_OUT_fops = +{ + Init, + DeInit, + AudioCmd, + VolumeCtl, + MuteCtl, + PeriodicTC, + GetState +}; + +static uint8_t AudioState = AUDIO_STATE_INACTIVE; + +/** + * @} + */ + +/** @defgroup usbd_audio_out_if_Private_Functions + * @{ + */ + +/** + * @brief Init + * Initialize and configures all required resources for audio play function. + * @param AudioFreq: Statrtup audio frequency. + * @param Volume: Startup volume to be set. + * @param options: specific options passed to low layer function. + * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. + */ +static uint8_t Init (uint32_t AudioFreq, + uint32_t Volume, + uint32_t options) +{ + static uint32_t Initialized = 0; + + /* Check if the low layer has already been initialized */ + if (Initialized == 0) + { + /* Call low layer function */ + if (EVAL_AUDIO_Init(OUTPUT_DEVICE_AUTO, Volume, AudioFreq) != 0) + { + AudioState = AUDIO_STATE_ERROR; + return AUDIO_FAIL; + } + + /* Set the Initialization flag to prevent reinitializing the interface again */ + Initialized = 1; + } + + /* Update the Audio state machine */ + AudioState = AUDIO_STATE_ACTIVE; + + return AUDIO_OK; +} + +/** + * @brief DeInit + * Free all resources used by low layer and stops audio-play function. + * @param options: options passed to low layer function. + * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. + */ +static uint8_t DeInit (uint32_t options) +{ + /* Update the Audio state machine */ + AudioState = AUDIO_STATE_INACTIVE; + + return AUDIO_OK; +} + +/** + * @brief AudioCmd + * Play, Stop, Pause or Resume current file. + * @param pbuf: address from which file shoud be played. + * @param size: size of the current buffer/file. + * @param cmd: command to be executed, can be AUDIO_CMD_PLAY , AUDIO_CMD_PAUSE, + * AUDIO_CMD_RESUME or AUDIO_CMD_STOP. + * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. + */ +static uint8_t AudioCmd(uint8_t* pbuf, + uint32_t size, + uint8_t cmd) +{ + /* Check the current state */ + if ((AudioState == AUDIO_STATE_INACTIVE) || (AudioState == AUDIO_STATE_ERROR)) + { + AudioState = AUDIO_STATE_ERROR; + return AUDIO_FAIL; + } + + switch (cmd) + { + /* Process the PLAY command ----------------------------*/ + case AUDIO_CMD_PLAY: + /* If current state is Active or Stopped */ + if ((AudioState == AUDIO_STATE_ACTIVE) || \ + (AudioState == AUDIO_STATE_STOPPED) || \ + (AudioState == AUDIO_STATE_PLAYING)) + { + Audio_MAL_Play((uint32_t)pbuf, (size/2)); + AudioState = AUDIO_STATE_PLAYING; + return AUDIO_OK; + } + /* If current state is Paused */ + else if (AudioState == AUDIO_STATE_PAUSED) + { + if (EVAL_AUDIO_PauseResume(AUDIO_RESUME, (uint32_t)pbuf, (size/2)) != 0) + { + AudioState = AUDIO_STATE_ERROR; + return AUDIO_FAIL; + } + else + { + AudioState = AUDIO_STATE_PLAYING; + return AUDIO_OK; + } + } + else /* Not allowed command */ + { + return AUDIO_FAIL; + } + + /* Process the STOP command ----------------------------*/ + case AUDIO_CMD_STOP: + if (AudioState != AUDIO_STATE_PLAYING) + { + /* Unsupported command */ + return AUDIO_FAIL; + } + else if (EVAL_AUDIO_Stop(CODEC_PDWN_SW) != 0) + { + AudioState = AUDIO_STATE_ERROR; + return AUDIO_FAIL; + } + else + { + AudioState = AUDIO_STATE_STOPPED; + return AUDIO_OK; + } + + /* Process the PAUSE command ---------------------------*/ + case AUDIO_CMD_PAUSE: + if (AudioState != AUDIO_STATE_PLAYING) + { + /* Unsupported command */ + return AUDIO_FAIL; + } + else if (EVAL_AUDIO_PauseResume(AUDIO_PAUSE, (uint32_t)pbuf, (size/2)) != 0) + { + AudioState = AUDIO_STATE_ERROR; + return AUDIO_FAIL; + } + else + { + AudioState = AUDIO_STATE_PAUSED; + return AUDIO_OK; + } + + /* Unsupported command ---------------------------------*/ + default: + return AUDIO_FAIL; + } +} + +/** + * @brief VolumeCtl + * Set the volume level in % + * @param vol: volume level to be set in % (from 0% to 100%) + * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. + */ +static uint8_t VolumeCtl (uint8_t vol) +{ + /* Call low layer volume setting function */ + if (EVAL_AUDIO_VolumeCtl(vol) != 0) + { + AudioState = AUDIO_STATE_ERROR; + return AUDIO_FAIL; + } + + return AUDIO_OK; +} + +/** + * @brief MuteCtl + * Mute or Unmute the audio current output + * @param cmd: can be 0 to unmute, or 1 to mute. + * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. + */ +static uint8_t MuteCtl (uint8_t cmd) +{ + /* Call low layer mute setting function */ + if (EVAL_AUDIO_Mute(cmd) != 0) + { + AudioState = AUDIO_STATE_ERROR; + return AUDIO_FAIL; + } + + return AUDIO_OK; +} + +/** + * @brief + * + * @param + * @param + * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. + */ +static uint8_t PeriodicTC (uint8_t cmd) +{ + + + return AUDIO_OK; +} + + +/** + * @brief GetState + * Return the current state of the audio machine + * @param None + * @retval Current State. + */ +static uint8_t GetState (void) +{ + return AudioState; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h index af352d88..926f42e1 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h @@ -1,137 +1,137 @@ -/** - ****************************************************************************** - * @file usbd_cdc_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_cdc_core.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_CDC_CORE_H_ -#define __USB_CDC_CORE_H_ - -#include "usbd_ioreq.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup usbd_cdc - * @brief This file is the Header file for USBD_cdc.c - * @{ - */ - - -/** @defgroup usbd_cdc_Exported_Defines - * @{ - */ -#define USB_CDC_CONFIG_DESC_SIZ (67) -#define USB_CDC_DESC_SIZ (67-9) - -#define CDC_DESCRIPTOR_TYPE 0x21 - -#define DEVICE_CLASS_CDC 0x02 -#define DEVICE_SUBCLASS_CDC 0x00 - - -#define USB_DEVICE_DESCRIPTOR_TYPE 0x01 -#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02 -#define USB_STRING_DESCRIPTOR_TYPE 0x03 -#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04 -#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05 - -#define STANDARD_ENDPOINT_DESC_SIZE 0x09 - -#define CDC_DATA_IN_PACKET_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 57) - -#define CDC_DATA_OUT_PACKET_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 64) - -/*---------------------------------------------------------------------*/ -/* CDC definitions */ -/*---------------------------------------------------------------------*/ - -/**************************************************/ -/* CDC Requests */ -/**************************************************/ -#define SEND_ENCAPSULATED_COMMAND 0x00 -#define GET_ENCAPSULATED_RESPONSE 0x01 -#define SET_COMM_FEATURE 0x02 -#define GET_COMM_FEATURE 0x03 -#define CLEAR_COMM_FEATURE 0x04 -#define SET_LINE_CODING 0x20 -#define GET_LINE_CODING 0x21 -#define SET_CONTROL_LINE_STATE 0x22 -#define SEND_BREAK 0x23 -#define NO_CMD 0xFF - -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ -typedef struct _CDC_IF_PROP -{ - uint16_t (*pIf_Init) (void); - uint16_t (*pIf_DeInit) (void); - uint16_t (*pIf_Ctrl) (uint32_t Cmd, uint8_t* Buf, uint32_t Len); - uint16_t (*pIf_DataTx) (uint8_t* Buf, uint32_t Len); - uint16_t (*pIf_DataRx) (uint8_t* Buf, uint32_t Len); -} -CDC_IF_Prop_TypeDef; -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -extern USBD_Class_cb_TypeDef USBD_CDC_cb; -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Functions - * @{ - */ -/** - * @} - */ - -#endif // __USB_CDC_CORE_H_ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_cdc_core.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header file for the usbd_cdc_core.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#ifndef __USB_CDC_CORE_H_ +#define __USB_CDC_CORE_H_ + +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_cdc + * @brief This file is the Header file for USBD_cdc.c + * @{ + */ + + +/** @defgroup usbd_cdc_Exported_Defines + * @{ + */ +#define USB_CDC_CONFIG_DESC_SIZ (67) +#define USB_CDC_DESC_SIZ (67-9) + +#define CDC_DESCRIPTOR_TYPE 0x21 + +#define DEVICE_CLASS_CDC 0x02 +#define DEVICE_SUBCLASS_CDC 0x00 + + +#define USB_DEVICE_DESCRIPTOR_TYPE 0x01 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02 +#define USB_STRING_DESCRIPTOR_TYPE 0x03 +#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05 + +#define STANDARD_ENDPOINT_DESC_SIZE 0x09 + +#define CDC_DATA_IN_PACKET_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 57) + +#define CDC_DATA_OUT_PACKET_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 64) + +/*---------------------------------------------------------------------*/ +/* CDC definitions */ +/*---------------------------------------------------------------------*/ + +/**************************************************/ +/* CDC Requests */ +/**************************************************/ +#define SEND_ENCAPSULATED_COMMAND 0x00 +#define GET_ENCAPSULATED_RESPONSE 0x01 +#define SET_COMM_FEATURE 0x02 +#define GET_COMM_FEATURE 0x03 +#define CLEAR_COMM_FEATURE 0x04 +#define SET_LINE_CODING 0x20 +#define GET_LINE_CODING 0x21 +#define SET_CONTROL_LINE_STATE 0x22 +#define SEND_BREAK 0x23 +#define NO_CMD 0xFF + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ +typedef struct _CDC_IF_PROP +{ + uint16_t (*pIf_Init) (void); + uint16_t (*pIf_DeInit) (void); + uint16_t (*pIf_Ctrl) (uint32_t Cmd, uint8_t* Buf, uint32_t Len); + uint16_t (*pIf_DataTx) (uint8_t* Buf, uint32_t Len); + uint16_t (*pIf_DataRx) (uint8_t* Buf, uint32_t Len); +} +CDC_IF_Prop_TypeDef; +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_Class_cb_TypeDef USBD_CDC_cb; +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +/** + * @} + */ + +#endif // __USB_CDC_CORE_H_ +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h index f272f6d2..1a12508e 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h @@ -1,45 +1,45 @@ -/** - ****************************************************************************** - * @file usbd_cdc_if_template.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header for dfu_mal.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CDC_IF_TEMPLATE_H -#define __USBD_CDC_IF_TEMPLATE_H - -/* Includes ------------------------------------------------------------------*/ -#ifdef STM32F2XX - #include "stm32f2xx.h" -#elif defined(STM32F10X_CL) - #include "stm32f10x.h" -#endif /* STM32F2XX */ - -#include "usbd_conf.h" -#include "usbd_cdc_core.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -extern CDC_IF_Prop_TypeDef TEMPLATE_fops; - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -#endif /* __USBD_CDC_IF_TEMPLATE_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_cdc_if_template.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Header for dfu_mal.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CDC_IF_TEMPLATE_H +#define __USBD_CDC_IF_TEMPLATE_H + +/* Includes ------------------------------------------------------------------*/ +#ifdef STM32F2XX + #include "stm32f2xx.h" +#elif defined(STM32F10X_CL) + #include "stm32f10x.h" +#endif /* STM32F2XX */ + +#include "usbd_conf.h" +#include "usbd_cdc_core.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +extern CDC_IF_Prop_TypeDef TEMPLATE_fops; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +#endif /* __USBD_CDC_IF_TEMPLATE_H */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c index 49d6800b..aac6776c 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c @@ -1,869 +1,869 @@ -/** - ****************************************************************************** - * @file usbd_cdc_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the high layer firmware functions to manage the - * following functionalities of the USB CDC Class: - * - Initialization and Configuration of high and low layer - * - Enumeration as CDC Device (and enumeration for each implemented memory interface) - * - OUT/IN data transfer - * - Command IN transfer (class requests management) - * - Error management - * - * @verbatim - * - * =================================================================== - * CDC Class Driver Description - * =================================================================== - * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices - * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus - * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007" - * This driver implements the following aspects of the specification: - * - Device descriptor management - * - Configuration descriptor management - * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN) - * - Requests management (as described in section 6.2 in specification) - * - Abstract Control Model compliant - * - Union Functional collection (using 1 IN endpoint for control) - * - Data interface class - - * @note - * For the Abstract Control Model, this core allows only transmitting the requests to - * lower layer dispatcher (ie. usbd_cdc_vcp.c/.h) which should manage each request and - * perform relative actions. - * - * These aspects may be enriched or modified for a specific user application. - * - * This driver doesn't implement the following aspects of the specification - * (but it is possible to manage these features with some modifications on this driver): - * - Any class-specific aspect relative to communication classes should be managed by user application. - * - All communication classes other than PSTN are not managed - * - * @endverbatim - * - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_cdc_core.h" -#include "usbd_desc.h" -#include "usbd_req.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup usbd_cdc - * @brief usbd core module - * @{ - */ - -/** @defgroup usbd_cdc_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_cdc_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_cdc_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_cdc_Private_FunctionPrototypes - * @{ - */ - -/********************************************* - CDC Device library callbacks - *********************************************/ -static uint8_t usbd_cdc_Init (void *pdev, uint8_t cfgidx); -static uint8_t usbd_cdc_DeInit (void *pdev, uint8_t cfgidx); -static uint8_t usbd_cdc_Setup (void *pdev, USB_SETUP_REQ *req); -static uint8_t usbd_cdc_EP0_RxReady (void *pdev); -static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum); -static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum); -static uint8_t usbd_cdc_SOF (void *pdev); - -/********************************************* - CDC specific management functions - *********************************************/ -static void Handle_USBAsynchXfer (void *pdev); -static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length); -#ifdef USE_USB_OTG_HS -static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length); -#endif -/** - * @} - */ - -/** @defgroup usbd_cdc_Private_Variables - * @{ - */ -extern CDC_IF_Prop_TypeDef APP_FOPS; -extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC]; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static __IO uint32_t usbd_cdc_AltSet __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t USB_Rx_Buffer [CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE] __ALIGN_END ; - - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ; - -volatile int APP_Rx_ptr_in = 0; -volatile int APP_Rx_ptr_out = 0; -uint32_t APP_Rx_length = 0; - -uint8_t USB_Tx_State = 0; - -static uint32_t cdcCmd = 0xFF; -static uint32_t cdcLen = 0; - -/* CDC interface class callbacks structure */ -USBD_Class_cb_TypeDef USBD_CDC_cb = -{ - usbd_cdc_Init, - usbd_cdc_DeInit, - usbd_cdc_Setup, - NULL, /* EP0_TxSent, */ - usbd_cdc_EP0_RxReady, - usbd_cdc_DataIn, - usbd_cdc_DataOut, - usbd_cdc_SOF, - NULL, - NULL, - USBD_cdc_GetCfgDesc, -#ifdef USE_USB_OTG_HS - USBD_cdc_GetOtherCfgDesc, /* use same cobfig as per FS */ -#endif /* USE_USB_OTG_HS */ -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - /*Configuration Descriptor*/ - 0x09, /* bLength: Configuration Descriptor size */ - USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ - USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ - 0x00, - 0x02, /* bNumInterfaces: 2 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ - - /*---------------------------------------------------------------------------*/ - - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ - /* Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass: Abstract Control Model */ - 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ - - /*Header Functional Descriptor*/ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ - 0x01, - - /*Call Management Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ - - /*ACM Functional Descriptor*/ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ - - /*Union Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union func desc */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /*Endpoint 2 Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */ - HIBYTE(CDC_CMD_PACKET_SZE), -#ifdef USE_USB_OTG_HS - 0x10, /* bInterval: */ -#else - 0xFF, /* bInterval: */ -#endif /* USE_USB_OTG_HS */ - - /*---------------------------------------------------------------------------*/ - - /*Data class interface descriptor*/ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ - - /*Endpoint OUT Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_DATA_MAX_PACKET_SIZE), - 0x00, /* bInterval: ignore for Bulk transfer */ - - /*Endpoint IN Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_DATA_MAX_PACKET_SIZE), - 0x00 /* bInterval: ignore for Bulk transfer */ -} ; - -#ifdef USE_USB_OTG_HS -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, - USB_CDC_CONFIG_DESC_SIZ, - 0x00, - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ - - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ - /* Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass: Abstract Control Model */ - 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ - - /*Header Functional Descriptor*/ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ - 0x01, - - /*Call Management Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ - - /*ACM Functional Descriptor*/ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ - - /*Union Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union func desc */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /*Endpoint 2 Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */ - HIBYTE(CDC_CMD_PACKET_SZE), - 0xFF, /* bInterval: */ - - /*---------------------------------------------------------------------------*/ - - /*Data class interface descriptor*/ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ - - /*Endpoint OUT Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ - 0x00, - 0x00, /* bInterval: ignore for Bulk transfer */ - - /*Endpoint IN Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ - 0x00, - 0x00 /* bInterval */ -}; -#endif /* USE_USB_OTG_HS */ - -/** - * @} - */ - -/** @defgroup usbd_cdc_Private_Functions - * @{ - */ - -/** - * @brief usbd_cdc_Init - * Initilaize the CDC interface - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t usbd_cdc_Init (void *pdev, - uint8_t cfgidx) -{ - uint8_t *pbuf; - - /* Open EP IN */ - DCD_EP_Open(pdev, - CDC_IN_EP, - CDC_DATA_IN_PACKET_SIZE, - USB_OTG_EP_BULK); - - /* Open EP OUT */ - DCD_EP_Open(pdev, - CDC_OUT_EP, - CDC_DATA_OUT_PACKET_SIZE, - USB_OTG_EP_BULK); - - /* Open Command IN EP */ - DCD_EP_Open(pdev, - CDC_CMD_EP, - CDC_CMD_PACKET_SZE, - USB_OTG_EP_INT); - - pbuf = (uint8_t *)USBD_DeviceDesc; - pbuf[4] = DEVICE_CLASS_CDC; - pbuf[5] = DEVICE_SUBCLASS_CDC; - - /* Initialize the Interface physical components */ - APP_FOPS.pIf_Init(); - - /* Prepare Out endpoint to receive next packet */ - DCD_EP_PrepareRx(pdev, - CDC_OUT_EP, - (uint8_t*)(USB_Rx_Buffer), - CDC_DATA_OUT_PACKET_SIZE); - - return USBD_OK; -} - -/** - * @brief usbd_cdc_Init - * DeInitialize the CDC layer - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t usbd_cdc_DeInit (void *pdev, - uint8_t cfgidx) -{ - /* Open EP IN */ - DCD_EP_Close(pdev, - CDC_IN_EP); - - /* Open EP OUT */ - DCD_EP_Close(pdev, - CDC_OUT_EP); - - /* Open Command IN EP */ - DCD_EP_Close(pdev, - CDC_CMD_EP); - - /* Restore default state of the Interface physical components */ - APP_FOPS.pIf_DeInit(); - - return USBD_OK; -} - -/** - * @brief usbd_cdc_Setup - * Handle the CDC specific requests - * @param pdev: instance - * @param req: usb requests - * @retval status - */ -static uint8_t usbd_cdc_Setup (void *pdev, - USB_SETUP_REQ *req) -{ - uint16_t len; - uint8_t *pbuf; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - /* CDC Class Requests -------------------------------*/ - case USB_REQ_TYPE_CLASS : - /* Check if the request is a data setup packet */ - if (req->wLength) - { - /* Check if the request is Device-to-Host */ - if (req->bmRequest & 0x80) - { - /* Get the data to be sent to Host from interface layer */ - APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength); - - /* Send the data to the host */ - USBD_CtlSendData (pdev, - CmdBuff, - req->wLength); - } - else /* Host-to-Device requeset */ - { - /* Set the value of the current command to be processed */ - cdcCmd = req->bRequest; - cdcLen = req->wLength; - - /* Prepare the reception of the buffer over EP0 - Next step: the received data will be managed in usbd_cdc_EP0_TxSent() - function. */ - USBD_CtlPrepareRx (pdev, - CmdBuff, - req->wLength); - } - } - else /* No Data request */ - { - /* Transfer the command to the interface layer */ - APP_FOPS.pIf_Ctrl(req->bRequest, (uint8_t*)&req->wValue, sizeof(req->wValue)); - } - - return USBD_OK; - - default: - USBD_CtlError (pdev, req); - return USBD_FAIL; - - - - /* Standard Requests -------------------------------*/ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE) - { -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - pbuf = usbd_cdc_Desc; -#else - pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM); -#endif - len = MIN(USB_CDC_DESC_SIZ , req->wLength); - - USBD_CtlSendData (pdev, - pbuf, - len); - } - break; - - case USB_REQ_GET_INTERFACE : - USBD_CtlSendData (pdev, - (uint8_t *)&usbd_cdc_AltSet, - 1); - break; - - case USB_REQ_SET_INTERFACE : - if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM) - { - usbd_cdc_AltSet = (uint8_t)(req->wValue); - } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - break; - } - } - return USBD_OK; -} - -/** - * @brief usbd_cdc_EP0_RxReady - * Data received on control endpoint - * @param pdev: device device instance - * @retval status - */ -static uint8_t usbd_cdc_EP0_RxReady (void *pdev) -{ - if (cdcCmd != NO_CMD) - { - /* Process the data */ - APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen); - - /* Reset the command variable to default value */ - cdcCmd = NO_CMD; - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_DataIn - * Data sent on non-control IN endpoint - * @param pdev: device instance - * @param epnum: endpoint number - * @retval status - */ -#if 0 -static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum) -{ - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if (USB_Tx_State == 1) - { - if (APP_Rx_length == 0) - { - USB_Tx_State = 0; - } - else - { - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){ - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - } - - /* Prepare the available data buffer to be sent on IN endpoint */ - DCD_EP_Tx (pdev, - CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], - USB_Tx_length); - } - } - - return USBD_OK; -} -#endif - -// ala42: applied fix from -//https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2f -//STe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fUSB%20CDC%20Device%20hung%20fix& -//FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=75 -static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum) -{ - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if (USB_Tx_State == 1) - { - if (APP_Rx_length == 0) - { - if (((USB_OTG_CORE_HANDLE*)pdev)->dev.in_ep[epnum].xfer_len != CDC_DATA_IN_PACKET_SIZE) - { - USB_Tx_State = 0; - return USBD_OK; - } - /* Transmit zero sized packet in case the last one has maximum allowed size. Otherwise - * the recipient may expect more data coming soon and not return buffered data to app. - * See section 5.8.3 Bulk Transfer Packet Size Constraints - * of the USB Specification document. - */ - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = 0; - } - else - { - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){ - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - } - } - - /* Prepare the available data buffer to be sent on IN endpoint */ - DCD_EP_Tx (pdev, - CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], - USB_Tx_length); - } - - return USBD_OK; -} - - -/** - * @brief usbd_audio_DataOut - * Data received on non-control Out endpoint - * @param pdev: device instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum) -{ - uint16_t USB_Rx_Cnt; - - /* Get the received data buffer and update the counter */ - USB_Rx_Cnt = ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count; - - /* USB data will be immediately processed, this allow next USB traffic being - NAKed till the end of the application Xfer */ - APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt); - - /* Prepare Out endpoint to receive next packet */ - DCD_EP_PrepareRx(pdev, - CDC_OUT_EP, - (uint8_t*)(USB_Rx_Buffer), - CDC_DATA_OUT_PACKET_SIZE); - - return USBD_OK; -} - -/** - * @brief usbd_audio_SOF - * Start Of Frame event management - * @param pdev: instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_cdc_SOF (void *pdev) -{ - static uint32_t FrameCount = 0; - - if (FrameCount++ == CDC_IN_FRAME_INTERVAL) - { - /* Reset the frame counter */ - FrameCount = 0; - - /* Check the data to be sent through IN pipe */ - Handle_USBAsynchXfer(pdev); - } - - return USBD_OK; -} - -/** - * @brief Handle_USBAsynchXfer - * Send data to USB - * @param pdev: instance - * @retval None - */ -static void Handle_USBAsynchXfer (void *pdev) -{ - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if(USB_Tx_State != 1) - { - if (APP_Rx_ptr_out == APP_RX_DATA_SIZE) - { - APP_Rx_ptr_out = 0; - } - - if(APP_Rx_ptr_out == APP_Rx_ptr_in) - { - USB_Tx_State = 0; - return; - } - - if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */ - { - APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out; - - } - else - { - APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out; - - } -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - APP_Rx_length &= ~0x03; -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE) - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - } - USB_Tx_State = 1; - - DCD_EP_Tx (pdev, - CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], - USB_Tx_length); - } - -} - -/** - * @brief USBD_cdc_GetCfgDesc - * Return configuration descriptor - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (usbd_cdc_CfgDesc); - return usbd_cdc_CfgDesc; -} - -/** - * @brief USBD_cdc_GetCfgDesc - * Return configuration descriptor - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -#ifdef USE_USB_OTG_HS -static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (usbd_cdc_OtherCfgDesc); - return usbd_cdc_OtherCfgDesc; -} -#endif -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_cdc_core.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB CDC Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as CDC Device (and enumeration for each implemented memory interface) + * - OUT/IN data transfer + * - Command IN transfer (class requests management) + * - Error management + * + * @verbatim + * + * =================================================================== + * CDC Class Driver Description + * =================================================================== + * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices + * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus + * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007" + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN) + * - Requests management (as described in section 6.2 in specification) + * - Abstract Control Model compliant + * - Union Functional collection (using 1 IN endpoint for control) + * - Data interface class + + * @note + * For the Abstract Control Model, this core allows only transmitting the requests to + * lower layer dispatcher (ie. usbd_cdc_vcp.c/.h) which should manage each request and + * perform relative actions. + * + * These aspects may be enriched or modified for a specific user application. + * + * This driver doesn't implement the following aspects of the specification + * (but it is possible to manage these features with some modifications on this driver): + * - Any class-specific aspect relative to communication classes should be managed by user application. + * - All communication classes other than PSTN are not managed + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc_core.h" +#include "usbd_desc.h" +#include "usbd_req.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup usbd_cdc + * @brief usbd core module + * @{ + */ + +/** @defgroup usbd_cdc_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_cdc_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_cdc_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_cdc_Private_FunctionPrototypes + * @{ + */ + +/********************************************* + CDC Device library callbacks + *********************************************/ +static uint8_t usbd_cdc_Init (void *pdev, uint8_t cfgidx); +static uint8_t usbd_cdc_DeInit (void *pdev, uint8_t cfgidx); +static uint8_t usbd_cdc_Setup (void *pdev, USB_SETUP_REQ *req); +static uint8_t usbd_cdc_EP0_RxReady (void *pdev); +static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum); +static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum); +static uint8_t usbd_cdc_SOF (void *pdev); + +/********************************************* + CDC specific management functions + *********************************************/ +static void Handle_USBAsynchXfer (void *pdev); +static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length); +#ifdef USE_USB_OTG_HS +static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length); +#endif +/** + * @} + */ + +/** @defgroup usbd_cdc_Private_Variables + * @{ + */ +extern CDC_IF_Prop_TypeDef APP_FOPS; +extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC]; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN static __IO uint32_t usbd_cdc_AltSet __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t USB_Rx_Buffer [CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE] __ALIGN_END ; + + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ; + +volatile int APP_Rx_ptr_in = 0; +volatile int APP_Rx_ptr_out = 0; +uint32_t APP_Rx_length = 0; + +uint8_t USB_Tx_State = 0; + +static uint32_t cdcCmd = 0xFF; +static uint32_t cdcLen = 0; + +/* CDC interface class callbacks structure */ +USBD_Class_cb_TypeDef USBD_CDC_cb = +{ + usbd_cdc_Init, + usbd_cdc_DeInit, + usbd_cdc_Setup, + NULL, /* EP0_TxSent, */ + usbd_cdc_EP0_RxReady, + usbd_cdc_DataIn, + usbd_cdc_DataOut, + usbd_cdc_SOF, + NULL, + NULL, + USBD_cdc_GetCfgDesc, +#ifdef USE_USB_OTG_HS + USBD_cdc_GetOtherCfgDesc, /* use same cobfig as per FS */ +#endif /* USE_USB_OTG_HS */ +}; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +/* USB CDC device Configuration Descriptor */ +__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + /*Configuration Descriptor*/ + 0x09, /* bLength: Configuration Descriptor size */ + USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ + USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + 0x00, + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 mA */ + + /*---------------------------------------------------------------------------*/ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface: */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface: 1 */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SZE), +#ifdef USE_USB_OTG_HS + 0x10, /* bInterval: */ +#else + 0xFF, /* bInterval: */ +#endif /* USE_USB_OTG_HS */ + + /*---------------------------------------------------------------------------*/ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x00, /* iInterface: */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_MAX_PACKET_SIZE), + 0x00, /* bInterval: ignore for Bulk transfer */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_MAX_PACKET_SIZE), + 0x00 /* bInterval: ignore for Bulk transfer */ +} ; + +#ifdef USE_USB_OTG_HS +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, + USB_CDC_CONFIG_DESC_SIZ, + 0x00, + 0x02, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface: */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface: 1 */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SZE), + 0xFF, /* bInterval: */ + + /*---------------------------------------------------------------------------*/ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x00, /* iInterface: */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ + 0x00, + 0x00, /* bInterval: ignore for Bulk transfer */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ + 0x00, + 0x00 /* bInterval */ +}; +#endif /* USE_USB_OTG_HS */ + +/** + * @} + */ + +/** @defgroup usbd_cdc_Private_Functions + * @{ + */ + +/** + * @brief usbd_cdc_Init + * Initilaize the CDC interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t usbd_cdc_Init (void *pdev, + uint8_t cfgidx) +{ + uint8_t *pbuf; + + /* Open EP IN */ + DCD_EP_Open(pdev, + CDC_IN_EP, + CDC_DATA_IN_PACKET_SIZE, + USB_OTG_EP_BULK); + + /* Open EP OUT */ + DCD_EP_Open(pdev, + CDC_OUT_EP, + CDC_DATA_OUT_PACKET_SIZE, + USB_OTG_EP_BULK); + + /* Open Command IN EP */ + DCD_EP_Open(pdev, + CDC_CMD_EP, + CDC_CMD_PACKET_SZE, + USB_OTG_EP_INT); + + pbuf = (uint8_t *)USBD_DeviceDesc; + pbuf[4] = DEVICE_CLASS_CDC; + pbuf[5] = DEVICE_SUBCLASS_CDC; + + /* Initialize the Interface physical components */ + APP_FOPS.pIf_Init(); + + /* Prepare Out endpoint to receive next packet */ + DCD_EP_PrepareRx(pdev, + CDC_OUT_EP, + (uint8_t*)(USB_Rx_Buffer), + CDC_DATA_OUT_PACKET_SIZE); + + return USBD_OK; +} + +/** + * @brief usbd_cdc_Init + * DeInitialize the CDC layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t usbd_cdc_DeInit (void *pdev, + uint8_t cfgidx) +{ + /* Open EP IN */ + DCD_EP_Close(pdev, + CDC_IN_EP); + + /* Open EP OUT */ + DCD_EP_Close(pdev, + CDC_OUT_EP); + + /* Open Command IN EP */ + DCD_EP_Close(pdev, + CDC_CMD_EP); + + /* Restore default state of the Interface physical components */ + APP_FOPS.pIf_DeInit(); + + return USBD_OK; +} + +/** + * @brief usbd_cdc_Setup + * Handle the CDC specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t usbd_cdc_Setup (void *pdev, + USB_SETUP_REQ *req) +{ + uint16_t len; + uint8_t *pbuf; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + /* CDC Class Requests -------------------------------*/ + case USB_REQ_TYPE_CLASS : + /* Check if the request is a data setup packet */ + if (req->wLength) + { + /* Check if the request is Device-to-Host */ + if (req->bmRequest & 0x80) + { + /* Get the data to be sent to Host from interface layer */ + APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength); + + /* Send the data to the host */ + USBD_CtlSendData (pdev, + CmdBuff, + req->wLength); + } + else /* Host-to-Device requeset */ + { + /* Set the value of the current command to be processed */ + cdcCmd = req->bRequest; + cdcLen = req->wLength; + + /* Prepare the reception of the buffer over EP0 + Next step: the received data will be managed in usbd_cdc_EP0_TxSent() + function. */ + USBD_CtlPrepareRx (pdev, + CmdBuff, + req->wLength); + } + } + else /* No Data request */ + { + /* Transfer the command to the interface layer */ + APP_FOPS.pIf_Ctrl(req->bRequest, (uint8_t*)&req->wValue, sizeof(req->wValue)); + } + + return USBD_OK; + + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + + + + /* Standard Requests -------------------------------*/ + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE) + { +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + pbuf = usbd_cdc_Desc; +#else + pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM); +#endif + len = MIN(USB_CDC_DESC_SIZ , req->wLength); + + USBD_CtlSendData (pdev, + pbuf, + len); + } + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&usbd_cdc_AltSet, + 1); + break; + + case USB_REQ_SET_INTERFACE : + if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM) + { + usbd_cdc_AltSet = (uint8_t)(req->wValue); + } + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + break; + } + } + return USBD_OK; +} + +/** + * @brief usbd_cdc_EP0_RxReady + * Data received on control endpoint + * @param pdev: device device instance + * @retval status + */ +static uint8_t usbd_cdc_EP0_RxReady (void *pdev) +{ + if (cdcCmd != NO_CMD) + { + /* Process the data */ + APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen); + + /* Reset the command variable to default value */ + cdcCmd = NO_CMD; + } + + return USBD_OK; +} + +/** + * @brief usbd_audio_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +#if 0 +static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum) +{ + uint16_t USB_Tx_ptr; + uint16_t USB_Tx_length; + + if (USB_Tx_State == 1) + { + if (APP_Rx_length == 0) + { + USB_Tx_State = 0; + } + else + { + if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){ + USB_Tx_ptr = APP_Rx_ptr_out; + USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; + + APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; + APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; + } + else + { + USB_Tx_ptr = APP_Rx_ptr_out; + USB_Tx_length = APP_Rx_length; + + APP_Rx_ptr_out += APP_Rx_length; + APP_Rx_length = 0; + } + + /* Prepare the available data buffer to be sent on IN endpoint */ + DCD_EP_Tx (pdev, + CDC_IN_EP, + (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], + USB_Tx_length); + } + } + + return USBD_OK; +} +#endif + +// ala42: applied fix from +//https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2f +//STe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fUSB%20CDC%20Device%20hung%20fix& +//FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=75 +static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum) +{ + uint16_t USB_Tx_ptr; + uint16_t USB_Tx_length; + + if (USB_Tx_State == 1) + { + if (APP_Rx_length == 0) + { + if (((USB_OTG_CORE_HANDLE*)pdev)->dev.in_ep[epnum].xfer_len != CDC_DATA_IN_PACKET_SIZE) + { + USB_Tx_State = 0; + return USBD_OK; + } + /* Transmit zero sized packet in case the last one has maximum allowed size. Otherwise + * the recipient may expect more data coming soon and not return buffered data to app. + * See section 5.8.3 Bulk Transfer Packet Size Constraints + * of the USB Specification document. + */ + USB_Tx_ptr = APP_Rx_ptr_out; + USB_Tx_length = 0; + } + else + { + if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){ + USB_Tx_ptr = APP_Rx_ptr_out; + USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; + + APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; + APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; + } + else + { + USB_Tx_ptr = APP_Rx_ptr_out; + USB_Tx_length = APP_Rx_length; + + APP_Rx_ptr_out += APP_Rx_length; + APP_Rx_length = 0; + } + } + + /* Prepare the available data buffer to be sent on IN endpoint */ + DCD_EP_Tx (pdev, + CDC_IN_EP, + (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], + USB_Tx_length); + } + + return USBD_OK; +} + + +/** + * @brief usbd_audio_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum) +{ + uint16_t USB_Rx_Cnt; + + /* Get the received data buffer and update the counter */ + USB_Rx_Cnt = ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count; + + /* USB data will be immediately processed, this allow next USB traffic being + NAKed till the end of the application Xfer */ + APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt); + + /* Prepare Out endpoint to receive next packet */ + DCD_EP_PrepareRx(pdev, + CDC_OUT_EP, + (uint8_t*)(USB_Rx_Buffer), + CDC_DATA_OUT_PACKET_SIZE); + + return USBD_OK; +} + +/** + * @brief usbd_audio_SOF + * Start Of Frame event management + * @param pdev: instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t usbd_cdc_SOF (void *pdev) +{ + static uint32_t FrameCount = 0; + + if (FrameCount++ == CDC_IN_FRAME_INTERVAL) + { + /* Reset the frame counter */ + FrameCount = 0; + + /* Check the data to be sent through IN pipe */ + Handle_USBAsynchXfer(pdev); + } + + return USBD_OK; +} + +/** + * @brief Handle_USBAsynchXfer + * Send data to USB + * @param pdev: instance + * @retval None + */ +static void Handle_USBAsynchXfer (void *pdev) +{ + uint16_t USB_Tx_ptr; + uint16_t USB_Tx_length; + + if(USB_Tx_State != 1) + { + if (APP_Rx_ptr_out == APP_RX_DATA_SIZE) + { + APP_Rx_ptr_out = 0; + } + + if(APP_Rx_ptr_out == APP_Rx_ptr_in) + { + USB_Tx_State = 0; + return; + } + + if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */ + { + APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out; + + } + else + { + APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out; + + } +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + APP_Rx_length &= ~0x03; +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + + if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE) + { + USB_Tx_ptr = APP_Rx_ptr_out; + USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; + + APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; + APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; + } + else + { + USB_Tx_ptr = APP_Rx_ptr_out; + USB_Tx_length = APP_Rx_length; + + APP_Rx_ptr_out += APP_Rx_length; + APP_Rx_length = 0; + } + USB_Tx_State = 1; + + DCD_EP_Tx (pdev, + CDC_IN_EP, + (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], + USB_Tx_length); + } + +} + +/** + * @brief USBD_cdc_GetCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length) +{ + *length = sizeof (usbd_cdc_CfgDesc); + return usbd_cdc_CfgDesc; +} + +/** + * @brief USBD_cdc_GetCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +#ifdef USE_USB_OTG_HS +static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length) +{ + *length = sizeof (usbd_cdc_OtherCfgDesc); + return usbd_cdc_OtherCfgDesc; +} +#endif +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c index 4447e488..9e041fc4 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c @@ -1,202 +1,202 @@ -/** - ****************************************************************************** - * @file usbd_cdc_if_template.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Generic media access Layer. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED -#pragma data_alignment = 4 -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_cdc_if_template.h" -#include "stm32_eval.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* These are external variables imported from CDC core to be used for IN - transfer management. */ -extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer. - These data will be sent over USB IN endpoint - in the CDC core functions. */ -extern int APP_Rx_ptr_in; /* Increment this pointer or roll it back to - start address when writing received data - in the buffer APP_Rx_Buffer. */ - -/* Private function prototypes -----------------------------------------------*/ -static uint16_t TEMPLATE_Init (void); -static uint16_t TEMPLATE_DeInit (void); -static uint16_t TEMPLATE_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len); -static uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len); -static uint16_t TEMPLATE_DataRx (uint8_t* Buf, uint32_t Len); - -CDC_IF_Prop_TypeDef TEMPLATE_fops = -{ - TEMPLATE_Init, - TEMPLATE_DeInit, - TEMPLATE_Ctrl, - TEMPLATE_DataTx, - TEMPLATE_DataRx -}; - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief TEMPLATE_Init - * Initializes the CDC media low layer - * @param None - * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL - */ -static uint16_t TEMPLATE_Init(void) -{ - /* - Add your initialization code here - */ - return USBD_OK; -} - -/** - * @brief TEMPLATE_DeInit - * DeInitializes the CDC media low layer - * @param None - * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL - */ -static uint16_t TEMPLATE_DeInit(void) -{ - /* - Add your deinitialization code here - */ - return USBD_OK; -} - - -/** - * @brief TEMPLATE_Ctrl - * Manage the CDC class requests - * @param Cmd: Command code - * @param Buf: Buffer containing command data (request parameters) - * @param Len: Number of data to be sent (in bytes) - * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL - */ -static uint16_t TEMPLATE_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) -{ - switch (Cmd) - { - case SEND_ENCAPSULATED_COMMAND: - /* Add your code here */ - break; - - case GET_ENCAPSULATED_RESPONSE: - /* Add your code here */ - break; - - case SET_COMM_FEATURE: - /* Add your code here */ - break; - - case GET_COMM_FEATURE: - /* Add your code here */ - break; - - case CLEAR_COMM_FEATURE: - /* Add your code here */ - break; - - case SET_LINE_CODING: - /* Add your code here */ - break; - - case GET_LINE_CODING: - /* Add your code here */ - break; - - case SET_CONTROL_LINE_STATE: - /* Add your code here */ - break; - - case SEND_BREAK: - /* Add your code here */ - break; - - default: - break; - } - - return USBD_OK; -} - -/** - * @brief TEMPLATE_DataTx - * CDC received data to be send over USB IN endpoint are managed in - * this function. - * @param Buf: Buffer of data to be sent - * @param Len: Number of data to be sent (in bytes) - * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL - */ -static uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len) -{ - - /* Get the data to be sent */ - for (i = 0; i < Len; i++) - { - /* APP_Rx_Buffer[APP_Rx_ptr_in] = XXX_ReceiveData(XXX); */ - } - - /* Increment the in pointer */ - APP_Rx_ptr_in++; - - /* To avoid buffer overflow */ - if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) - { - APP_Rx_ptr_in = 0; - } - - return USBD_OK; -} - -/** - * @brief TEMPLATE_DataRx - * Data received over USB OUT endpoint are sent over CDC interface - * through this function. - * - * @note - * This function will block any OUT packet reception on USB endpoint - * untill exiting this function. If you exit this function before transfer - * is complete on CDC interface (ie. using DMA controller) it will result - * in receiving more data while previous ones are still not sent. - * - * @param Buf: Buffer of data to be received - * @param Len: Number of data received (in bytes) - * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL - */ -static uint16_t TEMPLATE_DataRx (uint8_t* Buf, uint32_t Len) -{ - uint32_t i; - - /* Send the received buffer */ - for (i = 0; i < Len; i++) - { - /* XXXX_SendData(XXXX, *(Buf + i) ); */ - } - - return USBD_OK; -} - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_cdc_if_template.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Generic media access Layer. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED +#pragma data_alignment = 4 +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc_if_template.h" +#include "stm32_eval.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* These are external variables imported from CDC core to be used for IN + transfer management. */ +extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer. + These data will be sent over USB IN endpoint + in the CDC core functions. */ +extern int APP_Rx_ptr_in; /* Increment this pointer or roll it back to + start address when writing received data + in the buffer APP_Rx_Buffer. */ + +/* Private function prototypes -----------------------------------------------*/ +static uint16_t TEMPLATE_Init (void); +static uint16_t TEMPLATE_DeInit (void); +static uint16_t TEMPLATE_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len); +static uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len); +static uint16_t TEMPLATE_DataRx (uint8_t* Buf, uint32_t Len); + +CDC_IF_Prop_TypeDef TEMPLATE_fops = +{ + TEMPLATE_Init, + TEMPLATE_DeInit, + TEMPLATE_Ctrl, + TEMPLATE_DataTx, + TEMPLATE_DataRx +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief TEMPLATE_Init + * Initializes the CDC media low layer + * @param None + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static uint16_t TEMPLATE_Init(void) +{ + /* + Add your initialization code here + */ + return USBD_OK; +} + +/** + * @brief TEMPLATE_DeInit + * DeInitializes the CDC media low layer + * @param None + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static uint16_t TEMPLATE_DeInit(void) +{ + /* + Add your deinitialization code here + */ + return USBD_OK; +} + + +/** + * @brief TEMPLATE_Ctrl + * Manage the CDC class requests + * @param Cmd: Command code + * @param Buf: Buffer containing command data (request parameters) + * @param Len: Number of data to be sent (in bytes) + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static uint16_t TEMPLATE_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) +{ + switch (Cmd) + { + case SEND_ENCAPSULATED_COMMAND: + /* Add your code here */ + break; + + case GET_ENCAPSULATED_RESPONSE: + /* Add your code here */ + break; + + case SET_COMM_FEATURE: + /* Add your code here */ + break; + + case GET_COMM_FEATURE: + /* Add your code here */ + break; + + case CLEAR_COMM_FEATURE: + /* Add your code here */ + break; + + case SET_LINE_CODING: + /* Add your code here */ + break; + + case GET_LINE_CODING: + /* Add your code here */ + break; + + case SET_CONTROL_LINE_STATE: + /* Add your code here */ + break; + + case SEND_BREAK: + /* Add your code here */ + break; + + default: + break; + } + + return USBD_OK; +} + +/** + * @brief TEMPLATE_DataTx + * CDC received data to be send over USB IN endpoint are managed in + * this function. + * @param Buf: Buffer of data to be sent + * @param Len: Number of data to be sent (in bytes) + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len) +{ + + /* Get the data to be sent */ + for (i = 0; i < Len; i++) + { + /* APP_Rx_Buffer[APP_Rx_ptr_in] = XXX_ReceiveData(XXX); */ + } + + /* Increment the in pointer */ + APP_Rx_ptr_in++; + + /* To avoid buffer overflow */ + if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) + { + APP_Rx_ptr_in = 0; + } + + return USBD_OK; +} + +/** + * @brief TEMPLATE_DataRx + * Data received over USB OUT endpoint are sent over CDC interface + * through this function. + * + * @note + * This function will block any OUT packet reception on USB endpoint + * untill exiting this function. If you exit this function before transfer + * is complete on CDC interface (ie. using DMA controller) it will result + * in receiving more data while previous ones are still not sent. + * + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static uint16_t TEMPLATE_DataRx (uint8_t* Buf, uint32_t Len) +{ + uint32_t i; + + /* Send the received buffer */ + for (i = 0; i < Len; i++) + { + /* XXXX_SendData(XXXX, *(Buf + i) ); */ + } + + return USBD_OK; +} + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h index 82402ba9..aadffb14 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h @@ -1,187 +1,187 @@ -/** - ****************************************************************************** - * @file usbd_dfu_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_dfu_core.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_DFU_CORE_H_ -#define __USB_DFU_CORE_H_ - -#include "usbd_ioreq.h" -#include "usbd_dfu_mal.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup usbd_dfu - * @brief This file is the Header file for USBD_dfu.c - * @{ - */ - - -/** @defgroup usbd_dfu_Exported_Defines - * @{ - */ -#define USB_DFU_CONFIG_DESC_SIZ (18 + (9 * USBD_ITF_MAX_NUM)) -#define USB_DFU_DESC_SIZ 9 - -#define DFU_DESCRIPTOR_TYPE 0x21 - - -/*---------------------------------------------------------------------*/ -/* DFU definitions */ -/*---------------------------------------------------------------------*/ - - - -/**************************************************/ -/* DFU Requests DFU states */ -/**************************************************/ - - -#define STATE_appIDLE 0 -#define STATE_appDETACH 1 -#define STATE_dfuIDLE 2 -#define STATE_dfuDNLOAD_SYNC 3 -#define STATE_dfuDNBUSY 4 -#define STATE_dfuDNLOAD_IDLE 5 -#define STATE_dfuMANIFEST_SYNC 6 -#define STATE_dfuMANIFEST 7 -#define STATE_dfuMANIFEST_WAIT_RESET 8 -#define STATE_dfuUPLOAD_IDLE 9 -#define STATE_dfuERROR 10 - -/**************************************************/ -/* DFU Requests DFU status */ -/**************************************************/ - -#define STATUS_OK 0x00 -#define STATUS_ERRTARGET 0x01 -#define STATUS_ERRFILE 0x02 -#define STATUS_ERRWRITE 0x03 -#define STATUS_ERRERASE 0x04 -#define STATUS_ERRCHECK_ERASED 0x05 -#define STATUS_ERRPROG 0x06 -#define STATUS_ERRVERIFY 0x07 -#define STATUS_ERRADDRESS 0x08 -#define STATUS_ERRNOTDONE 0x09 -#define STATUS_ERRFIRMWARE 0x0A -#define STATUS_ERRVENDOR 0x0B -#define STATUS_ERRUSBR 0x0C -#define STATUS_ERRPOR 0x0D -#define STATUS_ERRUNKNOWN 0x0E -#define STATUS_ERRSTALLEDPKT 0x0F - -/**************************************************/ -/* DFU Requests DFU states Manifestation State */ -/**************************************************/ - -#define Manifest_complete 0x00 -#define Manifest_In_Progress 0x01 - - -/**************************************************/ -/* Special Commands with Download Request */ -/**************************************************/ - -#define CMD_GETCOMMANDS 0x00 -#define CMD_SETADDRESSPOINTER 0x21 -#define CMD_ERASE 0x41 - -/**************************************************/ -/* Other defines */ -/**************************************************/ -/* Bit Detach capable = bit 3 in bmAttributes field */ -#define DFU_DETACH_MASK (uint8_t)(1 << 4) -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ -/**************************************************/ -/* DFU Requests */ -/**************************************************/ - -typedef enum _DFU_REQUESTS { - DFU_DETACH = 0, - DFU_DNLOAD = 1, - DFU_UPLOAD, - DFU_GETSTATUS, - DFU_CLRSTATUS, - DFU_GETSTATE, - DFU_ABORT -} DFU_REQUESTS; - -typedef void (*pFunction)(void); -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ -/********** Descriptor of DFU interface 0 Alternate setting n ****************/ -#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ - 0x00, /* bInterfaceNumber: Number of Interface */ \ - (n), /* bAlternateSetting: Alternate setting */ \ - 0x00, /* bNumEndpoints*/ \ - 0xFE, /* bInterfaceClass: Application Specific Class Code */ \ - 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \ - 0x02, /* nInterfaceProtocol: DFU mode protocol */ \ - USBD_IDX_INTERFACE_STR + (n) + 1 /* iInterface: Index of string descriptor */ \ - /* 18 */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -extern USBD_Class_cb_TypeDef DFU_cb; -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Functions - * @{ - */ -/** - * @} - */ - -#endif // __USB_DFU_CORE_H_ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_dfu_core.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header file for the usbd_dfu_core.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#ifndef __USB_DFU_CORE_H_ +#define __USB_DFU_CORE_H_ + +#include "usbd_ioreq.h" +#include "usbd_dfu_mal.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_dfu + * @brief This file is the Header file for USBD_dfu.c + * @{ + */ + + +/** @defgroup usbd_dfu_Exported_Defines + * @{ + */ +#define USB_DFU_CONFIG_DESC_SIZ (18 + (9 * USBD_ITF_MAX_NUM)) +#define USB_DFU_DESC_SIZ 9 + +#define DFU_DESCRIPTOR_TYPE 0x21 + + +/*---------------------------------------------------------------------*/ +/* DFU definitions */ +/*---------------------------------------------------------------------*/ + + + +/**************************************************/ +/* DFU Requests DFU states */ +/**************************************************/ + + +#define STATE_appIDLE 0 +#define STATE_appDETACH 1 +#define STATE_dfuIDLE 2 +#define STATE_dfuDNLOAD_SYNC 3 +#define STATE_dfuDNBUSY 4 +#define STATE_dfuDNLOAD_IDLE 5 +#define STATE_dfuMANIFEST_SYNC 6 +#define STATE_dfuMANIFEST 7 +#define STATE_dfuMANIFEST_WAIT_RESET 8 +#define STATE_dfuUPLOAD_IDLE 9 +#define STATE_dfuERROR 10 + +/**************************************************/ +/* DFU Requests DFU status */ +/**************************************************/ + +#define STATUS_OK 0x00 +#define STATUS_ERRTARGET 0x01 +#define STATUS_ERRFILE 0x02 +#define STATUS_ERRWRITE 0x03 +#define STATUS_ERRERASE 0x04 +#define STATUS_ERRCHECK_ERASED 0x05 +#define STATUS_ERRPROG 0x06 +#define STATUS_ERRVERIFY 0x07 +#define STATUS_ERRADDRESS 0x08 +#define STATUS_ERRNOTDONE 0x09 +#define STATUS_ERRFIRMWARE 0x0A +#define STATUS_ERRVENDOR 0x0B +#define STATUS_ERRUSBR 0x0C +#define STATUS_ERRPOR 0x0D +#define STATUS_ERRUNKNOWN 0x0E +#define STATUS_ERRSTALLEDPKT 0x0F + +/**************************************************/ +/* DFU Requests DFU states Manifestation State */ +/**************************************************/ + +#define Manifest_complete 0x00 +#define Manifest_In_Progress 0x01 + + +/**************************************************/ +/* Special Commands with Download Request */ +/**************************************************/ + +#define CMD_GETCOMMANDS 0x00 +#define CMD_SETADDRESSPOINTER 0x21 +#define CMD_ERASE 0x41 + +/**************************************************/ +/* Other defines */ +/**************************************************/ +/* Bit Detach capable = bit 3 in bmAttributes field */ +#define DFU_DETACH_MASK (uint8_t)(1 << 4) +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ +/**************************************************/ +/* DFU Requests */ +/**************************************************/ + +typedef enum _DFU_REQUESTS { + DFU_DETACH = 0, + DFU_DNLOAD = 1, + DFU_UPLOAD, + DFU_GETSTATUS, + DFU_CLRSTATUS, + DFU_GETSTATE, + DFU_ABORT +} DFU_REQUESTS; + +typedef void (*pFunction)(void); +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ +/********** Descriptor of DFU interface 0 Alternate setting n ****************/ +#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ + 0x00, /* bInterfaceNumber: Number of Interface */ \ + (n), /* bAlternateSetting: Alternate setting */ \ + 0x00, /* bNumEndpoints*/ \ + 0xFE, /* bInterfaceClass: Application Specific Class Code */ \ + 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \ + 0x02, /* nInterfaceProtocol: DFU mode protocol */ \ + USBD_IDX_INTERFACE_STR + (n) + 1 /* iInterface: Index of string descriptor */ \ + /* 18 */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_Class_cb_TypeDef DFU_cb; +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +/** + * @} + */ + +#endif // __USB_DFU_CORE_H_ +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h index bb59e623..9ed095b7 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h @@ -1,79 +1,79 @@ -/** - ****************************************************************************** - * @file usbd_dfu_mal.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header for usbd_dfu_mal.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __DFU_MAL_H -#define __DFU_MAL_H - -/* Includes ------------------------------------------------------------------*/ -#ifdef STM32F2XX - #include "stm32f2xx.h" -#elif defined(STM32F10X_CL) - #include "stm32f10x.h" -#endif /* STM32F2XX */ - -#include "usbd_conf.h" -#include "usbd_dfu_core.h" - -/* Exported types ------------------------------------------------------------*/ -typedef struct _DFU_MAL_PROP -{ - const uint8_t* pStrDesc; - uint16_t (*pMAL_Init) (void); - uint16_t (*pMAL_DeInit) (void); - uint16_t (*pMAL_Erase) (uint32_t Add); - uint16_t (*pMAL_Write) (uint32_t Add, uint32_t Len); - uint8_t *(*pMAL_Read) (uint32_t Add, uint32_t Len); - uint16_t (*pMAL_CheckAdd) (uint32_t Add); - const uint32_t EraseTiming; - const uint32_t WriteTiming; -} -DFU_MAL_Prop_TypeDef; - - -/* Exported constants --------------------------------------------------------*/ -#define MAL_OK 0 -#define MAL_FAIL 1 - -/* utils macro ---------------------------------------------------------------*/ -#define _1st_BYTE(x) (uint8_t)((x)&0xFF) /* 1st addressing cycle */ -#define _2nd_BYTE(x) (uint8_t)(((x)&0xFF00)>>8) /* 2nd addressing cycle */ -#define _3rd_BYTE(x) (uint8_t)(((x)&0xFF0000)>>16) /* 3rd addressing cycle */ -#define _4th_BYTE(x) (uint8_t)(((x)&0xFF000000)>>24) /* 4th addressing cycle */ - -/* Exported macro ------------------------------------------------------------*/ -#define SET_POLLING_TIMING(x) buffer[1] = _1st_BYTE(x);\ - buffer[2] = _2nd_BYTE(x);\ - buffer[3] = _3rd_BYTE(x); - -/* Exported functions ------------------------------------------------------- */ - -uint16_t MAL_Init (void); -uint16_t MAL_DeInit (void); -uint16_t MAL_Erase (uint32_t SectorAddress); -uint16_t MAL_Write (uint32_t SectorAddress, uint32_t DataLength); -uint8_t *MAL_Read (uint32_t SectorAddress, uint32_t DataLength); -uint16_t MAL_GetStatus(uint32_t SectorAddress ,uint8_t Cmd, uint8_t *buffer); - -extern uint8_t MAL_Buffer[XFERSIZE]; /* RAM Buffer for Downloaded Data */ -#endif /* __DFU_MAL_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_dfu_mal.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Header for usbd_dfu_mal.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __DFU_MAL_H +#define __DFU_MAL_H + +/* Includes ------------------------------------------------------------------*/ +#ifdef STM32F2XX + #include "stm32f2xx.h" +#elif defined(STM32F10X_CL) + #include "stm32f10x.h" +#endif /* STM32F2XX */ + +#include "usbd_conf.h" +#include "usbd_dfu_core.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct _DFU_MAL_PROP +{ + const uint8_t* pStrDesc; + uint16_t (*pMAL_Init) (void); + uint16_t (*pMAL_DeInit) (void); + uint16_t (*pMAL_Erase) (uint32_t Add); + uint16_t (*pMAL_Write) (uint32_t Add, uint32_t Len); + uint8_t *(*pMAL_Read) (uint32_t Add, uint32_t Len); + uint16_t (*pMAL_CheckAdd) (uint32_t Add); + const uint32_t EraseTiming; + const uint32_t WriteTiming; +} +DFU_MAL_Prop_TypeDef; + + +/* Exported constants --------------------------------------------------------*/ +#define MAL_OK 0 +#define MAL_FAIL 1 + +/* utils macro ---------------------------------------------------------------*/ +#define _1st_BYTE(x) (uint8_t)((x)&0xFF) /* 1st addressing cycle */ +#define _2nd_BYTE(x) (uint8_t)(((x)&0xFF00)>>8) /* 2nd addressing cycle */ +#define _3rd_BYTE(x) (uint8_t)(((x)&0xFF0000)>>16) /* 3rd addressing cycle */ +#define _4th_BYTE(x) (uint8_t)(((x)&0xFF000000)>>24) /* 4th addressing cycle */ + +/* Exported macro ------------------------------------------------------------*/ +#define SET_POLLING_TIMING(x) buffer[1] = _1st_BYTE(x);\ + buffer[2] = _2nd_BYTE(x);\ + buffer[3] = _3rd_BYTE(x); + +/* Exported functions ------------------------------------------------------- */ + +uint16_t MAL_Init (void); +uint16_t MAL_DeInit (void); +uint16_t MAL_Erase (uint32_t SectorAddress); +uint16_t MAL_Write (uint32_t SectorAddress, uint32_t DataLength); +uint8_t *MAL_Read (uint32_t SectorAddress, uint32_t DataLength); +uint16_t MAL_GetStatus(uint32_t SectorAddress ,uint8_t Cmd, uint8_t *buffer); + +extern uint8_t MAL_Buffer[XFERSIZE]; /* RAM Buffer for Downloaded Data */ +#endif /* __DFU_MAL_H */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h index 171395f3..07e49dfb 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h @@ -1,49 +1,49 @@ -/** - ****************************************************************************** - * @file usbd_flash_if.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 18-March-2011 - * @brief Header for usbd_flash_if.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __FLASH_IF_MAL_H -#define __FLASH_IF_MAL_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_dfu_mal.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -#define FLASH_START_ADD 0x08000000 - -#ifdef STM32F2XX - #define FLASH_END_ADD 0x08100000 - #define FLASH_IF_STRING "@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg" -#elif defined(STM32F10X_CL) - #define FLASH_END_ADD 0x08040000 - #define FLASH_IF_STRING "@Internal Flash /0x08000000/06*002Ka,122*002Kg" -#endif /* STM32F2XX */ - - -extern DFU_MAL_Prop_TypeDef DFU_Flash_cb; - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#endif /* __FLASH_IF_MAL_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_flash_if.h + * @author MCD Application Team + * @version V1.0.0RC1 + * @date 18-March-2011 + * @brief Header for usbd_flash_if.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FLASH_IF_MAL_H +#define __FLASH_IF_MAL_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_dfu_mal.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +#define FLASH_START_ADD 0x08000000 + +#ifdef STM32F2XX + #define FLASH_END_ADD 0x08100000 + #define FLASH_IF_STRING "@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg" +#elif defined(STM32F10X_CL) + #define FLASH_END_ADD 0x08040000 + #define FLASH_IF_STRING "@Internal Flash /0x08000000/06*002Ka,122*002Kg" +#endif /* STM32F2XX */ + + +extern DFU_MAL_Prop_TypeDef DFU_Flash_cb; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* __FLASH_IF_MAL_H */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h index 9632a5bf..d1e0dda9 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h @@ -1,46 +1,46 @@ -/** - ****************************************************************************** - * @file usbd_mem_if_template.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header for usbd_mem_if_template.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MEM_IF_MAL_H -#define __MEM_IF_MAL_H - -/* Includes ------------------------------------------------------------------*/ -#ifdef STM32F2XX - #include "stm32f2xx.h" -#endif /* STM32F2XX */ -#include "usbd_dfu_mal.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -#define MEM_START_ADD 0x00000000 /* Dummy start address */ -#define MEM_END_ADD (uint32_t)(MEM_START_ADD + (5 * 1024)) /* Dummy Size = 5KB */ - -#define MEM_IF_STRING "@Dummy Memory /0x00000000/01*002Kg,03*001Kg" - -extern DFU_MAL_Prop_TypeDef DFU_Mem_cb; - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#endif /* __MEM_IF_MAL_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_mem_if_template.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Header for usbd_mem_if_template.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MEM_IF_MAL_H +#define __MEM_IF_MAL_H + +/* Includes ------------------------------------------------------------------*/ +#ifdef STM32F2XX + #include "stm32f2xx.h" +#endif /* STM32F2XX */ +#include "usbd_dfu_mal.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +#define MEM_START_ADD 0x00000000 /* Dummy start address */ +#define MEM_END_ADD (uint32_t)(MEM_START_ADD + (5 * 1024)) /* Dummy Size = 5KB */ + +#define MEM_IF_STRING "@Dummy Memory /0x00000000/01*002Kg,03*001Kg" + +extern DFU_MAL_Prop_TypeDef DFU_Mem_cb; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* __MEM_IF_MAL_H */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h index bb879cab..ef7e0610 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h @@ -1,43 +1,43 @@ -/** - ****************************************************************************** - * @file usbd_otp_if.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header for usbd_otp_if.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __OTP_IF_MAL_H -#define __OTP_IF_MAL_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_dfu_mal.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -#define OTP_START_ADD 0x1FFF7800 -#define OTP_END_ADD (uint32_t)(OTP_START_ADD + 528) - -#define OTP_IF_STRING "@OTP Area /0x1FFF7800/01*512 g,01*016 g" - -extern DFU_MAL_Prop_TypeDef DFU_Otp_cb; - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#endif /* __OTP_IF_MAL_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_otp_if.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Header for usbd_otp_if.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __OTP_IF_MAL_H +#define __OTP_IF_MAL_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_dfu_mal.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +#define OTP_START_ADD 0x1FFF7800 +#define OTP_END_ADD (uint32_t)(OTP_START_ADD + 528) + +#define OTP_IF_STRING "@OTP Area /0x1FFF7800/01*512 g,01*016 g" + +extern DFU_MAL_Prop_TypeDef DFU_Otp_cb; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* __OTP_IF_MAL_H */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c index 91db9aed..31603167 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c @@ -1,1046 +1,1046 @@ -/** - ****************************************************************************** - * @file usbd_dfu_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the high layer firmware functions to manage the - * following functionalities of the USB DFU Class: - * - Initialization and Configuration of high and low layer - * - Enumeration as DFU Device (and enumeration for each implemented memory interface) - * - Transfers to/from memory interfaces - * - Easy-to-customize "plug-in-like" modules for adding/removing memory interfaces. - * - Error management - * - * @verbatim - * - * =================================================================== - * DFU Class Driver Description - * =================================================================== - * This driver manages the DFU class V1.1 following the "Device Class Specification for - * Device Firmware Upgrade Version 1.1 Aug 5, 2004". - * This driver implements the following aspects of the specification: - * - Device descriptor management - * - Configuration descriptor management - * - Enumeration as DFU device (in DFU mode only) - * - Requests management (supporting ST DFU sub-protocol) - * - Memory operations management (Download/Upload/Erase/Detach/GetState/GetStatus) - * - DFU state machine implementation. - * - * @note - * ST DFU sub-protocol is compliant with DFU protocol and use sub-requests to manage - * memory addressing, commands processing, specific memories operations (ie. Erase) ... - * As required by the DFU specification, only endpoint 0 is used in this application. - * Other endpoints and functions may be added to the application (ie. DFU ...) - * - * These aspects may be enriched or modified for a specific user application. - * - * This driver doesn't implement the following aspects of the specification - * (but it is possible to manage these features with some modifications on this driver): - * - Manifestation Tolerant mode - * - * @endverbatim - * - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_dfu_core.h" -#include "usbd_desc.h" -#include "usbd_req.h" -#include "usb_bsp.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup usbd_dfu - * @brief usbd core module - * @{ - */ - -/** @defgroup usbd_dfu_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_dfu_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_dfu_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_dfu_Private_FunctionPrototypes - * @{ - */ - -/********************************************* - DFU Device library callbacks - *********************************************/ -static uint8_t usbd_dfu_Init (void *pdev, - uint8_t cfgidx); - -static uint8_t usbd_dfu_DeInit (void *pdev, - uint8_t cfgidx); - -static uint8_t usbd_dfu_Setup (void *pdev, - USB_SETUP_REQ *req); - -static uint8_t EP0_TxSent (void *pdev); - -static uint8_t EP0_RxReady (void *pdev); - - -static uint8_t *USBD_DFU_GetCfgDesc (uint8_t speed, - uint16_t *length); - - -#ifdef USB_OTG_HS_CORE -static uint8_t *USBD_DFU_GetOtherCfgDesc (uint8_t speed, - uint16_t *length); -#endif - -static uint8_t* USBD_DFU_GetUsrStringDesc (uint8_t speed, - uint8_t index , - uint16_t *length); - -/********************************************* - DFU Requests management functions - *********************************************/ -static void DFU_Req_DETACH (void *pdev, - USB_SETUP_REQ *req); - -static void DFU_Req_DNLOAD (void *pdev, - USB_SETUP_REQ *req); - -static void DFU_Req_UPLOAD (void *pdev, - USB_SETUP_REQ *req); - -static void DFU_Req_GETSTATUS (void *pdev); - -static void DFU_Req_CLRSTATUS (void *pdev); - -static void DFU_Req_GETSTATE (void *pdev); - -static void DFU_Req_ABORT (void *pdev); - -static void DFU_LeaveDFUMode (void *pdev); - -/** - * @} - */ - -/** @defgroup usbd_dfu_Private_Variables - * @{ - */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_dfu_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END ; - - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_dfu_OtherCfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END ; - -/* The list of Interface String descriptor pointers is defined in usbd_dfu_mal.c - file. This list can be updated whenever a memory has to be added or removed */ -extern const uint8_t* usbd_dfu_StringDesc[]; - -/* State Machine variables */ -uint8_t DeviceState; -uint8_t DeviceStatus[6]; -uint32_t Manifest_State = Manifest_complete; -/* Data Management variables */ -static uint32_t wBlockNum = 0, wlength = 0; -static uint32_t Pointer = APP_DEFAULT_ADD; /* Base Address to Erase, Program or Read */ -static __IO uint32_t usbd_dfu_AltSet = 0; - -extern uint8_t MAL_Buffer[]; - -/* DFU interface class callbacks structure */ -USBD_Class_cb_TypeDef DFU_cb = -{ - usbd_dfu_Init, - usbd_dfu_DeInit, - usbd_dfu_Setup, - EP0_TxSent, - EP0_RxReady, - NULL, /* DataIn, */ - NULL, /* DataOut, */ - NULL, /*SOF */ - NULL, - NULL, - USBD_DFU_GetCfgDesc, -#ifdef USB_OTG_HS_CORE - USBD_DFU_GetOtherCfgDesc, /* use same cobfig as per FS */ -#endif - USBD_DFU_GetUsrStringDesc, -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB DFU device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t usbd_dfu_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuation Descriptor size */ - USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ - USB_DFU_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ - 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ - /* 09 */ - - /********** Descriptor of DFU interface 0 Alternate setting 0 **************/ - USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */ - -#if (USBD_ITF_MAX_NUM > 1) - /********** Descriptor of DFU interface 0 Alternate setting 1 **************/ - USBD_DFU_IF_DESC(1), -#endif /* (USBD_ITF_MAX_NUM > 1) */ - -#if (USBD_ITF_MAX_NUM > 2) - /********** Descriptor of DFU interface 0 Alternate setting 2 **************/ - USBD_DFU_IF_DESC(2), -#endif /* (USBD_ITF_MAX_NUM > 2) */ - -#if (USBD_ITF_MAX_NUM > 3) - /********** Descriptor of DFU interface 0 Alternate setting 3 **************/ - USBD_DFU_IF_DESC(3), -#endif /* (USBD_ITF_MAX_NUM > 3) */ - -#if (USBD_ITF_MAX_NUM > 4) - /********** Descriptor of DFU interface 0 Alternate setting 4 **************/ - USBD_DFU_IF_DESC(4), -#endif /* (USBD_ITF_MAX_NUM > 4) */ - -#if (USBD_ITF_MAX_NUM > 5) - /********** Descriptor of DFU interface 0 Alternate setting 5 **************/ - USBD_DFU_IF_DESC(5), -#endif /* (USBD_ITF_MAX_NUM > 5) */ - -#if (USBD_ITF_MAX_NUM > 6) -#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!" -#endif /* (USBD_ITF_MAX_NUM > 6) */ - - /******************** DFU Functional Descriptor********************/ - 0x09, /*blength = 9 Bytes*/ - DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ - 0x0B, /*bmAttribute - bitCanDnload = 1 (bit 0) - bitCanUpload = 1 (bit 1) - bitManifestationTolerant = 0 (bit 2) - bitWillDetach = 1 (bit 3) - Reserved (bit4-6) - bitAcceleratedST = 0 (bit 7)*/ - 0xFF, /*DetachTimeOut= 255 ms*/ - 0x00, - /*WARNING: In DMA mode the multiple MPS packets feature is still not supported - ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */ - TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/ - 0x1A, /* bcdDFUVersion*/ - 0x01 - /***********************************************************/ - /* 9*/ -} ; - -#ifdef USE_USB_OTG_HS -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -__ALIGN_BEGIN uint8_t usbd_dfu_OtherCfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_DFU_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ - 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ - /* 09 */ - - /********** Descriptor of DFU interface 0 Alternate setting 0 **************/ - USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */ - -#if (USBD_ITF_MAX_NUM > 1) - /********** Descriptor of DFU interface 0 Alternate setting 1 **************/ - USBD_DFU_IF_DESC(1), -#endif /* (USBD_ITF_MAX_NUM > 1) */ - -#if (USBD_ITF_MAX_NUM > 2) - /********** Descriptor of DFU interface 0 Alternate setting 2 **************/ - USBD_DFU_IF_DESC(2), -#endif /* (USBD_ITF_MAX_NUM > 2) */ - -#if (USBD_ITF_MAX_NUM > 3) - /********** Descriptor of DFU interface 0 Alternate setting 3 **************/ - USBD_DFU_IF_DESC(3), -#endif /* (USBD_ITF_MAX_NUM > 3) */ - -#if (USBD_ITF_MAX_NUM > 4) - /********** Descriptor of DFU interface 0 Alternate setting 4 **************/ - USBD_DFU_IF_DESC(4), -#endif /* (USBD_ITF_MAX_NUM > 4) */ - -#if (USBD_ITF_MAX_NUM > 5) - /********** Descriptor of DFU interface 0 Alternate setting 5 **************/ - USBD_DFU_IF_DESC(5), -#endif /* (USBD_ITF_MAX_NUM > 5) */ - -#if (USBD_ITF_MAX_NUM > 6) -#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!" -#endif /* (USBD_ITF_MAX_NUM > 6) */ - - /******************** DFU Functional Descriptor********************/ - 0x09, /*blength = 9 Bytes*/ - DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ - 0x0B, /*bmAttribute - bitCanDnload = 1 (bit 0) - bitCanUpload = 1 (bit 1) - bitManifestationTolerant = 0 (bit 2) - bitWillDetach = 1 (bit 3) - Reserved (bit4-6) - bitAcceleratedST = 0 (bit 7)*/ - 0xFF, /*DetachTimeOut= 255 ms*/ - 0x00, - /*WARNING: In DMA mode the multiple MPS packets feature is still not supported - ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */ - TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/ - 0x1A, /* bcdDFUVersion*/ - 0x01 - /***********************************************************/ - /* 9*/ -}; -#endif /* USE_USB_OTG_HS */ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif - -__ALIGN_BEGIN static uint8_t usbd_dfu_Desc[USB_DFU_DESC_SIZ] __ALIGN_END = -{ - 0x09, /*blength = 9 Bytes*/ - DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ - 0x0B, /*bmAttribute - bitCanDnload = 1 (bit 0) - bitCanUpload = 1 (bit 1) - bitManifestationTolerant = 0 (bit 2) - bitWillDetach = 1 (bit 3) - Reserved (bit4-6) - bitAcceleratedST = 0 (bit 7)*/ - 0xFF, /*DetachTimeOut= 255 ms*/ - 0x00, - /*WARNING: In DMA mode the multiple MPS packets feature is still not supported - ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */ - TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/ - 0x1A, /* bcdDFUVersion*/ - 0x01 -}; -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/** - * @} - */ - -/** @defgroup usbd_dfu_Private_Functions - * @{ - */ - -/** - * @brief usbd_dfu_Init - * Initializes the DFU interface. - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t usbd_dfu_Init (void *pdev, - uint8_t cfgidx) -{ - /* Initilialize the MAL(Media Access Layer) */ - MAL_Init(); - - /* Initialize the state of the DFU interface */ - DeviceState = STATE_dfuIDLE; - DeviceStatus[0] = STATUS_OK; - DeviceStatus[4] = DeviceState; - - return USBD_OK; -} - -/** - * @brief usbd_dfu_Init - * De-initializes the DFU layer. - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t usbd_dfu_DeInit (void *pdev, - uint8_t cfgidx) -{ - /* Restore default state */ - DeviceState = STATE_dfuIDLE; - DeviceStatus[0] = STATUS_OK; - DeviceStatus[4] = DeviceState; - wBlockNum = 0; - wlength = 0; - - /* DeInitilialize the MAL(Media Access Layer) */ - MAL_DeInit(); - - return USBD_OK; -} - -/** - * @brief usbd_dfu_Setup - * Handles the DFU request parsing. - * @param pdev: instance - * @param req: usb requests - * @retval status - */ -static uint8_t usbd_dfu_Setup (void *pdev, - USB_SETUP_REQ *req) -{ - uint16_t len = 0; - uint8_t *pbuf = NULL; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - /* DFU Class Requests -------------------------------*/ - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case DFU_DNLOAD: - DFU_Req_DNLOAD(pdev, req); - break; - - case DFU_UPLOAD: - DFU_Req_UPLOAD(pdev, req); - break; - - case DFU_GETSTATUS: - DFU_Req_GETSTATUS(pdev); - break; - - case DFU_CLRSTATUS: - DFU_Req_CLRSTATUS(pdev); - break; - - case DFU_GETSTATE: - DFU_Req_GETSTATE(pdev); - break; - - case DFU_ABORT: - DFU_Req_ABORT(pdev); - break; - - case DFU_DETACH: - DFU_Req_DETACH(pdev, req); - break; - - default: - USBD_CtlError (pdev, req); - return USBD_FAIL; - } - break; - - /* Standard Requests -------------------------------*/ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if( (req->wValue >> 8) == DFU_DESCRIPTOR_TYPE) - { -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - pbuf = usbd_dfu_Desc; -#else - pbuf = usbd_dfu_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM); -#endif - len = MIN(USB_DFU_DESC_SIZ , req->wLength); - } - - USBD_CtlSendData (pdev, - pbuf, - len); - break; - - case USB_REQ_GET_INTERFACE : - USBD_CtlSendData (pdev, - (uint8_t *)&usbd_dfu_AltSet, - 1); - break; - - case USB_REQ_SET_INTERFACE : - if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM) - { - usbd_dfu_AltSet = (uint8_t)(req->wValue); - } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - break; - } - } - return USBD_OK; -} - -/** - * @brief EP0_TxSent - * Handles the DFU control endpoint data IN stage. - * @param pdev: device instance - * @retval status - */ -static uint8_t EP0_TxSent (void *pdev) -{ - uint32_t Addr; - USB_SETUP_REQ req; - - if (DeviceState == STATE_dfuDNBUSY) - { - /* Decode the Special Command*/ - if (wBlockNum == 0) - { - if ((MAL_Buffer[0] == CMD_GETCOMMANDS) && (wlength == 1)) - {} - else if (( MAL_Buffer[0] == CMD_SETADDRESSPOINTER ) && (wlength == 5)) - { - Pointer = MAL_Buffer[1]; - Pointer += MAL_Buffer[2] << 8; - Pointer += MAL_Buffer[3] << 16; - Pointer += MAL_Buffer[4] << 24; - } - else if (( MAL_Buffer[0] == CMD_ERASE ) && (wlength == 5)) - { - Pointer = MAL_Buffer[1]; - Pointer += MAL_Buffer[2] << 8; - Pointer += MAL_Buffer[3] << 16; - Pointer += MAL_Buffer[4] << 24; - MAL_Erase(Pointer); - } - else - { - /* Reset the global length and block number */ - wlength = 0; - wBlockNum = 0; - /* Call the error management function (command will be nacked) */ - req.bmRequest = 0; - req.wLength = 1; - USBD_CtlError (pdev, &req); - } - } - /* Regular Download Command */ - else if (wBlockNum > 1) - { - /* Decode the required address */ - Addr = ((wBlockNum - 2) * XFERSIZE) + Pointer; - - /* Preform the write operation */ - MAL_Write(Addr, wlength); - } - /* Reset the global lenght and block number */ - wlength = 0; - wBlockNum = 0; - - /* Update the state machine */ - DeviceState = STATE_dfuDNLOAD_SYNC; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - return USBD_OK; - } - else if (DeviceState == STATE_dfuMANIFEST)/* Manifestation in progress*/ - { - /* Start leaving DFU mode */ - DFU_LeaveDFUMode(pdev); - } - - return USBD_OK; -} - -/** - * @brief EP0_RxReady - * Handles the DFU control endpoint data OUT stage. - * @param pdev: device instance - * @retval status - */ -static uint8_t EP0_RxReady (void *pdev) -{ - return USBD_OK; -} - - -/****************************************************************************** - DFU Class requests management -******************************************************************************/ -/** - * @brief DFU_Req_DETACH - * Handles the DFU DETACH request. - * @param pdev: device instance - * @param req: pointer to the request structure. - * @retval None. - */ -static void DFU_Req_DETACH(void *pdev, USB_SETUP_REQ *req) -{ - if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC - || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC - || DeviceState == STATE_dfuUPLOAD_IDLE ) - { - /* Update the state machine */ - DeviceState = STATE_dfuIDLE; - DeviceStatus[0] = STATUS_OK; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ - DeviceStatus[4] = DeviceState; - DeviceStatus[5] = 0; /*iString*/ - wBlockNum = 0; - wlength = 0; - } - - /* Check the detach capability in the DFU functional descriptor */ - if ((usbd_dfu_CfgDesc[12 + (9 * USBD_ITF_MAX_NUM)]) & DFU_DETACH_MASK) - { - /* Perform an Attach-Detach operation on USB bus */ - DCD_DevDisconnect (pdev); - DCD_DevConnect (pdev); - } - else - { - /* Wait for the period of time specified in Detach request */ - USB_OTG_BSP_mDelay (req->wValue); - } -} - -/** - * @brief DFU_Req_DNLOAD - * Handles the DFU DNLOAD request. - * @param pdev: device instance - * @param req: pointer to the request structure - * @retval None - */ -static void DFU_Req_DNLOAD(void *pdev, USB_SETUP_REQ *req) -{ - /* Data setup request */ - if (req->wLength > 0) - { - if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuDNLOAD_IDLE)) - { - /* Update the global length and block number */ - wBlockNum = req->wValue; - wlength = req->wLength; - - /* Update the state machine */ - DeviceState = STATE_dfuDNLOAD_SYNC; - DeviceStatus[4] = DeviceState; - - /* Prepare the reception of the buffer over EP0 */ - USBD_CtlPrepareRx (pdev, - (uint8_t*)MAL_Buffer, - wlength); - } - /* Unsupported state */ - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - } - /* 0 Data DNLOAD request */ - else - { - /* End of DNLOAD operation*/ - if (DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuIDLE ) - { - Manifest_State = Manifest_In_Progress; - DeviceState = STATE_dfuMANIFEST_SYNC; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - DeviceStatus[4] = DeviceState; - } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - } -} - -/** - * @brief DFU_Req_UPLOAD - * Handles the DFU UPLOAD request. - * @param pdev: instance - * @param req: pointer to the request structure - * @retval status - */ -static void DFU_Req_UPLOAD(void *pdev, USB_SETUP_REQ *req) -{ - uint8_t *Phy_Addr = NULL; - uint32_t Addr = 0; - - /* Data setup request */ - if (req->wLength > 0) - { - if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuUPLOAD_IDLE)) - { - /* Update the global langth and block number */ - wBlockNum = req->wValue; - wlength = req->wLength; - - /* DFU Get Command */ - if (wBlockNum == 0) - { - /* Update the state machine */ - DeviceState = (wlength > 3)? STATE_dfuIDLE:STATE_dfuUPLOAD_IDLE; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - - /* Store the values of all supported commands */ - MAL_Buffer[0] = CMD_GETCOMMANDS; - MAL_Buffer[1] = CMD_SETADDRESSPOINTER; - MAL_Buffer[2] = CMD_ERASE; - - /* Send the status data over EP0 */ - USBD_CtlSendData (pdev, - (uint8_t *)(&(MAL_Buffer[0])), - 3); - } - else if (wBlockNum > 1) - { - DeviceState = STATE_dfuUPLOAD_IDLE ; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - Addr = ((wBlockNum - 2) * XFERSIZE) + Pointer; /* Change is Accelerated*/ - - /* Return the physical address where data are stored */ - Phy_Addr = MAL_Read(Addr, wlength); - - /* Send the status data over EP0 */ - USBD_CtlSendData (pdev, - Phy_Addr, - wlength); - } - else /* unsupported wBlockNum */ - { - DeviceState = STATUS_ERRSTALLEDPKT; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - } - /* Unsupported state */ - else - { - wlength = 0; - wBlockNum = 0; - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - } - /* No Data setup request */ - else - { - DeviceState = STATE_dfuIDLE; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - DeviceStatus[4] = DeviceState; - } -} - -/** - * @brief DFU_Req_GETSTATUS - * Handles the DFU GETSTATUS request. - * @param pdev: instance - * @retval status - */ -static void DFU_Req_GETSTATUS(void *pdev) -{ - switch (DeviceState) - { - case STATE_dfuDNLOAD_SYNC: - if (wlength != 0) - { - DeviceState = STATE_dfuDNBUSY; - DeviceStatus[4] = DeviceState; - if ((wBlockNum == 0) && (MAL_Buffer[0] == CMD_ERASE)) - { - MAL_GetStatus(Pointer, 0, DeviceStatus); - } - else - { - MAL_GetStatus(Pointer, 1, DeviceStatus); - } - } - else /* (wlength==0)*/ - { - DeviceState = STATE_dfuDNLOAD_IDLE; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - } - break; - - case STATE_dfuMANIFEST_SYNC : - if (Manifest_State == Manifest_In_Progress) - { - DeviceState = STATE_dfuMANIFEST; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 1; /*bwPollTimeout = 1ms*/ - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - //break; - } - else if ((Manifest_State == Manifest_complete) && \ - ((usbd_dfu_CfgDesc[(11 + (9 * USBD_ITF_MAX_NUM))]) & 0x04)) - { - DeviceState = STATE_dfuIDLE; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - //break; - } - break; - - default : - break; - } - - /* Send the status data over EP0 */ - USBD_CtlSendData (pdev, - (uint8_t *)(&(DeviceStatus[0])), - 6); -} - -/** - * @brief DFU_Req_CLRSTATUS - * Handles the DFU CLRSTATUS request. - * @param pdev: device instance - * @retval status - */ -static void DFU_Req_CLRSTATUS(void *pdev) -{ - if (DeviceState == STATE_dfuERROR) - { - DeviceState = STATE_dfuIDLE; - DeviceStatus[0] = STATUS_OK;/*bStatus*/ - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ - DeviceStatus[4] = DeviceState;/*bState*/ - DeviceStatus[5] = 0;/*iString*/ - } - else - { /*State Error*/ - DeviceState = STATE_dfuERROR; - DeviceStatus[0] = STATUS_ERRUNKNOWN;/*bStatus*/ - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ - DeviceStatus[4] = DeviceState;/*bState*/ - DeviceStatus[5] = 0;/*iString*/ - } -} - -/** - * @brief DFU_Req_GETSTATE - * Handles the DFU GETSTATE request. - * @param pdev: device instance - * @retval None - */ -static void DFU_Req_GETSTATE(void *pdev) -{ - /* Return the current state of the DFU interface */ - USBD_CtlSendData (pdev, - &DeviceState, - 1); -} - -/** - * @brief DFU_Req_ABORT - * Handles the DFU ABORT request. - * @param pdev: device instance - * @retval None - */ -static void DFU_Req_ABORT(void *pdev) -{ - if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC - || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC - || DeviceState == STATE_dfuUPLOAD_IDLE ) - { - DeviceState = STATE_dfuIDLE; - DeviceStatus[0] = STATUS_OK; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ - DeviceStatus[4] = DeviceState; - DeviceStatus[5] = 0; /*iString*/ - wBlockNum = 0; - wlength = 0; - } -} - -/** - * @brief DFU_LeaveDFUMode - * Handles the sub-protocol DFU leave DFU mode request (leaves DFU mode - * and resets device to jump to user loaded code). - * @param pdev: device instance - * @retval None - */ -void DFU_LeaveDFUMode(void *pdev) -{ - Manifest_State = Manifest_complete; - - if ((usbd_dfu_CfgDesc[(11 + (9 * USBD_ITF_MAX_NUM))]) & 0x04) - { - DeviceState = STATE_dfuMANIFEST_SYNC; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - return; - } - else - { - DeviceState = STATE_dfuMANIFEST_WAIT_RESET; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - - /* Disconnect the USB device */ - DCD_DevDisconnect (pdev); - - /* DeInitilialize the MAL(Media Access Layer) */ - MAL_DeInit(); - - /* Generate system reset to allow jumping to the user code */ - NVIC_SystemReset(); - - /* This instruction will not be reached (system reset) */ - return; - } -} - -/** - * @brief USBD_DFU_GetCfgDesc - * Returns configuration descriptor - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_DFU_GetCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (usbd_dfu_CfgDesc); - return usbd_dfu_CfgDesc; -} - -#ifdef USB_OTG_HS_CORE -/** - * @brief USBD_DFU_GetOtherCfgDesc - * Returns other speed configuration descriptor. - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_DFU_GetOtherCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (usbd_dfu_OtherCfgDesc); - return usbd_dfu_OtherCfgDesc; -} -#endif - -/** - * @brief USBD_DFU_GetUsrStringDesc - * Manages the transfer of memory interfaces string descriptors. - * @param speed : current device speed - * @param index: desciptor index - * @param length : pointer data length - * @retval pointer to the descriptor table or NULL if the descriptor is not supported. - */ -static uint8_t* USBD_DFU_GetUsrStringDesc (uint8_t speed, uint8_t index , uint16_t *length) -{ - /* Check if the requested string interface is supported */ - if (index <= (USBD_IDX_INTERFACE_STR + USBD_ITF_MAX_NUM)) - { - - - USBD_GetString ((uint8_t *)usbd_dfu_StringDesc[index - USBD_IDX_INTERFACE_STR - 1], USBD_StrDesc, length); - return USBD_StrDesc; - } - /* Not supported Interface Descriptor index */ - else - { - return NULL; - } -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_dfu_core.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB DFU Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as DFU Device (and enumeration for each implemented memory interface) + * - Transfers to/from memory interfaces + * - Easy-to-customize "plug-in-like" modules for adding/removing memory interfaces. + * - Error management + * + * @verbatim + * + * =================================================================== + * DFU Class Driver Description + * =================================================================== + * This driver manages the DFU class V1.1 following the "Device Class Specification for + * Device Firmware Upgrade Version 1.1 Aug 5, 2004". + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as DFU device (in DFU mode only) + * - Requests management (supporting ST DFU sub-protocol) + * - Memory operations management (Download/Upload/Erase/Detach/GetState/GetStatus) + * - DFU state machine implementation. + * + * @note + * ST DFU sub-protocol is compliant with DFU protocol and use sub-requests to manage + * memory addressing, commands processing, specific memories operations (ie. Erase) ... + * As required by the DFU specification, only endpoint 0 is used in this application. + * Other endpoints and functions may be added to the application (ie. DFU ...) + * + * These aspects may be enriched or modified for a specific user application. + * + * This driver doesn't implement the following aspects of the specification + * (but it is possible to manage these features with some modifications on this driver): + * - Manifestation Tolerant mode + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_dfu_core.h" +#include "usbd_desc.h" +#include "usbd_req.h" +#include "usb_bsp.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup usbd_dfu + * @brief usbd core module + * @{ + */ + +/** @defgroup usbd_dfu_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_dfu_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_dfu_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup usbd_dfu_Private_FunctionPrototypes + * @{ + */ + +/********************************************* + DFU Device library callbacks + *********************************************/ +static uint8_t usbd_dfu_Init (void *pdev, + uint8_t cfgidx); + +static uint8_t usbd_dfu_DeInit (void *pdev, + uint8_t cfgidx); + +static uint8_t usbd_dfu_Setup (void *pdev, + USB_SETUP_REQ *req); + +static uint8_t EP0_TxSent (void *pdev); + +static uint8_t EP0_RxReady (void *pdev); + + +static uint8_t *USBD_DFU_GetCfgDesc (uint8_t speed, + uint16_t *length); + + +#ifdef USB_OTG_HS_CORE +static uint8_t *USBD_DFU_GetOtherCfgDesc (uint8_t speed, + uint16_t *length); +#endif + +static uint8_t* USBD_DFU_GetUsrStringDesc (uint8_t speed, + uint8_t index , + uint16_t *length); + +/********************************************* + DFU Requests management functions + *********************************************/ +static void DFU_Req_DETACH (void *pdev, + USB_SETUP_REQ *req); + +static void DFU_Req_DNLOAD (void *pdev, + USB_SETUP_REQ *req); + +static void DFU_Req_UPLOAD (void *pdev, + USB_SETUP_REQ *req); + +static void DFU_Req_GETSTATUS (void *pdev); + +static void DFU_Req_CLRSTATUS (void *pdev); + +static void DFU_Req_GETSTATE (void *pdev); + +static void DFU_Req_ABORT (void *pdev); + +static void DFU_LeaveDFUMode (void *pdev); + +/** + * @} + */ + +/** @defgroup usbd_dfu_Private_Variables + * @{ + */ +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t usbd_dfu_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END ; + + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t usbd_dfu_OtherCfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END ; + +/* The list of Interface String descriptor pointers is defined in usbd_dfu_mal.c + file. This list can be updated whenever a memory has to be added or removed */ +extern const uint8_t* usbd_dfu_StringDesc[]; + +/* State Machine variables */ +uint8_t DeviceState; +uint8_t DeviceStatus[6]; +uint32_t Manifest_State = Manifest_complete; +/* Data Management variables */ +static uint32_t wBlockNum = 0, wlength = 0; +static uint32_t Pointer = APP_DEFAULT_ADD; /* Base Address to Erase, Program or Read */ +static __IO uint32_t usbd_dfu_AltSet = 0; + +extern uint8_t MAL_Buffer[]; + +/* DFU interface class callbacks structure */ +USBD_Class_cb_TypeDef DFU_cb = +{ + usbd_dfu_Init, + usbd_dfu_DeInit, + usbd_dfu_Setup, + EP0_TxSent, + EP0_RxReady, + NULL, /* DataIn, */ + NULL, /* DataOut, */ + NULL, /*SOF */ + NULL, + NULL, + USBD_DFU_GetCfgDesc, +#ifdef USB_OTG_HS_CORE + USBD_DFU_GetOtherCfgDesc, /* use same cobfig as per FS */ +#endif + USBD_DFU_GetUsrStringDesc, +}; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +/* USB DFU device Configuration Descriptor */ +__ALIGN_BEGIN uint8_t usbd_dfu_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuation Descriptor size */ + USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ + USB_DFU_CONFIG_DESC_SIZ, + /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /*bNumInterfaces: 1 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ + 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + /* 09 */ + + /********** Descriptor of DFU interface 0 Alternate setting 0 **************/ + USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */ + +#if (USBD_ITF_MAX_NUM > 1) + /********** Descriptor of DFU interface 0 Alternate setting 1 **************/ + USBD_DFU_IF_DESC(1), +#endif /* (USBD_ITF_MAX_NUM > 1) */ + +#if (USBD_ITF_MAX_NUM > 2) + /********** Descriptor of DFU interface 0 Alternate setting 2 **************/ + USBD_DFU_IF_DESC(2), +#endif /* (USBD_ITF_MAX_NUM > 2) */ + +#if (USBD_ITF_MAX_NUM > 3) + /********** Descriptor of DFU interface 0 Alternate setting 3 **************/ + USBD_DFU_IF_DESC(3), +#endif /* (USBD_ITF_MAX_NUM > 3) */ + +#if (USBD_ITF_MAX_NUM > 4) + /********** Descriptor of DFU interface 0 Alternate setting 4 **************/ + USBD_DFU_IF_DESC(4), +#endif /* (USBD_ITF_MAX_NUM > 4) */ + +#if (USBD_ITF_MAX_NUM > 5) + /********** Descriptor of DFU interface 0 Alternate setting 5 **************/ + USBD_DFU_IF_DESC(5), +#endif /* (USBD_ITF_MAX_NUM > 5) */ + +#if (USBD_ITF_MAX_NUM > 6) +#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!" +#endif /* (USBD_ITF_MAX_NUM > 6) */ + + /******************** DFU Functional Descriptor********************/ + 0x09, /*blength = 9 Bytes*/ + DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ + 0x0B, /*bmAttribute + bitCanDnload = 1 (bit 0) + bitCanUpload = 1 (bit 1) + bitManifestationTolerant = 0 (bit 2) + bitWillDetach = 1 (bit 3) + Reserved (bit4-6) + bitAcceleratedST = 0 (bit 7)*/ + 0xFF, /*DetachTimeOut= 255 ms*/ + 0x00, + /*WARNING: In DMA mode the multiple MPS packets feature is still not supported + ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */ + TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/ + 0x1A, /* bcdDFUVersion*/ + 0x01 + /***********************************************************/ + /* 9*/ +} ; + +#ifdef USE_USB_OTG_HS +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + +__ALIGN_BEGIN uint8_t usbd_dfu_OtherCfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_DFU_CONFIG_DESC_SIZ, + /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /*bNumInterfaces: 1 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ + 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + /* 09 */ + + /********** Descriptor of DFU interface 0 Alternate setting 0 **************/ + USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */ + +#if (USBD_ITF_MAX_NUM > 1) + /********** Descriptor of DFU interface 0 Alternate setting 1 **************/ + USBD_DFU_IF_DESC(1), +#endif /* (USBD_ITF_MAX_NUM > 1) */ + +#if (USBD_ITF_MAX_NUM > 2) + /********** Descriptor of DFU interface 0 Alternate setting 2 **************/ + USBD_DFU_IF_DESC(2), +#endif /* (USBD_ITF_MAX_NUM > 2) */ + +#if (USBD_ITF_MAX_NUM > 3) + /********** Descriptor of DFU interface 0 Alternate setting 3 **************/ + USBD_DFU_IF_DESC(3), +#endif /* (USBD_ITF_MAX_NUM > 3) */ + +#if (USBD_ITF_MAX_NUM > 4) + /********** Descriptor of DFU interface 0 Alternate setting 4 **************/ + USBD_DFU_IF_DESC(4), +#endif /* (USBD_ITF_MAX_NUM > 4) */ + +#if (USBD_ITF_MAX_NUM > 5) + /********** Descriptor of DFU interface 0 Alternate setting 5 **************/ + USBD_DFU_IF_DESC(5), +#endif /* (USBD_ITF_MAX_NUM > 5) */ + +#if (USBD_ITF_MAX_NUM > 6) +#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!" +#endif /* (USBD_ITF_MAX_NUM > 6) */ + + /******************** DFU Functional Descriptor********************/ + 0x09, /*blength = 9 Bytes*/ + DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ + 0x0B, /*bmAttribute + bitCanDnload = 1 (bit 0) + bitCanUpload = 1 (bit 1) + bitManifestationTolerant = 0 (bit 2) + bitWillDetach = 1 (bit 3) + Reserved (bit4-6) + bitAcceleratedST = 0 (bit 7)*/ + 0xFF, /*DetachTimeOut= 255 ms*/ + 0x00, + /*WARNING: In DMA mode the multiple MPS packets feature is still not supported + ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */ + TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/ + 0x1A, /* bcdDFUVersion*/ + 0x01 + /***********************************************************/ + /* 9*/ +}; +#endif /* USE_USB_OTG_HS */ + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif + +__ALIGN_BEGIN static uint8_t usbd_dfu_Desc[USB_DFU_DESC_SIZ] __ALIGN_END = +{ + 0x09, /*blength = 9 Bytes*/ + DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ + 0x0B, /*bmAttribute + bitCanDnload = 1 (bit 0) + bitCanUpload = 1 (bit 1) + bitManifestationTolerant = 0 (bit 2) + bitWillDetach = 1 (bit 3) + Reserved (bit4-6) + bitAcceleratedST = 0 (bit 7)*/ + 0xFF, /*DetachTimeOut= 255 ms*/ + 0x00, + /*WARNING: In DMA mode the multiple MPS packets feature is still not supported + ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */ + TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/ + 0x1A, /* bcdDFUVersion*/ + 0x01 +}; +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + +/** + * @} + */ + +/** @defgroup usbd_dfu_Private_Functions + * @{ + */ + +/** + * @brief usbd_dfu_Init + * Initializes the DFU interface. + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t usbd_dfu_Init (void *pdev, + uint8_t cfgidx) +{ + /* Initilialize the MAL(Media Access Layer) */ + MAL_Init(); + + /* Initialize the state of the DFU interface */ + DeviceState = STATE_dfuIDLE; + DeviceStatus[0] = STATUS_OK; + DeviceStatus[4] = DeviceState; + + return USBD_OK; +} + +/** + * @brief usbd_dfu_Init + * De-initializes the DFU layer. + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t usbd_dfu_DeInit (void *pdev, + uint8_t cfgidx) +{ + /* Restore default state */ + DeviceState = STATE_dfuIDLE; + DeviceStatus[0] = STATUS_OK; + DeviceStatus[4] = DeviceState; + wBlockNum = 0; + wlength = 0; + + /* DeInitilialize the MAL(Media Access Layer) */ + MAL_DeInit(); + + return USBD_OK; +} + +/** + * @brief usbd_dfu_Setup + * Handles the DFU request parsing. + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t usbd_dfu_Setup (void *pdev, + USB_SETUP_REQ *req) +{ + uint16_t len = 0; + uint8_t *pbuf = NULL; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + /* DFU Class Requests -------------------------------*/ + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + case DFU_DNLOAD: + DFU_Req_DNLOAD(pdev, req); + break; + + case DFU_UPLOAD: + DFU_Req_UPLOAD(pdev, req); + break; + + case DFU_GETSTATUS: + DFU_Req_GETSTATUS(pdev); + break; + + case DFU_CLRSTATUS: + DFU_Req_CLRSTATUS(pdev); + break; + + case DFU_GETSTATE: + DFU_Req_GETSTATE(pdev); + break; + + case DFU_ABORT: + DFU_Req_ABORT(pdev); + break; + + case DFU_DETACH: + DFU_Req_DETACH(pdev, req); + break; + + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + } + break; + + /* Standard Requests -------------------------------*/ + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( (req->wValue >> 8) == DFU_DESCRIPTOR_TYPE) + { +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + pbuf = usbd_dfu_Desc; +#else + pbuf = usbd_dfu_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM); +#endif + len = MIN(USB_DFU_DESC_SIZ , req->wLength); + } + + USBD_CtlSendData (pdev, + pbuf, + len); + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&usbd_dfu_AltSet, + 1); + break; + + case USB_REQ_SET_INTERFACE : + if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM) + { + usbd_dfu_AltSet = (uint8_t)(req->wValue); + } + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + break; + } + } + return USBD_OK; +} + +/** + * @brief EP0_TxSent + * Handles the DFU control endpoint data IN stage. + * @param pdev: device instance + * @retval status + */ +static uint8_t EP0_TxSent (void *pdev) +{ + uint32_t Addr; + USB_SETUP_REQ req; + + if (DeviceState == STATE_dfuDNBUSY) + { + /* Decode the Special Command*/ + if (wBlockNum == 0) + { + if ((MAL_Buffer[0] == CMD_GETCOMMANDS) && (wlength == 1)) + {} + else if (( MAL_Buffer[0] == CMD_SETADDRESSPOINTER ) && (wlength == 5)) + { + Pointer = MAL_Buffer[1]; + Pointer += MAL_Buffer[2] << 8; + Pointer += MAL_Buffer[3] << 16; + Pointer += MAL_Buffer[4] << 24; + } + else if (( MAL_Buffer[0] == CMD_ERASE ) && (wlength == 5)) + { + Pointer = MAL_Buffer[1]; + Pointer += MAL_Buffer[2] << 8; + Pointer += MAL_Buffer[3] << 16; + Pointer += MAL_Buffer[4] << 24; + MAL_Erase(Pointer); + } + else + { + /* Reset the global length and block number */ + wlength = 0; + wBlockNum = 0; + /* Call the error management function (command will be nacked) */ + req.bmRequest = 0; + req.wLength = 1; + USBD_CtlError (pdev, &req); + } + } + /* Regular Download Command */ + else if (wBlockNum > 1) + { + /* Decode the required address */ + Addr = ((wBlockNum - 2) * XFERSIZE) + Pointer; + + /* Preform the write operation */ + MAL_Write(Addr, wlength); + } + /* Reset the global lenght and block number */ + wlength = 0; + wBlockNum = 0; + + /* Update the state machine */ + DeviceState = STATE_dfuDNLOAD_SYNC; + DeviceStatus[4] = DeviceState; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + return USBD_OK; + } + else if (DeviceState == STATE_dfuMANIFEST)/* Manifestation in progress*/ + { + /* Start leaving DFU mode */ + DFU_LeaveDFUMode(pdev); + } + + return USBD_OK; +} + +/** + * @brief EP0_RxReady + * Handles the DFU control endpoint data OUT stage. + * @param pdev: device instance + * @retval status + */ +static uint8_t EP0_RxReady (void *pdev) +{ + return USBD_OK; +} + + +/****************************************************************************** + DFU Class requests management +******************************************************************************/ +/** + * @brief DFU_Req_DETACH + * Handles the DFU DETACH request. + * @param pdev: device instance + * @param req: pointer to the request structure. + * @retval None. + */ +static void DFU_Req_DETACH(void *pdev, USB_SETUP_REQ *req) +{ + if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC + || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC + || DeviceState == STATE_dfuUPLOAD_IDLE ) + { + /* Update the state machine */ + DeviceState = STATE_dfuIDLE; + DeviceStatus[0] = STATUS_OK; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ + DeviceStatus[4] = DeviceState; + DeviceStatus[5] = 0; /*iString*/ + wBlockNum = 0; + wlength = 0; + } + + /* Check the detach capability in the DFU functional descriptor */ + if ((usbd_dfu_CfgDesc[12 + (9 * USBD_ITF_MAX_NUM)]) & DFU_DETACH_MASK) + { + /* Perform an Attach-Detach operation on USB bus */ + DCD_DevDisconnect (pdev); + DCD_DevConnect (pdev); + } + else + { + /* Wait for the period of time specified in Detach request */ + USB_OTG_BSP_mDelay (req->wValue); + } +} + +/** + * @brief DFU_Req_DNLOAD + * Handles the DFU DNLOAD request. + * @param pdev: device instance + * @param req: pointer to the request structure + * @retval None + */ +static void DFU_Req_DNLOAD(void *pdev, USB_SETUP_REQ *req) +{ + /* Data setup request */ + if (req->wLength > 0) + { + if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuDNLOAD_IDLE)) + { + /* Update the global length and block number */ + wBlockNum = req->wValue; + wlength = req->wLength; + + /* Update the state machine */ + DeviceState = STATE_dfuDNLOAD_SYNC; + DeviceStatus[4] = DeviceState; + + /* Prepare the reception of the buffer over EP0 */ + USBD_CtlPrepareRx (pdev, + (uint8_t*)MAL_Buffer, + wlength); + } + /* Unsupported state */ + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + } + /* 0 Data DNLOAD request */ + else + { + /* End of DNLOAD operation*/ + if (DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuIDLE ) + { + Manifest_State = Manifest_In_Progress; + DeviceState = STATE_dfuMANIFEST_SYNC; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + DeviceStatus[4] = DeviceState; + } + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + } +} + +/** + * @brief DFU_Req_UPLOAD + * Handles the DFU UPLOAD request. + * @param pdev: instance + * @param req: pointer to the request structure + * @retval status + */ +static void DFU_Req_UPLOAD(void *pdev, USB_SETUP_REQ *req) +{ + uint8_t *Phy_Addr = NULL; + uint32_t Addr = 0; + + /* Data setup request */ + if (req->wLength > 0) + { + if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuUPLOAD_IDLE)) + { + /* Update the global langth and block number */ + wBlockNum = req->wValue; + wlength = req->wLength; + + /* DFU Get Command */ + if (wBlockNum == 0) + { + /* Update the state machine */ + DeviceState = (wlength > 3)? STATE_dfuIDLE:STATE_dfuUPLOAD_IDLE; + DeviceStatus[4] = DeviceState; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + + /* Store the values of all supported commands */ + MAL_Buffer[0] = CMD_GETCOMMANDS; + MAL_Buffer[1] = CMD_SETADDRESSPOINTER; + MAL_Buffer[2] = CMD_ERASE; + + /* Send the status data over EP0 */ + USBD_CtlSendData (pdev, + (uint8_t *)(&(MAL_Buffer[0])), + 3); + } + else if (wBlockNum > 1) + { + DeviceState = STATE_dfuUPLOAD_IDLE ; + DeviceStatus[4] = DeviceState; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + Addr = ((wBlockNum - 2) * XFERSIZE) + Pointer; /* Change is Accelerated*/ + + /* Return the physical address where data are stored */ + Phy_Addr = MAL_Read(Addr, wlength); + + /* Send the status data over EP0 */ + USBD_CtlSendData (pdev, + Phy_Addr, + wlength); + } + else /* unsupported wBlockNum */ + { + DeviceState = STATUS_ERRSTALLEDPKT; + DeviceStatus[4] = DeviceState; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + } + /* Unsupported state */ + else + { + wlength = 0; + wBlockNum = 0; + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + } + /* No Data setup request */ + else + { + DeviceState = STATE_dfuIDLE; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + DeviceStatus[4] = DeviceState; + } +} + +/** + * @brief DFU_Req_GETSTATUS + * Handles the DFU GETSTATUS request. + * @param pdev: instance + * @retval status + */ +static void DFU_Req_GETSTATUS(void *pdev) +{ + switch (DeviceState) + { + case STATE_dfuDNLOAD_SYNC: + if (wlength != 0) + { + DeviceState = STATE_dfuDNBUSY; + DeviceStatus[4] = DeviceState; + if ((wBlockNum == 0) && (MAL_Buffer[0] == CMD_ERASE)) + { + MAL_GetStatus(Pointer, 0, DeviceStatus); + } + else + { + MAL_GetStatus(Pointer, 1, DeviceStatus); + } + } + else /* (wlength==0)*/ + { + DeviceState = STATE_dfuDNLOAD_IDLE; + DeviceStatus[4] = DeviceState; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + } + break; + + case STATE_dfuMANIFEST_SYNC : + if (Manifest_State == Manifest_In_Progress) + { + DeviceState = STATE_dfuMANIFEST; + DeviceStatus[4] = DeviceState; + DeviceStatus[1] = 1; /*bwPollTimeout = 1ms*/ + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + //break; + } + else if ((Manifest_State == Manifest_complete) && \ + ((usbd_dfu_CfgDesc[(11 + (9 * USBD_ITF_MAX_NUM))]) & 0x04)) + { + DeviceState = STATE_dfuIDLE; + DeviceStatus[4] = DeviceState; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + //break; + } + break; + + default : + break; + } + + /* Send the status data over EP0 */ + USBD_CtlSendData (pdev, + (uint8_t *)(&(DeviceStatus[0])), + 6); +} + +/** + * @brief DFU_Req_CLRSTATUS + * Handles the DFU CLRSTATUS request. + * @param pdev: device instance + * @retval status + */ +static void DFU_Req_CLRSTATUS(void *pdev) +{ + if (DeviceState == STATE_dfuERROR) + { + DeviceState = STATE_dfuIDLE; + DeviceStatus[0] = STATUS_OK;/*bStatus*/ + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ + DeviceStatus[4] = DeviceState;/*bState*/ + DeviceStatus[5] = 0;/*iString*/ + } + else + { /*State Error*/ + DeviceState = STATE_dfuERROR; + DeviceStatus[0] = STATUS_ERRUNKNOWN;/*bStatus*/ + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ + DeviceStatus[4] = DeviceState;/*bState*/ + DeviceStatus[5] = 0;/*iString*/ + } +} + +/** + * @brief DFU_Req_GETSTATE + * Handles the DFU GETSTATE request. + * @param pdev: device instance + * @retval None + */ +static void DFU_Req_GETSTATE(void *pdev) +{ + /* Return the current state of the DFU interface */ + USBD_CtlSendData (pdev, + &DeviceState, + 1); +} + +/** + * @brief DFU_Req_ABORT + * Handles the DFU ABORT request. + * @param pdev: device instance + * @retval None + */ +static void DFU_Req_ABORT(void *pdev) +{ + if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC + || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC + || DeviceState == STATE_dfuUPLOAD_IDLE ) + { + DeviceState = STATE_dfuIDLE; + DeviceStatus[0] = STATUS_OK; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ + DeviceStatus[4] = DeviceState; + DeviceStatus[5] = 0; /*iString*/ + wBlockNum = 0; + wlength = 0; + } +} + +/** + * @brief DFU_LeaveDFUMode + * Handles the sub-protocol DFU leave DFU mode request (leaves DFU mode + * and resets device to jump to user loaded code). + * @param pdev: device instance + * @retval None + */ +void DFU_LeaveDFUMode(void *pdev) +{ + Manifest_State = Manifest_complete; + + if ((usbd_dfu_CfgDesc[(11 + (9 * USBD_ITF_MAX_NUM))]) & 0x04) + { + DeviceState = STATE_dfuMANIFEST_SYNC; + DeviceStatus[4] = DeviceState; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + return; + } + else + { + DeviceState = STATE_dfuMANIFEST_WAIT_RESET; + DeviceStatus[4] = DeviceState; + DeviceStatus[1] = 0; + DeviceStatus[2] = 0; + DeviceStatus[3] = 0; + + /* Disconnect the USB device */ + DCD_DevDisconnect (pdev); + + /* DeInitilialize the MAL(Media Access Layer) */ + MAL_DeInit(); + + /* Generate system reset to allow jumping to the user code */ + NVIC_SystemReset(); + + /* This instruction will not be reached (system reset) */ + return; + } +} + +/** + * @brief USBD_DFU_GetCfgDesc + * Returns configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_DFU_GetCfgDesc (uint8_t speed, uint16_t *length) +{ + *length = sizeof (usbd_dfu_CfgDesc); + return usbd_dfu_CfgDesc; +} + +#ifdef USB_OTG_HS_CORE +/** + * @brief USBD_DFU_GetOtherCfgDesc + * Returns other speed configuration descriptor. + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_DFU_GetOtherCfgDesc (uint8_t speed, uint16_t *length) +{ + *length = sizeof (usbd_dfu_OtherCfgDesc); + return usbd_dfu_OtherCfgDesc; +} +#endif + +/** + * @brief USBD_DFU_GetUsrStringDesc + * Manages the transfer of memory interfaces string descriptors. + * @param speed : current device speed + * @param index: desciptor index + * @param length : pointer data length + * @retval pointer to the descriptor table or NULL if the descriptor is not supported. + */ +static uint8_t* USBD_DFU_GetUsrStringDesc (uint8_t speed, uint8_t index , uint16_t *length) +{ + /* Check if the requested string interface is supported */ + if (index <= (USBD_IDX_INTERFACE_STR + USBD_ITF_MAX_NUM)) + { + + + USBD_GetString ((uint8_t *)usbd_dfu_StringDesc[index - USBD_IDX_INTERFACE_STR - 1], USBD_StrDesc, length); + return USBD_StrDesc; + } + /* Not supported Interface Descriptor index */ + else + { + return NULL; + } +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c index 94d69522..3d301e93 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c @@ -1,281 +1,281 @@ -/** - ****************************************************************************** - * @file usbd_dfu_mal.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Generic media access Layer. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_dfu_mal.h" - -#include "usbd_flash_if.h" - -#ifdef DFU_MAL_SUPPORT_OTP - #include "usbd_otp_if.h" -#endif - -#ifdef DFU_MAL_SUPPORT_MEM - #include "usbd_mem_if_template.h" -#endif - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ - -/* Global Memories callback and string descriptors reference tables. - To add a new memory, modify the value of MAX_USED_MEDIA in usbd_dfu_mal.h - and add the pointer to the callback structure in this table. - Then add the pointer to the memory string descriptor in usbd_dfu_StringDesc table. - No other operation is required. */ -DFU_MAL_Prop_TypeDef* tMALTab[MAX_USED_MEDIA] = { - &DFU_Flash_cb -#ifdef DFU_MAL_SUPPORT_OTP - , &DFU_Otp_cb -#endif -#ifdef DFU_MAL_SUPPORT_MEM - , &DFU_Mem_cb -#endif -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -__ALIGN_BEGIN const uint8_t* usbd_dfu_StringDesc[MAX_USED_MEDIA] __ALIGN_END = { - FLASH_IF_STRING -#ifdef DFU_MAL_SUPPORT_OTP - , OTP_IF_STRING -#endif -#ifdef DFU_MAL_SUPPORT_MEM - , MEM_IF_STRING -#endif -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* RAM Buffer for Downloaded Data */ -__ALIGN_BEGIN uint8_t MAL_Buffer[XFERSIZE] __ALIGN_END ; - -/* Private function prototypes -----------------------------------------------*/ -static uint8_t MAL_CheckAdd (uint32_t Add); -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief MAL_Init - * Initializes the Media on the STM32 - * @param None - * @retval Result of the opeartion (MAL_OK in all cases) - */ -uint16_t MAL_Init(void) -{ - uint32_t memIdx = 0; - - /* Init all supported memories */ - for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++) - { - /* If the check addres is positive, exit with the memory index */ - if (tMALTab[memIdx]->pMAL_Init != NULL) - { - tMALTab[memIdx]->pMAL_Init(); - } - } - - return MAL_OK; -} - -/** - * @brief MAL_DeInit - * DeInitializes the Media on the STM32 - * @param None - * @retval Result of the opeartion (MAL_OK in all cases) - */ -uint16_t MAL_DeInit(void) -{ - uint32_t memIdx = 0; - - /* Init all supported memories */ - for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++) - { - /* Check if the command is supported */ - if (tMALTab[memIdx]->pMAL_DeInit != NULL) - { - tMALTab[memIdx]->pMAL_DeInit(); - } - } - - return MAL_OK; -} - -/** - * @brief MAL_Erase - * Erase a sector of memory. - * @param Add: Sector address/code - * @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL - */ -uint16_t MAL_Erase(uint32_t Add) -{ - uint32_t memIdx = MAL_CheckAdd(Add); - - /* Check if the area is protected */ - if (DFU_MAL_IS_PROTECTED_AREA(Add)) - { - return MAL_FAIL; - } - - if (memIdx < MAX_USED_MEDIA) - { - /* Check if the command is supported */ - if (tMALTab[memIdx]->pMAL_Erase != NULL) - { - return tMALTab[memIdx]->pMAL_Erase(Add); - } - else - { - return MAL_FAIL; - } - } - else - { - return MAL_FAIL; - } -} - -/** - * @brief MAL_Write - * Write sectors of memory. - * @param Add: Sector address/code - * @param Len: Number of data to be written (in bytes) - * @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL - */ -uint16_t MAL_Write (uint32_t Add, uint32_t Len) -{ - uint32_t memIdx = MAL_CheckAdd(Add); - - /* Check if the area is protected */ - if (DFU_MAL_IS_PROTECTED_AREA(Add)) - { - return MAL_FAIL; - } - - if (memIdx < MAX_USED_MEDIA) - { - /* Check if the command is supported */ - if (tMALTab[memIdx]->pMAL_Write != NULL) - { - return tMALTab[memIdx]->pMAL_Write(Add, Len); - } - else - { - return MAL_FAIL; - } - } - else - { - return MAL_FAIL; - } -} - -/** - * @brief MAL_Read - * Read sectors of memory. - * @param Add: Sector address/code - * @param Len: Number of data to be written (in bytes) - * @retval Buffer pointer - */ -uint8_t *MAL_Read (uint32_t Add, uint32_t Len) -{ - uint32_t memIdx = MAL_CheckAdd(Add); - - if (memIdx < MAX_USED_MEDIA) - { - /* Check if the command is supported */ - if (tMALTab[memIdx]->pMAL_Read != NULL) - { - return tMALTab[memIdx]->pMAL_Read(Add, Len); - } - else - { - return MAL_Buffer; - } - } - else - { - return MAL_Buffer; - } -} - -/** - * @brief MAL_GetStatus - * Get the status of a given memory. - * @param Add: Sector address/code (allow to determine which memory will be addressed) - * @param Cmd: 0 for erase and 1 for write - * @param buffer: pointer to the buffer where the status data will be stored. - * @retval Buffer pointer - */ -uint16_t MAL_GetStatus(uint32_t Add , uint8_t Cmd, uint8_t *buffer) -{ - uint32_t memIdx = MAL_CheckAdd(Add); - - if (memIdx < MAX_USED_MEDIA) - { - if (Cmd & 0x01) - { - SET_POLLING_TIMING(tMALTab[memIdx]->EraseTiming); - } - else - { - SET_POLLING_TIMING(tMALTab[memIdx]->WriteTiming); - } - - return MAL_OK; - } - else - { - return MAL_FAIL; - } -} - -/** - * @brief MAL_CheckAdd - * Determine which memory should be managed. - * @param Add: Sector address/code (allow to determine which memory will be addressed) - * @retval Index of the addressed memory. - */ -static uint8_t MAL_CheckAdd(uint32_t Add) -{ - uint32_t memIdx = 0; - - /* Check with all supported memories */ - for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++) - { - /* If the check addres is positive, exit with the memory index */ - if (tMALTab[memIdx]->pMAL_CheckAdd(Add) == MAL_OK) - { - return memIdx; - } - } - /* If no memory found, return MAX_USED_MEDIA */ - return (MAX_USED_MEDIA); -} - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_dfu_mal.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Generic media access Layer. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_dfu_mal.h" + +#include "usbd_flash_if.h" + +#ifdef DFU_MAL_SUPPORT_OTP + #include "usbd_otp_if.h" +#endif + +#ifdef DFU_MAL_SUPPORT_MEM + #include "usbd_mem_if_template.h" +#endif + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Global Memories callback and string descriptors reference tables. + To add a new memory, modify the value of MAX_USED_MEDIA in usbd_dfu_mal.h + and add the pointer to the callback structure in this table. + Then add the pointer to the memory string descriptor in usbd_dfu_StringDesc table. + No other operation is required. */ +DFU_MAL_Prop_TypeDef* tMALTab[MAX_USED_MEDIA] = { + &DFU_Flash_cb +#ifdef DFU_MAL_SUPPORT_OTP + , &DFU_Otp_cb +#endif +#ifdef DFU_MAL_SUPPORT_MEM + , &DFU_Mem_cb +#endif +}; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + +__ALIGN_BEGIN const uint8_t* usbd_dfu_StringDesc[MAX_USED_MEDIA] __ALIGN_END = { + FLASH_IF_STRING +#ifdef DFU_MAL_SUPPORT_OTP + , OTP_IF_STRING +#endif +#ifdef DFU_MAL_SUPPORT_MEM + , MEM_IF_STRING +#endif +}; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +/* RAM Buffer for Downloaded Data */ +__ALIGN_BEGIN uint8_t MAL_Buffer[XFERSIZE] __ALIGN_END ; + +/* Private function prototypes -----------------------------------------------*/ +static uint8_t MAL_CheckAdd (uint32_t Add); +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief MAL_Init + * Initializes the Media on the STM32 + * @param None + * @retval Result of the opeartion (MAL_OK in all cases) + */ +uint16_t MAL_Init(void) +{ + uint32_t memIdx = 0; + + /* Init all supported memories */ + for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++) + { + /* If the check addres is positive, exit with the memory index */ + if (tMALTab[memIdx]->pMAL_Init != NULL) + { + tMALTab[memIdx]->pMAL_Init(); + } + } + + return MAL_OK; +} + +/** + * @brief MAL_DeInit + * DeInitializes the Media on the STM32 + * @param None + * @retval Result of the opeartion (MAL_OK in all cases) + */ +uint16_t MAL_DeInit(void) +{ + uint32_t memIdx = 0; + + /* Init all supported memories */ + for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++) + { + /* Check if the command is supported */ + if (tMALTab[memIdx]->pMAL_DeInit != NULL) + { + tMALTab[memIdx]->pMAL_DeInit(); + } + } + + return MAL_OK; +} + +/** + * @brief MAL_Erase + * Erase a sector of memory. + * @param Add: Sector address/code + * @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL + */ +uint16_t MAL_Erase(uint32_t Add) +{ + uint32_t memIdx = MAL_CheckAdd(Add); + + /* Check if the area is protected */ + if (DFU_MAL_IS_PROTECTED_AREA(Add)) + { + return MAL_FAIL; + } + + if (memIdx < MAX_USED_MEDIA) + { + /* Check if the command is supported */ + if (tMALTab[memIdx]->pMAL_Erase != NULL) + { + return tMALTab[memIdx]->pMAL_Erase(Add); + } + else + { + return MAL_FAIL; + } + } + else + { + return MAL_FAIL; + } +} + +/** + * @brief MAL_Write + * Write sectors of memory. + * @param Add: Sector address/code + * @param Len: Number of data to be written (in bytes) + * @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL + */ +uint16_t MAL_Write (uint32_t Add, uint32_t Len) +{ + uint32_t memIdx = MAL_CheckAdd(Add); + + /* Check if the area is protected */ + if (DFU_MAL_IS_PROTECTED_AREA(Add)) + { + return MAL_FAIL; + } + + if (memIdx < MAX_USED_MEDIA) + { + /* Check if the command is supported */ + if (tMALTab[memIdx]->pMAL_Write != NULL) + { + return tMALTab[memIdx]->pMAL_Write(Add, Len); + } + else + { + return MAL_FAIL; + } + } + else + { + return MAL_FAIL; + } +} + +/** + * @brief MAL_Read + * Read sectors of memory. + * @param Add: Sector address/code + * @param Len: Number of data to be written (in bytes) + * @retval Buffer pointer + */ +uint8_t *MAL_Read (uint32_t Add, uint32_t Len) +{ + uint32_t memIdx = MAL_CheckAdd(Add); + + if (memIdx < MAX_USED_MEDIA) + { + /* Check if the command is supported */ + if (tMALTab[memIdx]->pMAL_Read != NULL) + { + return tMALTab[memIdx]->pMAL_Read(Add, Len); + } + else + { + return MAL_Buffer; + } + } + else + { + return MAL_Buffer; + } +} + +/** + * @brief MAL_GetStatus + * Get the status of a given memory. + * @param Add: Sector address/code (allow to determine which memory will be addressed) + * @param Cmd: 0 for erase and 1 for write + * @param buffer: pointer to the buffer where the status data will be stored. + * @retval Buffer pointer + */ +uint16_t MAL_GetStatus(uint32_t Add , uint8_t Cmd, uint8_t *buffer) +{ + uint32_t memIdx = MAL_CheckAdd(Add); + + if (memIdx < MAX_USED_MEDIA) + { + if (Cmd & 0x01) + { + SET_POLLING_TIMING(tMALTab[memIdx]->EraseTiming); + } + else + { + SET_POLLING_TIMING(tMALTab[memIdx]->WriteTiming); + } + + return MAL_OK; + } + else + { + return MAL_FAIL; + } +} + +/** + * @brief MAL_CheckAdd + * Determine which memory should be managed. + * @param Add: Sector address/code (allow to determine which memory will be addressed) + * @retval Index of the addressed memory. + */ +static uint8_t MAL_CheckAdd(uint32_t Add) +{ + uint32_t memIdx = 0; + + /* Check with all supported memories */ + for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++) + { + /* If the check addres is positive, exit with the memory index */ + if (tMALTab[memIdx]->pMAL_CheckAdd(Add) == MAL_OK) + { + return memIdx; + } + } + /* If no memory found, return MAX_USED_MEDIA */ + return (MAX_USED_MEDIA); +} + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c index f2b51340..d5604d83 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c @@ -1,221 +1,221 @@ -/** - ****************************************************************************** - * @file usbd_flash_if.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Specific media access Layer for internal flash. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_flash_if.h" -#include "usbd_dfu_mal.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ - -/* Private function prototypes -----------------------------------------------*/ -uint16_t FLASH_If_Init(void); -uint16_t FLASH_If_Erase (uint32_t Add); -uint16_t FLASH_If_Write (uint32_t Add, uint32_t Len); -uint8_t *FLASH_If_Read (uint32_t Add, uint32_t Len); -uint16_t FLASH_If_DeInit(void); -uint16_t FLASH_If_CheckAdd(uint32_t Add); - - -/* Private variables ---------------------------------------------------------*/ -DFU_MAL_Prop_TypeDef DFU_Flash_cb = - { - FLASH_IF_STRING, - FLASH_If_Init, - FLASH_If_DeInit, - FLASH_If_Erase, - FLASH_If_Write, - FLASH_If_Read, - FLASH_If_CheckAdd, - 50, /* Erase Time in ms */ - 50 /* Programming Time in ms */ - }; - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief FLASH_If_Init - * Memory initialization routine. - * @param None - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t FLASH_If_Init(void) -{ - /* Unlock the internal flash */ - FLASH_Unlock(); - - return MAL_OK; -} - -/** - * @brief FLASH_If_DeInit - * Memory deinitialization routine. - * @param None - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t FLASH_If_DeInit(void) -{ - /* Lock the internal flash */ - FLASH_Lock(); - - return MAL_OK; -} - -/******************************************************************************* -* Function Name : FLASH_If_Erase -* Description : Erase sector -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -uint16_t FLASH_If_Erase(uint32_t Add) -{ -#ifdef STM32F2XX - /* Check which sector has to be erased */ - if (Add < 0x08004000) - { - FLASH_EraseSector(FLASH_Sector_0, VoltageRange_3); - } - else if (Add < 0x08008000) - { - FLASH_EraseSector(FLASH_Sector_1, VoltageRange_3); - } - else if (Add < 0x0800C000) - { - FLASH_EraseSector(FLASH_Sector_2, VoltageRange_3); - } - else if (Add < 0x08010000) - { - FLASH_EraseSector(FLASH_Sector_3, VoltageRange_3); - } - else if (Add < 0x08020000) - { - FLASH_EraseSector(FLASH_Sector_4, VoltageRange_3); - } - else if (Add < 0x08040000) - { - FLASH_EraseSector(FLASH_Sector_5, VoltageRange_3); - } - else if (Add < 0x08060000) - { - FLASH_EraseSector(FLASH_Sector_6, VoltageRange_3); - } - else if (Add < 0x08080000) - { - FLASH_EraseSector(FLASH_Sector_7, VoltageRange_3); - } - else if (Add < 0x080A0000) - { - FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3); - } - else if (Add < 0x080C0000) - { - FLASH_EraseSector(FLASH_Sector_9, VoltageRange_3); - } - else if (Add < 0x080E0000) - { - FLASH_EraseSector(FLASH_Sector_10, VoltageRange_3); - } - else if (Add < 0x08100000) - { - FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3); - } - else - { - return MAL_FAIL; - } -#elif defined(STM32F10X_CL) - /* Call the standard Flash erase function */ - FLASH_ErasePage(Add); -#endif /* STM32F2XX */ - - return MAL_OK; -} - -/** - * @brief FLASH_If_Write - * Memory write routine. - * @param Add: Address to be written to. - * @param Len: Number of data to be written (in bytes). - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t FLASH_If_Write(uint32_t Add, uint32_t Len) -{ - uint32_t idx = 0; - - if (Len & 0x3) /* Not an aligned data */ - { - for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++) - { - MAL_Buffer[idx] = 0xFF; - } - } - - /* Data received are Word multiple */ - for (idx = 0; idx < Len; idx = idx + 4) - { - FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx)); - Add += 4; - } - return MAL_OK; -} - -/** - * @brief FLASH_If_Read - * Memory read routine. - * @param Add: Address to be read from. - * @param Len: Number of data to be read (in bytes). - * @retval Pointer to the phyisical address where data should be read. - */ -uint8_t *FLASH_If_Read (uint32_t Add, uint32_t Len) -{ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - uint32_t idx = 0; - for (idx = 0; idx < Len; idx += 4) - { - *(uint32_t*)(MAL_Buffer + idx) = *(uint32_t *)(Add + idx); - } - return (uint8_t*)(MAL_Buffer); -#else - return (uint8_t *)(Add); -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -} - -/** - * @brief FLASH_If_CheckAdd - * Check if the address is an allowed address for this memory. - * @param Add: Address to be checked. - * @param Len: Number of data to be read (in bytes). - * @retval MAL_OK if the address is allowed, MAL_FAIL else. - */ -uint16_t FLASH_If_CheckAdd(uint32_t Add) -{ - if ((Add >= FLASH_START_ADD) && (Add < FLASH_END_ADD)) - { - return MAL_OK; - } - else - { - return MAL_FAIL; - } -} -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_flash_if.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Specific media access Layer for internal flash. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_flash_if.h" +#include "usbd_dfu_mal.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + +/* Private function prototypes -----------------------------------------------*/ +uint16_t FLASH_If_Init(void); +uint16_t FLASH_If_Erase (uint32_t Add); +uint16_t FLASH_If_Write (uint32_t Add, uint32_t Len); +uint8_t *FLASH_If_Read (uint32_t Add, uint32_t Len); +uint16_t FLASH_If_DeInit(void); +uint16_t FLASH_If_CheckAdd(uint32_t Add); + + +/* Private variables ---------------------------------------------------------*/ +DFU_MAL_Prop_TypeDef DFU_Flash_cb = + { + FLASH_IF_STRING, + FLASH_If_Init, + FLASH_If_DeInit, + FLASH_If_Erase, + FLASH_If_Write, + FLASH_If_Read, + FLASH_If_CheckAdd, + 50, /* Erase Time in ms */ + 50 /* Programming Time in ms */ + }; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief FLASH_If_Init + * Memory initialization routine. + * @param None + * @retval MAL_OK if operation is successeful, MAL_FAIL else. + */ +uint16_t FLASH_If_Init(void) +{ + /* Unlock the internal flash */ + FLASH_Unlock(); + + return MAL_OK; +} + +/** + * @brief FLASH_If_DeInit + * Memory deinitialization routine. + * @param None + * @retval MAL_OK if operation is successeful, MAL_FAIL else. + */ +uint16_t FLASH_If_DeInit(void) +{ + /* Lock the internal flash */ + FLASH_Lock(); + + return MAL_OK; +} + +/******************************************************************************* +* Function Name : FLASH_If_Erase +* Description : Erase sector +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +uint16_t FLASH_If_Erase(uint32_t Add) +{ +#ifdef STM32F2XX + /* Check which sector has to be erased */ + if (Add < 0x08004000) + { + FLASH_EraseSector(FLASH_Sector_0, VoltageRange_3); + } + else if (Add < 0x08008000) + { + FLASH_EraseSector(FLASH_Sector_1, VoltageRange_3); + } + else if (Add < 0x0800C000) + { + FLASH_EraseSector(FLASH_Sector_2, VoltageRange_3); + } + else if (Add < 0x08010000) + { + FLASH_EraseSector(FLASH_Sector_3, VoltageRange_3); + } + else if (Add < 0x08020000) + { + FLASH_EraseSector(FLASH_Sector_4, VoltageRange_3); + } + else if (Add < 0x08040000) + { + FLASH_EraseSector(FLASH_Sector_5, VoltageRange_3); + } + else if (Add < 0x08060000) + { + FLASH_EraseSector(FLASH_Sector_6, VoltageRange_3); + } + else if (Add < 0x08080000) + { + FLASH_EraseSector(FLASH_Sector_7, VoltageRange_3); + } + else if (Add < 0x080A0000) + { + FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3); + } + else if (Add < 0x080C0000) + { + FLASH_EraseSector(FLASH_Sector_9, VoltageRange_3); + } + else if (Add < 0x080E0000) + { + FLASH_EraseSector(FLASH_Sector_10, VoltageRange_3); + } + else if (Add < 0x08100000) + { + FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3); + } + else + { + return MAL_FAIL; + } +#elif defined(STM32F10X_CL) + /* Call the standard Flash erase function */ + FLASH_ErasePage(Add); +#endif /* STM32F2XX */ + + return MAL_OK; +} + +/** + * @brief FLASH_If_Write + * Memory write routine. + * @param Add: Address to be written to. + * @param Len: Number of data to be written (in bytes). + * @retval MAL_OK if operation is successeful, MAL_FAIL else. + */ +uint16_t FLASH_If_Write(uint32_t Add, uint32_t Len) +{ + uint32_t idx = 0; + + if (Len & 0x3) /* Not an aligned data */ + { + for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++) + { + MAL_Buffer[idx] = 0xFF; + } + } + + /* Data received are Word multiple */ + for (idx = 0; idx < Len; idx = idx + 4) + { + FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx)); + Add += 4; + } + return MAL_OK; +} + +/** + * @brief FLASH_If_Read + * Memory read routine. + * @param Add: Address to be read from. + * @param Len: Number of data to be read (in bytes). + * @retval Pointer to the phyisical address where data should be read. + */ +uint8_t *FLASH_If_Read (uint32_t Add, uint32_t Len) +{ +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + uint32_t idx = 0; + for (idx = 0; idx < Len; idx += 4) + { + *(uint32_t*)(MAL_Buffer + idx) = *(uint32_t *)(Add + idx); + } + return (uint8_t*)(MAL_Buffer); +#else + return (uint8_t *)(Add); +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +} + +/** + * @brief FLASH_If_CheckAdd + * Check if the address is an allowed address for this memory. + * @param Add: Address to be checked. + * @param Len: Number of data to be read (in bytes). + * @retval MAL_OK if the address is allowed, MAL_FAIL else. + */ +uint16_t FLASH_If_CheckAdd(uint32_t Add) +{ + if ((Add >= FLASH_START_ADD) && (Add < FLASH_END_ADD)) + { + return MAL_OK; + } + else + { + return MAL_FAIL; + } +} +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c index 7e01472c..4295e40f 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c @@ -1,133 +1,133 @@ -/** - ****************************************************************************** - * @file usbd_mem_if_template.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Specific media access Layer for a template memory. This file is - provided as template example showing how to implement a new memory - interface based on pre-defined API. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_mem_if_template.h" -#include "usbd_dfu_mal.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ - -/* Private function prototypes -----------------------------------------------*/ -uint16_t MEM_If_Init(void); -uint16_t MEM_If_Erase (uint32_t Add); -uint16_t MEM_If_Write (uint32_t Add, uint32_t Len); -uint8_t *MEM_If_Read (uint32_t Add, uint32_t Len); -uint16_t MEM_If_DeInit(void); -uint16_t MEM_If_CheckAdd(uint32_t Add); - - -/* Private variables ---------------------------------------------------------*/ -DFU_MAL_Prop_TypeDef DFU_Mem_cb = - { - MEM_IF_STRING, - MEM_If_Init, - MEM_If_DeInit, - MEM_If_Erase, - MEM_If_Write, - MEM_If_Read, - MEM_If_CheckAdd, - 10, /* Erase Time in ms */ - 10 /* Programming Time in ms */ - }; - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief MEM_If_Init - * Memory initialization routine. - * @param None - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t MEM_If_Init(void) -{ - return MAL_OK; -} - -/** - * @brief MEM_If_DeInit - * Memory deinitialization routine. - * @param None - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t MEM_If_DeInit(void) -{ - return MAL_OK; -} - -/** - * @brief MEM_If_Erase - * Erase sector. - * @param Add: Address of sector to be erased. - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t MEM_If_Erase(uint32_t Add) -{ - return MAL_OK; -} - -/** - * @brief MEM_If_Write - * Memory write routine. - * @param Add: Address to be written to. - * @param Len: Number of data to be written (in bytes). - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t MEM_If_Write(uint32_t Add, uint32_t Len) -{ - return MAL_OK; -} - -/** - * @brief MEM_If_Read - * Memory read routine. - * @param Add: Address to be read from. - * @param Len: Number of data to be read (in bytes). - * @retval Pointer to the phyisical address where data should be read. - */ -uint8_t *MEM_If_Read (uint32_t Add, uint32_t Len) -{ - /* Return a valid address to avoid HardFault */ - return (uint8_t*)(MAL_Buffer); -} - -/** - * @brief MEM_If_CheckAdd - * Check if the address is an allowed address for this memory. - * @param Add: Address to be checked. - * @param Len: Number of data to be read (in bytes). - * @retval MAL_OK if the address is allowed, MAL_FAIL else. - */ -uint16_t MEM_If_CheckAdd(uint32_t Add) -{ - if ((Add >= MEM_START_ADD) && (Add < MEM_END_ADD)) - { - return MAL_OK; - } - else - { - return MAL_FAIL; - } -} -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_mem_if_template.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Specific media access Layer for a template memory. This file is + provided as template example showing how to implement a new memory + interface based on pre-defined API. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_mem_if_template.h" +#include "usbd_dfu_mal.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + +/* Private function prototypes -----------------------------------------------*/ +uint16_t MEM_If_Init(void); +uint16_t MEM_If_Erase (uint32_t Add); +uint16_t MEM_If_Write (uint32_t Add, uint32_t Len); +uint8_t *MEM_If_Read (uint32_t Add, uint32_t Len); +uint16_t MEM_If_DeInit(void); +uint16_t MEM_If_CheckAdd(uint32_t Add); + + +/* Private variables ---------------------------------------------------------*/ +DFU_MAL_Prop_TypeDef DFU_Mem_cb = + { + MEM_IF_STRING, + MEM_If_Init, + MEM_If_DeInit, + MEM_If_Erase, + MEM_If_Write, + MEM_If_Read, + MEM_If_CheckAdd, + 10, /* Erase Time in ms */ + 10 /* Programming Time in ms */ + }; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief MEM_If_Init + * Memory initialization routine. + * @param None + * @retval MAL_OK if operation is successeful, MAL_FAIL else. + */ +uint16_t MEM_If_Init(void) +{ + return MAL_OK; +} + +/** + * @brief MEM_If_DeInit + * Memory deinitialization routine. + * @param None + * @retval MAL_OK if operation is successeful, MAL_FAIL else. + */ +uint16_t MEM_If_DeInit(void) +{ + return MAL_OK; +} + +/** + * @brief MEM_If_Erase + * Erase sector. + * @param Add: Address of sector to be erased. + * @retval MAL_OK if operation is successeful, MAL_FAIL else. + */ +uint16_t MEM_If_Erase(uint32_t Add) +{ + return MAL_OK; +} + +/** + * @brief MEM_If_Write + * Memory write routine. + * @param Add: Address to be written to. + * @param Len: Number of data to be written (in bytes). + * @retval MAL_OK if operation is successeful, MAL_FAIL else. + */ +uint16_t MEM_If_Write(uint32_t Add, uint32_t Len) +{ + return MAL_OK; +} + +/** + * @brief MEM_If_Read + * Memory read routine. + * @param Add: Address to be read from. + * @param Len: Number of data to be read (in bytes). + * @retval Pointer to the phyisical address where data should be read. + */ +uint8_t *MEM_If_Read (uint32_t Add, uint32_t Len) +{ + /* Return a valid address to avoid HardFault */ + return (uint8_t*)(MAL_Buffer); +} + +/** + * @brief MEM_If_CheckAdd + * Check if the address is an allowed address for this memory. + * @param Add: Address to be checked. + * @param Len: Number of data to be read (in bytes). + * @retval MAL_OK if the address is allowed, MAL_FAIL else. + */ +uint16_t MEM_If_CheckAdd(uint32_t Add) +{ + if ((Add >= MEM_START_ADD) && (Add < MEM_END_ADD)) + { + return MAL_OK; + } + else + { + return MAL_FAIL; + } +} +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c index 292fc625..5970c0ea 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c @@ -1,120 +1,120 @@ -/** - ****************************************************************************** - * @file usbd_otp_if.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Specific media access Layer for OTP (One Time Programming) memory. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_otp_if.h" -#include "usbd_dfu_mal.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ - -/* Private function prototypes -----------------------------------------------*/ -uint16_t OTP_If_Write (uint32_t Add, uint32_t Len); -uint8_t *OTP_If_Read (uint32_t Add, uint32_t Len); -uint16_t OTP_If_DeInit(void); -uint16_t OTP_If_CheckAdd(uint32_t Add); - - -/* Private variables ---------------------------------------------------------*/ -DFU_MAL_Prop_TypeDef DFU_Otp_cb = - { - OTP_IF_STRING, - NULL, /* Init not supported*/ - NULL, /* DeInit not supported */ - NULL, /* Erase not supported */ - OTP_If_Write, - OTP_If_Read, - OTP_If_CheckAdd, - 1, /* Erase Time in ms */ - 10 /* Programming Time in ms */ - }; - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief OTP_If_Write - * Memory write routine. - * @param Add: Address to be written to. - * @param Len: Number of data to be written (in bytes). - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t OTP_If_Write(uint32_t Add, uint32_t Len) -{ - uint32_t idx = 0; - - if (Len & 0x3) /* Not an aligned data */ - { - for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++) - { - MAL_Buffer[idx] = 0xFF; - } - } - - /* Data received are Word multiple */ - for (idx = 0; idx < Len; idx = idx + 4) - { - FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx)); - Add += 4; - } - return MAL_OK; -} - -/** - * @brief OTP_If_Read - * Memory read routine. - * @param Add: Address to be read from. - * @param Len: Number of data to be read (in bytes). - * @retval Pointer to the phyisical address where data should be read. - */ -uint8_t *OTP_If_Read (uint32_t Add, uint32_t Len) -{ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - uint32_t idx = 0; - for (idx = 0; idx < Len; idx += 4) - { - *(uint32_t*)(MAL_Buffer + idx) = *(uint32_t *)(Add + idx); - } - return (uint8_t*)(MAL_Buffer); -#else - return (uint8_t*)(Add); -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -} - -/** - * @brief OTP_If_CheckAdd - * Check if the address is an allowed address for this memory. - * @param Add: Address to be checked. - * @param Len: Number of data to be read (in bytes). - * @retval MAL_OK if the address is allowed, MAL_FAIL else. - */ -uint16_t OTP_If_CheckAdd(uint32_t Add) -{ - if ((Add >= OTP_START_ADD) && (Add < OTP_END_ADD)) - { - return MAL_OK; - } - else - { - return MAL_FAIL; - } -} -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_otp_if.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Specific media access Layer for OTP (One Time Programming) memory. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_otp_if.h" +#include "usbd_dfu_mal.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + +/* Private function prototypes -----------------------------------------------*/ +uint16_t OTP_If_Write (uint32_t Add, uint32_t Len); +uint8_t *OTP_If_Read (uint32_t Add, uint32_t Len); +uint16_t OTP_If_DeInit(void); +uint16_t OTP_If_CheckAdd(uint32_t Add); + + +/* Private variables ---------------------------------------------------------*/ +DFU_MAL_Prop_TypeDef DFU_Otp_cb = + { + OTP_IF_STRING, + NULL, /* Init not supported*/ + NULL, /* DeInit not supported */ + NULL, /* Erase not supported */ + OTP_If_Write, + OTP_If_Read, + OTP_If_CheckAdd, + 1, /* Erase Time in ms */ + 10 /* Programming Time in ms */ + }; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief OTP_If_Write + * Memory write routine. + * @param Add: Address to be written to. + * @param Len: Number of data to be written (in bytes). + * @retval MAL_OK if operation is successeful, MAL_FAIL else. + */ +uint16_t OTP_If_Write(uint32_t Add, uint32_t Len) +{ + uint32_t idx = 0; + + if (Len & 0x3) /* Not an aligned data */ + { + for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++) + { + MAL_Buffer[idx] = 0xFF; + } + } + + /* Data received are Word multiple */ + for (idx = 0; idx < Len; idx = idx + 4) + { + FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx)); + Add += 4; + } + return MAL_OK; +} + +/** + * @brief OTP_If_Read + * Memory read routine. + * @param Add: Address to be read from. + * @param Len: Number of data to be read (in bytes). + * @retval Pointer to the phyisical address where data should be read. + */ +uint8_t *OTP_If_Read (uint32_t Add, uint32_t Len) +{ +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + uint32_t idx = 0; + for (idx = 0; idx < Len; idx += 4) + { + *(uint32_t*)(MAL_Buffer + idx) = *(uint32_t *)(Add + idx); + } + return (uint8_t*)(MAL_Buffer); +#else + return (uint8_t*)(Add); +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +} + +/** + * @brief OTP_If_CheckAdd + * Check if the address is an allowed address for this memory. + * @param Add: Address to be checked. + * @param Len: Number of data to be read (in bytes). + * @retval MAL_OK if the address is allowed, MAL_FAIL else. + */ +uint16_t OTP_If_CheckAdd(uint32_t Add) +{ + if ((Add >= OTP_START_ADD) && (Add < OTP_END_ADD)) + { + return MAL_OK; + } + else + { + return MAL_FAIL; + } +} +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h index 65ba74af..d93fc77d 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h @@ -1,110 +1,110 @@ -/** - ****************************************************************************** - * @file usbd_hid_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_hid_core.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_HID_CORE_H_ -#define __USB_HID_CORE_H_ - -#include "usbd_ioreq.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_HID - * @brief This file is the Header file for USBD_msc.c - * @{ - */ - - -/** @defgroup USBD_HID_Exported_Defines - * @{ - */ -#define USB_HID_CONFIG_DESC_SIZ 34 -#define USB_HID_DESC_SIZ 9 -#define HID_MOUSE_REPORT_DESC_SIZE 74 - -#define HID_DESCRIPTOR_TYPE 0x21 -#define HID_REPORT_DESC 0x22 - - -#define HID_REQ_SET_PROTOCOL 0x0B -#define HID_REQ_GET_PROTOCOL 0x03 - -#define HID_REQ_SET_IDLE 0x0A -#define HID_REQ_GET_IDLE 0x02 - -#define HID_REQ_SET_REPORT 0x09 -#define HID_REQ_GET_REPORT 0x01 -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ - - -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -extern USBD_Class_cb_TypeDef USBD_HID_cb; -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Functions - * @{ - */ -uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev, - uint8_t *report, - uint16_t len); -/** - * @} - */ - -#endif // __USB_HID_CORE_H_ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_hid_core.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header file for the usbd_hid_core.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#ifndef __USB_HID_CORE_H_ +#define __USB_HID_CORE_H_ + +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_HID + * @brief This file is the Header file for USBD_msc.c + * @{ + */ + + +/** @defgroup USBD_HID_Exported_Defines + * @{ + */ +#define USB_HID_CONFIG_DESC_SIZ 34 +#define USB_HID_DESC_SIZ 9 +#define HID_MOUSE_REPORT_DESC_SIZE 74 + +#define HID_DESCRIPTOR_TYPE 0x21 +#define HID_REPORT_DESC 0x22 + + +#define HID_REQ_SET_PROTOCOL 0x0B +#define HID_REQ_GET_PROTOCOL 0x03 + +#define HID_REQ_SET_IDLE 0x0A +#define HID_REQ_GET_IDLE 0x02 + +#define HID_REQ_SET_REPORT 0x09 +#define HID_REQ_GET_REPORT 0x01 +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_Class_cb_TypeDef USBD_HID_cb; +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev, + uint8_t *report, + uint16_t len); +/** + * @} + */ + +#endif // __USB_HID_CORE_H_ +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c index bd77406b..a56c5ed4 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c @@ -1,460 +1,460 @@ -/** - ****************************************************************************** - * @file usbd_hid_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the HID core functions. - * - * @verbatim - * - * =================================================================== - * HID Class Description - * =================================================================== - * This module manages the HID class V1.11 following the "Device Class Definition - * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". - * This driver implements the following aspects of the specification: - * - The Boot Interface Subclass - * - The Mouse protocol - * - Usage Page : Generic Desktop - * - Usage : Joystick) - * - Collection : Application - * - * @note In HS mode and when the DMA is used, all variables and data structures - * dealing with the DMA during the transaction process should be 32-bit aligned. - * - * - * @endverbatim - * - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_hid_core.h" -#include "usbd_desc.h" -#include "usbd_req.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_HID - * @brief usbd core module - * @{ - */ - -/** @defgroup USBD_HID_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_HID_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_HID_Private_Macros - * @{ - */ -/** - * @} - */ - - - - -/** @defgroup USBD_HID_Private_FunctionPrototypes - * @{ - */ - - -static uint8_t USBD_HID_Init (void *pdev, - uint8_t cfgidx); - -static uint8_t USBD_HID_DeInit (void *pdev, - uint8_t cfgidx); - -static uint8_t USBD_HID_Setup (void *pdev, - USB_SETUP_REQ *req); - -static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length); - -static uint8_t USBD_HID_DataIn (void *pdev, uint8_t epnum); -/** - * @} - */ - -/** @defgroup USBD_HID_Private_Variables - * @{ - */ - -USBD_Class_cb_TypeDef USBD_HID_cb = -{ - USBD_HID_Init, - USBD_HID_DeInit, - USBD_HID_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ - USBD_HID_DataIn, /*DataIn*/ - NULL, /*DataOut*/ - NULL, /*SOF */ - NULL, - NULL, - USBD_HID_GetCfgDesc, -#ifdef USB_OTG_HS_CORE - USBD_HID_GetCfgDesc, /* use same config as per FS */ -#endif -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint32_t USBD_HID_AltSet __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint32_t USBD_HID_Protocol __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint32_t USBD_HID_IdleState __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB HID device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ - USB_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x00, /*iConfiguration: Index of string descriptor describing - the configuration*/ - 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /*bLength: Interface Descriptor size*/ - USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/ - 0x00, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x01, /*bNumEndpoints*/ - 0x03, /*bInterfaceClass: HID*/ - 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ - 0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ - 0, /*iInterface: Index of string descriptor*/ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bcdHID: HID Class Spec release number*/ - 0x01, - 0x00, /*bCountryCode: Hardware target country*/ - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/ - - HID_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - HID_IN_PACKET, /*wMaxPacketSize: 4 Byte max */ - 0x00, - 0x0A, /*bInterval: Polling Interval (10 ms)*/ - /* 34 */ -} ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = -{ - 0x05, 0x01, - 0x09, 0x02, - 0xA1, 0x01, - 0x09, 0x01, - - 0xA1, 0x00, - 0x05, 0x09, - 0x19, 0x01, - 0x29, 0x03, - - 0x15, 0x00, - 0x25, 0x01, - 0x95, 0x03, - 0x75, 0x01, - - 0x81, 0x02, - 0x95, 0x01, - 0x75, 0x05, - 0x81, 0x01, - - 0x05, 0x01, - 0x09, 0x30, - 0x09, 0x31, - 0x09, 0x38, - - 0x15, 0x81, - 0x25, 0x7F, - 0x75, 0x08, - 0x95, 0x03, - - 0x81, 0x06, - 0xC0, 0x09, - 0x3c, 0x05, - 0xff, 0x09, - - 0x01, 0x15, - 0x00, 0x25, - 0x01, 0x75, - 0x01, 0x95, - - 0x02, 0xb1, - 0x22, 0x75, - 0x06, 0x95, - 0x01, 0xb1, - - 0x01, 0xc0 -}; - -/** - * @} - */ - -/** @defgroup USBD_HID_Private_Functions - * @{ - */ - -/** - * @brief USBD_HID_Init - * Initialize the HID interface - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t USBD_HID_Init (void *pdev, - uint8_t cfgidx) -{ - - /* Open EP IN */ - DCD_EP_Open(pdev, - HID_IN_EP, - HID_IN_PACKET, - USB_OTG_EP_INT); - - /* Open EP OUT */ - DCD_EP_Open(pdev, - HID_OUT_EP, - HID_OUT_PACKET, - USB_OTG_EP_INT); - - return USBD_OK; -} - -/** - * @brief USBD_HID_Init - * DeInitialize the HID layer - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t USBD_HID_DeInit (void *pdev, - uint8_t cfgidx) -{ - /* Close HID EPs */ - DCD_EP_Close (pdev , HID_IN_EP); - DCD_EP_Close (pdev , HID_OUT_EP); - - - return USBD_OK; -} - -/** - * @brief USBD_HID_Setup - * Handle the HID specific requests - * @param pdev: instance - * @param req: usb requests - * @retval status - */ -static uint8_t USBD_HID_Setup (void *pdev, - USB_SETUP_REQ *req) -{ - uint16_t len = 0; - uint8_t *pbuf = NULL; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - - - case HID_REQ_SET_PROTOCOL: - USBD_HID_Protocol = (uint8_t)(req->wValue); - break; - - case HID_REQ_GET_PROTOCOL: - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_HID_Protocol, - 1); - break; - - case HID_REQ_SET_IDLE: - USBD_HID_IdleState = (uint8_t)(req->wValue >> 8); - break; - - case HID_REQ_GET_IDLE: - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_HID_IdleState, - 1); - break; - - default: - USBD_CtlError (pdev, req); - return USBD_FAIL; - } - break; - - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if( req->wValue >> 8 == HID_REPORT_DESC) - { - len = MIN(HID_MOUSE_REPORT_DESC_SIZE , req->wLength); - pbuf = HID_MOUSE_ReportDesc; - } - else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE) - { - -//#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED -// pbuf = USBD_HID_Desc; -//#else - pbuf = USBD_HID_CfgDesc + 0x12; -//#endif - len = MIN(USB_HID_DESC_SIZ , req->wLength); - } - - USBD_CtlSendData (pdev, - pbuf, - len); - - break; - - case USB_REQ_GET_INTERFACE : - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_HID_AltSet, - 1); - break; - - case USB_REQ_SET_INTERFACE : - USBD_HID_AltSet = (uint8_t)(req->wValue); - break; - } - } - return USBD_OK; -} - -/** - * @brief USBD_HID_SendReport - * Send HID Report - * @param pdev: device instance - * @param buff: pointer to report - * @retval status - */ -uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev, - uint8_t *report, - uint16_t len) -{ - if (pdev->dev.device_status == USB_OTG_CONFIGURED ) - { - DCD_EP_Tx (pdev, HID_IN_EP, report, len); - } - return USBD_OK; -} - -/** - * @brief USBD_HID_GetCfgDesc - * return configuration descriptor - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (USBD_HID_CfgDesc); - return USBD_HID_CfgDesc; -} - -/** - * @brief USBD_HID_DataIn - * handle data IN Stage - * @param pdev: device instance - * @param epnum: endpoint index - * @retval status - */ -static uint8_t USBD_HID_DataIn (void *pdev, - uint8_t epnum) -{ - - /* Ensure that the FIFO is empty before a new transfer, this condition could - be caused by a new transfer before the end of the previous transfer */ - DCD_EP_Flush(pdev, HID_IN_EP); - return USBD_OK; -} - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_hid_core.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides the HID core functions. + * + * @verbatim + * + * =================================================================== + * HID Class Description + * =================================================================== + * This module manages the HID class V1.11 following the "Device Class Definition + * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". + * This driver implements the following aspects of the specification: + * - The Boot Interface Subclass + * - The Mouse protocol + * - Usage Page : Generic Desktop + * - Usage : Joystick) + * - Collection : Application + * + * @note In HS mode and when the DMA is used, all variables and data structures + * dealing with the DMA during the transaction process should be 32-bit aligned. + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_hid_core.h" +#include "usbd_desc.h" +#include "usbd_req.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_HID + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_HID_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_HID_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_HID_Private_Macros + * @{ + */ +/** + * @} + */ + + + + +/** @defgroup USBD_HID_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_HID_Init (void *pdev, + uint8_t cfgidx); + +static uint8_t USBD_HID_DeInit (void *pdev, + uint8_t cfgidx); + +static uint8_t USBD_HID_Setup (void *pdev, + USB_SETUP_REQ *req); + +static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length); + +static uint8_t USBD_HID_DataIn (void *pdev, uint8_t epnum); +/** + * @} + */ + +/** @defgroup USBD_HID_Private_Variables + * @{ + */ + +USBD_Class_cb_TypeDef USBD_HID_cb = +{ + USBD_HID_Init, + USBD_HID_DeInit, + USBD_HID_Setup, + NULL, /*EP0_TxSent*/ + NULL, /*EP0_RxReady*/ + USBD_HID_DataIn, /*DataIn*/ + NULL, /*DataOut*/ + NULL, /*SOF */ + NULL, + NULL, + USBD_HID_GetCfgDesc, +#ifdef USB_OTG_HS_CORE + USBD_HID_GetCfgDesc, /* use same config as per FS */ +#endif +}; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN static uint32_t USBD_HID_AltSet __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN static uint32_t USBD_HID_Protocol __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN static uint32_t USBD_HID_IdleState __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +/* USB HID device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuration Descriptor size */ + USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ + USB_HID_CONFIG_DESC_SIZ, + /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /*bNumInterfaces: 1 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x00, /*iConfiguration: Index of string descriptor describing + the configuration*/ + 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + + /************** Descriptor of Joystick Mouse interface ****************/ + /* 09 */ + 0x09, /*bLength: Interface Descriptor size*/ + USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/ + 0x00, /*bInterfaceNumber: Number of Interface*/ + 0x00, /*bAlternateSetting: Alternate setting*/ + 0x01, /*bNumEndpoints*/ + 0x03, /*bInterfaceClass: HID*/ + 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ + 0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ + 0, /*iInterface: Index of string descriptor*/ + /******************** Descriptor of Joystick Mouse HID ********************/ + /* 18 */ + 0x09, /*bLength: HID Descriptor size*/ + HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ + 0x11, /*bcdHID: HID Class Spec release number*/ + 0x01, + 0x00, /*bCountryCode: Hardware target country*/ + 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ + 0x22, /*bDescriptorType*/ + HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, + /******************** Descriptor of Mouse endpoint ********************/ + /* 27 */ + 0x07, /*bLength: Endpoint Descriptor size*/ + USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/ + + HID_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/ + 0x03, /*bmAttributes: Interrupt endpoint*/ + HID_IN_PACKET, /*wMaxPacketSize: 4 Byte max */ + 0x00, + 0x0A, /*bInterval: Polling Interval (10 ms)*/ + /* 34 */ +} ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = +{ + 0x05, 0x01, + 0x09, 0x02, + 0xA1, 0x01, + 0x09, 0x01, + + 0xA1, 0x00, + 0x05, 0x09, + 0x19, 0x01, + 0x29, 0x03, + + 0x15, 0x00, + 0x25, 0x01, + 0x95, 0x03, + 0x75, 0x01, + + 0x81, 0x02, + 0x95, 0x01, + 0x75, 0x05, + 0x81, 0x01, + + 0x05, 0x01, + 0x09, 0x30, + 0x09, 0x31, + 0x09, 0x38, + + 0x15, 0x81, + 0x25, 0x7F, + 0x75, 0x08, + 0x95, 0x03, + + 0x81, 0x06, + 0xC0, 0x09, + 0x3c, 0x05, + 0xff, 0x09, + + 0x01, 0x15, + 0x00, 0x25, + 0x01, 0x75, + 0x01, 0x95, + + 0x02, 0xb1, + 0x22, 0x75, + 0x06, 0x95, + 0x01, 0xb1, + + 0x01, 0xc0 +}; + +/** + * @} + */ + +/** @defgroup USBD_HID_Private_Functions + * @{ + */ + +/** + * @brief USBD_HID_Init + * Initialize the HID interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_HID_Init (void *pdev, + uint8_t cfgidx) +{ + + /* Open EP IN */ + DCD_EP_Open(pdev, + HID_IN_EP, + HID_IN_PACKET, + USB_OTG_EP_INT); + + /* Open EP OUT */ + DCD_EP_Open(pdev, + HID_OUT_EP, + HID_OUT_PACKET, + USB_OTG_EP_INT); + + return USBD_OK; +} + +/** + * @brief USBD_HID_Init + * DeInitialize the HID layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_HID_DeInit (void *pdev, + uint8_t cfgidx) +{ + /* Close HID EPs */ + DCD_EP_Close (pdev , HID_IN_EP); + DCD_EP_Close (pdev , HID_OUT_EP); + + + return USBD_OK; +} + +/** + * @brief USBD_HID_Setup + * Handle the HID specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_HID_Setup (void *pdev, + USB_SETUP_REQ *req) +{ + uint16_t len = 0; + uint8_t *pbuf = NULL; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + + + case HID_REQ_SET_PROTOCOL: + USBD_HID_Protocol = (uint8_t)(req->wValue); + break; + + case HID_REQ_GET_PROTOCOL: + USBD_CtlSendData (pdev, + (uint8_t *)&USBD_HID_Protocol, + 1); + break; + + case HID_REQ_SET_IDLE: + USBD_HID_IdleState = (uint8_t)(req->wValue >> 8); + break; + + case HID_REQ_GET_IDLE: + USBD_CtlSendData (pdev, + (uint8_t *)&USBD_HID_IdleState, + 1); + break; + + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( req->wValue >> 8 == HID_REPORT_DESC) + { + len = MIN(HID_MOUSE_REPORT_DESC_SIZE , req->wLength); + pbuf = HID_MOUSE_ReportDesc; + } + else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE) + { + +//#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED +// pbuf = USBD_HID_Desc; +//#else + pbuf = USBD_HID_CfgDesc + 0x12; +//#endif + len = MIN(USB_HID_DESC_SIZ , req->wLength); + } + + USBD_CtlSendData (pdev, + pbuf, + len); + + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&USBD_HID_AltSet, + 1); + break; + + case USB_REQ_SET_INTERFACE : + USBD_HID_AltSet = (uint8_t)(req->wValue); + break; + } + } + return USBD_OK; +} + +/** + * @brief USBD_HID_SendReport + * Send HID Report + * @param pdev: device instance + * @param buff: pointer to report + * @retval status + */ +uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev, + uint8_t *report, + uint16_t len) +{ + if (pdev->dev.device_status == USB_OTG_CONFIGURED ) + { + DCD_EP_Tx (pdev, HID_IN_EP, report, len); + } + return USBD_OK; +} + +/** + * @brief USBD_HID_GetCfgDesc + * return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length) +{ + *length = sizeof (USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; +} + +/** + * @brief USBD_HID_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_HID_DataIn (void *pdev, + uint8_t epnum) +{ + + /* Ensure that the FIFO is empty before a new transfer, this condition could + be caused by a new transfer before the end of the previous transfer */ + DCD_EP_Flush(pdev, HID_IN_EP); + return USBD_OK; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h index 72babe10..64b6d262 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h @@ -1,147 +1,147 @@ -/** - ****************************************************************************** - * @file usbd_msc_bot.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header for the usbd_msc_bot.c file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#include "usbd_core.h" - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_MSC_BOT_H -#define __USBD_MSC_BOT_H - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup MSC_BOT - * @brief This file is the Header file for usbd_bot.c - * @{ - */ - - -/** @defgroup USBD_CORE_Exported_Defines - * @{ - */ -#define BOT_IDLE 0 /* Idle state */ -#define BOT_DATA_OUT 1 /* Data Out state */ -#define BOT_DATA_IN 2 /* Data In state */ -#define BOT_LAST_DATA_IN 3 /* Last Data In Last */ -#define BOT_SEND_DATA 4 /* Send Immediate data */ - -#define BOT_CBW_SIGNATURE 0x43425355 -#define BOT_CSW_SIGNATURE 0x53425355 -#define BOT_CBW_LENGTH 31 -#define BOT_CSW_LENGTH 13 - -/* CSW Status Definitions */ -#define CSW_CMD_PASSED 0x00 -#define CSW_CMD_FAILED 0x01 -#define CSW_PHASE_ERROR 0x02 - -/* BOT Status */ -#define BOT_STATE_NORMAL 0 -#define BOT_STATE_RECOVERY 1 -#define BOT_STATE_ERROR 2 - - -#define DIR_IN 0 -#define DIR_OUT 1 -#define BOTH_DIR 2 - -/** - * @} - */ - -/** @defgroup MSC_CORE_Private_TypesDefinitions - * @{ - */ - -typedef struct _MSC_BOT_CBW -{ - uint32_t dSignature; - uint32_t dTag; - uint32_t dDataLength; - uint8_t bmFlags; - uint8_t bLUN; - uint8_t bCBLength; - uint8_t CB[16]; -} -MSC_BOT_CBW_TypeDef; - - -typedef struct _MSC_BOT_CSW -{ - uint32_t dSignature; - uint32_t dTag; - uint32_t dDataResidue; - uint8_t bStatus; -} -MSC_BOT_CSW_TypeDef; - -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_Types - * @{ - */ - -extern uint8_t MSC_BOT_Data[]; -extern uint16_t MSC_BOT_DataLen; -extern uint8_t MSC_BOT_State; -extern uint8_t MSC_BOT_BurstMode; -extern MSC_BOT_CBW_TypeDef MSC_BOT_cbw; -extern MSC_BOT_CSW_TypeDef MSC_BOT_csw; -/** - * @} - */ -/** @defgroup USBD_CORE_Exported_FunctionsPrototypes - * @{ - */ -void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev); -void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev); -void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev); -void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); - -void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); - -void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev, - uint8_t CSW_Status); - -void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); -/** - * @} - */ - -#endif /* __USBD_MSC_BOT_H */ -/** - * @} - */ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usbd_msc_bot.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header for the usbd_msc_bot.c file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#include "usbd_core.h" + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_BOT_H +#define __USBD_MSC_BOT_H + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup MSC_BOT + * @brief This file is the Header file for usbd_bot.c + * @{ + */ + + +/** @defgroup USBD_CORE_Exported_Defines + * @{ + */ +#define BOT_IDLE 0 /* Idle state */ +#define BOT_DATA_OUT 1 /* Data Out state */ +#define BOT_DATA_IN 2 /* Data In state */ +#define BOT_LAST_DATA_IN 3 /* Last Data In Last */ +#define BOT_SEND_DATA 4 /* Send Immediate data */ + +#define BOT_CBW_SIGNATURE 0x43425355 +#define BOT_CSW_SIGNATURE 0x53425355 +#define BOT_CBW_LENGTH 31 +#define BOT_CSW_LENGTH 13 + +/* CSW Status Definitions */ +#define CSW_CMD_PASSED 0x00 +#define CSW_CMD_FAILED 0x01 +#define CSW_PHASE_ERROR 0x02 + +/* BOT Status */ +#define BOT_STATE_NORMAL 0 +#define BOT_STATE_RECOVERY 1 +#define BOT_STATE_ERROR 2 + + +#define DIR_IN 0 +#define DIR_OUT 1 +#define BOTH_DIR 2 + +/** + * @} + */ + +/** @defgroup MSC_CORE_Private_TypesDefinitions + * @{ + */ + +typedef struct _MSC_BOT_CBW +{ + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataLength; + uint8_t bmFlags; + uint8_t bLUN; + uint8_t bCBLength; + uint8_t CB[16]; +} +MSC_BOT_CBW_TypeDef; + + +typedef struct _MSC_BOT_CSW +{ + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataResidue; + uint8_t bStatus; +} +MSC_BOT_CSW_TypeDef; + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_Types + * @{ + */ + +extern uint8_t MSC_BOT_Data[]; +extern uint16_t MSC_BOT_DataLen; +extern uint8_t MSC_BOT_State; +extern uint8_t MSC_BOT_BurstMode; +extern MSC_BOT_CBW_TypeDef MSC_BOT_cbw; +extern MSC_BOT_CSW_TypeDef MSC_BOT_csw; +/** + * @} + */ +/** @defgroup USBD_CORE_Exported_FunctionsPrototypes + * @{ + */ +void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev); +void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev); +void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev); +void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev, + uint8_t epnum); + +void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev, + uint8_t epnum); + +void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev, + uint8_t CSW_Status); + +void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev, + uint8_t epnum); +/** + * @} + */ + +#endif /* __USBD_MSC_BOT_H */ +/** + * @} + */ + +/** +* @} +*/ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h index 55d29644..be1d401e 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h @@ -1,72 +1,72 @@ -/** - ****************************************************************************** - * @file usbd_msc_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header for the usbd_msc_core.c file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef _USB_MSC_CORE_H_ -#define _USB_MSC_CORE_H_ - -#include "usbd_ioreq.h" - -/** @addtogroup USBD_MSC_BOT - * @{ - */ - -/** @defgroup USBD_MSC - * @brief This file is the Header file for USBD_msc.c - * @{ - */ - - -/** @defgroup USBD_BOT_Exported_Defines - * @{ - */ - - -#define BOT_GET_MAX_LUN 0xFE -#define BOT_RESET 0xFF -#define USB_MSC_CONFIG_DESC_SIZ 32 - -#define MSC_EPIN_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 22) - -#define MSC_EPOUT_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 29) - -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Types - * @{ - */ - -extern USBD_Class_cb_TypeDef USBD_MSC_cb; -/** - * @} - */ - -/** - * @} - */ -#endif // _USB_MSC_CORE_H_ -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_msc_core.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header for the usbd_msc_core.c file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef _USB_MSC_CORE_H_ +#define _USB_MSC_CORE_H_ + +#include "usbd_ioreq.h" + +/** @addtogroup USBD_MSC_BOT + * @{ + */ + +/** @defgroup USBD_MSC + * @brief This file is the Header file for USBD_msc.c + * @{ + */ + + +/** @defgroup USBD_BOT_Exported_Defines + * @{ + */ + + +#define BOT_GET_MAX_LUN 0xFE +#define BOT_RESET 0xFF +#define USB_MSC_CONFIG_DESC_SIZ 32 + +#define MSC_EPIN_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 22) + +#define MSC_EPOUT_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 29) + +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Types + * @{ + */ + +extern USBD_Class_cb_TypeDef USBD_MSC_cb; +/** + * @} + */ + +/** + * @} + */ +#endif // _USB_MSC_CORE_H_ +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h index 0b0978a3..e0a677f8 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h @@ -1,98 +1,98 @@ -/** - ****************************************************************************** - * @file usbd_msc_data.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header for the usbd_msc_data.c file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef _USBD_MSC_DATA_H_ -#define _USBD_MSC_DATA_H_ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_conf.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USB_INFO - * @brief general defines for the usb device library file - * @{ - */ - -/** @defgroup USB_INFO_Exported_Defines - * @{ - */ -#define MODE_SENSE6_LEN 8 -#define MODE_SENSE10_LEN 8 -#define LENGTH_INQUIRY_PAGE00 7 -#define LENGTH_FORMAT_CAPACITIES 20 - -/** - * @} - */ - - -/** @defgroup USBD_INFO_Exported_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_INFO_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_INFO_Exported_Variables - * @{ - */ -extern const uint8_t MSC_Page00_Inquiry_Data[]; -extern const uint8_t MSC_Mode_Sense6_data[]; -extern const uint8_t MSC_Mode_Sense10_data[] ; - -/** - * @} - */ - -/** @defgroup USBD_INFO_Exported_FunctionsPrototype - * @{ - */ - -/** - * @} - */ - -#endif /* _USBD_MSC_DATA_H_ */ - -/** - * @} - */ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_msc_data.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header for the usbd_msc_data.c file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef _USBD_MSC_DATA_H_ +#define _USBD_MSC_DATA_H_ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USB_INFO + * @brief general defines for the usb device library file + * @{ + */ + +/** @defgroup USB_INFO_Exported_Defines + * @{ + */ +#define MODE_SENSE6_LEN 8 +#define MODE_SENSE10_LEN 8 +#define LENGTH_INQUIRY_PAGE00 7 +#define LENGTH_FORMAT_CAPACITIES 20 + +/** + * @} + */ + + +/** @defgroup USBD_INFO_Exported_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_INFO_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_INFO_Exported_Variables + * @{ + */ +extern const uint8_t MSC_Page00_Inquiry_Data[]; +extern const uint8_t MSC_Mode_Sense6_data[]; +extern const uint8_t MSC_Mode_Sense10_data[] ; + +/** + * @} + */ + +/** @defgroup USBD_INFO_Exported_FunctionsPrototype + * @{ + */ + +/** + * @} + */ + +#endif /* _USBD_MSC_DATA_H_ */ + +/** + * @} + */ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h index 744ff63c..811e9ee8 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h @@ -1,106 +1,106 @@ -/** - ****************************************************************************** - * @file usbd_msc_mem.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header for the STORAGE DISK file file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USBD_MEM_H -#define __USBD_MEM_H -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_MEM - * @brief header file for the storage disk file - * @{ - */ - -/** @defgroup USBD_MEM_Exported_Defines - * @{ - */ -#define USBD_STD_INQUIRY_LENGTH 36 -/** - * @} - */ - - -/** @defgroup USBD_MEM_Exported_TypesDefinitions - * @{ - */ - -typedef struct _USBD_STORAGE -{ - int8_t (* Init) (uint8_t lun); - int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint32_t *block_size); - int8_t (* IsReady) (uint8_t lun); - int8_t (* IsWriteProtected) (uint8_t lun); - int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); - int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); - int8_t (* GetMaxLun)(void); - int8_t *pInquiry; - -}USBD_STORAGE_cb_TypeDef; -/** - * @} - */ - - - -/** @defgroup USBD_MEM_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_MEM_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_MEM_Exported_FunctionsPrototype - * @{ - */ -extern USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops; -/** - * @} - */ - -#endif /* __USBD_MEM_H */ -/** - * @} - */ - -/** - * @} - */ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_msc_mem.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header for the STORAGE DISK file file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __USBD_MEM_H +#define __USBD_MEM_H +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_MEM + * @brief header file for the storage disk file + * @{ + */ + +/** @defgroup USBD_MEM_Exported_Defines + * @{ + */ +#define USBD_STD_INQUIRY_LENGTH 36 +/** + * @} + */ + + +/** @defgroup USBD_MEM_Exported_TypesDefinitions + * @{ + */ + +typedef struct _USBD_STORAGE +{ + int8_t (* Init) (uint8_t lun); + int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint32_t *block_size); + int8_t (* IsReady) (uint8_t lun); + int8_t (* IsWriteProtected) (uint8_t lun); + int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t (* GetMaxLun)(void); + int8_t *pInquiry; + +}USBD_STORAGE_cb_TypeDef; +/** + * @} + */ + + + +/** @defgroup USBD_MEM_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_MEM_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_MEM_Exported_FunctionsPrototype + * @{ + */ +extern USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops; +/** + * @} + */ + +#endif /* __USBD_MEM_H */ +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h index ae8fb3eb..5ba83ad1 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h @@ -1,189 +1,189 @@ -/** - ****************************************************************************** - * @file usbd_msc_scsi.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header for the usbd_msc_scsi.c file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_MSC_SCSI_H -#define __USBD_MSC_SCSI_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_SCSI - * @brief header file for the storage disk file - * @{ - */ - -/** @defgroup USBD_SCSI_Exported_Defines - * @{ - */ - -#define SENSE_LIST_DEEPTH 4 - -/* SCSI Commands */ -#define SCSI_FORMAT_UNIT 0x04 -#define SCSI_INQUIRY 0x12 -#define SCSI_MODE_SELECT6 0x15 -#define SCSI_MODE_SELECT10 0x55 -#define SCSI_MODE_SENSE6 0x1A -#define SCSI_MODE_SENSE10 0x5A -#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E -#define SCSI_READ6 0x08 -#define SCSI_READ10 0x28 -#define SCSI_READ12 0xA8 -#define SCSI_READ16 0x88 - -#define SCSI_READ_CAPACITY10 0x25 -#define SCSI_READ_CAPACITY16 0x9E - -#define SCSI_REQUEST_SENSE 0x03 -#define SCSI_START_STOP_UNIT 0x1B -#define SCSI_TEST_UNIT_READY 0x00 -#define SCSI_WRITE6 0x0A -#define SCSI_WRITE10 0x2A -#define SCSI_WRITE12 0xAA -#define SCSI_WRITE16 0x8A - -#define SCSI_VERIFY10 0x2F -#define SCSI_VERIFY12 0xAF -#define SCSI_VERIFY16 0x8F - -#define SCSI_SEND_DIAGNOSTIC 0x1D -#define SCSI_READ_FORMAT_CAPACITIES 0x23 - -#define NO_SENSE 0 -#define RECOVERED_ERROR 1 -#define NOT_READY 2 -#define MEDIUM_ERROR 3 -#define HARDWARE_ERROR 4 -#define ILLEGAL_REQUEST 5 -#define UNIT_ATTENTION 6 -#define DATA_PROTECT 7 -#define BLANK_CHECK 8 -#define VENDOR_SPECIFIC 9 -#define COPY_ABORTED 10 -#define ABORTED_COMMAND 11 -#define VOLUME_OVERFLOW 13 -#define MISCOMPARE 14 - - -#define INVALID_CDB 0x20 -#define INVALID_FIELED_IN_COMMAND 0x24 -#define PARAMETER_LIST_LENGTH_ERROR 0x1A -#define INVALID_FIELD_IN_PARAMETER_LIST 0x26 -#define ADDRESS_OUT_OF_RANGE 0x21 -#define MEDIUM_NOT_PRESENT 0x3A -#define MEDIUM_HAVE_CHANGED 0x28 -#define WRITE_PROTECTED 0x27 -#define UNRECOVERED_READ_ERROR 0x11 -#define WRITE_FAULT 0x03 - -#define READ_FORMAT_CAPACITY_DATA_LEN 0x0C -#define READ_CAPACITY10_DATA_LEN 0x08 -#define MODE_SENSE10_DATA_LEN 0x08 -#define MODE_SENSE6_DATA_LEN 0x04 -#define REQUEST_SENSE_DATA_LEN 0x12 -#define STANDARD_INQUIRY_DATA_LEN 0x24 -#define BLKVFY 0x04 - -extern uint8_t Page00_Inquiry_Data[]; -extern uint8_t Standard_Inquiry_Data[]; -extern uint8_t Standard_Inquiry_Data2[]; -extern uint8_t Mode_Sense6_data[]; -extern uint8_t Mode_Sense10_data[]; -extern uint8_t Scsi_Sense_Data[]; -extern uint8_t ReadCapacity10_Data[]; -extern uint8_t ReadFormatCapacity_Data []; -/** - * @} - */ - - -/** @defgroup USBD_SCSI_Exported_TypesDefinitions - * @{ - */ - -typedef struct _SENSE_ITEM { - char Skey; - union { - struct _ASCs { - char ASC; - char ASCQ; - }b; - unsigned int ASC; - char *pData; - } w; -} SCSI_Sense_TypeDef; -/** - * @} - */ - -/** @defgroup USBD_SCSI_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_SCSI_Exported_Variables - * @{ - */ -extern SCSI_Sense_TypeDef SCSI_Sense [SENSE_LIST_DEEPTH]; -extern uint8_t SCSI_Sense_Head; -extern uint8_t SCSI_Sense_Tail; - -/** - * @} - */ -/** @defgroup USBD_SCSI_Exported_FunctionsPrototype - * @{ - */ -int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev, - uint8_t lun, - uint8_t *cmd); - -void SCSI_SenseCode(uint8_t lun, - uint8_t sKey, - uint8_t ASC); - -/** - * @} - */ - -#endif /* __USBD_MSC_SCSI_H */ -/** - * @} - */ - -/** - * @} - */ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usbd_msc_scsi.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header for the usbd_msc_scsi.c file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_SCSI_H +#define __USBD_MSC_SCSI_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_SCSI + * @brief header file for the storage disk file + * @{ + */ + +/** @defgroup USBD_SCSI_Exported_Defines + * @{ + */ + +#define SENSE_LIST_DEEPTH 4 + +/* SCSI Commands */ +#define SCSI_FORMAT_UNIT 0x04 +#define SCSI_INQUIRY 0x12 +#define SCSI_MODE_SELECT6 0x15 +#define SCSI_MODE_SELECT10 0x55 +#define SCSI_MODE_SENSE6 0x1A +#define SCSI_MODE_SENSE10 0x5A +#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E +#define SCSI_READ6 0x08 +#define SCSI_READ10 0x28 +#define SCSI_READ12 0xA8 +#define SCSI_READ16 0x88 + +#define SCSI_READ_CAPACITY10 0x25 +#define SCSI_READ_CAPACITY16 0x9E + +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_START_STOP_UNIT 0x1B +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_WRITE6 0x0A +#define SCSI_WRITE10 0x2A +#define SCSI_WRITE12 0xAA +#define SCSI_WRITE16 0x8A + +#define SCSI_VERIFY10 0x2F +#define SCSI_VERIFY12 0xAF +#define SCSI_VERIFY16 0x8F + +#define SCSI_SEND_DIAGNOSTIC 0x1D +#define SCSI_READ_FORMAT_CAPACITIES 0x23 + +#define NO_SENSE 0 +#define RECOVERED_ERROR 1 +#define NOT_READY 2 +#define MEDIUM_ERROR 3 +#define HARDWARE_ERROR 4 +#define ILLEGAL_REQUEST 5 +#define UNIT_ATTENTION 6 +#define DATA_PROTECT 7 +#define BLANK_CHECK 8 +#define VENDOR_SPECIFIC 9 +#define COPY_ABORTED 10 +#define ABORTED_COMMAND 11 +#define VOLUME_OVERFLOW 13 +#define MISCOMPARE 14 + + +#define INVALID_CDB 0x20 +#define INVALID_FIELED_IN_COMMAND 0x24 +#define PARAMETER_LIST_LENGTH_ERROR 0x1A +#define INVALID_FIELD_IN_PARAMETER_LIST 0x26 +#define ADDRESS_OUT_OF_RANGE 0x21 +#define MEDIUM_NOT_PRESENT 0x3A +#define MEDIUM_HAVE_CHANGED 0x28 +#define WRITE_PROTECTED 0x27 +#define UNRECOVERED_READ_ERROR 0x11 +#define WRITE_FAULT 0x03 + +#define READ_FORMAT_CAPACITY_DATA_LEN 0x0C +#define READ_CAPACITY10_DATA_LEN 0x08 +#define MODE_SENSE10_DATA_LEN 0x08 +#define MODE_SENSE6_DATA_LEN 0x04 +#define REQUEST_SENSE_DATA_LEN 0x12 +#define STANDARD_INQUIRY_DATA_LEN 0x24 +#define BLKVFY 0x04 + +extern uint8_t Page00_Inquiry_Data[]; +extern uint8_t Standard_Inquiry_Data[]; +extern uint8_t Standard_Inquiry_Data2[]; +extern uint8_t Mode_Sense6_data[]; +extern uint8_t Mode_Sense10_data[]; +extern uint8_t Scsi_Sense_Data[]; +extern uint8_t ReadCapacity10_Data[]; +extern uint8_t ReadFormatCapacity_Data []; +/** + * @} + */ + + +/** @defgroup USBD_SCSI_Exported_TypesDefinitions + * @{ + */ + +typedef struct _SENSE_ITEM { + char Skey; + union { + struct _ASCs { + char ASC; + char ASCQ; + }b; + unsigned int ASC; + char *pData; + } w; +} SCSI_Sense_TypeDef; +/** + * @} + */ + +/** @defgroup USBD_SCSI_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_SCSI_Exported_Variables + * @{ + */ +extern SCSI_Sense_TypeDef SCSI_Sense [SENSE_LIST_DEEPTH]; +extern uint8_t SCSI_Sense_Head; +extern uint8_t SCSI_Sense_Tail; + +/** + * @} + */ +/** @defgroup USBD_SCSI_Exported_FunctionsPrototype + * @{ + */ +int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev, + uint8_t lun, + uint8_t *cmd); + +void SCSI_SenseCode(uint8_t lun, + uint8_t sKey, + uint8_t ASC); + +/** + * @} + */ + +#endif /* __USBD_MSC_SCSI_H */ +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c index 4499bf6f..01c88ddd 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c @@ -1,393 +1,393 @@ -/** - ****************************************************************************** - * @file usbd_msc_bot.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides all the BOT protocol core functions. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_bot.h" -#include "usbd_msc_scsi.h" -#include "usbd_ioreq.h" -#include "usbd_msc_mem.h" -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup MSC_BOT - * @brief BOT protocol module - * @{ - */ - -/** @defgroup MSC_BOT_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_BOT_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup MSC_BOT_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_BOT_Private_Variables - * @{ - */ -uint16_t MSC_BOT_DataLen; -uint8_t MSC_BOT_State; -uint8_t MSC_BOT_Status; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t MSC_BOT_Data[MSC_MEDIA_PACKET] __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN MSC_BOT_CBW_TypeDef MSC_BOT_cbw __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN MSC_BOT_CSW_TypeDef MSC_BOT_csw __ALIGN_END ; -/** - * @} - */ - - -/** @defgroup MSC_BOT_Private_FunctionPrototypes - * @{ - */ -static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev); - -static void MSC_BOT_SendData (USB_OTG_CORE_HANDLE *pdev, - uint8_t* pbuf, - uint16_t len); - -static void MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev); -/** - * @} - */ - - -/** @defgroup MSC_BOT_Private_Functions - * @{ - */ - - - -/** -* @brief MSC_BOT_Init -* Initialize the BOT Process -* @param pdev: device instance -* @retval None -*/ -void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev) -{ - MSC_BOT_State = BOT_IDLE; - MSC_BOT_Status = BOT_STATE_NORMAL; - USBD_STORAGE_fops->Init(0); - - DCD_EP_Flush(pdev, MSC_OUT_EP); - DCD_EP_Flush(pdev, MSC_IN_EP); - /* Prapare EP to Receive First BOT Cmd */ - DCD_EP_PrepareRx (pdev, - MSC_OUT_EP, - (uint8_t *)&MSC_BOT_cbw, - BOT_CBW_LENGTH); -} - -/** -* @brief MSC_BOT_Reset -* Reset the BOT Machine -* @param pdev: device instance -* @retval None -*/ -void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev) -{ - MSC_BOT_State = BOT_IDLE; - MSC_BOT_Status = BOT_STATE_RECOVERY; - /* Prapare EP to Receive First BOT Cmd */ - DCD_EP_PrepareRx (pdev, - MSC_OUT_EP, - (uint8_t *)&MSC_BOT_cbw, - BOT_CBW_LENGTH); -} - -/** -* @brief MSC_BOT_DeInit -* Uninitialize the BOT Machine -* @param pdev: device instance -* @retval None -*/ -void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev) -{ - MSC_BOT_State = BOT_IDLE; -} - -/** -* @brief MSC_BOT_DataIn -* Handle BOT IN data stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval None -*/ -void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum) -{ - - switch (MSC_BOT_State) - { - case BOT_DATA_IN: - if(SCSI_ProcessCmd(pdev, - MSC_BOT_cbw.bLUN, - &MSC_BOT_cbw.CB[0]) < 0) - { - MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED); - } - break; - - case BOT_SEND_DATA: - case BOT_LAST_DATA_IN: - MSC_BOT_SendCSW (pdev, CSW_CMD_PASSED); - - break; - - default: - break; - } -} -/** -* @brief MSC_BOT_DataOut -* Proccess MSC OUT data -* @param pdev: device instance -* @param epnum: endpoint index -* @retval None -*/ -void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum) -{ - switch (MSC_BOT_State) - { - case BOT_IDLE: - MSC_BOT_CBW_Decode(pdev); - break; - - case BOT_DATA_OUT: - - if(SCSI_ProcessCmd(pdev, - MSC_BOT_cbw.bLUN, - &MSC_BOT_cbw.CB[0]) < 0) - { - MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED); - } - - break; - - default: - break; - } - -} - -/** -* @brief MSC_BOT_CBW_Decode -* Decode the CBW command and set the BOT state machine accordingtly -* @param pdev: device instance -* @retval None -*/ -static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev) -{ - - MSC_BOT_csw.dTag = MSC_BOT_cbw.dTag; - MSC_BOT_csw.dDataResidue = MSC_BOT_cbw.dDataLength; - - if ((USBD_GetRxCount (pdev ,MSC_OUT_EP) != BOT_CBW_LENGTH) || - (MSC_BOT_cbw.dSignature != BOT_CBW_SIGNATURE)|| - (MSC_BOT_cbw.bLUN > 1) || - (MSC_BOT_cbw.bCBLength < 1) || - (MSC_BOT_cbw.bCBLength > 16)) - { - - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - MSC_BOT_Status = BOT_STATE_ERROR; - MSC_BOT_Abort(pdev); - - } - else - { - if(SCSI_ProcessCmd(pdev, - MSC_BOT_cbw.bLUN, - &MSC_BOT_cbw.CB[0]) < 0) - { - MSC_BOT_Abort(pdev); - } - /*Burst xfer handled internally*/ - else if ((MSC_BOT_State != BOT_DATA_IN) && - (MSC_BOT_State != BOT_DATA_OUT) && - (MSC_BOT_State != BOT_LAST_DATA_IN)) - { - if (MSC_BOT_DataLen > 0) - { - MSC_BOT_SendData(pdev, - MSC_BOT_Data, - MSC_BOT_DataLen); - } - else if (MSC_BOT_DataLen == 0) - { - MSC_BOT_SendCSW (pdev, - CSW_CMD_PASSED); - } - } - } -} - -/** -* @brief MSC_BOT_SendData -* Send the requested data -* @param pdev: device instance -* @param buf: pointer to data buffer -* @param len: Data Length -* @retval None -*/ -static void MSC_BOT_SendData(USB_OTG_CORE_HANDLE *pdev, - uint8_t* buf, - uint16_t len) -{ - - len = MIN (MSC_BOT_cbw.dDataLength, len); - MSC_BOT_csw.dDataResidue -= len; - MSC_BOT_csw.bStatus = CSW_CMD_PASSED; - MSC_BOT_State = BOT_SEND_DATA; - - DCD_EP_Tx (pdev, MSC_IN_EP, buf, len); -} - -/** -* @brief MSC_BOT_SendCSW -* Send the Command Status Wrapper -* @param pdev: device instance -* @param status : CSW status -* @retval None -*/ -void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev, - uint8_t CSW_Status) -{ - MSC_BOT_csw.dSignature = BOT_CSW_SIGNATURE; - MSC_BOT_csw.bStatus = CSW_Status; - MSC_BOT_State = BOT_IDLE; - - DCD_EP_Tx (pdev, - MSC_IN_EP, - (uint8_t *)&MSC_BOT_csw, - BOT_CSW_LENGTH); - - /* Prapare EP to Receive next Cmd */ - DCD_EP_PrepareRx (pdev, - MSC_OUT_EP, - (uint8_t *)&MSC_BOT_cbw, - BOT_CBW_LENGTH); - -} - -/** -* @brief MSC_BOT_Abort -* Abort the current transfer -* @param pdev: device instance -* @retval status -*/ - -static void MSC_BOT_Abort (USB_OTG_CORE_HANDLE *pdev) -{ - - if ((MSC_BOT_cbw.bmFlags == 0) && - (MSC_BOT_cbw.dDataLength != 0) && - (MSC_BOT_Status == BOT_STATE_NORMAL) ) - { - DCD_EP_Stall(pdev, MSC_OUT_EP ); - } - DCD_EP_Stall(pdev, MSC_IN_EP); - - if(MSC_BOT_Status == BOT_STATE_ERROR) - { - DCD_EP_PrepareRx (pdev, - MSC_OUT_EP, - (uint8_t *)&MSC_BOT_cbw, - BOT_CBW_LENGTH); - } -} - -/** -* @brief MSC_BOT_CplClrFeature -* Complete the clear feature request -* @param pdev: device instance -* @param epnum: endpoint index -* @retval None -*/ - -void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) -{ - if(MSC_BOT_Status == BOT_STATE_ERROR )/* Bad CBW Signature */ - { - DCD_EP_Stall(pdev, MSC_IN_EP); - MSC_BOT_Status = BOT_STATE_NORMAL; - } - else if(((epnum & 0x80) == 0x80) && ( MSC_BOT_Status != BOT_STATE_RECOVERY)) - { - MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED); - } - -} -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_msc_bot.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides all the BOT protocol core functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_bot.h" +#include "usbd_msc_scsi.h" +#include "usbd_ioreq.h" +#include "usbd_msc_mem.h" +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_BOT + * @brief BOT protocol module + * @{ + */ + +/** @defgroup MSC_BOT_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Variables + * @{ + */ +uint16_t MSC_BOT_DataLen; +uint8_t MSC_BOT_State; +uint8_t MSC_BOT_Status; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t MSC_BOT_Data[MSC_MEDIA_PACKET] __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN MSC_BOT_CBW_TypeDef MSC_BOT_cbw __ALIGN_END ; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN MSC_BOT_CSW_TypeDef MSC_BOT_csw __ALIGN_END ; +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_FunctionPrototypes + * @{ + */ +static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev); + +static void MSC_BOT_SendData (USB_OTG_CORE_HANDLE *pdev, + uint8_t* pbuf, + uint16_t len); + +static void MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev); +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Functions + * @{ + */ + + + +/** +* @brief MSC_BOT_Init +* Initialize the BOT Process +* @param pdev: device instance +* @retval None +*/ +void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev) +{ + MSC_BOT_State = BOT_IDLE; + MSC_BOT_Status = BOT_STATE_NORMAL; + USBD_STORAGE_fops->Init(0); + + DCD_EP_Flush(pdev, MSC_OUT_EP); + DCD_EP_Flush(pdev, MSC_IN_EP); + /* Prapare EP to Receive First BOT Cmd */ + DCD_EP_PrepareRx (pdev, + MSC_OUT_EP, + (uint8_t *)&MSC_BOT_cbw, + BOT_CBW_LENGTH); +} + +/** +* @brief MSC_BOT_Reset +* Reset the BOT Machine +* @param pdev: device instance +* @retval None +*/ +void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev) +{ + MSC_BOT_State = BOT_IDLE; + MSC_BOT_Status = BOT_STATE_RECOVERY; + /* Prapare EP to Receive First BOT Cmd */ + DCD_EP_PrepareRx (pdev, + MSC_OUT_EP, + (uint8_t *)&MSC_BOT_cbw, + BOT_CBW_LENGTH); +} + +/** +* @brief MSC_BOT_DeInit +* Uninitialize the BOT Machine +* @param pdev: device instance +* @retval None +*/ +void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev) +{ + MSC_BOT_State = BOT_IDLE; +} + +/** +* @brief MSC_BOT_DataIn +* Handle BOT IN data stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval None +*/ +void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev, + uint8_t epnum) +{ + + switch (MSC_BOT_State) + { + case BOT_DATA_IN: + if(SCSI_ProcessCmd(pdev, + MSC_BOT_cbw.bLUN, + &MSC_BOT_cbw.CB[0]) < 0) + { + MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED); + } + break; + + case BOT_SEND_DATA: + case BOT_LAST_DATA_IN: + MSC_BOT_SendCSW (pdev, CSW_CMD_PASSED); + + break; + + default: + break; + } +} +/** +* @brief MSC_BOT_DataOut +* Proccess MSC OUT data +* @param pdev: device instance +* @param epnum: endpoint index +* @retval None +*/ +void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev, + uint8_t epnum) +{ + switch (MSC_BOT_State) + { + case BOT_IDLE: + MSC_BOT_CBW_Decode(pdev); + break; + + case BOT_DATA_OUT: + + if(SCSI_ProcessCmd(pdev, + MSC_BOT_cbw.bLUN, + &MSC_BOT_cbw.CB[0]) < 0) + { + MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED); + } + + break; + + default: + break; + } + +} + +/** +* @brief MSC_BOT_CBW_Decode +* Decode the CBW command and set the BOT state machine accordingtly +* @param pdev: device instance +* @retval None +*/ +static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev) +{ + + MSC_BOT_csw.dTag = MSC_BOT_cbw.dTag; + MSC_BOT_csw.dDataResidue = MSC_BOT_cbw.dDataLength; + + if ((USBD_GetRxCount (pdev ,MSC_OUT_EP) != BOT_CBW_LENGTH) || + (MSC_BOT_cbw.dSignature != BOT_CBW_SIGNATURE)|| + (MSC_BOT_cbw.bLUN > 1) || + (MSC_BOT_cbw.bCBLength < 1) || + (MSC_BOT_cbw.bCBLength > 16)) + { + + SCSI_SenseCode(MSC_BOT_cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + MSC_BOT_Status = BOT_STATE_ERROR; + MSC_BOT_Abort(pdev); + + } + else + { + if(SCSI_ProcessCmd(pdev, + MSC_BOT_cbw.bLUN, + &MSC_BOT_cbw.CB[0]) < 0) + { + MSC_BOT_Abort(pdev); + } + /*Burst xfer handled internally*/ + else if ((MSC_BOT_State != BOT_DATA_IN) && + (MSC_BOT_State != BOT_DATA_OUT) && + (MSC_BOT_State != BOT_LAST_DATA_IN)) + { + if (MSC_BOT_DataLen > 0) + { + MSC_BOT_SendData(pdev, + MSC_BOT_Data, + MSC_BOT_DataLen); + } + else if (MSC_BOT_DataLen == 0) + { + MSC_BOT_SendCSW (pdev, + CSW_CMD_PASSED); + } + } + } +} + +/** +* @brief MSC_BOT_SendData +* Send the requested data +* @param pdev: device instance +* @param buf: pointer to data buffer +* @param len: Data Length +* @retval None +*/ +static void MSC_BOT_SendData(USB_OTG_CORE_HANDLE *pdev, + uint8_t* buf, + uint16_t len) +{ + + len = MIN (MSC_BOT_cbw.dDataLength, len); + MSC_BOT_csw.dDataResidue -= len; + MSC_BOT_csw.bStatus = CSW_CMD_PASSED; + MSC_BOT_State = BOT_SEND_DATA; + + DCD_EP_Tx (pdev, MSC_IN_EP, buf, len); +} + +/** +* @brief MSC_BOT_SendCSW +* Send the Command Status Wrapper +* @param pdev: device instance +* @param status : CSW status +* @retval None +*/ +void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev, + uint8_t CSW_Status) +{ + MSC_BOT_csw.dSignature = BOT_CSW_SIGNATURE; + MSC_BOT_csw.bStatus = CSW_Status; + MSC_BOT_State = BOT_IDLE; + + DCD_EP_Tx (pdev, + MSC_IN_EP, + (uint8_t *)&MSC_BOT_csw, + BOT_CSW_LENGTH); + + /* Prapare EP to Receive next Cmd */ + DCD_EP_PrepareRx (pdev, + MSC_OUT_EP, + (uint8_t *)&MSC_BOT_cbw, + BOT_CBW_LENGTH); + +} + +/** +* @brief MSC_BOT_Abort +* Abort the current transfer +* @param pdev: device instance +* @retval status +*/ + +static void MSC_BOT_Abort (USB_OTG_CORE_HANDLE *pdev) +{ + + if ((MSC_BOT_cbw.bmFlags == 0) && + (MSC_BOT_cbw.dDataLength != 0) && + (MSC_BOT_Status == BOT_STATE_NORMAL) ) + { + DCD_EP_Stall(pdev, MSC_OUT_EP ); + } + DCD_EP_Stall(pdev, MSC_IN_EP); + + if(MSC_BOT_Status == BOT_STATE_ERROR) + { + DCD_EP_PrepareRx (pdev, + MSC_OUT_EP, + (uint8_t *)&MSC_BOT_cbw, + BOT_CBW_LENGTH); + } +} + +/** +* @brief MSC_BOT_CplClrFeature +* Complete the clear feature request +* @param pdev: device instance +* @param epnum: endpoint index +* @retval None +*/ + +void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) +{ + if(MSC_BOT_Status == BOT_STATE_ERROR )/* Bad CBW Signature */ + { + DCD_EP_Stall(pdev, MSC_IN_EP); + MSC_BOT_Status = BOT_STATE_NORMAL; + } + else if(((epnum & 0x80) == 0x80) && ( MSC_BOT_Status != BOT_STATE_RECOVERY)) + { + MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED); + } + +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c index 5152733e..cf03ef4d 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c @@ -1,490 +1,490 @@ -/** - ****************************************************************************** - * @file usbd_msc_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides all the MSC core functions. - * - * @verbatim - * - * =================================================================== - * MSC Class Description - * =================================================================== - * This module manages the MSC class V1.0 following the "Universal - * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0 - * Sep. 31, 1999". - * This driver implements the following aspects of the specification: - * - Bulk-Only Transport protocol - * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3)) - * - * @endverbatim - * - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_mem.h" -#include "usbd_msc_core.h" -#include "usbd_msc_bot.h" -#include "usbd_req.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup MSC_CORE - * @brief Mass storage core module - * @{ - */ - -/** @defgroup MSC_CORE_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_CORE_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup MSC_CORE_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_CORE_Private_FunctionPrototypes - * @{ - */ -uint8_t USBD_MSC_Init (void *pdev, - uint8_t cfgidx); - -uint8_t USBD_MSC_DeInit (void *pdev, - uint8_t cfgidx); - -uint8_t USBD_MSC_Setup (void *pdev, - USB_SETUP_REQ *req); - -uint8_t USBD_MSC_DataIn (void *pdev, - uint8_t epnum); - - -uint8_t USBD_MSC_DataOut (void *pdev, - uint8_t epnum); - -uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed, - uint16_t *length); - -#ifdef USB_OTG_HS_CORE -uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed, - uint16_t *length); -#endif - - -uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ]; - - - - -/** - * @} - */ - - -/** @defgroup MSC_CORE_Private_Variables - * @{ - */ - - -USBD_Class_cb_TypeDef USBD_MSC_cb = -{ - USBD_MSC_Init, - USBD_MSC_DeInit, - USBD_MSC_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ - USBD_MSC_DataIn, - USBD_MSC_DataOut, - NULL, /*SOF */ - NULL, - NULL, - USBD_MSC_GetCfgDesc, -#ifdef USB_OTG_HS_CORE - USBD_MSC_GetOtherCfgDesc, -#endif -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB Mass storage device Configuration Descriptor */ -/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ -__ALIGN_BEGIN uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_MSC_CONFIG_DESC_SIZ, - - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ - - /******************** Mass Storage interface ********************/ - 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType: */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints*/ - 0x08, /* bInterfaceClass: MSC Class */ - 0x06, /* bInterfaceSubClass : SCSI transparent*/ - 0x50, /* nInterfaceProtocol */ - 0x05, /* iInterface: */ - /******************** Mass Storage Endpoints ********************/ - 0x07, /*Endpoint descriptor length = 7*/ - 0x05, /*Endpoint descriptor type */ - MSC_IN_EP, /*Endpoint address (IN, address 1) */ - 0x02, /*Bulk endpoint type */ - LOBYTE(MSC_MAX_PACKET), - HIBYTE(MSC_MAX_PACKET), - 0x00, /*Polling interval in milliseconds */ - - 0x07, /*Endpoint descriptor length = 7 */ - 0x05, /*Endpoint descriptor type */ - MSC_OUT_EP, /*Endpoint address (OUT, address 1) */ - 0x02, /*Bulk endpoint type */ - LOBYTE(MSC_MAX_PACKET), - HIBYTE(MSC_MAX_PACKET), - 0x00 /*Polling interval in milliseconds*/ -}; -#ifdef USB_OTG_HS_CORE - #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif - #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t USBD_MSC_OtherCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, - USB_MSC_CONFIG_DESC_SIZ, - - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ - - /******************** Mass Storage interface ********************/ - 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType: */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints*/ - 0x08, /* bInterfaceClass: MSC Class */ - 0x06, /* bInterfaceSubClass : SCSI transparent command set*/ - 0x50, /* nInterfaceProtocol */ - 0x05, /* iInterface: */ - /******************** Mass Storage Endpoints ********************/ - 0x07, /*Endpoint descriptor length = 7*/ - 0x05, /*Endpoint descriptor type */ - MSC_IN_EP, /*Endpoint address (IN, address 1) */ - 0x02, /*Bulk endpoint type */ - 0x40, - 0x00, - 0x00, /*Polling interval in milliseconds */ - - 0x07, /*Endpoint descriptor length = 7 */ - 0x05, /*Endpoint descriptor type */ - MSC_OUT_EP, /*Endpoint address (OUT, address 1) */ - 0x02, /*Bulk endpoint type */ - 0x40, - 0x00, - 0x00 /*Polling interval in milliseconds*/ -}; -#endif - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint8_t USBD_MSC_MaxLun __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint8_t USBD_MSC_AltSet __ALIGN_END = 0; - -/** - * @} - */ - - -/** @defgroup MSC_CORE_Private_Functions - * @{ - */ - -/** -* @brief USBD_MSC_Init -* Initialize the mass storage configuration -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status -*/ -uint8_t USBD_MSC_Init (void *pdev, - uint8_t cfgidx) -{ - USBD_MSC_DeInit(pdev , cfgidx ); - - /* Open EP IN */ - DCD_EP_Open(pdev, - MSC_IN_EP, - MSC_EPIN_SIZE, - USB_OTG_EP_BULK); - - /* Open EP OUT */ - DCD_EP_Open(pdev, - MSC_OUT_EP, - MSC_EPOUT_SIZE, - USB_OTG_EP_BULK); - - /* Init the BOT layer */ - MSC_BOT_Init(pdev); - - return USBD_OK; -} - -/** -* @brief USBD_MSC_DeInit -* DeInitilaize the mass storage configuration -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status -*/ -uint8_t USBD_MSC_DeInit (void *pdev, - uint8_t cfgidx) -{ - /* Close MSC EPs */ - DCD_EP_Close (pdev , MSC_IN_EP); - DCD_EP_Close (pdev , MSC_OUT_EP); - - /* Un Init the BOT layer */ - MSC_BOT_DeInit(pdev); - return USBD_OK; -} -/** -* @brief USBD_MSC_Setup -* Handle the MSC specific requests -* @param pdev: device instance -* @param req: USB request -* @retval status -*/ -uint8_t USBD_MSC_Setup (void *pdev, USB_SETUP_REQ *req) -{ - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - - /* Class request */ - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case BOT_GET_MAX_LUN : - - if((req->wValue == 0) && - (req->wLength == 1) && - ((req->bmRequest & 0x80) == 0x80)) - { - USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun(); - if(USBD_MSC_MaxLun > 0) - { - USBD_CtlSendData (pdev, - &USBD_MSC_MaxLun, - 1); - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - - } - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - - case BOT_RESET : - if((req->wValue == 0) && - (req->wLength == 0) && - ((req->bmRequest & 0x80) != 0x80)) - { - MSC_BOT_Reset(pdev); - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - - default: - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - /* Interface & Endpoint request */ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_INTERFACE : - USBD_CtlSendData (pdev, - &USBD_MSC_AltSet, - 1); - break; - - case USB_REQ_SET_INTERFACE : - USBD_MSC_AltSet = (uint8_t)(req->wValue); - break; - - case USB_REQ_CLEAR_FEATURE: - - /* Flush the FIFO and Clear the stall status */ - DCD_EP_Flush(pdev, (uint8_t)req->wIndex); - - /* Re-activate the EP */ - DCD_EP_Close (pdev , (uint8_t)req->wIndex); - if((((uint8_t)req->wIndex) & 0x80) == 0x80) - { - DCD_EP_Open(pdev, - ((uint8_t)req->wIndex), - MSC_EPIN_SIZE, - USB_OTG_EP_BULK); - } - else - { - DCD_EP_Open(pdev, - ((uint8_t)req->wIndex), - MSC_EPOUT_SIZE, - USB_OTG_EP_BULK); - } - - /* Handle BOT error */ - MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); - break; - - } - break; - - default: - break; - } - return USBD_OK; -} - -/** -* @brief USBD_MSC_DataIn -* handle data IN Stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ -uint8_t USBD_MSC_DataIn (void *pdev, - uint8_t epnum) -{ - MSC_BOT_DataIn(pdev , epnum); - return USBD_OK; -} - -/** -* @brief USBD_MSC_DataOut -* handle data OUT Stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ -uint8_t USBD_MSC_DataOut (void *pdev, - uint8_t epnum) -{ - MSC_BOT_DataOut(pdev , epnum); - return USBD_OK; -} - -/** -* @brief USBD_MSC_GetCfgDesc -* return configuration descriptor -* @param speed : current device speed -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ -uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (USBD_MSC_CfgDesc); - return USBD_MSC_CfgDesc; -} - -/** -* @brief USBD_MSC_GetOtherCfgDesc -* return other speed configuration descriptor -* @param speed : current device speed -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ -#ifdef USB_OTG_HS_CORE -uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed, - uint16_t *length) -{ - *length = sizeof (USBD_MSC_OtherCfgDesc); - return USBD_MSC_OtherCfgDesc; -} -#endif -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_msc_core.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides all the MSC core functions. + * + * @verbatim + * + * =================================================================== + * MSC Class Description + * =================================================================== + * This module manages the MSC class V1.0 following the "Universal + * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0 + * Sep. 31, 1999". + * This driver implements the following aspects of the specification: + * - Bulk-Only Transport protocol + * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3)) + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_mem.h" +#include "usbd_msc_core.h" +#include "usbd_msc_bot.h" +#include "usbd_req.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_CORE + * @brief Mass storage core module + * @{ + */ + +/** @defgroup MSC_CORE_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_CORE_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_CORE_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_CORE_Private_FunctionPrototypes + * @{ + */ +uint8_t USBD_MSC_Init (void *pdev, + uint8_t cfgidx); + +uint8_t USBD_MSC_DeInit (void *pdev, + uint8_t cfgidx); + +uint8_t USBD_MSC_Setup (void *pdev, + USB_SETUP_REQ *req); + +uint8_t USBD_MSC_DataIn (void *pdev, + uint8_t epnum); + + +uint8_t USBD_MSC_DataOut (void *pdev, + uint8_t epnum); + +uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed, + uint16_t *length); + +#ifdef USB_OTG_HS_CORE +uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed, + uint16_t *length); +#endif + + +uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ]; + + + + +/** + * @} + */ + + +/** @defgroup MSC_CORE_Private_Variables + * @{ + */ + + +USBD_Class_cb_TypeDef USBD_MSC_cb = +{ + USBD_MSC_Init, + USBD_MSC_DeInit, + USBD_MSC_Setup, + NULL, /*EP0_TxSent*/ + NULL, /*EP0_RxReady*/ + USBD_MSC_DataIn, + USBD_MSC_DataOut, + NULL, /*SOF */ + NULL, + NULL, + USBD_MSC_GetCfgDesc, +#ifdef USB_OTG_HS_CORE + USBD_MSC_GetOtherCfgDesc, +#endif +}; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +/* USB Mass storage device Configuration Descriptor */ +/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ +__ALIGN_BEGIN uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_MSC_CONFIG_DESC_SIZ, + + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ + + /******************** Mass Storage interface ********************/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints*/ + 0x08, /* bInterfaceClass: MSC Class */ + 0x06, /* bInterfaceSubClass : SCSI transparent*/ + 0x50, /* nInterfaceProtocol */ + 0x05, /* iInterface: */ + /******************** Mass Storage Endpoints ********************/ + 0x07, /*Endpoint descriptor length = 7*/ + 0x05, /*Endpoint descriptor type */ + MSC_IN_EP, /*Endpoint address (IN, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(MSC_MAX_PACKET), + HIBYTE(MSC_MAX_PACKET), + 0x00, /*Polling interval in milliseconds */ + + 0x07, /*Endpoint descriptor length = 7 */ + 0x05, /*Endpoint descriptor type */ + MSC_OUT_EP, /*Endpoint address (OUT, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(MSC_MAX_PACKET), + HIBYTE(MSC_MAX_PACKET), + 0x00 /*Polling interval in milliseconds*/ +}; +#ifdef USB_OTG_HS_CORE + #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif + #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t USBD_MSC_OtherCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, + USB_MSC_CONFIG_DESC_SIZ, + + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ + + /******************** Mass Storage interface ********************/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints*/ + 0x08, /* bInterfaceClass: MSC Class */ + 0x06, /* bInterfaceSubClass : SCSI transparent command set*/ + 0x50, /* nInterfaceProtocol */ + 0x05, /* iInterface: */ + /******************** Mass Storage Endpoints ********************/ + 0x07, /*Endpoint descriptor length = 7*/ + 0x05, /*Endpoint descriptor type */ + MSC_IN_EP, /*Endpoint address (IN, address 1) */ + 0x02, /*Bulk endpoint type */ + 0x40, + 0x00, + 0x00, /*Polling interval in milliseconds */ + + 0x07, /*Endpoint descriptor length = 7 */ + 0x05, /*Endpoint descriptor type */ + MSC_OUT_EP, /*Endpoint address (OUT, address 1) */ + 0x02, /*Bulk endpoint type */ + 0x40, + 0x00, + 0x00 /*Polling interval in milliseconds*/ +}; +#endif + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN static uint8_t USBD_MSC_MaxLun __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN static uint8_t USBD_MSC_AltSet __ALIGN_END = 0; + +/** + * @} + */ + + +/** @defgroup MSC_CORE_Private_Functions + * @{ + */ + +/** +* @brief USBD_MSC_Init +* Initialize the mass storage configuration +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status +*/ +uint8_t USBD_MSC_Init (void *pdev, + uint8_t cfgidx) +{ + USBD_MSC_DeInit(pdev , cfgidx ); + + /* Open EP IN */ + DCD_EP_Open(pdev, + MSC_IN_EP, + MSC_EPIN_SIZE, + USB_OTG_EP_BULK); + + /* Open EP OUT */ + DCD_EP_Open(pdev, + MSC_OUT_EP, + MSC_EPOUT_SIZE, + USB_OTG_EP_BULK); + + /* Init the BOT layer */ + MSC_BOT_Init(pdev); + + return USBD_OK; +} + +/** +* @brief USBD_MSC_DeInit +* DeInitilaize the mass storage configuration +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status +*/ +uint8_t USBD_MSC_DeInit (void *pdev, + uint8_t cfgidx) +{ + /* Close MSC EPs */ + DCD_EP_Close (pdev , MSC_IN_EP); + DCD_EP_Close (pdev , MSC_OUT_EP); + + /* Un Init the BOT layer */ + MSC_BOT_DeInit(pdev); + return USBD_OK; +} +/** +* @brief USBD_MSC_Setup +* Handle the MSC specific requests +* @param pdev: device instance +* @param req: USB request +* @retval status +*/ +uint8_t USBD_MSC_Setup (void *pdev, USB_SETUP_REQ *req) +{ + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + + /* Class request */ + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + case BOT_GET_MAX_LUN : + + if((req->wValue == 0) && + (req->wLength == 1) && + ((req->bmRequest & 0x80) == 0x80)) + { + USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun(); + if(USBD_MSC_MaxLun > 0) + { + USBD_CtlSendData (pdev, + &USBD_MSC_MaxLun, + 1); + } + else + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + + } + } + else + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + + case BOT_RESET : + if((req->wValue == 0) && + (req->wLength == 0) && + ((req->bmRequest & 0x80) != 0x80)) + { + MSC_BOT_Reset(pdev); + } + else + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + + default: + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + /* Interface & Endpoint request */ + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + &USBD_MSC_AltSet, + 1); + break; + + case USB_REQ_SET_INTERFACE : + USBD_MSC_AltSet = (uint8_t)(req->wValue); + break; + + case USB_REQ_CLEAR_FEATURE: + + /* Flush the FIFO and Clear the stall status */ + DCD_EP_Flush(pdev, (uint8_t)req->wIndex); + + /* Re-activate the EP */ + DCD_EP_Close (pdev , (uint8_t)req->wIndex); + if((((uint8_t)req->wIndex) & 0x80) == 0x80) + { + DCD_EP_Open(pdev, + ((uint8_t)req->wIndex), + MSC_EPIN_SIZE, + USB_OTG_EP_BULK); + } + else + { + DCD_EP_Open(pdev, + ((uint8_t)req->wIndex), + MSC_EPOUT_SIZE, + USB_OTG_EP_BULK); + } + + /* Handle BOT error */ + MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); + break; + + } + break; + + default: + break; + } + return USBD_OK; +} + +/** +* @brief USBD_MSC_DataIn +* handle data IN Stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +uint8_t USBD_MSC_DataIn (void *pdev, + uint8_t epnum) +{ + MSC_BOT_DataIn(pdev , epnum); + return USBD_OK; +} + +/** +* @brief USBD_MSC_DataOut +* handle data OUT Stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +uint8_t USBD_MSC_DataOut (void *pdev, + uint8_t epnum) +{ + MSC_BOT_DataOut(pdev , epnum); + return USBD_OK; +} + +/** +* @brief USBD_MSC_GetCfgDesc +* return configuration descriptor +* @param speed : current device speed +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed, uint16_t *length) +{ + *length = sizeof (USBD_MSC_CfgDesc); + return USBD_MSC_CfgDesc; +} + +/** +* @brief USBD_MSC_GetOtherCfgDesc +* return other speed configuration descriptor +* @param speed : current device speed +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +#ifdef USB_OTG_HS_CORE +uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed, + uint16_t *length) +{ + *length = sizeof (USBD_MSC_OtherCfgDesc); + return USBD_MSC_OtherCfgDesc; +} +#endif +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c index 08af5c50..b5b0f2db 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c @@ -1,128 +1,128 @@ -/** - ****************************************************************************** - * @file usbd_msc_data.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides all the vital inquiry pages and sense data. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_data.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup MSC_DATA - * @brief Mass storage info/data module - * @{ - */ - -/** @defgroup MSC_DATA_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_DATA_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_DATA_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_DATA_Private_Variables - * @{ - */ - - -/* USB Mass storage Page 0 Inquiry Data */ -const uint8_t MSC_Page00_Inquiry_Data[] = {//7 - 0x00, - 0x00, - 0x00, - (LENGTH_INQUIRY_PAGE00 - 4), - 0x00, - 0x80, - 0x83 -}; -/* USB Mass storage sense 6 Data */ -const uint8_t MSC_Mode_Sense6_data[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; -/* USB Mass storage sense 10 Data */ -const uint8_t MSC_Mode_Sense10_data[] = { - 0x00, - 0x06, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; -/** - * @} - */ - - -/** @defgroup MSC_DATA_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_DATA_Private_Functions - * @{ - */ - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_msc_data.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides all the vital inquiry pages and sense data. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_data.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_DATA + * @brief Mass storage info/data module + * @{ + */ + +/** @defgroup MSC_DATA_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Variables + * @{ + */ + + +/* USB Mass storage Page 0 Inquiry Data */ +const uint8_t MSC_Page00_Inquiry_Data[] = {//7 + 0x00, + 0x00, + 0x00, + (LENGTH_INQUIRY_PAGE00 - 4), + 0x00, + 0x80, + 0x83 +}; +/* USB Mass storage sense 6 Data */ +const uint8_t MSC_Mode_Sense6_data[] = { + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; +/* USB Mass storage sense 10 Data */ +const uint8_t MSC_Mode_Sense10_data[] = { + 0x00, + 0x06, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Functions + * @{ + */ + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c index 9e031192..8cff583b 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c @@ -1,722 +1,722 @@ -/** - ****************************************************************************** - * @file usbd_msc_scsi.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides all the USBD SCSI layer functions. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_bot.h" -#include "usbd_msc_scsi.h" -#include "usbd_msc_mem.h" -#include "usbd_msc_data.h" - - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup MSC_SCSI - * @brief Mass storage SCSI layer module - * @{ - */ - -/** @defgroup MSC_SCSI_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Variables - * @{ - */ - -SCSI_Sense_TypeDef SCSI_Sense [SENSE_LIST_DEEPTH]; -uint8_t SCSI_Sense_Head; -uint8_t SCSI_Sense_Tail; - -uint32_t SCSI_blk_size; -uint32_t SCSI_blk_nbr; - -uint32_t SCSI_blk_addr; -uint32_t SCSI_blk_len; - -USB_OTG_CORE_HANDLE *cdev; -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_FunctionPrototypes - * @{ - */ -static int8_t SCSI_TestUnitReady(uint8_t lun, uint8_t *params); -static int8_t SCSI_Inquiry(uint8_t lun, uint8_t *params); -static int8_t SCSI_ReadFormatCapacity(uint8_t lun, uint8_t *params); -static int8_t SCSI_ReadCapacity10(uint8_t lun, uint8_t *params); -static int8_t SCSI_RequestSense (uint8_t lun, uint8_t *params); -static int8_t SCSI_StartStopUnit(uint8_t lun, uint8_t *params); -static int8_t SCSI_ModeSense6 (uint8_t lun, uint8_t *params); -static int8_t SCSI_ModeSense10 (uint8_t lun, uint8_t *params); -static int8_t SCSI_Write10(uint8_t lun , uint8_t *params); -static int8_t SCSI_Read10(uint8_t lun , uint8_t *params); -static int8_t SCSI_Verify10(uint8_t lun, uint8_t *params); -static int8_t SCSI_CheckAddressRange (uint8_t lun , - uint32_t blk_offset , - uint16_t blk_nbr); -static int8_t SCSI_ProcessRead (uint8_t lun); - -static int8_t SCSI_ProcessWrite (uint8_t lun); -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Functions - * @{ - */ - - -/** -* @brief SCSI_ProcessCmd -* Process SCSI commands -* @param pdev: device instance -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev, - uint8_t lun, - uint8_t *params) -{ - cdev = pdev; - - switch (params[0]) - { - case SCSI_TEST_UNIT_READY: - return SCSI_TestUnitReady(lun, params); - - case SCSI_REQUEST_SENSE: - return SCSI_RequestSense (lun, params); - case SCSI_INQUIRY: - return SCSI_Inquiry(lun, params); - - case SCSI_START_STOP_UNIT: - return SCSI_StartStopUnit(lun, params); - - case SCSI_ALLOW_MEDIUM_REMOVAL: - return SCSI_StartStopUnit(lun, params); - - case SCSI_MODE_SENSE6: - return SCSI_ModeSense6 (lun, params); - - case SCSI_MODE_SENSE10: - return SCSI_ModeSense10 (lun, params); - - case SCSI_READ_FORMAT_CAPACITIES: - return SCSI_ReadFormatCapacity(lun, params); - - case SCSI_READ_CAPACITY10: - return SCSI_ReadCapacity10(lun, params); - - case SCSI_READ10: - return SCSI_Read10(lun, params); - - case SCSI_WRITE10: - return SCSI_Write10(lun, params); - - case SCSI_VERIFY10: - return SCSI_Verify10(lun, params); - - default: - SCSI_SenseCode(lun, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } -} - - -/** -* @brief SCSI_TestUnitReady -* Process SCSI Test Unit Ready Command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_TestUnitReady(uint8_t lun, uint8_t *params) -{ - - /* case 9 : Hi > D0 */ - if (MSC_BOT_cbw.dDataLength != 0) - { - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } - - if(USBD_STORAGE_fops->IsReady(lun) !=0 ) - { - SCSI_SenseCode(lun, - NOT_READY, - MEDIUM_NOT_PRESENT); - return -1; - } - MSC_BOT_DataLen = 0; - return 0; -} - -/** -* @brief SCSI_Inquiry -* Process Inquiry command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_Inquiry(uint8_t lun, uint8_t *params) -{ - uint8_t* pPage; - uint16_t len; - - if (params[1] & 0x01)/*Evpd is set*/ - { - pPage = (uint8_t *)MSC_Page00_Inquiry_Data; - len = LENGTH_INQUIRY_PAGE00; - } - else - { - - pPage = (uint8_t *)&USBD_STORAGE_fops->pInquiry[lun * USBD_STD_INQUIRY_LENGTH]; - len = pPage[4] + 5; - - if (params[4] <= len) - { - len = params[4]; - } - } - MSC_BOT_DataLen = len; - - while (len) - { - len--; - MSC_BOT_Data[len] = pPage[len]; - } - return 0; -} - -/** -* @brief SCSI_ReadCapacity10 -* Process Read Capacity 10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_ReadCapacity10(uint8_t lun, uint8_t *params) -{ - - if(USBD_STORAGE_fops->GetCapacity(lun, &SCSI_blk_nbr, &SCSI_blk_size) != 0) - { - SCSI_SenseCode(lun, - NOT_READY, - MEDIUM_NOT_PRESENT); - return -1; - } - else - { - - MSC_BOT_Data[0] = (uint8_t)(SCSI_blk_nbr - 1 >> 24); - MSC_BOT_Data[1] = (uint8_t)(SCSI_blk_nbr - 1 >> 16); - MSC_BOT_Data[2] = (uint8_t)(SCSI_blk_nbr - 1 >> 8); - MSC_BOT_Data[3] = (uint8_t)(SCSI_blk_nbr - 1); - - MSC_BOT_Data[4] = (uint8_t)(SCSI_blk_size >> 24); - MSC_BOT_Data[5] = (uint8_t)(SCSI_blk_size >> 16); - MSC_BOT_Data[6] = (uint8_t)(SCSI_blk_size >> 8); - MSC_BOT_Data[7] = (uint8_t)(SCSI_blk_size); - - MSC_BOT_DataLen = 8; - return 0; - } -} -/** -* @brief SCSI_ReadFormatCapacity -* Process Read Format Capacity command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_ReadFormatCapacity(uint8_t lun, uint8_t *params) -{ - - uint32_t blk_size; - uint32_t blk_nbr; - uint16_t i; - - for(i=0 ; i < 12 ; i++) - { - MSC_BOT_Data[i] = 0; - } - - if(USBD_STORAGE_fops->GetCapacity(lun, &blk_nbr, &blk_size) != 0) - { - SCSI_SenseCode(lun, - NOT_READY, - MEDIUM_NOT_PRESENT); - return -1; - } - else - { - MSC_BOT_Data[3] = 0x08; - MSC_BOT_Data[4] = (uint8_t)(blk_nbr - 1 >> 24); - MSC_BOT_Data[5] = (uint8_t)(blk_nbr - 1 >> 16); - MSC_BOT_Data[6] = (uint8_t)(blk_nbr - 1 >> 8); - MSC_BOT_Data[7] = (uint8_t)(blk_nbr - 1); - - MSC_BOT_Data[8] = 0x02; - MSC_BOT_Data[9] = (uint8_t)(blk_size >> 16); - MSC_BOT_Data[10] = (uint8_t)(blk_size >> 8); - MSC_BOT_Data[11] = (uint8_t)(blk_size); - - MSC_BOT_DataLen = 12; - return 0; - } -} -/** -* @brief SCSI_ModeSense6 -* Process Mode Sense6 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_ModeSense6 (uint8_t lun, uint8_t *params) -{ - - uint16_t len = 8 ; - MSC_BOT_DataLen = len; - - while (len) - { - len--; - MSC_BOT_Data[len] = MSC_Mode_Sense6_data[len]; - } - return 0; -} - -/** -* @brief SCSI_ModeSense10 -* Process Mode Sense10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_ModeSense10 (uint8_t lun, uint8_t *params) -{ - uint16_t len = 8; - - MSC_BOT_DataLen = len; - - while (len) - { - len--; - MSC_BOT_Data[len] = MSC_Mode_Sense10_data[len]; - } - return 0; -} - -/** -* @brief SCSI_RequestSense -* Process Request Sense command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ - -static int8_t SCSI_RequestSense (uint8_t lun, uint8_t *params) -{ - uint8_t i; - - for(i=0 ; i < REQUEST_SENSE_DATA_LEN ; i++) - { - MSC_BOT_Data[i] = 0; - } - - MSC_BOT_Data[0] = 0x70; - MSC_BOT_Data[7] = REQUEST_SENSE_DATA_LEN - 6; - - if((SCSI_Sense_Head != SCSI_Sense_Tail)) { - - MSC_BOT_Data[2] = SCSI_Sense[SCSI_Sense_Head].Skey; - MSC_BOT_Data[12] = SCSI_Sense[SCSI_Sense_Head].w.b.ASCQ; - MSC_BOT_Data[13] = SCSI_Sense[SCSI_Sense_Head].w.b.ASC; - SCSI_Sense_Head++; - - if (SCSI_Sense_Head == SENSE_LIST_DEEPTH) - { - SCSI_Sense_Head = 0; - } - } - MSC_BOT_DataLen = REQUEST_SENSE_DATA_LEN; - - if (params[4] <= REQUEST_SENSE_DATA_LEN) - { - MSC_BOT_DataLen = params[4]; - } - return 0; -} - -/** -* @brief SCSI_SenseCode -* Load the last error code in the error list -* @param lun: Logical unit number -* @param sKey: Sense Key -* @param ASC: Additional Sense Key -* @retval none - -*/ -void SCSI_SenseCode(uint8_t lun, uint8_t sKey, uint8_t ASC) -{ - SCSI_Sense[SCSI_Sense_Tail].Skey = sKey; - SCSI_Sense[SCSI_Sense_Tail].w.ASC = ASC << 8; - SCSI_Sense_Tail++; - if (SCSI_Sense_Tail == SENSE_LIST_DEEPTH) - { - SCSI_Sense_Tail = 0; - } -} -/** -* @brief SCSI_StartStopUnit -* Process Start Stop Unit command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_StartStopUnit(uint8_t lun, uint8_t *params) -{ - MSC_BOT_DataLen = 0; - return 0; -} - -/** -* @brief SCSI_Read10 -* Process Read10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_Read10(uint8_t lun , uint8_t *params) -{ - if(MSC_BOT_State == BOT_IDLE) /* Idle */ - { - - /* case 10 : Ho <> Di */ - - if ((MSC_BOT_cbw.bmFlags & 0x80) != 0x80) - { - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } - - if(USBD_STORAGE_fops->IsReady(lun) !=0 ) - { - SCSI_SenseCode(lun, - NOT_READY, - MEDIUM_NOT_PRESENT); - return -1; - } - - SCSI_blk_addr = (params[2] << 24) | \ - (params[3] << 16) | \ - (params[4] << 8) | \ - params[5]; - - SCSI_blk_len = (params[7] << 8) | \ - params[8]; - - - - if( SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) - { - return -1; /* error */ - } - - MSC_BOT_State = BOT_DATA_IN; - SCSI_blk_addr *= SCSI_blk_size; - SCSI_blk_len *= SCSI_blk_size; - - /* cases 4,5 : Hi <> Dn */ - if (MSC_BOT_cbw.dDataLength != SCSI_blk_len) - { - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } - } - MSC_BOT_DataLen = MSC_MEDIA_PACKET; - - return SCSI_ProcessRead(lun); -} - -/** -* @brief SCSI_Write10 -* Process Write10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ - -static int8_t SCSI_Write10 (uint8_t lun , uint8_t *params) -{ - if (MSC_BOT_State == BOT_IDLE) /* Idle */ - { - - /* case 8 : Hi <> Do */ - - if ((MSC_BOT_cbw.bmFlags & 0x80) == 0x80) - { - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } - - /* Check whether Media is ready */ - if(USBD_STORAGE_fops->IsReady(lun) !=0 ) - { - SCSI_SenseCode(lun, - NOT_READY, - MEDIUM_NOT_PRESENT); - return -1; - } - - /* Check If media is write-protected */ - if(USBD_STORAGE_fops->IsWriteProtected(lun) !=0 ) - { - SCSI_SenseCode(lun, - NOT_READY, - WRITE_PROTECTED); - return -1; - } - - - SCSI_blk_addr = (params[2] << 24) | \ - (params[3] << 16) | \ - (params[4] << 8) | \ - params[5]; - SCSI_blk_len = (params[7] << 8) | \ - params[8]; - - /* check if LBA address is in the right range */ - if(SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) - { - return -1; /* error */ - } - - SCSI_blk_addr *= SCSI_blk_size; - SCSI_blk_len *= SCSI_blk_size; - - /* cases 3,11,13 : Hn,Ho <> D0 */ - if (MSC_BOT_cbw.dDataLength != SCSI_blk_len) - { - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } - - /* Prepare EP to receive first data packet */ - MSC_BOT_State = BOT_DATA_OUT; - DCD_EP_PrepareRx (cdev, - MSC_OUT_EP, - MSC_BOT_Data, - MIN (SCSI_blk_len, MSC_MEDIA_PACKET)); - } - else /* Write Process ongoing */ - { - return SCSI_ProcessWrite(lun); - } - return 0; -} - - -/** -* @brief SCSI_Verify10 -* Process Verify10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ - -static int8_t SCSI_Verify10(uint8_t lun , uint8_t *params){ - if ((params[1]& 0x02) == 0x02) - { - SCSI_SenseCode (lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); - return -1; /* Error, Verify Mode Not supported*/ - } - - if(SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) - { - return -1; /* error */ - } - MSC_BOT_DataLen = 0; - return 0; -} - -/** -* @brief SCSI_CheckAddressRange -* Check address range -* @param lun: Logical unit number -* @param blk_offset: first block address -* @param blk_nbr: number of block to be processed -* @retval status -*/ -static int8_t SCSI_CheckAddressRange (uint8_t lun , uint32_t blk_offset , uint16_t blk_nbr) -{ - - if ((blk_offset + blk_nbr) > SCSI_blk_nbr ) - { - SCSI_SenseCode(lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE); - return -1; - } - return 0; -} - -/** -* @brief SCSI_ProcessRead -* Handle Read Process -* @param lun: Logical unit number -* @retval status -*/ -static int8_t SCSI_ProcessRead (uint8_t lun) -{ - uint32_t len; - - len = MIN(SCSI_blk_len , MSC_MEDIA_PACKET); - - if( USBD_STORAGE_fops->Read(lun , - MSC_BOT_Data, - SCSI_blk_addr / SCSI_blk_size, - len / SCSI_blk_size) < 0) - { - - SCSI_SenseCode(lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR); - return -1; - } - - - DCD_EP_Tx (cdev, - MSC_IN_EP, - MSC_BOT_Data, - len); - - - SCSI_blk_addr += len; - SCSI_blk_len -= len; - - /* case 6 : Hi = Di */ - MSC_BOT_csw.dDataResidue -= len; - - if (SCSI_blk_len == 0) - { - MSC_BOT_State = BOT_LAST_DATA_IN; - } - return 0; -} - -/** -* @brief SCSI_ProcessWrite -* Handle Write Process -* @param lun: Logical unit number -* @retval status -*/ - -static int8_t SCSI_ProcessWrite (uint8_t lun) -{ - uint32_t len; - - len = MIN(SCSI_blk_len , MSC_MEDIA_PACKET); - - if(USBD_STORAGE_fops->Write(lun , - MSC_BOT_Data, - SCSI_blk_addr / SCSI_blk_size, - len / SCSI_blk_size) < 0) - { - SCSI_SenseCode(lun, HARDWARE_ERROR, WRITE_FAULT); - return -1; - } - - - SCSI_blk_addr += len; - SCSI_blk_len -= len; - - /* case 12 : Ho = Do */ - MSC_BOT_csw.dDataResidue -= len; - - if (SCSI_blk_len == 0) - { - MSC_BOT_SendCSW (cdev, CSW_CMD_PASSED); - } - else - { - /* Prapare EP to Receive next packet */ - DCD_EP_PrepareRx (cdev, - MSC_OUT_EP, - MSC_BOT_Data, - MIN (SCSI_blk_len, MSC_MEDIA_PACKET)); - } - - return 0; -} -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_msc_scsi.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides all the USBD SCSI layer functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_bot.h" +#include "usbd_msc_scsi.h" +#include "usbd_msc_mem.h" +#include "usbd_msc_data.h" + + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_SCSI + * @brief Mass storage SCSI layer module + * @{ + */ + +/** @defgroup MSC_SCSI_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Variables + * @{ + */ + +SCSI_Sense_TypeDef SCSI_Sense [SENSE_LIST_DEEPTH]; +uint8_t SCSI_Sense_Head; +uint8_t SCSI_Sense_Tail; + +uint32_t SCSI_blk_size; +uint32_t SCSI_blk_nbr; + +uint32_t SCSI_blk_addr; +uint32_t SCSI_blk_len; + +USB_OTG_CORE_HANDLE *cdev; +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_FunctionPrototypes + * @{ + */ +static int8_t SCSI_TestUnitReady(uint8_t lun, uint8_t *params); +static int8_t SCSI_Inquiry(uint8_t lun, uint8_t *params); +static int8_t SCSI_ReadFormatCapacity(uint8_t lun, uint8_t *params); +static int8_t SCSI_ReadCapacity10(uint8_t lun, uint8_t *params); +static int8_t SCSI_RequestSense (uint8_t lun, uint8_t *params); +static int8_t SCSI_StartStopUnit(uint8_t lun, uint8_t *params); +static int8_t SCSI_ModeSense6 (uint8_t lun, uint8_t *params); +static int8_t SCSI_ModeSense10 (uint8_t lun, uint8_t *params); +static int8_t SCSI_Write10(uint8_t lun , uint8_t *params); +static int8_t SCSI_Read10(uint8_t lun , uint8_t *params); +static int8_t SCSI_Verify10(uint8_t lun, uint8_t *params); +static int8_t SCSI_CheckAddressRange (uint8_t lun , + uint32_t blk_offset , + uint16_t blk_nbr); +static int8_t SCSI_ProcessRead (uint8_t lun); + +static int8_t SCSI_ProcessWrite (uint8_t lun); +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Functions + * @{ + */ + + +/** +* @brief SCSI_ProcessCmd +* Process SCSI commands +* @param pdev: device instance +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev, + uint8_t lun, + uint8_t *params) +{ + cdev = pdev; + + switch (params[0]) + { + case SCSI_TEST_UNIT_READY: + return SCSI_TestUnitReady(lun, params); + + case SCSI_REQUEST_SENSE: + return SCSI_RequestSense (lun, params); + case SCSI_INQUIRY: + return SCSI_Inquiry(lun, params); + + case SCSI_START_STOP_UNIT: + return SCSI_StartStopUnit(lun, params); + + case SCSI_ALLOW_MEDIUM_REMOVAL: + return SCSI_StartStopUnit(lun, params); + + case SCSI_MODE_SENSE6: + return SCSI_ModeSense6 (lun, params); + + case SCSI_MODE_SENSE10: + return SCSI_ModeSense10 (lun, params); + + case SCSI_READ_FORMAT_CAPACITIES: + return SCSI_ReadFormatCapacity(lun, params); + + case SCSI_READ_CAPACITY10: + return SCSI_ReadCapacity10(lun, params); + + case SCSI_READ10: + return SCSI_Read10(lun, params); + + case SCSI_WRITE10: + return SCSI_Write10(lun, params); + + case SCSI_VERIFY10: + return SCSI_Verify10(lun, params); + + default: + SCSI_SenseCode(lun, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } +} + + +/** +* @brief SCSI_TestUnitReady +* Process SCSI Test Unit Ready Command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_TestUnitReady(uint8_t lun, uint8_t *params) +{ + + /* case 9 : Hi > D0 */ + if (MSC_BOT_cbw.dDataLength != 0) + { + SCSI_SenseCode(MSC_BOT_cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } + + if(USBD_STORAGE_fops->IsReady(lun) !=0 ) + { + SCSI_SenseCode(lun, + NOT_READY, + MEDIUM_NOT_PRESENT); + return -1; + } + MSC_BOT_DataLen = 0; + return 0; +} + +/** +* @brief SCSI_Inquiry +* Process Inquiry command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_Inquiry(uint8_t lun, uint8_t *params) +{ + uint8_t* pPage; + uint16_t len; + + if (params[1] & 0x01)/*Evpd is set*/ + { + pPage = (uint8_t *)MSC_Page00_Inquiry_Data; + len = LENGTH_INQUIRY_PAGE00; + } + else + { + + pPage = (uint8_t *)&USBD_STORAGE_fops->pInquiry[lun * USBD_STD_INQUIRY_LENGTH]; + len = pPage[4] + 5; + + if (params[4] <= len) + { + len = params[4]; + } + } + MSC_BOT_DataLen = len; + + while (len) + { + len--; + MSC_BOT_Data[len] = pPage[len]; + } + return 0; +} + +/** +* @brief SCSI_ReadCapacity10 +* Process Read Capacity 10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ReadCapacity10(uint8_t lun, uint8_t *params) +{ + + if(USBD_STORAGE_fops->GetCapacity(lun, &SCSI_blk_nbr, &SCSI_blk_size) != 0) + { + SCSI_SenseCode(lun, + NOT_READY, + MEDIUM_NOT_PRESENT); + return -1; + } + else + { + + MSC_BOT_Data[0] = (uint8_t)(SCSI_blk_nbr - 1 >> 24); + MSC_BOT_Data[1] = (uint8_t)(SCSI_blk_nbr - 1 >> 16); + MSC_BOT_Data[2] = (uint8_t)(SCSI_blk_nbr - 1 >> 8); + MSC_BOT_Data[3] = (uint8_t)(SCSI_blk_nbr - 1); + + MSC_BOT_Data[4] = (uint8_t)(SCSI_blk_size >> 24); + MSC_BOT_Data[5] = (uint8_t)(SCSI_blk_size >> 16); + MSC_BOT_Data[6] = (uint8_t)(SCSI_blk_size >> 8); + MSC_BOT_Data[7] = (uint8_t)(SCSI_blk_size); + + MSC_BOT_DataLen = 8; + return 0; + } +} +/** +* @brief SCSI_ReadFormatCapacity +* Process Read Format Capacity command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ReadFormatCapacity(uint8_t lun, uint8_t *params) +{ + + uint32_t blk_size; + uint32_t blk_nbr; + uint16_t i; + + for(i=0 ; i < 12 ; i++) + { + MSC_BOT_Data[i] = 0; + } + + if(USBD_STORAGE_fops->GetCapacity(lun, &blk_nbr, &blk_size) != 0) + { + SCSI_SenseCode(lun, + NOT_READY, + MEDIUM_NOT_PRESENT); + return -1; + } + else + { + MSC_BOT_Data[3] = 0x08; + MSC_BOT_Data[4] = (uint8_t)(blk_nbr - 1 >> 24); + MSC_BOT_Data[5] = (uint8_t)(blk_nbr - 1 >> 16); + MSC_BOT_Data[6] = (uint8_t)(blk_nbr - 1 >> 8); + MSC_BOT_Data[7] = (uint8_t)(blk_nbr - 1); + + MSC_BOT_Data[8] = 0x02; + MSC_BOT_Data[9] = (uint8_t)(blk_size >> 16); + MSC_BOT_Data[10] = (uint8_t)(blk_size >> 8); + MSC_BOT_Data[11] = (uint8_t)(blk_size); + + MSC_BOT_DataLen = 12; + return 0; + } +} +/** +* @brief SCSI_ModeSense6 +* Process Mode Sense6 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ModeSense6 (uint8_t lun, uint8_t *params) +{ + + uint16_t len = 8 ; + MSC_BOT_DataLen = len; + + while (len) + { + len--; + MSC_BOT_Data[len] = MSC_Mode_Sense6_data[len]; + } + return 0; +} + +/** +* @brief SCSI_ModeSense10 +* Process Mode Sense10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ModeSense10 (uint8_t lun, uint8_t *params) +{ + uint16_t len = 8; + + MSC_BOT_DataLen = len; + + while (len) + { + len--; + MSC_BOT_Data[len] = MSC_Mode_Sense10_data[len]; + } + return 0; +} + +/** +* @brief SCSI_RequestSense +* Process Request Sense command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ + +static int8_t SCSI_RequestSense (uint8_t lun, uint8_t *params) +{ + uint8_t i; + + for(i=0 ; i < REQUEST_SENSE_DATA_LEN ; i++) + { + MSC_BOT_Data[i] = 0; + } + + MSC_BOT_Data[0] = 0x70; + MSC_BOT_Data[7] = REQUEST_SENSE_DATA_LEN - 6; + + if((SCSI_Sense_Head != SCSI_Sense_Tail)) { + + MSC_BOT_Data[2] = SCSI_Sense[SCSI_Sense_Head].Skey; + MSC_BOT_Data[12] = SCSI_Sense[SCSI_Sense_Head].w.b.ASCQ; + MSC_BOT_Data[13] = SCSI_Sense[SCSI_Sense_Head].w.b.ASC; + SCSI_Sense_Head++; + + if (SCSI_Sense_Head == SENSE_LIST_DEEPTH) + { + SCSI_Sense_Head = 0; + } + } + MSC_BOT_DataLen = REQUEST_SENSE_DATA_LEN; + + if (params[4] <= REQUEST_SENSE_DATA_LEN) + { + MSC_BOT_DataLen = params[4]; + } + return 0; +} + +/** +* @brief SCSI_SenseCode +* Load the last error code in the error list +* @param lun: Logical unit number +* @param sKey: Sense Key +* @param ASC: Additional Sense Key +* @retval none + +*/ +void SCSI_SenseCode(uint8_t lun, uint8_t sKey, uint8_t ASC) +{ + SCSI_Sense[SCSI_Sense_Tail].Skey = sKey; + SCSI_Sense[SCSI_Sense_Tail].w.ASC = ASC << 8; + SCSI_Sense_Tail++; + if (SCSI_Sense_Tail == SENSE_LIST_DEEPTH) + { + SCSI_Sense_Tail = 0; + } +} +/** +* @brief SCSI_StartStopUnit +* Process Start Stop Unit command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_StartStopUnit(uint8_t lun, uint8_t *params) +{ + MSC_BOT_DataLen = 0; + return 0; +} + +/** +* @brief SCSI_Read10 +* Process Read10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_Read10(uint8_t lun , uint8_t *params) +{ + if(MSC_BOT_State == BOT_IDLE) /* Idle */ + { + + /* case 10 : Ho <> Di */ + + if ((MSC_BOT_cbw.bmFlags & 0x80) != 0x80) + { + SCSI_SenseCode(MSC_BOT_cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } + + if(USBD_STORAGE_fops->IsReady(lun) !=0 ) + { + SCSI_SenseCode(lun, + NOT_READY, + MEDIUM_NOT_PRESENT); + return -1; + } + + SCSI_blk_addr = (params[2] << 24) | \ + (params[3] << 16) | \ + (params[4] << 8) | \ + params[5]; + + SCSI_blk_len = (params[7] << 8) | \ + params[8]; + + + + if( SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) + { + return -1; /* error */ + } + + MSC_BOT_State = BOT_DATA_IN; + SCSI_blk_addr *= SCSI_blk_size; + SCSI_blk_len *= SCSI_blk_size; + + /* cases 4,5 : Hi <> Dn */ + if (MSC_BOT_cbw.dDataLength != SCSI_blk_len) + { + SCSI_SenseCode(MSC_BOT_cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } + } + MSC_BOT_DataLen = MSC_MEDIA_PACKET; + + return SCSI_ProcessRead(lun); +} + +/** +* @brief SCSI_Write10 +* Process Write10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ + +static int8_t SCSI_Write10 (uint8_t lun , uint8_t *params) +{ + if (MSC_BOT_State == BOT_IDLE) /* Idle */ + { + + /* case 8 : Hi <> Do */ + + if ((MSC_BOT_cbw.bmFlags & 0x80) == 0x80) + { + SCSI_SenseCode(MSC_BOT_cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } + + /* Check whether Media is ready */ + if(USBD_STORAGE_fops->IsReady(lun) !=0 ) + { + SCSI_SenseCode(lun, + NOT_READY, + MEDIUM_NOT_PRESENT); + return -1; + } + + /* Check If media is write-protected */ + if(USBD_STORAGE_fops->IsWriteProtected(lun) !=0 ) + { + SCSI_SenseCode(lun, + NOT_READY, + WRITE_PROTECTED); + return -1; + } + + + SCSI_blk_addr = (params[2] << 24) | \ + (params[3] << 16) | \ + (params[4] << 8) | \ + params[5]; + SCSI_blk_len = (params[7] << 8) | \ + params[8]; + + /* check if LBA address is in the right range */ + if(SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) + { + return -1; /* error */ + } + + SCSI_blk_addr *= SCSI_blk_size; + SCSI_blk_len *= SCSI_blk_size; + + /* cases 3,11,13 : Hn,Ho <> D0 */ + if (MSC_BOT_cbw.dDataLength != SCSI_blk_len) + { + SCSI_SenseCode(MSC_BOT_cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } + + /* Prepare EP to receive first data packet */ + MSC_BOT_State = BOT_DATA_OUT; + DCD_EP_PrepareRx (cdev, + MSC_OUT_EP, + MSC_BOT_Data, + MIN (SCSI_blk_len, MSC_MEDIA_PACKET)); + } + else /* Write Process ongoing */ + { + return SCSI_ProcessWrite(lun); + } + return 0; +} + + +/** +* @brief SCSI_Verify10 +* Process Verify10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ + +static int8_t SCSI_Verify10(uint8_t lun , uint8_t *params){ + if ((params[1]& 0x02) == 0x02) + { + SCSI_SenseCode (lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); + return -1; /* Error, Verify Mode Not supported*/ + } + + if(SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) + { + return -1; /* error */ + } + MSC_BOT_DataLen = 0; + return 0; +} + +/** +* @brief SCSI_CheckAddressRange +* Check address range +* @param lun: Logical unit number +* @param blk_offset: first block address +* @param blk_nbr: number of block to be processed +* @retval status +*/ +static int8_t SCSI_CheckAddressRange (uint8_t lun , uint32_t blk_offset , uint16_t blk_nbr) +{ + + if ((blk_offset + blk_nbr) > SCSI_blk_nbr ) + { + SCSI_SenseCode(lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE); + return -1; + } + return 0; +} + +/** +* @brief SCSI_ProcessRead +* Handle Read Process +* @param lun: Logical unit number +* @retval status +*/ +static int8_t SCSI_ProcessRead (uint8_t lun) +{ + uint32_t len; + + len = MIN(SCSI_blk_len , MSC_MEDIA_PACKET); + + if( USBD_STORAGE_fops->Read(lun , + MSC_BOT_Data, + SCSI_blk_addr / SCSI_blk_size, + len / SCSI_blk_size) < 0) + { + + SCSI_SenseCode(lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR); + return -1; + } + + + DCD_EP_Tx (cdev, + MSC_IN_EP, + MSC_BOT_Data, + len); + + + SCSI_blk_addr += len; + SCSI_blk_len -= len; + + /* case 6 : Hi = Di */ + MSC_BOT_csw.dDataResidue -= len; + + if (SCSI_blk_len == 0) + { + MSC_BOT_State = BOT_LAST_DATA_IN; + } + return 0; +} + +/** +* @brief SCSI_ProcessWrite +* Handle Write Process +* @param lun: Logical unit number +* @retval status +*/ + +static int8_t SCSI_ProcessWrite (uint8_t lun) +{ + uint32_t len; + + len = MIN(SCSI_blk_len , MSC_MEDIA_PACKET); + + if(USBD_STORAGE_fops->Write(lun , + MSC_BOT_Data, + SCSI_blk_addr / SCSI_blk_size, + len / SCSI_blk_size) < 0) + { + SCSI_SenseCode(lun, HARDWARE_ERROR, WRITE_FAULT); + return -1; + } + + + SCSI_blk_addr += len; + SCSI_blk_len -= len; + + /* case 12 : Ho = Do */ + MSC_BOT_csw.dDataResidue -= len; + + if (SCSI_blk_len == 0) + { + MSC_BOT_SendCSW (cdev, CSW_CMD_PASSED); + } + else + { + /* Prapare EP to Receive next packet */ + DCD_EP_PrepareRx (cdev, + MSC_OUT_EP, + MSC_BOT_Data, + MIN (SCSI_blk_len, MSC_MEDIA_PACKET)); + } + + return 0; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c index ce16bae4..927e9dd4 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c @@ -1,179 +1,179 @@ -/** - ****************************************************************************** - * @file usbd_storage_template.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Memory management layer - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_mem.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Extern function prototypes ------------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -#define STORAGE_LUN_NBR 1 - -int8_t STORAGE_Init (uint8_t lun); - -int8_t STORAGE_GetCapacity (uint8_t lun, - uint32_t *block_num, - uint16_t *block_size); - -int8_t STORAGE_IsReady (uint8_t lun); - -int8_t STORAGE_IsWriteProtected (uint8_t lun); - -int8_t STORAGE_Read (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len); - -int8_t STORAGE_Write (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len); - -int8_t STORAGE_GetMaxLun (void); - -/* USB Mass storage Standard Inquiry Data */ -const int8_t STORAGE_Inquirydata[] = {//36 - - /* LUN 0 */ - 0x00, - 0x80, - 0x02, - 0x02, - (USBD_STD_INQUIRY_LENGTH - 5), - 0x00, - 0x00, - 0x00, - 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */ - 'P', 'r', 'o', 'd', 'u', 't', ' ', ' ', /* Product : 16 Bytes */ - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - '0', '.', '0' ,'1', /* Version : 4 Bytes */ -}; - -USBD_STORAGE_cb_TypeDef USBD_MICRO_SDIO_fops = -{ - STORAGE_Init, - STORAGE_GetCapacity, - STORAGE_IsReady, - STORAGE_IsWriteProtected, - STORAGE_Read, - STORAGE_Write, - STORAGE_GetMaxLun, - STORAGE_Inquirydata, - -}; - -USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops = &USBD_MICRO_SDIO_fops; -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the microSD card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_Init (uint8_t lun) -{ - return (0); -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size) -{ - return (0); -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_IsReady (uint8_t lun) -{ - return (0); -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_IsWriteProtected (uint8_t lun) -{ - return 0; -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_Read (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len) -{ - return 0; -} -/******************************************************************************* -* Function Name : Write_Memory -* Description : Handle the Write operation to the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_Write (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len) -{ - return (0); -} -/******************************************************************************* -* Function Name : Write_Memory -* Description : Handle the Write operation to the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_GetMaxLun (void) -{ - return (STORAGE_LUN_NBR - 1); -} - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usbd_storage_template.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Memory management layer + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_mem.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Extern function prototypes ------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +#define STORAGE_LUN_NBR 1 + +int8_t STORAGE_Init (uint8_t lun); + +int8_t STORAGE_GetCapacity (uint8_t lun, + uint32_t *block_num, + uint16_t *block_size); + +int8_t STORAGE_IsReady (uint8_t lun); + +int8_t STORAGE_IsWriteProtected (uint8_t lun); + +int8_t STORAGE_Read (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len); + +int8_t STORAGE_Write (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len); + +int8_t STORAGE_GetMaxLun (void); + +/* USB Mass storage Standard Inquiry Data */ +const int8_t STORAGE_Inquirydata[] = {//36 + + /* LUN 0 */ + 0x00, + 0x80, + 0x02, + 0x02, + (USBD_STD_INQUIRY_LENGTH - 5), + 0x00, + 0x00, + 0x00, + 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */ + 'P', 'r', 'o', 'd', 'u', 't', ' ', ' ', /* Product : 16 Bytes */ + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + '0', '.', '0' ,'1', /* Version : 4 Bytes */ +}; + +USBD_STORAGE_cb_TypeDef USBD_MICRO_SDIO_fops = +{ + STORAGE_Init, + STORAGE_GetCapacity, + STORAGE_IsReady, + STORAGE_IsWriteProtected, + STORAGE_Read, + STORAGE_Write, + STORAGE_GetMaxLun, + STORAGE_Inquirydata, + +}; + +USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops = &USBD_MICRO_SDIO_fops; +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the microSD card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_Init (uint8_t lun) +{ + return (0); +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size) +{ + return (0); +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_IsReady (uint8_t lun) +{ + return (0); +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_IsWriteProtected (uint8_t lun) +{ + return 0; +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_Read (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len) +{ + return 0; +} +/******************************************************************************* +* Function Name : Write_Memory +* Description : Handle the Write operation to the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_Write (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len) +{ + return (0); +} +/******************************************************************************* +* Function Name : Write_Memory +* Description : Handle the Write operation to the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_GetMaxLun (void) +{ + return (STORAGE_LUN_NBR - 1); +} + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h index aa722af3..34cd39d1 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h @@ -1,78 +1,78 @@ -/** - ****************************************************************************** - * @file usbd_conf_template.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief usb device configuration template file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CONF__H__ -#define __USBD_CONF__H__ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f2xx.h" - - - -/** @defgroup USB_CONF_Exported_Defines - * @{ - */ -#define USE_USB_OTG_HS - -#define USBD_CFG_MAX_NUM 1 -#define USB_MAX_STR_DESC_SIZ 64 -#define USBD_EP0_MAX_PACKET_SIZE 64 - -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USBD_CONF__H__ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usbd_conf_template.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief usb device configuration template file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CONF__H__ +#define __USBD_CONF__H__ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f2xx.h" + + + +/** @defgroup USB_CONF_Exported_Defines + * @{ + */ +#define USE_USB_OTG_HS + +#define USBD_CFG_MAX_NUM 1 +#define USB_MAX_STR_DESC_SIZ 64 +#define USBD_EP0_MAX_PACKET_SIZE 64 + +/** + * @} + */ + + +/** @defgroup USB_CONF_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_CONF_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_CONF_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_CONF_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + + +#endif //__USBD_CONF__H__ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_core.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_core.h index 3e5ecfc2..b876856a 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_core.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_core.h @@ -1,116 +1,116 @@ -/** - ****************************************************************************** - * @file usbd_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header file for usbd_core.c - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CORE_H -#define __USBD_CORE_H - -/* Includes ------------------------------------------------------------------*/ -#include "usb_dcd.h" -#include "usbd_def.h" -#include "usbd_conf.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_CORE - * @brief This file is the Header file for usbd_core.c file - * @{ - */ - - -/** @defgroup USBD_CORE_Exported_Defines - * @{ - */ - -typedef enum { - USBD_OK = 0, - USBD_BUSY, - USBD_FAIL, -}USBD_Status; -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ - - -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_FunctionsPrototype - * @{ - */ -void USBD_Init(USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID, - USBD_DEVICE *pDevice, - USBD_Class_cb_TypeDef *class_cb, - USBD_Usr_cb_TypeDef *usr_cb); - -USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev); - -USBD_Status USBD_DeInitFull(USB_OTG_CORE_HANDLE *pdev); - -USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx); - -USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx); - -/** - * @} - */ - -#endif /* __USBD_CORE_H */ - -/** - * @} - */ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - +/** + ****************************************************************************** + * @file usbd_core.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Header file for usbd_core.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CORE_H +#define __USBD_CORE_H + +/* Includes ------------------------------------------------------------------*/ +#include "usb_dcd.h" +#include "usbd_def.h" +#include "usbd_conf.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_CORE + * @brief This file is the Header file for usbd_core.c file + * @{ + */ + + +/** @defgroup USBD_CORE_Exported_Defines + * @{ + */ + +typedef enum { + USBD_OK = 0, + USBD_BUSY, + USBD_FAIL, +}USBD_Status; +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_FunctionsPrototype + * @{ + */ +void USBD_Init(USB_OTG_CORE_HANDLE *pdev, + USB_OTG_CORE_ID_TypeDef coreID, + USBD_DEVICE *pDevice, + USBD_Class_cb_TypeDef *class_cb, + USBD_Usr_cb_TypeDef *usr_cb); + +USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev); + +USBD_Status USBD_DeInitFull(USB_OTG_CORE_HANDLE *pdev); + +USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx); + +USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx); + +/** + * @} + */ + +#endif /* __USBD_CORE_H */ + +/** + * @} + */ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_def.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_def.h index a2efc5d6..a8c86710 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_def.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_def.h @@ -1,149 +1,149 @@ -/** - ****************************************************************************** - * @file usbd_def.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief general defines for the usb device library - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USBD_DEF_H -#define __USBD_DEF_H -/* Includes ------------------------------------------------------------------*/ -#include "usbd_conf.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USB_DEF - * @brief general defines for the usb device library file - * @{ - */ - -/** @defgroup USB_DEF_Exported_Defines - * @{ - */ - -#ifndef NULL -#define NULL 0 -#endif - -#define USB_LEN_DEV_QUALIFIER_DESC 0x0A -#define USB_LEN_DEV_DESC 0x12 -#define USB_LEN_CFG_DESC 0x09 -#define USB_LEN_IF_DESC 0x09 -#define USB_LEN_EP_DESC 0x07 -#define USB_LEN_OTG_DESC 0x03 - -#define USBD_IDX_LANGID_STR 0x00 -#define USBD_IDX_MFC_STR 0x01 -#define USBD_IDX_PRODUCT_STR 0x02 -#define USBD_IDX_SERIAL_STR 0x03 -#define USBD_IDX_CONFIG_STR 0x04 -#define USBD_IDX_INTERFACE_STR 0x05 - -#define USB_REQ_TYPE_STANDARD 0x00 -#define USB_REQ_TYPE_CLASS 0x20 -#define USB_REQ_TYPE_VENDOR 0x40 -#define USB_REQ_TYPE_MASK 0x60 - -#define USB_REQ_RECIPIENT_DEVICE 0x00 -#define USB_REQ_RECIPIENT_INTERFACE 0x01 -#define USB_REQ_RECIPIENT_ENDPOINT 0x02 -#define USB_REQ_RECIPIENT_MASK 0x03 - -#define USB_REQ_GET_STATUS 0x00 -#define USB_REQ_CLEAR_FEATURE 0x01 -#define USB_REQ_SET_FEATURE 0x03 -#define USB_REQ_SET_ADDRESS 0x05 -#define USB_REQ_GET_DESCRIPTOR 0x06 -#define USB_REQ_SET_DESCRIPTOR 0x07 -#define USB_REQ_GET_CONFIGURATION 0x08 -#define USB_REQ_SET_CONFIGURATION 0x09 -#define USB_REQ_GET_INTERFACE 0x0A -#define USB_REQ_SET_INTERFACE 0x0B -#define USB_REQ_SYNCH_FRAME 0x0C - -#define USB_DESC_TYPE_DEVICE 1 -#define USB_DESC_TYPE_CONFIGURATION 2 -#define USB_DESC_TYPE_STRING 3 -#define USB_DESC_TYPE_INTERFACE 4 -#define USB_DESC_TYPE_ENDPOINT 5 -#define USB_DESC_TYPE_DEVICE_QUALIFIER 6 -#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 - - -#define USB_CONFIG_REMOTE_WAKEUP 2 -#define USB_CONFIG_SELF_POWERED 1 - -#define USB_FEATURE_EP_HALT 0 -#define USB_FEATURE_REMOTE_WAKEUP 1 -#define USB_FEATURE_TEST_MODE 2 - -/** - * @} - */ - - -/** @defgroup USBD_DEF_Exported_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_DEF_Exported_Macros - * @{ - */ -#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ - (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) - -#define LOBYTE(x) ((uint8_t)(x & 0x00FF)) -#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) -/** - * @} - */ - -/** @defgroup USBD_DEF_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_DEF_Exported_FunctionsPrototype - * @{ - */ - -/** - * @} - */ - -#endif /* __USBD_DEF_H */ - -/** - * @} - */ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_def.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief general defines for the usb device library + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __USBD_DEF_H +#define __USBD_DEF_H +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USB_DEF + * @brief general defines for the usb device library file + * @{ + */ + +/** @defgroup USB_DEF_Exported_Defines + * @{ + */ + +#ifndef NULL +#define NULL 0 +#endif + +#define USB_LEN_DEV_QUALIFIER_DESC 0x0A +#define USB_LEN_DEV_DESC 0x12 +#define USB_LEN_CFG_DESC 0x09 +#define USB_LEN_IF_DESC 0x09 +#define USB_LEN_EP_DESC 0x07 +#define USB_LEN_OTG_DESC 0x03 + +#define USBD_IDX_LANGID_STR 0x00 +#define USBD_IDX_MFC_STR 0x01 +#define USBD_IDX_PRODUCT_STR 0x02 +#define USBD_IDX_SERIAL_STR 0x03 +#define USBD_IDX_CONFIG_STR 0x04 +#define USBD_IDX_INTERFACE_STR 0x05 + +#define USB_REQ_TYPE_STANDARD 0x00 +#define USB_REQ_TYPE_CLASS 0x20 +#define USB_REQ_TYPE_VENDOR 0x40 +#define USB_REQ_TYPE_MASK 0x60 + +#define USB_REQ_RECIPIENT_DEVICE 0x00 +#define USB_REQ_RECIPIENT_INTERFACE 0x01 +#define USB_REQ_RECIPIENT_ENDPOINT 0x02 +#define USB_REQ_RECIPIENT_MASK 0x03 + +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +#define USB_DESC_TYPE_DEVICE 1 +#define USB_DESC_TYPE_CONFIGURATION 2 +#define USB_DESC_TYPE_STRING 3 +#define USB_DESC_TYPE_INTERFACE 4 +#define USB_DESC_TYPE_ENDPOINT 5 +#define USB_DESC_TYPE_DEVICE_QUALIFIER 6 +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 + + +#define USB_CONFIG_REMOTE_WAKEUP 2 +#define USB_CONFIG_SELF_POWERED 1 + +#define USB_FEATURE_EP_HALT 0 +#define USB_FEATURE_REMOTE_WAKEUP 1 +#define USB_FEATURE_TEST_MODE 2 + +/** + * @} + */ + + +/** @defgroup USBD_DEF_Exported_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_DEF_Exported_Macros + * @{ + */ +#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ + (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) + +#define LOBYTE(x) ((uint8_t)(x & 0x00FF)) +#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_FunctionsPrototype + * @{ + */ + +/** + * @} + */ + +#endif /* __USBD_DEF_H */ + +/** + * @} + */ + +/** +* @} +*/ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h index 4737ff8d..ca755f2b 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h @@ -1,115 +1,115 @@ -/** - ****************************************************************************** - * @file usbd_ioreq.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_ioreq.c file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USBD_IOREQ_H_ -#define __USBD_IOREQ_H_ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" -#include "usbd_core.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_IOREQ - * @brief header file for the usbd_ioreq.c file - * @{ - */ - -/** @defgroup USBD_IOREQ_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Exported_Types - * @{ - */ - - -/** - * @} - */ - - - -/** @defgroup USBD_IOREQ_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_IOREQ_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype - * @{ - */ - -USBD_Status USBD_CtlSendData (USB_OTG_CORE_HANDLE *pdev, - uint8_t *buf, - uint16_t len); - -USBD_Status USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len); - -USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len); - -USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len); - -USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev); - -USBD_Status USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE *pdev); - -uint16_t USBD_GetRxCount (USB_OTG_CORE_HANDLE *pdev , - uint8_t epnum); - -/** - * @} - */ - -#endif /* __USBD_IOREQ_H_ */ - -/** - * @} - */ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_ioreq.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header file for the usbd_ioreq.c file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __USBD_IOREQ_H_ +#define __USBD_IOREQ_H_ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" +#include "usbd_core.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_IOREQ + * @brief header file for the usbd_ioreq.c file + * @{ + */ + +/** @defgroup USBD_IOREQ_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Exported_Types + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_IOREQ_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_IOREQ_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype + * @{ + */ + +USBD_Status USBD_CtlSendData (USB_OTG_CORE_HANDLE *pdev, + uint8_t *buf, + uint16_t len); + +USBD_Status USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev); + +USBD_Status USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE *pdev); + +uint16_t USBD_GetRxCount (USB_OTG_CORE_HANDLE *pdev , + uint8_t epnum); + +/** + * @} + */ + +#endif /* __USBD_IOREQ_H_ */ + +/** + * @} + */ + +/** +* @} +*/ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_req.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_req.h index dcfa8930..9aa9e44a 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_req.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_req.h @@ -1,102 +1,102 @@ -/** - ****************************************************************************** - * @file usbd_req.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_req.c file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USB_REQUEST_H_ -#define __USB_REQUEST_H_ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" -#include "usbd_core.h" -#include "usbd_conf.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_REQ - * @brief header file for the usbd_ioreq.c file - * @{ - */ - -/** @defgroup USBD_REQ_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_REQ_Exported_Types - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_REQ_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_REQ_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_REQ_Exported_FunctionsPrototype - * @{ - */ - -USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req); -USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req); -USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req); -void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); -/** - * @} - */ - -#endif /* __USB_REQUEST_H_ */ - -/** - * @} - */ - -/** -* @} -*/ - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_req.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief header file for the usbd_req.c file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __USB_REQUEST_H_ +#define __USB_REQUEST_H_ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" +#include "usbd_core.h" +#include "usbd_conf.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_REQ + * @brief header file for the usbd_ioreq.c file + * @{ + */ + +/** @defgroup USBD_REQ_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Exported_Types + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_REQ_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_REQ_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_REQ_Exported_FunctionsPrototype + * @{ + */ + +USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req); +USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req); +USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req); +void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); +/** + * @} + */ + +#endif /* __USB_REQUEST_H_ */ + +/** + * @} + */ + +/** +* @} +*/ + + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_usr.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_usr.h index 096759b5..44e7b1dd 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_usr.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/inc/usbd_usr.h @@ -1,135 +1,135 @@ -/** - ****************************************************************************** - * @file usbd_usr.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header file for usbd_usr.c - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_USR_H__ -#define __USBD_USR_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_core.h" - - -/** @addtogroup USBD_USER - * @{ - */ - -/** @addtogroup USBD_MSC_DEMO_USER_CALLBACKS - * @{ - */ - -/** @defgroup USBD_USR - * @brief This file is the Header file for usbd_usr.c - * @{ - */ - - -/** @defgroup USBD_USR_Exported_Types - * @{ - */ - -extern USBD_Usr_cb_TypeDef USR_cb; -extern USBD_Usr_cb_TypeDef USR_FS_cb; -extern USBD_Usr_cb_TypeDef USR_HS_cb; - - - -/** - * @} - */ - - - -/** @defgroup USBD_USR_Exported_Defines - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_USR_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_USR_Exported_Variables - * @{ - */ - -void USBD_USR_Init(void); -void USBD_USR_DeviceReset (uint8_t speed); -void USBD_USR_DeviceConfigured (void); -void USBD_USR_DeviceSuspended(void); -void USBD_USR_DeviceResumed(void); - -void USBD_USR_DeviceConnected(void); -void USBD_USR_DeviceDisconnected(void); - -void USBD_USR_FS_Init(void); -void USBD_USR_FS_DeviceReset (uint8_t speed); -void USBD_USR_FS_DeviceConfigured (void); -void USBD_USR_FS_DeviceSuspended(void); -void USBD_USR_FS_DeviceResumed(void); - -void USBD_USR_FS_DeviceConnected(void); -void USBD_USR_FS_DeviceDisconnected(void); - -void USBD_USR_HS_Init(void); -void USBD_USR_HS_DeviceReset (uint8_t speed); -void USBD_USR_HS_DeviceConfigured (void); -void USBD_USR_HS_DeviceSuspended(void); -void USBD_USR_HS_DeviceResumed(void); - -void USBD_USR_HS_DeviceConnected(void); -void USBD_USR_HS_DeviceDisconnected(void); - -/** - * @} - */ - -/** @defgroup USBD_USR_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - -#endif /*__USBD_USR_H__*/ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - - +/** + ****************************************************************************** + * @file usbd_usr.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Header file for usbd_usr.c + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_USR_H__ +#define __USBD_USR_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" + + +/** @addtogroup USBD_USER + * @{ + */ + +/** @addtogroup USBD_MSC_DEMO_USER_CALLBACKS + * @{ + */ + +/** @defgroup USBD_USR + * @brief This file is the Header file for usbd_usr.c + * @{ + */ + + +/** @defgroup USBD_USR_Exported_Types + * @{ + */ + +extern USBD_Usr_cb_TypeDef USR_cb; +extern USBD_Usr_cb_TypeDef USR_FS_cb; +extern USBD_Usr_cb_TypeDef USR_HS_cb; + + + +/** + * @} + */ + + + +/** @defgroup USBD_USR_Exported_Defines + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_USR_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_USR_Exported_Variables + * @{ + */ + +void USBD_USR_Init(void); +void USBD_USR_DeviceReset (uint8_t speed); +void USBD_USR_DeviceConfigured (void); +void USBD_USR_DeviceSuspended(void); +void USBD_USR_DeviceResumed(void); + +void USBD_USR_DeviceConnected(void); +void USBD_USR_DeviceDisconnected(void); + +void USBD_USR_FS_Init(void); +void USBD_USR_FS_DeviceReset (uint8_t speed); +void USBD_USR_FS_DeviceConfigured (void); +void USBD_USR_FS_DeviceSuspended(void); +void USBD_USR_FS_DeviceResumed(void); + +void USBD_USR_FS_DeviceConnected(void); +void USBD_USR_FS_DeviceDisconnected(void); + +void USBD_USR_HS_Init(void); +void USBD_USR_HS_DeviceReset (uint8_t speed); +void USBD_USR_HS_DeviceConfigured (void); +void USBD_USR_HS_DeviceSuspended(void); +void USBD_USR_HS_DeviceResumed(void); + +void USBD_USR_HS_DeviceConnected(void); +void USBD_USR_HS_DeviceDisconnected(void); + +/** + * @} + */ + +/** @defgroup USBD_USR_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + +#endif /*__USBD_USR_H__*/ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + + + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c index 289d9d28..af758427 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c @@ -1,483 +1,483 @@ -/** - ****************************************************************************** - * @file usbd_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides all the USBD core functions. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_core.h" -#include "usbd_req.h" -#include "usbd_ioreq.h" -#include "usb_dcd_int.h" -#include "usb_bsp.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY -* @{ -*/ - - -/** @defgroup USBD_CORE -* @brief usbd core module -* @{ -*/ - -/** @defgroup USBD_CORE_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBD_CORE_Private_Defines -* @{ -*/ - -/** -* @} -*/ - - -/** @defgroup USBD_CORE_Private_Macros -* @{ -*/ -/** -* @} -*/ - - - - -/** @defgroup USBD_CORE_Private_FunctionPrototypes -* @{ -*/ -static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); -static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); -static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev); -#ifdef VBUS_SENSING_ENABLED -static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev); -#endif -static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev); -/** -* @} -*/ - -/** @defgroup USBD_CORE_Private_Variables -* @{ -*/ - - - -USBD_DCD_INT_cb_TypeDef USBD_DCD_INT_cb = -{ - USBD_DataOutStage, - USBD_DataInStage, - USBD_SetupStage, - USBD_SOF, - USBD_Reset, - USBD_Suspend, - USBD_Resume, - USBD_IsoINIncomplete, - USBD_IsoOUTIncomplete, -#ifdef VBUS_SENSING_ENABLED -USBD_DevConnected, -USBD_DevDisconnected, -#endif -}; - -USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops = &USBD_DCD_INT_cb; -/** -* @} -*/ - -/** @defgroup USBD_CORE_Private_Functions -* @{ -*/ - -/** -* @brief USBD_Init -* Initailizes the device stack and load the class driver -* @param pdev: device instance -* @param core_address: USB OTG core ID -* @param class_cb: Class callback structure address -* @param usr_cb: User callback structure address -* @retval None -*/ -void USBD_Init(USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID, - USBD_DEVICE *pDevice, - USBD_Class_cb_TypeDef *class_cb, - USBD_Usr_cb_TypeDef *usr_cb) -{ - /* Hardware Init */ - USB_OTG_BSP_Init(pdev); - - USBD_DeInit(pdev); - - /*Register class and user callbacks */ - pdev->dev.class_cb = class_cb; - pdev->dev.usr_cb = usr_cb; - pdev->dev.usr_device = pDevice; - - /* set USB OTG core params */ - DCD_Init(pdev , coreID); - - /* Upon Init call usr callback */ - pdev->dev.usr_cb->Init(); - - /* Enable Interrupts */ - USB_OTG_BSP_EnableInterrupt(pdev); -} - -/** -* @brief USBD_DeInit -* Re-Initialize th deviuce library -* @param pdev: device instance -* @retval status: status -*/ -USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev) -{ - return USBD_OK; -} - -USBD_Status USBD_DeInitFull(USB_OTG_CORE_HANDLE *pdev) -{ - /* Software Init */ - USB_OTG_BSP_DisableInterrupt(pdev); - USB_OTG_BSP_DeInit(pdev); - - return USBD_OK; -} - -/** -* @brief USBD_SetupStage -* Handle the setup stage -* @param pdev: device instance -* @retval status -*/ -static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev) -{ - USB_SETUP_REQ req; - - USBD_ParseSetupRequest(pdev , &req); - - switch (req.bmRequest & 0x1F) - { - case USB_REQ_RECIPIENT_DEVICE: - USBD_StdDevReq (pdev, &req); - break; - - case USB_REQ_RECIPIENT_INTERFACE: - USBD_StdItfReq(pdev, &req); - break; - - case USB_REQ_RECIPIENT_ENDPOINT: - USBD_StdEPReq(pdev, &req); - break; - - default: - DCD_EP_Stall(pdev , req.bmRequest & 0x80); - break; - } - return USBD_OK; -} - -/** -* @brief USBD_DataOutStage -* Handle data out stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ -static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - USB_OTG_EP *ep; - - if(epnum == 0) - { - ep = &pdev->dev.out_ep[0]; - if ( pdev->dev.device_state == USB_OTG_EP0_DATA_OUT) - { - if(ep->rem_data_len > ep->maxpacket) - { - ep->rem_data_len -= ep->maxpacket; - - if(pdev->cfg.dma_enable == 1) - { - /* in slave mode this, is handled by the RxSTSQLvl ISR */ - ep->xfer_buff += ep->maxpacket; - } - USBD_CtlContinueRx (pdev, - ep->xfer_buff, - MIN(ep->rem_data_len ,ep->maxpacket)); - } - else - { - if((pdev->dev.class_cb->EP0_RxReady != NULL)&& - (pdev->dev.device_status == USB_OTG_CONFIGURED)) - { - pdev->dev.class_cb->EP0_RxReady(pdev); - } - USBD_CtlSendStatus(pdev); - } - } - } - else if((pdev->dev.class_cb->DataOut != NULL)&& - (pdev->dev.device_status == USB_OTG_CONFIGURED)) - { - pdev->dev.class_cb->DataOut(pdev, epnum); - } - return USBD_OK; -} - -/** -* @brief USBD_DataInStage -* Handle data in stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ -static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - USB_OTG_EP *ep; - - if(epnum == 0) - { - ep = &pdev->dev.in_ep[0]; - if ( pdev->dev.device_state == USB_OTG_EP0_DATA_IN) - { - if(ep->rem_data_len > ep->maxpacket) - { - ep->rem_data_len -= ep->maxpacket; - if(pdev->cfg.dma_enable == 1) - { - /* in slave mode this, is handled by the TxFifoEmpty ISR */ - ep->xfer_buff += ep->maxpacket; - } - USBD_CtlContinueSendData (pdev, - ep->xfer_buff, - ep->rem_data_len); - } - else - { /* last packet is MPS multiple, so send ZLP packet */ - if((ep->total_data_len % ep->maxpacket == 0) && - (ep->total_data_len >= ep->maxpacket) && - (ep->total_data_len < ep->ctl_data_len )) - { - - USBD_CtlContinueSendData(pdev , NULL, 0); - ep->ctl_data_len = 0; - } - else - { - if((pdev->dev.class_cb->EP0_TxSent != NULL)&& - (pdev->dev.device_status == USB_OTG_CONFIGURED)) - { - pdev->dev.class_cb->EP0_TxSent(pdev); - } - USBD_CtlReceiveStatus(pdev); - } - } - } - } - else if((pdev->dev.class_cb->DataIn != NULL)&& - (pdev->dev.device_status == USB_OTG_CONFIGURED)) - { - pdev->dev.class_cb->DataIn(pdev, epnum); - } - return USBD_OK; -} - -/** -* @brief USBD_Reset -* Handle Reset event -* @param pdev: device instance -* @retval status -*/ - -static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev) -{ - /* Open EP0 OUT */ - DCD_EP_Open(pdev, - 0x00, - USB_OTG_MAX_EP0_SIZE, - EP_TYPE_CTRL); - - /* Open EP0 IN */ - DCD_EP_Open(pdev, - 0x80, - USB_OTG_MAX_EP0_SIZE, - EP_TYPE_CTRL); - - /* Upon Reset call usr call back */ - pdev->dev.device_status = USB_OTG_DEFAULT; - pdev->dev.usr_cb->DeviceReset(pdev->cfg.speed); - - return USBD_OK; -} - -/** -* @brief USBD_Resume -* Handle Resume event -* @param pdev: device instance -* @retval status -*/ - -static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev) -{ - /* Upon Resume call usr call back */ - pdev->dev.usr_cb->DeviceResumed(); - pdev->dev.device_status = USB_OTG_CONFIGURED; - return USBD_OK; -} - - -/** -* @brief USBD_Suspend -* Handle Suspend event -* @param pdev: device instance -* @retval status -*/ - -static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev) -{ - - pdev->dev.device_status = USB_OTG_SUSPENDED; - /* Upon Resume call usr call back */ - pdev->dev.usr_cb->DeviceSuspended(); - return USBD_OK; -} - - -/** -* @brief USBD_SOF -* Handle SOF event -* @param pdev: device instance -* @retval status -*/ - -static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev) -{ - if(pdev->dev.class_cb->SOF) - { - pdev->dev.class_cb->SOF(pdev); - } - return USBD_OK; -} -/** -* @brief USBD_SetCfg -* Configure device and start the interface -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status -*/ - -USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx) -{ - pdev->dev.class_cb->Init(pdev, cfgidx); - - /* Upon set config call usr call back */ - pdev->dev.usr_cb->DeviceConfigured(); - return USBD_OK; -} - -/** -* @brief USBD_ClrCfg -* Clear current configuration -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status: USBD_Status -*/ -USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx) -{ - pdev->dev.class_cb->DeInit(pdev, cfgidx); - return USBD_OK; -} - -/** -* @brief USBD_IsoINIncomplete -* Handle iso in incomplete event -* @param pdev: device instance -* @retval status -*/ -static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev) -{ - pdev->dev.class_cb->IsoINIncomplete(pdev); - return USBD_OK; -} - -/** -* @brief USBD_IsoOUTIncomplete -* Handle iso out incomplete event -* @param pdev: device instance -* @retval status -*/ -static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev) -{ - pdev->dev.class_cb->IsoOUTIncomplete(pdev); - return USBD_OK; -} - -#ifdef VBUS_SENSING_ENABLED -/** -* @brief USBD_DevConnected -* Handle device connection event -* @param pdev: device instance -* @retval status -*/ -static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev) -{ - pdev->dev.usr_cb->DeviceConnected(); - return USBD_OK; -} - -/** -* @brief USBD_DevDisconnected -* Handle device disconnection event -* @param pdev: device instance -* @retval status -*/ -static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev) -{ - pdev->dev.usr_cb->DeviceDisconnected(); - pdev->dev.class_cb->DeInit(pdev, 0); - return USBD_OK; -} -#endif -/** -* @} -*/ - - -/** -* @} -*/ - - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usbd_core.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides all the USBD core functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" +#include "usbd_req.h" +#include "usbd_ioreq.h" +#include "usb_dcd_int.h" +#include "usb_bsp.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY +* @{ +*/ + + +/** @defgroup USBD_CORE +* @brief usbd core module +* @{ +*/ + +/** @defgroup USBD_CORE_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBD_CORE_Private_Defines +* @{ +*/ + +/** +* @} +*/ + + +/** @defgroup USBD_CORE_Private_Macros +* @{ +*/ +/** +* @} +*/ + + + + +/** @defgroup USBD_CORE_Private_FunctionPrototypes +* @{ +*/ +static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev); +static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); +static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); +static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev); +static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev); +static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev); +static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev); +#ifdef VBUS_SENSING_ENABLED +static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev); +static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev); +#endif +static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev); +static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev); +/** +* @} +*/ + +/** @defgroup USBD_CORE_Private_Variables +* @{ +*/ + + + +USBD_DCD_INT_cb_TypeDef USBD_DCD_INT_cb = +{ + USBD_DataOutStage, + USBD_DataInStage, + USBD_SetupStage, + USBD_SOF, + USBD_Reset, + USBD_Suspend, + USBD_Resume, + USBD_IsoINIncomplete, + USBD_IsoOUTIncomplete, +#ifdef VBUS_SENSING_ENABLED +USBD_DevConnected, +USBD_DevDisconnected, +#endif +}; + +USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops = &USBD_DCD_INT_cb; +/** +* @} +*/ + +/** @defgroup USBD_CORE_Private_Functions +* @{ +*/ + +/** +* @brief USBD_Init +* Initailizes the device stack and load the class driver +* @param pdev: device instance +* @param core_address: USB OTG core ID +* @param class_cb: Class callback structure address +* @param usr_cb: User callback structure address +* @retval None +*/ +void USBD_Init(USB_OTG_CORE_HANDLE *pdev, + USB_OTG_CORE_ID_TypeDef coreID, + USBD_DEVICE *pDevice, + USBD_Class_cb_TypeDef *class_cb, + USBD_Usr_cb_TypeDef *usr_cb) +{ + /* Hardware Init */ + USB_OTG_BSP_Init(pdev); + + USBD_DeInit(pdev); + + /*Register class and user callbacks */ + pdev->dev.class_cb = class_cb; + pdev->dev.usr_cb = usr_cb; + pdev->dev.usr_device = pDevice; + + /* set USB OTG core params */ + DCD_Init(pdev , coreID); + + /* Upon Init call usr callback */ + pdev->dev.usr_cb->Init(); + + /* Enable Interrupts */ + USB_OTG_BSP_EnableInterrupt(pdev); +} + +/** +* @brief USBD_DeInit +* Re-Initialize th deviuce library +* @param pdev: device instance +* @retval status: status +*/ +USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev) +{ + return USBD_OK; +} + +USBD_Status USBD_DeInitFull(USB_OTG_CORE_HANDLE *pdev) +{ + /* Software Init */ + USB_OTG_BSP_DisableInterrupt(pdev); + USB_OTG_BSP_DeInit(pdev); + + return USBD_OK; +} + +/** +* @brief USBD_SetupStage +* Handle the setup stage +* @param pdev: device instance +* @retval status +*/ +static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev) +{ + USB_SETUP_REQ req; + + USBD_ParseSetupRequest(pdev , &req); + + switch (req.bmRequest & 0x1F) + { + case USB_REQ_RECIPIENT_DEVICE: + USBD_StdDevReq (pdev, &req); + break; + + case USB_REQ_RECIPIENT_INTERFACE: + USBD_StdItfReq(pdev, &req); + break; + + case USB_REQ_RECIPIENT_ENDPOINT: + USBD_StdEPReq(pdev, &req); + break; + + default: + DCD_EP_Stall(pdev , req.bmRequest & 0x80); + break; + } + return USBD_OK; +} + +/** +* @brief USBD_DataOutStage +* Handle data out stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) +{ + USB_OTG_EP *ep; + + if(epnum == 0) + { + ep = &pdev->dev.out_ep[0]; + if ( pdev->dev.device_state == USB_OTG_EP0_DATA_OUT) + { + if(ep->rem_data_len > ep->maxpacket) + { + ep->rem_data_len -= ep->maxpacket; + + if(pdev->cfg.dma_enable == 1) + { + /* in slave mode this, is handled by the RxSTSQLvl ISR */ + ep->xfer_buff += ep->maxpacket; + } + USBD_CtlContinueRx (pdev, + ep->xfer_buff, + MIN(ep->rem_data_len ,ep->maxpacket)); + } + else + { + if((pdev->dev.class_cb->EP0_RxReady != NULL)&& + (pdev->dev.device_status == USB_OTG_CONFIGURED)) + { + pdev->dev.class_cb->EP0_RxReady(pdev); + } + USBD_CtlSendStatus(pdev); + } + } + } + else if((pdev->dev.class_cb->DataOut != NULL)&& + (pdev->dev.device_status == USB_OTG_CONFIGURED)) + { + pdev->dev.class_cb->DataOut(pdev, epnum); + } + return USBD_OK; +} + +/** +* @brief USBD_DataInStage +* Handle data in stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) +{ + USB_OTG_EP *ep; + + if(epnum == 0) + { + ep = &pdev->dev.in_ep[0]; + if ( pdev->dev.device_state == USB_OTG_EP0_DATA_IN) + { + if(ep->rem_data_len > ep->maxpacket) + { + ep->rem_data_len -= ep->maxpacket; + if(pdev->cfg.dma_enable == 1) + { + /* in slave mode this, is handled by the TxFifoEmpty ISR */ + ep->xfer_buff += ep->maxpacket; + } + USBD_CtlContinueSendData (pdev, + ep->xfer_buff, + ep->rem_data_len); + } + else + { /* last packet is MPS multiple, so send ZLP packet */ + if((ep->total_data_len % ep->maxpacket == 0) && + (ep->total_data_len >= ep->maxpacket) && + (ep->total_data_len < ep->ctl_data_len )) + { + + USBD_CtlContinueSendData(pdev , NULL, 0); + ep->ctl_data_len = 0; + } + else + { + if((pdev->dev.class_cb->EP0_TxSent != NULL)&& + (pdev->dev.device_status == USB_OTG_CONFIGURED)) + { + pdev->dev.class_cb->EP0_TxSent(pdev); + } + USBD_CtlReceiveStatus(pdev); + } + } + } + } + else if((pdev->dev.class_cb->DataIn != NULL)&& + (pdev->dev.device_status == USB_OTG_CONFIGURED)) + { + pdev->dev.class_cb->DataIn(pdev, epnum); + } + return USBD_OK; +} + +/** +* @brief USBD_Reset +* Handle Reset event +* @param pdev: device instance +* @retval status +*/ + +static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev) +{ + /* Open EP0 OUT */ + DCD_EP_Open(pdev, + 0x00, + USB_OTG_MAX_EP0_SIZE, + EP_TYPE_CTRL); + + /* Open EP0 IN */ + DCD_EP_Open(pdev, + 0x80, + USB_OTG_MAX_EP0_SIZE, + EP_TYPE_CTRL); + + /* Upon Reset call usr call back */ + pdev->dev.device_status = USB_OTG_DEFAULT; + pdev->dev.usr_cb->DeviceReset(pdev->cfg.speed); + + return USBD_OK; +} + +/** +* @brief USBD_Resume +* Handle Resume event +* @param pdev: device instance +* @retval status +*/ + +static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev) +{ + /* Upon Resume call usr call back */ + pdev->dev.usr_cb->DeviceResumed(); + pdev->dev.device_status = USB_OTG_CONFIGURED; + return USBD_OK; +} + + +/** +* @brief USBD_Suspend +* Handle Suspend event +* @param pdev: device instance +* @retval status +*/ + +static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev) +{ + + pdev->dev.device_status = USB_OTG_SUSPENDED; + /* Upon Resume call usr call back */ + pdev->dev.usr_cb->DeviceSuspended(); + return USBD_OK; +} + + +/** +* @brief USBD_SOF +* Handle SOF event +* @param pdev: device instance +* @retval status +*/ + +static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev) +{ + if(pdev->dev.class_cb->SOF) + { + pdev->dev.class_cb->SOF(pdev); + } + return USBD_OK; +} +/** +* @brief USBD_SetCfg +* Configure device and start the interface +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status +*/ + +USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx) +{ + pdev->dev.class_cb->Init(pdev, cfgidx); + + /* Upon set config call usr call back */ + pdev->dev.usr_cb->DeviceConfigured(); + return USBD_OK; +} + +/** +* @brief USBD_ClrCfg +* Clear current configuration +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status: USBD_Status +*/ +USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx) +{ + pdev->dev.class_cb->DeInit(pdev, cfgidx); + return USBD_OK; +} + +/** +* @brief USBD_IsoINIncomplete +* Handle iso in incomplete event +* @param pdev: device instance +* @retval status +*/ +static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev) +{ + pdev->dev.class_cb->IsoINIncomplete(pdev); + return USBD_OK; +} + +/** +* @brief USBD_IsoOUTIncomplete +* Handle iso out incomplete event +* @param pdev: device instance +* @retval status +*/ +static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev) +{ + pdev->dev.class_cb->IsoOUTIncomplete(pdev); + return USBD_OK; +} + +#ifdef VBUS_SENSING_ENABLED +/** +* @brief USBD_DevConnected +* Handle device connection event +* @param pdev: device instance +* @retval status +*/ +static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev) +{ + pdev->dev.usr_cb->DeviceConnected(); + return USBD_OK; +} + +/** +* @brief USBD_DevDisconnected +* Handle device disconnection event +* @param pdev: device instance +* @retval status +*/ +static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev) +{ + pdev->dev.usr_cb->DeviceDisconnected(); + pdev->dev.class_cb->DeInit(pdev, 0); + return USBD_OK; +} +#endif +/** +* @} +*/ + + +/** +* @} +*/ + + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c index 72cf3b17..6964766b 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c @@ -1,237 +1,237 @@ -/** - ****************************************************************************** - * @file usbd_ioreq.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the IO requests APIs for control endpoints. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_ioreq.h" -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_IOREQ - * @brief control I/O requests module - * @{ - */ - -/** @defgroup USBD_IOREQ_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Variables - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Functions - * @{ - */ - -/** -* @brief USBD_CtlSendData -* send data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be sent -* @retval status -*/ -USBD_Status USBD_CtlSendData (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len) -{ - USBD_Status ret = USBD_OK; - - pdev->dev.in_ep[0].total_data_len = len; - pdev->dev.in_ep[0].rem_data_len = len; - pdev->dev.device_state = USB_OTG_EP0_DATA_IN; - - DCD_EP_Tx (pdev, 0, pbuf, len); - - return ret; -} - -/** -* @brief USBD_CtlContinueSendData -* continue sending data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be sent -* @retval status -*/ -USBD_Status USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len) -{ - USBD_Status ret = USBD_OK; - - DCD_EP_Tx (pdev, 0, pbuf, len); - - - return ret; -} - -/** -* @brief USBD_CtlPrepareRx -* receive data on the ctl pipe -* @param pdev: USB OTG device instance -* @param buff: pointer to data buffer -* @param len: length of data to be received -* @retval status -*/ -USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len) -{ - USBD_Status ret = USBD_OK; - - pdev->dev.out_ep[0].total_data_len = len; - pdev->dev.out_ep[0].rem_data_len = len; - pdev->dev.device_state = USB_OTG_EP0_DATA_OUT; - - DCD_EP_PrepareRx (pdev, - 0, - pbuf, - len); - - - return ret; -} - -/** -* @brief USBD_CtlContinueRx -* continue receive data on the ctl pipe -* @param pdev: USB OTG device instance -* @param buff: pointer to data buffer -* @param len: length of data to be received -* @retval status -*/ -USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len) -{ - USBD_Status ret = USBD_OK; - - DCD_EP_PrepareRx (pdev, - 0, - pbuf, - len); - return ret; -} -/** -* @brief USBD_CtlSendStatus -* send zero lzngth packet on the ctl pipe -* @param pdev: USB OTG device instance -* @retval status -*/ -USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev) -{ - USBD_Status ret = USBD_OK; - pdev->dev.device_state = USB_OTG_EP0_STATUS_IN; - DCD_EP_Tx (pdev, - 0, - NULL, - 0); - - USB_OTG_EP0_OutStart(pdev); - - return ret; -} - -/** -* @brief USBD_CtlReceiveStatus -* receive zero lzngth packet on the ctl pipe -* @param pdev: USB OTG device instance -* @retval status -*/ -USBD_Status USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE *pdev) -{ - USBD_Status ret = USBD_OK; - pdev->dev.device_state = USB_OTG_EP0_STATUS_OUT; - DCD_EP_PrepareRx ( pdev, - 0, - NULL, - 0); - - USB_OTG_EP0_OutStart(pdev); - - return ret; -} - - -/** -* @brief USBD_GetRxCount -* returns the received data length -* @param pdev: USB OTG device instance -* epnum: endpoint index -* @retval Rx Data blength -*/ -uint16_t USBD_GetRxCount (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - return pdev->dev.out_ep[epnum].xfer_count; -} - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_ioreq.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides the IO requests APIs for control endpoints. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_IOREQ + * @brief control I/O requests module + * @{ + */ + +/** @defgroup USBD_IOREQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Functions + * @{ + */ + +/** +* @brief USBD_CtlSendData +* send data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be sent +* @retval status +*/ +USBD_Status USBD_CtlSendData (USB_OTG_CORE_HANDLE *pdev, + uint8_t *pbuf, + uint16_t len) +{ + USBD_Status ret = USBD_OK; + + pdev->dev.in_ep[0].total_data_len = len; + pdev->dev.in_ep[0].rem_data_len = len; + pdev->dev.device_state = USB_OTG_EP0_DATA_IN; + + DCD_EP_Tx (pdev, 0, pbuf, len); + + return ret; +} + +/** +* @brief USBD_CtlContinueSendData +* continue sending data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be sent +* @retval status +*/ +USBD_Status USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE *pdev, + uint8_t *pbuf, + uint16_t len) +{ + USBD_Status ret = USBD_OK; + + DCD_EP_Tx (pdev, 0, pbuf, len); + + + return ret; +} + +/** +* @brief USBD_CtlPrepareRx +* receive data on the ctl pipe +* @param pdev: USB OTG device instance +* @param buff: pointer to data buffer +* @param len: length of data to be received +* @retval status +*/ +USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE *pdev, + uint8_t *pbuf, + uint16_t len) +{ + USBD_Status ret = USBD_OK; + + pdev->dev.out_ep[0].total_data_len = len; + pdev->dev.out_ep[0].rem_data_len = len; + pdev->dev.device_state = USB_OTG_EP0_DATA_OUT; + + DCD_EP_PrepareRx (pdev, + 0, + pbuf, + len); + + + return ret; +} + +/** +* @brief USBD_CtlContinueRx +* continue receive data on the ctl pipe +* @param pdev: USB OTG device instance +* @param buff: pointer to data buffer +* @param len: length of data to be received +* @retval status +*/ +USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev, + uint8_t *pbuf, + uint16_t len) +{ + USBD_Status ret = USBD_OK; + + DCD_EP_PrepareRx (pdev, + 0, + pbuf, + len); + return ret; +} +/** +* @brief USBD_CtlSendStatus +* send zero lzngth packet on the ctl pipe +* @param pdev: USB OTG device instance +* @retval status +*/ +USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev) +{ + USBD_Status ret = USBD_OK; + pdev->dev.device_state = USB_OTG_EP0_STATUS_IN; + DCD_EP_Tx (pdev, + 0, + NULL, + 0); + + USB_OTG_EP0_OutStart(pdev); + + return ret; +} + +/** +* @brief USBD_CtlReceiveStatus +* receive zero lzngth packet on the ctl pipe +* @param pdev: USB OTG device instance +* @retval status +*/ +USBD_Status USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE *pdev) +{ + USBD_Status ret = USBD_OK; + pdev->dev.device_state = USB_OTG_EP0_STATUS_OUT; + DCD_EP_PrepareRx ( pdev, + 0, + NULL, + 0); + + USB_OTG_EP0_OutStart(pdev); + + return ret; +} + + +/** +* @brief USBD_GetRxCount +* returns the received data length +* @param pdev: USB OTG device instance +* epnum: endpoint index +* @retval Rx Data blength +*/ +uint16_t USBD_GetRxCount (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) +{ + return pdev->dev.out_ep[epnum].xfer_count; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_req.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_req.c index 9a9e8022..f08d26c6 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_req.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_Device_Library/Core/src/usbd_req.c @@ -1,868 +1,868 @@ -/** - ****************************************************************************** - * @file usbd_req.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the standard USB requests following chapter 9. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_req.h" -#include "usbd_ioreq.h" -#include "usbd_desc.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_REQ - * @brief USB standard requests module - * @{ - */ - -/** @defgroup USBD_REQ_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Variables - * @{ - */ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint32_t USBD_ep_status __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint32_t USBD_default_cfg __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint32_t USBD_cfg_status __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ] __ALIGN_END ; -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_FunctionPrototypes - * @{ - */ -static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static uint8_t USBD_GetLen(uint8_t *buf); -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Functions - * @{ - */ - - -/** -* @brief USBD_StdDevReq -* Handle standard usb device requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) -{ - USBD_Status ret = USBD_OK; - - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - - USBD_GetDescriptor (pdev, req) ; - break; - - case USB_REQ_SET_ADDRESS: - USBD_SetAddress(pdev, req); - break; - - case USB_REQ_SET_CONFIGURATION: - USBD_SetConfig (pdev , req); - break; - - case USB_REQ_GET_CONFIGURATION: - USBD_GetConfig (pdev , req); - break; - - case USB_REQ_GET_STATUS: - USBD_GetStatus (pdev , req); - break; - - - case USB_REQ_SET_FEATURE: - USBD_SetFeature (pdev , req); - break; - - case USB_REQ_CLEAR_FEATURE: - USBD_ClrFeature (pdev , req); - break; - - default: - USBD_CtlError(pdev , req); - break; - } - - return ret; -} - -/** -* @brief USBD_StdItfReq -* Handle standard usb interface requests -* @param pdev: USB OTG device instance -* @param req: usb request -* @retval status -*/ -USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) -{ - USBD_Status ret = USBD_OK; - - switch (pdev->dev.device_status) - { - case USB_OTG_CONFIGURED: - - if (LOBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) - { - pdev->dev.class_cb->Setup (pdev, req); - - if((req->wLength == 0)&& (ret == USBD_OK)) - { - USBD_CtlSendStatus(pdev); - } - } - else - { - USBD_CtlError(pdev , req); - } - break; - - default: - USBD_CtlError(pdev , req); - break; - } - return ret; -} - -/** -* @brief USBD_StdEPReq -* Handle standard usb endpoint requests -* @param pdev: USB OTG device instance -* @param req: usb request -* @retval status -*/ -USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) -{ - - uint8_t ep_addr; - USBD_Status ret = USBD_OK; - - ep_addr = LOBYTE(req->wIndex); - - switch (req->bRequest) - { - - case USB_REQ_SET_FEATURE : - - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - DCD_EP_Stall(pdev , ep_addr); - } - break; - - case USB_OTG_CONFIGURED: - if (req->wValue == USB_FEATURE_EP_HALT) - { - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - DCD_EP_Stall(pdev , ep_addr); - - } - } - pdev->dev.class_cb->Setup (pdev, req); - USBD_CtlSendStatus(pdev); - - break; - - default: - USBD_CtlError(pdev , req); - break; - } - break; - - case USB_REQ_CLEAR_FEATURE : - - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - DCD_EP_Stall(pdev , ep_addr); - } - break; - - case USB_OTG_CONFIGURED: - if (req->wValue == USB_FEATURE_EP_HALT) - { - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - DCD_EP_ClrStall(pdev , ep_addr); - pdev->dev.class_cb->Setup (pdev, req); - } - USBD_CtlSendStatus(pdev); - } - break; - - default: - USBD_CtlError(pdev , req); - break; - } - break; - - case USB_REQ_GET_STATUS: - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - DCD_EP_Stall(pdev , ep_addr); - } - break; - - case USB_OTG_CONFIGURED: - - - if ((ep_addr & 0x80)== 0x80) - { - if(pdev->dev.in_ep[ep_addr & 0x7F].is_stall) - { - USBD_ep_status = 0x0001; - } - else - { - USBD_ep_status = 0x0000; - } - } - else if ((ep_addr & 0x80)== 0x00) - { - if(pdev->dev.out_ep[ep_addr].is_stall) - { - USBD_ep_status = 0x0001; - } - - else - { - USBD_ep_status = 0x0000; - } - } - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_ep_status, - 2); - break; - - default: - USBD_CtlError(pdev , req); - break; - } - break; - - default: - break; - } - return ret; -} -/** -* @brief USBD_GetDescriptor -* Handle Get Descriptor requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - uint16_t len; - uint8_t *pbuf; - - switch (req->wValue >> 8) - { - case USB_DESC_TYPE_DEVICE: - pbuf = pdev->dev.usr_device->GetDeviceDescriptor(pdev->cfg.speed, &len); - if ((req->wLength == 64) ||( pdev->dev.device_status == USB_OTG_DEFAULT)) - { - len = 8; - } - break; - - case USB_DESC_TYPE_CONFIGURATION: - pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len); -#ifdef USB_OTG_HS_CORE - if((pdev->cfg.speed == USB_OTG_SPEED_FULL )&& - (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)) - { - pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len); - } -#endif - pbuf[1] = USB_DESC_TYPE_CONFIGURATION; - pdev->dev.pConfig_descriptor = pbuf; - break; - - case USB_DESC_TYPE_STRING: - switch ((uint8_t)(req->wValue)) - { - case USBD_IDX_LANGID_STR: - pbuf = pdev->dev.usr_device->GetLangIDStrDescriptor(pdev->cfg.speed, &len); - break; - - case USBD_IDX_MFC_STR: - pbuf = pdev->dev.usr_device->GetManufacturerStrDescriptor(pdev->cfg.speed, &len); - break; - - case USBD_IDX_PRODUCT_STR: - pbuf = pdev->dev.usr_device->GetProductStrDescriptor(pdev->cfg.speed, &len); - break; - - case USBD_IDX_SERIAL_STR: - pbuf = pdev->dev.usr_device->GetSerialStrDescriptor(pdev->cfg.speed, &len); - break; - - case USBD_IDX_CONFIG_STR: - pbuf = pdev->dev.usr_device->GetConfigurationStrDescriptor(pdev->cfg.speed, &len); - break; - - case USBD_IDX_INTERFACE_STR: - pbuf = pdev->dev.usr_device->GetInterfaceStrDescriptor(pdev->cfg.speed, &len); - break; - - default: -#ifdef USB_SUPPORT_USER_STRING_DESC - pbuf = pdev->dev.class_cb->GetUsrStrDescriptor(pdev->cfg.speed, (req->wValue) , &len); - break; -#else - USBD_CtlError(pdev , req); - return; -#endif /* USBD_CtlError(pdev , req); */ - } - break; - case USB_DESC_TYPE_DEVICE_QUALIFIER: -#ifdef USB_OTG_HS_CORE - if(pdev->cfg.speed == USB_OTG_SPEED_HIGH ) - { - - pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len); - - USBD_DeviceQualifierDesc[4]= pbuf[14]; - USBD_DeviceQualifierDesc[5]= pbuf[15]; - USBD_DeviceQualifierDesc[6]= pbuf[16]; - - pbuf = USBD_DeviceQualifierDesc; - len = USB_LEN_DEV_QUALIFIER_DESC; - break; - } - else - { - USBD_CtlError(pdev , req); - return; - } -#else - USBD_CtlError(pdev , req); - return; -#endif - - case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: -#ifdef USB_OTG_HS_CORE - - if(pdev->cfg.speed == USB_OTG_SPEED_HIGH ) - { - pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len); - pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; - break; - } - else - { - USBD_CtlError(pdev , req); - return; - } -#else - USBD_CtlError(pdev , req); - return; -#endif - - - default: - USBD_CtlError(pdev , req); - return; - } - - if((len != 0)&& (req->wLength != 0)) - { - - len = MIN(len , req->wLength); - - USBD_CtlSendData (pdev, - pbuf, - len); - } - -} - -/** -* @brief USBD_SetAddress -* Set device address -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - uint8_t dev_addr; - - if ((req->wIndex == 0) && (req->wLength == 0)) - { - dev_addr = (uint8_t)(req->wValue) & 0x7F; - - if (pdev->dev.device_status == USB_OTG_CONFIGURED) - { - USBD_CtlError(pdev , req); - } - else - { - pdev->dev.device_address = dev_addr; - DCD_EP_SetAddress(pdev, dev_addr); - USBD_CtlSendStatus(pdev); - - if (dev_addr != 0) - { - pdev->dev.device_status = USB_OTG_ADDRESSED; - } - else - { - pdev->dev.device_status = USB_OTG_DEFAULT; - } - } - } - else - { - USBD_CtlError(pdev , req); - } -} - -/** -* @brief USBD_SetConfig -* Handle Set device configuration request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - - static uint8_t cfgidx; - - cfgidx = (uint8_t)(req->wValue); - - if (cfgidx > USBD_CFG_MAX_NUM ) - { - USBD_CtlError(pdev , req); - } - else - { - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - if (cfgidx) - { - pdev->dev.device_config = cfgidx; - pdev->dev.device_status = USB_OTG_CONFIGURED; - USBD_SetCfg(pdev , cfgidx); - USBD_CtlSendStatus(pdev); - } - else - { - USBD_CtlSendStatus(pdev); - } - break; - - case USB_OTG_CONFIGURED: - if (cfgidx == 0) - { - pdev->dev.device_status = USB_OTG_ADDRESSED; - pdev->dev.device_config = cfgidx; - USBD_ClrCfg(pdev , cfgidx); - USBD_CtlSendStatus(pdev); - - } - else if (cfgidx != pdev->dev.device_config) - { - /* Clear old configuration */ - USBD_ClrCfg(pdev , pdev->dev.device_config); - - /* set new configuration */ - pdev->dev.device_config = cfgidx; - USBD_SetCfg(pdev , cfgidx); - USBD_CtlSendStatus(pdev); - } - else - { - USBD_CtlSendStatus(pdev); - } - break; - - default: - USBD_CtlError(pdev , req); - break; - } - } -} - -/** -* @brief USBD_GetConfig -* Handle Get device configuration request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - - if (req->wLength != 1) - { - USBD_CtlError(pdev , req); - } - else - { - switch (pdev->dev.device_status ) - { - case USB_OTG_ADDRESSED: - - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_default_cfg, - 1); - break; - - case USB_OTG_CONFIGURED: - - USBD_CtlSendData (pdev, - &pdev->dev.device_config, - 1); - break; - - default: - USBD_CtlError(pdev , req); - break; - } - } -} - -/** -* @brief USBD_GetStatus -* Handle Get Status request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - case USB_OTG_CONFIGURED: - - if (pdev->dev.DevRemoteWakeup) - { - USBD_cfg_status = USB_CONFIG_SELF_POWERED | USB_CONFIG_REMOTE_WAKEUP; - } - else - { - USBD_cfg_status = USB_CONFIG_SELF_POWERED; - } - - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_cfg_status, - 1); - break; - - default : - USBD_CtlError(pdev , req); - break; - } -} - - -/** -* @brief USBD_SetFeature -* Handle Set device feature request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - - USB_OTG_DCTL_TypeDef dctl; - uint8_t test_mode = 0; - - if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) - { - pdev->dev.DevRemoteWakeup = 1; - pdev->dev.class_cb->Setup (pdev, req); - USBD_CtlSendStatus(pdev); - } - - else if ((req->wValue == USB_FEATURE_TEST_MODE) && - ((req->wIndex & 0xFF) == 0)) - { - dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); - - test_mode = req->wIndex >> 8; - switch (test_mode) - { - case 1: // TEST_J - dctl.b.tstctl = 1; - break; - - case 2: // TEST_K - dctl.b.tstctl = 2; - break; - - case 3: // TEST_SE0_NAK - dctl.b.tstctl = 3; - break; - - case 4: // TEST_PACKET - dctl.b.tstctl = 4; - break; - - case 5: // TEST_FORCE_ENABLE - dctl.b.tstctl = 5; - break; - } - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); - USBD_CtlSendStatus(pdev); - } - -} - - -/** -* @brief USBD_ClrFeature -* Handle clear device feature request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - case USB_OTG_CONFIGURED: - if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) - { - pdev->dev.DevRemoteWakeup = 0; - pdev->dev.class_cb->Setup (pdev, req); - USBD_CtlSendStatus(pdev); - } - break; - - default : - USBD_CtlError(pdev , req); - break; - } -} - -/** -* @brief USBD_ParseSetupRequest -* Copy buffer into setup structure -* @param pdev: device instance -* @param req: usb request -* @retval None -*/ - -void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - req->bmRequest = *(uint8_t *) (pdev->dev.setup_packet); - req->bRequest = *(uint8_t *) (pdev->dev.setup_packet + 1); - req->wValue = SWAPBYTE (pdev->dev.setup_packet + 2); - req->wIndex = SWAPBYTE (pdev->dev.setup_packet + 4); - req->wLength = SWAPBYTE (pdev->dev.setup_packet + 6); - - pdev->dev.in_ep[0].ctl_data_len = req->wLength ; - pdev->dev.device_state = USB_OTG_EP0_SETUP; -} - -/** -* @brief USBD_CtlError -* Handle USB low level Error -* @param pdev: device instance -* @param req: usb request -* @retval None -*/ - -void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - if((req->bmRequest & 0x80) == 0x80) - { - DCD_EP_Stall(pdev , 0x80); - } - else - { - if(req->wLength == 0) - { - DCD_EP_Stall(pdev , 0x80); - } - else - { - DCD_EP_Stall(pdev , 0); - } - } - USB_OTG_EP0_OutStart(pdev); -} - - -/** - * @brief USBD_GetString - * Convert Ascii string into unicode one - * @param desc : descriptor buffer - * @param unicode : Formatted string buffer (unicode) - * @param len : descriptor length - * @retval None - */ -void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) -{ - uint8_t idx = 0; - - if (desc != NULL) - { - *len = USBD_GetLen(desc) * 2 + 2; - unicode[idx++] = *len; - unicode[idx++] = USB_DESC_TYPE_STRING; - - while (*desc != NULL) - { - unicode[idx++] = *desc++; - unicode[idx++] = 0x00; - } - } -} - -/** - * @brief USBD_GetLen - * return the string length - * @param buf : pointer to the ascii string buffer - * @retval string length - */ -static uint8_t USBD_GetLen(uint8_t *buf) -{ - uint8_t len = 0; - - while (*buf != NULL) - { - len++; - buf++; - } - - return len; -} -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_req.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides the standard USB requests following chapter 9. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_req.h" +#include "usbd_ioreq.h" +#include "usbd_desc.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_REQ + * @brief USB standard requests module + * @{ + */ + +/** @defgroup USBD_REQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Variables + * @{ + */ + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint32_t USBD_ep_status __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint32_t USBD_default_cfg __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint32_t USBD_cfg_status __ALIGN_END = 0; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +__ALIGN_BEGIN uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ] __ALIGN_END ; +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_FunctionPrototypes + * @{ + */ +static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req); + +static uint8_t USBD_GetLen(uint8_t *buf); +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Functions + * @{ + */ + + +/** +* @brief USBD_StdDevReq +* Handle standard usb device requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) +{ + USBD_Status ret = USBD_OK; + + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + + USBD_GetDescriptor (pdev, req) ; + break; + + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + break; + + case USB_REQ_SET_CONFIGURATION: + USBD_SetConfig (pdev , req); + break; + + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig (pdev , req); + break; + + case USB_REQ_GET_STATUS: + USBD_GetStatus (pdev , req); + break; + + + case USB_REQ_SET_FEATURE: + USBD_SetFeature (pdev , req); + break; + + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature (pdev , req); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + + return ret; +} + +/** +* @brief USBD_StdItfReq +* Handle standard usb interface requests +* @param pdev: USB OTG device instance +* @param req: usb request +* @retval status +*/ +USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) +{ + USBD_Status ret = USBD_OK; + + switch (pdev->dev.device_status) + { + case USB_OTG_CONFIGURED: + + if (LOBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) + { + pdev->dev.class_cb->Setup (pdev, req); + + if((req->wLength == 0)&& (ret == USBD_OK)) + { + USBD_CtlSendStatus(pdev); + } + } + else + { + USBD_CtlError(pdev , req); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + return ret; +} + +/** +* @brief USBD_StdEPReq +* Handle standard usb endpoint requests +* @param pdev: USB OTG device instance +* @param req: usb request +* @retval status +*/ +USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) +{ + + uint8_t ep_addr; + USBD_Status ret = USBD_OK; + + ep_addr = LOBYTE(req->wIndex); + + switch (req->bRequest) + { + + case USB_REQ_SET_FEATURE : + + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + DCD_EP_Stall(pdev , ep_addr); + } + break; + + case USB_OTG_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + DCD_EP_Stall(pdev , ep_addr); + + } + } + pdev->dev.class_cb->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + case USB_REQ_CLEAR_FEATURE : + + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + DCD_EP_Stall(pdev , ep_addr); + } + break; + + case USB_OTG_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + DCD_EP_ClrStall(pdev , ep_addr); + pdev->dev.class_cb->Setup (pdev, req); + } + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + case USB_REQ_GET_STATUS: + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + DCD_EP_Stall(pdev , ep_addr); + } + break; + + case USB_OTG_CONFIGURED: + + + if ((ep_addr & 0x80)== 0x80) + { + if(pdev->dev.in_ep[ep_addr & 0x7F].is_stall) + { + USBD_ep_status = 0x0001; + } + else + { + USBD_ep_status = 0x0000; + } + } + else if ((ep_addr & 0x80)== 0x00) + { + if(pdev->dev.out_ep[ep_addr].is_stall) + { + USBD_ep_status = 0x0001; + } + + else + { + USBD_ep_status = 0x0000; + } + } + USBD_CtlSendData (pdev, + (uint8_t *)&USBD_ep_status, + 2); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + default: + break; + } + return ret; +} +/** +* @brief USBD_GetDescriptor +* Handle Get Descriptor requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + uint16_t len; + uint8_t *pbuf; + + switch (req->wValue >> 8) + { + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->dev.usr_device->GetDeviceDescriptor(pdev->cfg.speed, &len); + if ((req->wLength == 64) ||( pdev->dev.device_status == USB_OTG_DEFAULT)) + { + len = 8; + } + break; + + case USB_DESC_TYPE_CONFIGURATION: + pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len); +#ifdef USB_OTG_HS_CORE + if((pdev->cfg.speed == USB_OTG_SPEED_FULL )&& + (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)) + { + pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len); + } +#endif + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + pdev->dev.pConfig_descriptor = pbuf; + break; + + case USB_DESC_TYPE_STRING: + switch ((uint8_t)(req->wValue)) + { + case USBD_IDX_LANGID_STR: + pbuf = pdev->dev.usr_device->GetLangIDStrDescriptor(pdev->cfg.speed, &len); + break; + + case USBD_IDX_MFC_STR: + pbuf = pdev->dev.usr_device->GetManufacturerStrDescriptor(pdev->cfg.speed, &len); + break; + + case USBD_IDX_PRODUCT_STR: + pbuf = pdev->dev.usr_device->GetProductStrDescriptor(pdev->cfg.speed, &len); + break; + + case USBD_IDX_SERIAL_STR: + pbuf = pdev->dev.usr_device->GetSerialStrDescriptor(pdev->cfg.speed, &len); + break; + + case USBD_IDX_CONFIG_STR: + pbuf = pdev->dev.usr_device->GetConfigurationStrDescriptor(pdev->cfg.speed, &len); + break; + + case USBD_IDX_INTERFACE_STR: + pbuf = pdev->dev.usr_device->GetInterfaceStrDescriptor(pdev->cfg.speed, &len); + break; + + default: +#ifdef USB_SUPPORT_USER_STRING_DESC + pbuf = pdev->dev.class_cb->GetUsrStrDescriptor(pdev->cfg.speed, (req->wValue) , &len); + break; +#else + USBD_CtlError(pdev , req); + return; +#endif /* USBD_CtlError(pdev , req); */ + } + break; + case USB_DESC_TYPE_DEVICE_QUALIFIER: +#ifdef USB_OTG_HS_CORE + if(pdev->cfg.speed == USB_OTG_SPEED_HIGH ) + { + + pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len); + + USBD_DeviceQualifierDesc[4]= pbuf[14]; + USBD_DeviceQualifierDesc[5]= pbuf[15]; + USBD_DeviceQualifierDesc[6]= pbuf[16]; + + pbuf = USBD_DeviceQualifierDesc; + len = USB_LEN_DEV_QUALIFIER_DESC; + break; + } + else + { + USBD_CtlError(pdev , req); + return; + } +#else + USBD_CtlError(pdev , req); + return; +#endif + + case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: +#ifdef USB_OTG_HS_CORE + + if(pdev->cfg.speed == USB_OTG_SPEED_HIGH ) + { + pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len); + pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; + break; + } + else + { + USBD_CtlError(pdev , req); + return; + } +#else + USBD_CtlError(pdev , req); + return; +#endif + + + default: + USBD_CtlError(pdev , req); + return; + } + + if((len != 0)&& (req->wLength != 0)) + { + + len = MIN(len , req->wLength); + + USBD_CtlSendData (pdev, + pbuf, + len); + } + +} + +/** +* @brief USBD_SetAddress +* Set device address +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + uint8_t dev_addr; + + if ((req->wIndex == 0) && (req->wLength == 0)) + { + dev_addr = (uint8_t)(req->wValue) & 0x7F; + + if (pdev->dev.device_status == USB_OTG_CONFIGURED) + { + USBD_CtlError(pdev , req); + } + else + { + pdev->dev.device_address = dev_addr; + DCD_EP_SetAddress(pdev, dev_addr); + USBD_CtlSendStatus(pdev); + + if (dev_addr != 0) + { + pdev->dev.device_status = USB_OTG_ADDRESSED; + } + else + { + pdev->dev.device_status = USB_OTG_DEFAULT; + } + } + } + else + { + USBD_CtlError(pdev , req); + } +} + +/** +* @brief USBD_SetConfig +* Handle Set device configuration request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + + static uint8_t cfgidx; + + cfgidx = (uint8_t)(req->wValue); + + if (cfgidx > USBD_CFG_MAX_NUM ) + { + USBD_CtlError(pdev , req); + } + else + { + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + if (cfgidx) + { + pdev->dev.device_config = cfgidx; + pdev->dev.device_status = USB_OTG_CONFIGURED; + USBD_SetCfg(pdev , cfgidx); + USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + + case USB_OTG_CONFIGURED: + if (cfgidx == 0) + { + pdev->dev.device_status = USB_OTG_ADDRESSED; + pdev->dev.device_config = cfgidx; + USBD_ClrCfg(pdev , cfgidx); + USBD_CtlSendStatus(pdev); + + } + else if (cfgidx != pdev->dev.device_config) + { + /* Clear old configuration */ + USBD_ClrCfg(pdev , pdev->dev.device_config); + + /* set new configuration */ + pdev->dev.device_config = cfgidx; + USBD_SetCfg(pdev , cfgidx); + USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + } +} + +/** +* @brief USBD_GetConfig +* Handle Get device configuration request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + + if (req->wLength != 1) + { + USBD_CtlError(pdev , req); + } + else + { + switch (pdev->dev.device_status ) + { + case USB_OTG_ADDRESSED: + + USBD_CtlSendData (pdev, + (uint8_t *)&USBD_default_cfg, + 1); + break; + + case USB_OTG_CONFIGURED: + + USBD_CtlSendData (pdev, + &pdev->dev.device_config, + 1); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + } +} + +/** +* @brief USBD_GetStatus +* Handle Get Status request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + case USB_OTG_CONFIGURED: + + if (pdev->dev.DevRemoteWakeup) + { + USBD_cfg_status = USB_CONFIG_SELF_POWERED | USB_CONFIG_REMOTE_WAKEUP; + } + else + { + USBD_cfg_status = USB_CONFIG_SELF_POWERED; + } + + USBD_CtlSendData (pdev, + (uint8_t *)&USBD_cfg_status, + 1); + break; + + default : + USBD_CtlError(pdev , req); + break; + } +} + + +/** +* @brief USBD_SetFeature +* Handle Set device feature request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + + USB_OTG_DCTL_TypeDef dctl; + uint8_t test_mode = 0; + + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev.DevRemoteWakeup = 1; + pdev->dev.class_cb->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + } + + else if ((req->wValue == USB_FEATURE_TEST_MODE) && + ((req->wIndex & 0xFF) == 0)) + { + dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); + + test_mode = req->wIndex >> 8; + switch (test_mode) + { + case 1: // TEST_J + dctl.b.tstctl = 1; + break; + + case 2: // TEST_K + dctl.b.tstctl = 2; + break; + + case 3: // TEST_SE0_NAK + dctl.b.tstctl = 3; + break; + + case 4: // TEST_PACKET + dctl.b.tstctl = 4; + break; + + case 5: // TEST_FORCE_ENABLE + dctl.b.tstctl = 5; + break; + } + USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); + USBD_CtlSendStatus(pdev); + } + +} + + +/** +* @brief USBD_ClrFeature +* Handle clear device feature request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + switch (pdev->dev.device_status) + { + case USB_OTG_ADDRESSED: + case USB_OTG_CONFIGURED: + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev.DevRemoteWakeup = 0; + pdev->dev.class_cb->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + } + break; + + default : + USBD_CtlError(pdev , req); + break; + } +} + +/** +* @brief USBD_ParseSetupRequest +* Copy buffer into setup structure +* @param pdev: device instance +* @param req: usb request +* @retval None +*/ + +void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + req->bmRequest = *(uint8_t *) (pdev->dev.setup_packet); + req->bRequest = *(uint8_t *) (pdev->dev.setup_packet + 1); + req->wValue = SWAPBYTE (pdev->dev.setup_packet + 2); + req->wIndex = SWAPBYTE (pdev->dev.setup_packet + 4); + req->wLength = SWAPBYTE (pdev->dev.setup_packet + 6); + + pdev->dev.in_ep[0].ctl_data_len = req->wLength ; + pdev->dev.device_state = USB_OTG_EP0_SETUP; +} + +/** +* @brief USBD_CtlError +* Handle USB low level Error +* @param pdev: device instance +* @param req: usb request +* @retval None +*/ + +void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev, + USB_SETUP_REQ *req) +{ + if((req->bmRequest & 0x80) == 0x80) + { + DCD_EP_Stall(pdev , 0x80); + } + else + { + if(req->wLength == 0) + { + DCD_EP_Stall(pdev , 0x80); + } + else + { + DCD_EP_Stall(pdev , 0); + } + } + USB_OTG_EP0_OutStart(pdev); +} + + +/** + * @brief USBD_GetString + * Convert Ascii string into unicode one + * @param desc : descriptor buffer + * @param unicode : Formatted string buffer (unicode) + * @param len : descriptor length + * @retval None + */ +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) +{ + uint8_t idx = 0; + + if (desc != NULL) + { + *len = USBD_GetLen(desc) * 2 + 2; + unicode[idx++] = *len; + unicode[idx++] = USB_DESC_TYPE_STRING; + + while (*desc != NULL) + { + unicode[idx++] = *desc++; + unicode[idx++] = 0x00; + } + } +} + +/** + * @brief USBD_GetLen + * return the string length + * @param buf : pointer to the ascii string buffer + * @retval string length + */ +static uint8_t USBD_GetLen(uint8_t *buf) +{ + uint8_t len = 0; + + while (*buf != NULL) + { + len++; + buf++; + } + + return len; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_bsp.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_bsp.h index 71005753..dad600ae 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_bsp.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_bsp.h @@ -1,99 +1,99 @@ -/** - ****************************************************************************** - * @file usb_bsp.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Specific api's relative to the used hardware platform - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_BSP__H__ -#define __USB_BSP__H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_core.h" -//#include "stm32f4_discovery.h" - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_BSP - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_BSP_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_BSP_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_BSP_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_BSP_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_BSP_Exported_FunctionsPrototype - * @{ - */ -void BSP_Init(void); - -void USB_OTG_BSP_Init (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_BSP_DeInit (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_BSP_uDelay (const uint32_t usec); -void USB_OTG_BSP_mDelay (const uint32_t msec); -void USB_OTG_BSP_EnableInterrupt (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_BSP_DisableInterrupt (USB_OTG_CORE_HANDLE *pdev); -#ifdef USE_HOST_MODE -void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev,uint8_t state); -#endif -/** - * @} - */ - -#endif //__USB_BSP__H__ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_bsp.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Specific api's relative to the used hardware platform + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_BSP__H__ +#define __USB_BSP__H__ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_core.h" +//#include "stm32f4_discovery.h" + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_BSP + * @brief This file is the + * @{ + */ + + +/** @defgroup USB_BSP_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_BSP_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_BSP_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_BSP_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_BSP_Exported_FunctionsPrototype + * @{ + */ +void BSP_Init(void); + +void USB_OTG_BSP_Init (USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_BSP_DeInit (USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_BSP_uDelay (const uint32_t usec); +void USB_OTG_BSP_mDelay (const uint32_t msec); +void USB_OTG_BSP_EnableInterrupt (USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_BSP_DisableInterrupt (USB_OTG_CORE_HANDLE *pdev); +#ifdef USE_HOST_MODE +void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev,uint8_t state); +#endif +/** + * @} + */ + +#endif //__USB_BSP__H__ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_conf_template.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_conf_template.h index f48cbe41..39b35529 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_conf_template.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_conf_template.h @@ -1,287 +1,287 @@ -/** - ****************************************************************************** - * @file usb_conf.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief general low level driver configuration - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CONF__H__ -#define __USB_CONF__H__ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f2xx.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_CONF - * @brief USB low level driver configuration file - * @{ - */ - -/** @defgroup USB_CONF_Exported_Defines - * @{ - */ - -/* USB Core and PHY interface configuration. - Tip: To avoid modifying these defines each time you need to change the USB - configuration, you can declare the needed define in your toolchain - compiler preprocessor. - */ -#ifndef USE_USB_OTG_FS - //#define USE_USB_OTG_FS -#endif /* USE_USB_OTG_FS */ - -#ifndef USE_USB_OTG_HS - //#define USE_USB_OTG_HS -#endif /* USE_USB_OTG_HS */ - -#ifndef USE_ULPI_PHY - //#define USE_ULPI_PHY -#endif /* USE_ULPI_PHY */ - -#ifndef USE_EMBEDDED_PHY - //#define USE_EMBEDDED_PHY -#endif /* USE_EMBEDDED_PHY */ - -#ifndef USE_I2C_PHY - //#define USE_I2C_PHY -#endif /* USE_I2C_PHY */ - - -#ifdef USE_USB_OTG_FS - #define USB_OTG_FS_CORE -#endif - -#ifdef USE_USB_OTG_HS - #define USB_OTG_HS_CORE -#endif - -/******************************************************************************* -* FIFO Size Configuration in Device mode -* -* (i) Receive data FIFO size = RAM for setup packets + -* OUT endpoint control information + -* data OUT packets + miscellaneous -* Space = ONE 32-bits words -* --> RAM for setup packets = 10 spaces -* (n is the nbr of CTRL EPs the device core supports) -* --> OUT EP CTRL info = 1 space -* (one space for status information written to the FIFO along with each -* received packet) -* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces -* (MINIMUM to receive packets) -* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces -* (if high-bandwidth EP is enabled or multiple isochronous EPs) -* --> miscellaneous = 1 space per OUT EP -* (one space for transfer complete status information also pushed to the -* FIFO with each endpoint's last packet) -* -* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for -* that particular IN EP. More space allocated in the IN EP Tx FIFO results -* in a better performance on the USB and can hide latencies on the AHB. -* -* (iii) TXn min size = 16 words. (n : Transmit FIFO index) -* (iv) When a TxFIFO is not used, the Configuration should be as follows: -* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) -* --> Txm can use the space allocated for Txn. -* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) -* --> Txn should be configured with the minimum space of 16 words -* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top -* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. -*******************************************************************************/ - -/******************************************************************************* -* FIFO Size Configuration in Host mode -* -* (i) Receive data FIFO size = (Largest Packet Size / 4) + 1 or -* 2x (Largest Packet Size / 4) + 1, If a -* high-bandwidth channel or multiple isochronous -* channels are enabled -* -* (ii) For the host nonperiodic Transmit FIFO is the largest maximum packet size -* for all supported nonperiodic OUT channels. Typically, a space -* corresponding to two Largest Packet Size is recommended. -* -* (iii) The minimum amount of RAM required for Host periodic Transmit FIFO is -* the largest maximum packet size for all supported periodic OUT channels. -* If there is at least one High Bandwidth Isochronous OUT endpoint, -* then the space must be at least two times the maximum packet size for -* that channel. -*******************************************************************************/ - -/****************** USB OTG HS CONFIGURATION **********************************/ -#ifdef USB_OTG_HS_CORE - #define RX_FIFO_HS_SIZE 512 - #define TX0_FIFO_HS_SIZE 512 - #define TX1_FIFO_HS_SIZE 512 - #define TX2_FIFO_HS_SIZE 0 - #define TX3_FIFO_HS_SIZE 0 - #define TX4_FIFO_HS_SIZE 0 - #define TX5_FIFO_HS_SIZE 0 - #define TXH_NP_HS_FIFOSIZ 96 - #define TXH_P_HS_FIFOSIZ 96 - - //#define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT - //#define USB_OTG_HS_SOF_OUTPUT_ENABLED - - //#define USB_OTG_INTERNAL_VBUS_ENABLED - #define USB_OTG_EXTERNAL_VBUS_ENABLED - - #ifdef USE_ULPI_PHY - #define USB_OTG_ULPI_PHY_ENABLED - #endif - #ifdef USE_EMBEDDED_PHY - #define USB_OTG_EMBEDDED_PHY_ENABLED - #endif - #ifdef USE_I2C_PHY - #define USB_OTG_I2C_PHY_ENABLED - #endif - #define USB_OTG_HS_INTERNAL_DMA_ENABLED - #define USB_OTG_HS_DEDICATED_EP1_ENABLED -#endif - -/****************** USB OTG FS CONFIGURATION **********************************/ -#ifdef USB_OTG_FS_CORE - #define RX_FIFO_FS_SIZE 128 - #define TX0_FIFO_FS_SIZE 64 - #define TX1_FIFO_FS_SIZE 128 - #define TX2_FIFO_FS_SIZE 0 - #define TX3_FIFO_FS_SIZE 0 - #define TXH_NP_HS_FIFOSIZ 96 - #define TXH_P_HS_FIFOSIZ 96 - - //#define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - //#define USB_OTG_FS_SOF_OUTPUT_ENABLED -#endif - -/****************** USB OTG MODE CONFIGURATION ********************************/ -//#define USE_HOST_MODE -#define USE_DEVICE_MODE -//#define USE_OTG_MODE - - -#ifndef USB_OTG_FS_CORE - #ifndef USB_OTG_HS_CORE - #error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined" - #endif -#endif - - -#ifndef USE_DEVICE_MODE - #ifndef USE_HOST_MODE - #error "USE_DEVICE_MODE or USE_HOST_MODE should be defined" - #endif -#endif - -#ifndef USE_USB_OTG_HS - #ifndef USE_USB_OTG_FS - #error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined" - #endif -#else //USE_USB_OTG_HS - #ifndef USE_ULPI_PHY - #ifndef USE_EMBEDDED_PHY - #ifndef USE_I2C_PHY - #error "USE_ULPI_PHY or USE_EMBEDDED_PHY or USE_I2C_PHY should be defined" - #endif - #endif - #endif -#endif - -/****************** C Compilers dependant keywords ****************************/ -/* In HS mode and when the DMA is used, all variables and data structures dealing - with the DMA during the transaction process should be 4-bytes aligned */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined (__GNUC__) /* GNU Compiler */ - #define __ALIGN_END __attribute__ ((aligned (4))) - #define __ALIGN_BEGIN - #else - #define __ALIGN_END - #if defined (__CC_ARM) /* ARM Compiler */ - #define __ALIGN_BEGIN __align(4) - #elif defined (__ICCARM__) /* IAR Compiler */ - #define __ALIGN_BEGIN - #elif defined (__TASKING__) /* TASKING Compiler */ - #define __ALIGN_BEGIN __align(4) - #endif /* __CC_ARM */ - #endif /* __GNUC__ */ -#else - #define __ALIGN_BEGIN - #define __ALIGN_END -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/* __packed keyword used to decrease the data type alignment to 1-byte */ -#if defined (__CC_ARM) /* ARM Compiler */ - #define __packed __packed -#elif defined (__ICCARM__) /* IAR Compiler */ - #define __packed __packed -#elif defined ( __GNUC__ ) /* GNU Compiler */ - #define __packed __attribute__ ((__packed__)) -#elif defined (__TASKING__) /* TASKING Compiler */ - #define __packed __unaligned -#endif /* __CC_ARM */ - -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USB_CONF__H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_conf.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief general low level driver configuration + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CONF__H__ +#define __USB_CONF__H__ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f2xx.h" + + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_CONF + * @brief USB low level driver configuration file + * @{ + */ + +/** @defgroup USB_CONF_Exported_Defines + * @{ + */ + +/* USB Core and PHY interface configuration. + Tip: To avoid modifying these defines each time you need to change the USB + configuration, you can declare the needed define in your toolchain + compiler preprocessor. + */ +#ifndef USE_USB_OTG_FS + //#define USE_USB_OTG_FS +#endif /* USE_USB_OTG_FS */ + +#ifndef USE_USB_OTG_HS + //#define USE_USB_OTG_HS +#endif /* USE_USB_OTG_HS */ + +#ifndef USE_ULPI_PHY + //#define USE_ULPI_PHY +#endif /* USE_ULPI_PHY */ + +#ifndef USE_EMBEDDED_PHY + //#define USE_EMBEDDED_PHY +#endif /* USE_EMBEDDED_PHY */ + +#ifndef USE_I2C_PHY + //#define USE_I2C_PHY +#endif /* USE_I2C_PHY */ + + +#ifdef USE_USB_OTG_FS + #define USB_OTG_FS_CORE +#endif + +#ifdef USE_USB_OTG_HS + #define USB_OTG_HS_CORE +#endif + +/******************************************************************************* +* FIFO Size Configuration in Device mode +* +* (i) Receive data FIFO size = RAM for setup packets + +* OUT endpoint control information + +* data OUT packets + miscellaneous +* Space = ONE 32-bits words +* --> RAM for setup packets = 10 spaces +* (n is the nbr of CTRL EPs the device core supports) +* --> OUT EP CTRL info = 1 space +* (one space for status information written to the FIFO along with each +* received packet) +* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces +* (MINIMUM to receive packets) +* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces +* (if high-bandwidth EP is enabled or multiple isochronous EPs) +* --> miscellaneous = 1 space per OUT EP +* (one space for transfer complete status information also pushed to the +* FIFO with each endpoint's last packet) +* +* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for +* that particular IN EP. More space allocated in the IN EP Tx FIFO results +* in a better performance on the USB and can hide latencies on the AHB. +* +* (iii) TXn min size = 16 words. (n : Transmit FIFO index) +* (iv) When a TxFIFO is not used, the Configuration should be as follows: +* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) +* --> Txm can use the space allocated for Txn. +* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) +* --> Txn should be configured with the minimum space of 16 words +* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top +* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. +*******************************************************************************/ + +/******************************************************************************* +* FIFO Size Configuration in Host mode +* +* (i) Receive data FIFO size = (Largest Packet Size / 4) + 1 or +* 2x (Largest Packet Size / 4) + 1, If a +* high-bandwidth channel or multiple isochronous +* channels are enabled +* +* (ii) For the host nonperiodic Transmit FIFO is the largest maximum packet size +* for all supported nonperiodic OUT channels. Typically, a space +* corresponding to two Largest Packet Size is recommended. +* +* (iii) The minimum amount of RAM required for Host periodic Transmit FIFO is +* the largest maximum packet size for all supported periodic OUT channels. +* If there is at least one High Bandwidth Isochronous OUT endpoint, +* then the space must be at least two times the maximum packet size for +* that channel. +*******************************************************************************/ + +/****************** USB OTG HS CONFIGURATION **********************************/ +#ifdef USB_OTG_HS_CORE + #define RX_FIFO_HS_SIZE 512 + #define TX0_FIFO_HS_SIZE 512 + #define TX1_FIFO_HS_SIZE 512 + #define TX2_FIFO_HS_SIZE 0 + #define TX3_FIFO_HS_SIZE 0 + #define TX4_FIFO_HS_SIZE 0 + #define TX5_FIFO_HS_SIZE 0 + #define TXH_NP_HS_FIFOSIZ 96 + #define TXH_P_HS_FIFOSIZ 96 + + //#define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT + //#define USB_OTG_HS_SOF_OUTPUT_ENABLED + + //#define USB_OTG_INTERNAL_VBUS_ENABLED + #define USB_OTG_EXTERNAL_VBUS_ENABLED + + #ifdef USE_ULPI_PHY + #define USB_OTG_ULPI_PHY_ENABLED + #endif + #ifdef USE_EMBEDDED_PHY + #define USB_OTG_EMBEDDED_PHY_ENABLED + #endif + #ifdef USE_I2C_PHY + #define USB_OTG_I2C_PHY_ENABLED + #endif + #define USB_OTG_HS_INTERNAL_DMA_ENABLED + #define USB_OTG_HS_DEDICATED_EP1_ENABLED +#endif + +/****************** USB OTG FS CONFIGURATION **********************************/ +#ifdef USB_OTG_FS_CORE + #define RX_FIFO_FS_SIZE 128 + #define TX0_FIFO_FS_SIZE 64 + #define TX1_FIFO_FS_SIZE 128 + #define TX2_FIFO_FS_SIZE 0 + #define TX3_FIFO_FS_SIZE 0 + #define TXH_NP_HS_FIFOSIZ 96 + #define TXH_P_HS_FIFOSIZ 96 + + //#define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT + //#define USB_OTG_FS_SOF_OUTPUT_ENABLED +#endif + +/****************** USB OTG MODE CONFIGURATION ********************************/ +//#define USE_HOST_MODE +#define USE_DEVICE_MODE +//#define USE_OTG_MODE + + +#ifndef USB_OTG_FS_CORE + #ifndef USB_OTG_HS_CORE + #error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined" + #endif +#endif + + +#ifndef USE_DEVICE_MODE + #ifndef USE_HOST_MODE + #error "USE_DEVICE_MODE or USE_HOST_MODE should be defined" + #endif +#endif + +#ifndef USE_USB_OTG_HS + #ifndef USE_USB_OTG_FS + #error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined" + #endif +#else //USE_USB_OTG_HS + #ifndef USE_ULPI_PHY + #ifndef USE_EMBEDDED_PHY + #ifndef USE_I2C_PHY + #error "USE_ULPI_PHY or USE_EMBEDDED_PHY or USE_I2C_PHY should be defined" + #endif + #endif + #endif +#endif + +/****************** C Compilers dependant keywords ****************************/ +/* In HS mode and when the DMA is used, all variables and data structures dealing + with the DMA during the transaction process should be 4-bytes aligned */ +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined (__GNUC__) /* GNU Compiler */ + #define __ALIGN_END __attribute__ ((aligned (4))) + #define __ALIGN_BEGIN + #else + #define __ALIGN_END + #if defined (__CC_ARM) /* ARM Compiler */ + #define __ALIGN_BEGIN __align(4) + #elif defined (__ICCARM__) /* IAR Compiler */ + #define __ALIGN_BEGIN + #elif defined (__TASKING__) /* TASKING Compiler */ + #define __ALIGN_BEGIN __align(4) + #endif /* __CC_ARM */ + #endif /* __GNUC__ */ +#else + #define __ALIGN_BEGIN + #define __ALIGN_END +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + +/* __packed keyword used to decrease the data type alignment to 1-byte */ +#if defined (__CC_ARM) /* ARM Compiler */ + #define __packed __packed +#elif defined (__ICCARM__) /* IAR Compiler */ + #define __packed __packed +#elif defined ( __GNUC__ ) /* GNU Compiler */ + #define __packed __attribute__ ((__packed__)) +#elif defined (__TASKING__) /* TASKING Compiler */ + #define __packed __unaligned +#endif /* __CC_ARM */ + +/** + * @} + */ + + +/** @defgroup USB_CONF_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_CONF_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_CONF_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_CONF_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + + +#endif //__USB_CONF__H__ + + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_core.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_core.h index 7e9cb8c9..82a09e15 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_core.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_core.h @@ -1,408 +1,408 @@ -/** - ****************************************************************************** - * @file usb_core.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header of the Core Layer - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CORE_H__ -#define __USB_CORE_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_conf.h" -#include "usb_regs.h" -#include "usb_defines.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_CORE - * @brief usb otg driver core layer - * @{ - */ - - -/** @defgroup USB_CORE_Exported_Defines - * @{ - */ - -#define USB_OTG_EP0_IDLE 0 -#define USB_OTG_EP0_SETUP 1 -#define USB_OTG_EP0_DATA_IN 2 -#define USB_OTG_EP0_DATA_OUT 3 -#define USB_OTG_EP0_STATUS_IN 4 -#define USB_OTG_EP0_STATUS_OUT 5 -#define USB_OTG_EP0_STALL 6 - -#define USB_OTG_EP_TX_DIS 0x0000 -#define USB_OTG_EP_TX_STALL 0x0010 -#define USB_OTG_EP_TX_NAK 0x0020 -#define USB_OTG_EP_TX_VALID 0x0030 - -#define USB_OTG_EP_RX_DIS 0x0000 -#define USB_OTG_EP_RX_STALL 0x1000 -#define USB_OTG_EP_RX_NAK 0x2000 -#define USB_OTG_EP_RX_VALID 0x3000 -/** - * @} - */ -#define MAX_DATA_LENGTH 0xFF - -/** @defgroup USB_CORE_Exported_Types - * @{ - */ - - -typedef enum { - USB_OTG_OK = 0, - USB_OTG_FAIL -}USB_OTG_STS; - -typedef enum { - HC_IDLE = 0, - HC_XFRC, - HC_HALTED, - HC_NAK, - HC_NYET, - HC_STALL, - HC_XACTERR, - HC_BBLERR, - HC_DATATGLERR, -}HC_STATUS; - -typedef enum { - URB_IDLE = 0, - URB_DONE, - URB_NOTREADY, - URB_ERROR, - URB_STALL -}URB_STATE; - -typedef enum { - CTRL_START = 0, - CTRL_XFRC, - CTRL_HALTED, - CTRL_NAK, - CTRL_STALL, - CTRL_XACTERR, - CTRL_BBLERR, - CTRL_DATATGLERR, - CTRL_FAIL -}CTRL_STATUS; - - -typedef struct USB_OTG_hc -{ - uint8_t dev_addr ; - uint8_t ep_num; - uint8_t ep_is_in; - uint8_t speed; - uint8_t do_ping; - uint8_t ep_type; - uint16_t max_packet; - uint8_t data_pid; - uint8_t *xfer_buff; - uint32_t xfer_len; - uint32_t xfer_count; - uint8_t toggle_in; - uint8_t toggle_out; - uint32_t dma_addr; -} -USB_OTG_HC , *PUSB_OTG_HC; - -typedef struct USB_OTG_ep -{ - uint8_t num; - uint8_t is_in; - uint8_t is_stall; - uint8_t type; - uint8_t data_pid_start; - uint8_t even_odd_frame; - uint16_t tx_fifo_num; - uint32_t maxpacket; - /* transaction level variables*/ - uint8_t *xfer_buff; - uint32_t dma_addr; - uint32_t xfer_len; - uint32_t xfer_count; - /* Transfer level variables*/ - uint32_t rem_data_len; - uint32_t total_data_len; - uint32_t ctl_data_len; - -} - -USB_OTG_EP , *PUSB_OTG_EP; - - - -typedef struct USB_OTG_core_cfg -{ - uint8_t host_channels; - uint8_t dev_endpoints; - uint8_t speed; - uint8_t dma_enable; - uint16_t mps; - uint16_t TotalFifoSize; - uint8_t phy_itface; - uint8_t Sof_output; - uint8_t low_power; - uint8_t coreID; - -} -USB_OTG_CORE_CFGS, *PUSB_OTG_CORE_CFGS; - - - -typedef struct usb_setup_req { - - uint8_t bmRequest; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} USB_SETUP_REQ; - -typedef struct _Device_TypeDef -{ - uint8_t *(*GetDeviceDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetLangIDStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetManufacturerStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetProductStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetSerialStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetConfigurationStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetInterfaceStrDescriptor)( uint8_t speed , uint16_t *length); -} USBD_DEVICE, *pUSBD_DEVICE; - -typedef struct USB_OTG_hPort -{ - void (*Disconnect) (void *phost); - void (*Connect) (void *phost); - uint8_t ConnStatus; - uint8_t DisconnStatus; - uint8_t ConnHandled; - uint8_t DisconnHandled; -} USB_OTG_hPort_TypeDef; - -typedef struct _Device_cb -{ - uint8_t (*Init) (void *pdev , uint8_t cfgidx); - uint8_t (*DeInit) (void *pdev , uint8_t cfgidx); - /* Control Endpoints*/ - uint8_t (*Setup) (void *pdev , USB_SETUP_REQ *req); - uint8_t (*EP0_TxSent) (void *pdev ); - uint8_t (*EP0_RxReady) (void *pdev ); - /* Class Specific Endpoints*/ - uint8_t (*DataIn) (void *pdev , uint8_t epnum); - uint8_t (*DataOut) (void *pdev , uint8_t epnum); - uint8_t (*SOF) (void *pdev); - uint8_t (*IsoINIncomplete) (void *pdev); - uint8_t (*IsoOUTIncomplete) (void *pdev); - - uint8_t *(*GetConfigDescriptor)( uint8_t speed , uint16_t *length); -#ifdef USB_OTG_HS_CORE - uint8_t *(*GetOtherConfigDescriptor)( uint8_t speed , uint16_t *length); -#endif - -#ifdef USB_SUPPORT_USER_STRING_DESC - uint8_t *(*GetUsrStrDescriptor)( uint8_t speed ,uint8_t index, uint16_t *length); -#endif - -} USBD_Class_cb_TypeDef; - - - -typedef struct _USBD_USR_PROP -{ - void (*Init)(void); - void (*DeviceReset)(uint8_t speed); - void (*DeviceConfigured)(void); - void (*DeviceSuspended)(void); - void (*DeviceResumed)(void); - - void (*DeviceConnected)(void); - void (*DeviceDisconnected)(void); - -} -USBD_Usr_cb_TypeDef; - -typedef struct _DCD -{ - uint8_t device_config; - uint8_t device_state; - uint8_t device_status; - uint8_t device_address; - uint32_t DevRemoteWakeup; - USB_OTG_EP in_ep [USB_OTG_MAX_TX_FIFOS]; - USB_OTG_EP out_ep [USB_OTG_MAX_TX_FIFOS]; - uint8_t setup_packet [8*3]; - USBD_Class_cb_TypeDef *class_cb; - USBD_Usr_cb_TypeDef *usr_cb; - USBD_DEVICE *usr_device; - uint8_t *pConfig_descriptor; - } -DCD_DEV , *DCD_PDEV; - - -typedef struct _HCD -{ - uint8_t Rx_Buffer [MAX_DATA_LENGTH]; - __IO uint32_t ConnSts; - __IO uint32_t ErrCnt[USB_OTG_MAX_TX_FIFOS]; - __IO uint32_t XferCnt[USB_OTG_MAX_TX_FIFOS]; - __IO HC_STATUS HC_Status[USB_OTG_MAX_TX_FIFOS]; - __IO URB_STATE URB_State[USB_OTG_MAX_TX_FIFOS]; - USB_OTG_HC hc [USB_OTG_MAX_TX_FIFOS]; - uint16_t channel [USB_OTG_MAX_TX_FIFOS]; - USB_OTG_hPort_TypeDef *port_cb; -} -HCD_DEV , *USB_OTG_USBH_PDEV; - - -typedef struct _OTG -{ - uint8_t OTG_State; - uint8_t OTG_PrevState; - uint8_t OTG_Mode; -} -OTG_DEV , *USB_OTG_USBO_PDEV; - -typedef struct USB_OTG_handle -{ - USB_OTG_CORE_CFGS cfg; - USB_OTG_CORE_REGS regs; -#ifdef USE_DEVICE_MODE - DCD_DEV dev; -#endif -#ifdef USE_HOST_MODE - HCD_DEV host; -#endif -#ifdef USE_OTG_MODE - OTG_DEV otg; -#endif -} -USB_OTG_CORE_HANDLE , *PUSB_OTG_CORE_HANDLE; - -/** - * @} - */ - - -/** @defgroup USB_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_FunctionsPrototype - * @{ - */ - - -USB_OTG_STS USB_OTG_CoreInit (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_SelectCore (USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID); -USB_OTG_STS USB_OTG_EnableGlobalInt (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev); -void* USB_OTG_ReadPacket (USB_OTG_CORE_HANDLE *pdev , - uint8_t *dest, - uint16_t len); -USB_OTG_STS USB_OTG_WritePacket (USB_OTG_CORE_HANDLE *pdev , - uint8_t *src, - uint8_t ch_ep_num, - uint16_t len); -USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num); -USB_OTG_STS USB_OTG_FlushRxFifo (USB_OTG_CORE_HANDLE *pdev); - -uint32_t USB_OTG_ReadCoreItr (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev); -uint8_t USB_OTG_IsHostMode (USB_OTG_CORE_HANDLE *pdev); -uint8_t USB_OTG_IsDeviceMode (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_GetMode (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_PhyInit (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_SetCurrentMode (USB_OTG_CORE_HANDLE *pdev, - uint8_t mode); - -/*********************** HOST APIs ********************************************/ -#ifdef USE_HOST_MODE -USB_OTG_STS USB_OTG_CoreInitHost (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EnableHostInt (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_HC_Init (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); -USB_OTG_STS USB_OTG_HC_Halt (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); -USB_OTG_STS USB_OTG_HC_StartXfer (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); -USB_OTG_STS USB_OTG_HC_DoPing (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num); -uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ResetPort (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadHPRT0 (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state); -void USB_OTG_InitFSLSPClkSel (USB_OTG_CORE_HANDLE *pdev ,uint8_t freq); -uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) ; -void USB_OTG_StopHost (USB_OTG_CORE_HANDLE *pdev); -#endif -/********************* DEVICE APIs ********************************************/ -#ifdef USE_DEVICE_MODE -USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EnableDevInt (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev); -enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EP0Activate (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EPActivate (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPStartXfer (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPSetStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPClearStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -uint32_t USB_OTG_ReadDevAllOutEp_itr (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadDevOutEP_itr (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); -uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_InitDevSpeed (USB_OTG_CORE_HANDLE *pdev , uint8_t speed); -uint8_t USBH_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status); -uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep); -#endif -/** - * @} - */ - -#endif /* __USB_CORE_H__ */ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_core.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Header of the Core Layer + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CORE_H__ +#define __USB_CORE_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_conf.h" +#include "usb_regs.h" +#include "usb_defines.h" + + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_CORE + * @brief usb otg driver core layer + * @{ + */ + + +/** @defgroup USB_CORE_Exported_Defines + * @{ + */ + +#define USB_OTG_EP0_IDLE 0 +#define USB_OTG_EP0_SETUP 1 +#define USB_OTG_EP0_DATA_IN 2 +#define USB_OTG_EP0_DATA_OUT 3 +#define USB_OTG_EP0_STATUS_IN 4 +#define USB_OTG_EP0_STATUS_OUT 5 +#define USB_OTG_EP0_STALL 6 + +#define USB_OTG_EP_TX_DIS 0x0000 +#define USB_OTG_EP_TX_STALL 0x0010 +#define USB_OTG_EP_TX_NAK 0x0020 +#define USB_OTG_EP_TX_VALID 0x0030 + +#define USB_OTG_EP_RX_DIS 0x0000 +#define USB_OTG_EP_RX_STALL 0x1000 +#define USB_OTG_EP_RX_NAK 0x2000 +#define USB_OTG_EP_RX_VALID 0x3000 +/** + * @} + */ +#define MAX_DATA_LENGTH 0xFF + +/** @defgroup USB_CORE_Exported_Types + * @{ + */ + + +typedef enum { + USB_OTG_OK = 0, + USB_OTG_FAIL +}USB_OTG_STS; + +typedef enum { + HC_IDLE = 0, + HC_XFRC, + HC_HALTED, + HC_NAK, + HC_NYET, + HC_STALL, + HC_XACTERR, + HC_BBLERR, + HC_DATATGLERR, +}HC_STATUS; + +typedef enum { + URB_IDLE = 0, + URB_DONE, + URB_NOTREADY, + URB_ERROR, + URB_STALL +}URB_STATE; + +typedef enum { + CTRL_START = 0, + CTRL_XFRC, + CTRL_HALTED, + CTRL_NAK, + CTRL_STALL, + CTRL_XACTERR, + CTRL_BBLERR, + CTRL_DATATGLERR, + CTRL_FAIL +}CTRL_STATUS; + + +typedef struct USB_OTG_hc +{ + uint8_t dev_addr ; + uint8_t ep_num; + uint8_t ep_is_in; + uint8_t speed; + uint8_t do_ping; + uint8_t ep_type; + uint16_t max_packet; + uint8_t data_pid; + uint8_t *xfer_buff; + uint32_t xfer_len; + uint32_t xfer_count; + uint8_t toggle_in; + uint8_t toggle_out; + uint32_t dma_addr; +} +USB_OTG_HC , *PUSB_OTG_HC; + +typedef struct USB_OTG_ep +{ + uint8_t num; + uint8_t is_in; + uint8_t is_stall; + uint8_t type; + uint8_t data_pid_start; + uint8_t even_odd_frame; + uint16_t tx_fifo_num; + uint32_t maxpacket; + /* transaction level variables*/ + uint8_t *xfer_buff; + uint32_t dma_addr; + uint32_t xfer_len; + uint32_t xfer_count; + /* Transfer level variables*/ + uint32_t rem_data_len; + uint32_t total_data_len; + uint32_t ctl_data_len; + +} + +USB_OTG_EP , *PUSB_OTG_EP; + + + +typedef struct USB_OTG_core_cfg +{ + uint8_t host_channels; + uint8_t dev_endpoints; + uint8_t speed; + uint8_t dma_enable; + uint16_t mps; + uint16_t TotalFifoSize; + uint8_t phy_itface; + uint8_t Sof_output; + uint8_t low_power; + uint8_t coreID; + +} +USB_OTG_CORE_CFGS, *PUSB_OTG_CORE_CFGS; + + + +typedef struct usb_setup_req { + + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} USB_SETUP_REQ; + +typedef struct _Device_TypeDef +{ + uint8_t *(*GetDeviceDescriptor)( uint8_t speed , uint16_t *length); + uint8_t *(*GetLangIDStrDescriptor)( uint8_t speed , uint16_t *length); + uint8_t *(*GetManufacturerStrDescriptor)( uint8_t speed , uint16_t *length); + uint8_t *(*GetProductStrDescriptor)( uint8_t speed , uint16_t *length); + uint8_t *(*GetSerialStrDescriptor)( uint8_t speed , uint16_t *length); + uint8_t *(*GetConfigurationStrDescriptor)( uint8_t speed , uint16_t *length); + uint8_t *(*GetInterfaceStrDescriptor)( uint8_t speed , uint16_t *length); +} USBD_DEVICE, *pUSBD_DEVICE; + +typedef struct USB_OTG_hPort +{ + void (*Disconnect) (void *phost); + void (*Connect) (void *phost); + uint8_t ConnStatus; + uint8_t DisconnStatus; + uint8_t ConnHandled; + uint8_t DisconnHandled; +} USB_OTG_hPort_TypeDef; + +typedef struct _Device_cb +{ + uint8_t (*Init) (void *pdev , uint8_t cfgidx); + uint8_t (*DeInit) (void *pdev , uint8_t cfgidx); + /* Control Endpoints*/ + uint8_t (*Setup) (void *pdev , USB_SETUP_REQ *req); + uint8_t (*EP0_TxSent) (void *pdev ); + uint8_t (*EP0_RxReady) (void *pdev ); + /* Class Specific Endpoints*/ + uint8_t (*DataIn) (void *pdev , uint8_t epnum); + uint8_t (*DataOut) (void *pdev , uint8_t epnum); + uint8_t (*SOF) (void *pdev); + uint8_t (*IsoINIncomplete) (void *pdev); + uint8_t (*IsoOUTIncomplete) (void *pdev); + + uint8_t *(*GetConfigDescriptor)( uint8_t speed , uint16_t *length); +#ifdef USB_OTG_HS_CORE + uint8_t *(*GetOtherConfigDescriptor)( uint8_t speed , uint16_t *length); +#endif + +#ifdef USB_SUPPORT_USER_STRING_DESC + uint8_t *(*GetUsrStrDescriptor)( uint8_t speed ,uint8_t index, uint16_t *length); +#endif + +} USBD_Class_cb_TypeDef; + + + +typedef struct _USBD_USR_PROP +{ + void (*Init)(void); + void (*DeviceReset)(uint8_t speed); + void (*DeviceConfigured)(void); + void (*DeviceSuspended)(void); + void (*DeviceResumed)(void); + + void (*DeviceConnected)(void); + void (*DeviceDisconnected)(void); + +} +USBD_Usr_cb_TypeDef; + +typedef struct _DCD +{ + uint8_t device_config; + uint8_t device_state; + uint8_t device_status; + uint8_t device_address; + uint32_t DevRemoteWakeup; + USB_OTG_EP in_ep [USB_OTG_MAX_TX_FIFOS]; + USB_OTG_EP out_ep [USB_OTG_MAX_TX_FIFOS]; + uint8_t setup_packet [8*3]; + USBD_Class_cb_TypeDef *class_cb; + USBD_Usr_cb_TypeDef *usr_cb; + USBD_DEVICE *usr_device; + uint8_t *pConfig_descriptor; + } +DCD_DEV , *DCD_PDEV; + + +typedef struct _HCD +{ + uint8_t Rx_Buffer [MAX_DATA_LENGTH]; + __IO uint32_t ConnSts; + __IO uint32_t ErrCnt[USB_OTG_MAX_TX_FIFOS]; + __IO uint32_t XferCnt[USB_OTG_MAX_TX_FIFOS]; + __IO HC_STATUS HC_Status[USB_OTG_MAX_TX_FIFOS]; + __IO URB_STATE URB_State[USB_OTG_MAX_TX_FIFOS]; + USB_OTG_HC hc [USB_OTG_MAX_TX_FIFOS]; + uint16_t channel [USB_OTG_MAX_TX_FIFOS]; + USB_OTG_hPort_TypeDef *port_cb; +} +HCD_DEV , *USB_OTG_USBH_PDEV; + + +typedef struct _OTG +{ + uint8_t OTG_State; + uint8_t OTG_PrevState; + uint8_t OTG_Mode; +} +OTG_DEV , *USB_OTG_USBO_PDEV; + +typedef struct USB_OTG_handle +{ + USB_OTG_CORE_CFGS cfg; + USB_OTG_CORE_REGS regs; +#ifdef USE_DEVICE_MODE + DCD_DEV dev; +#endif +#ifdef USE_HOST_MODE + HCD_DEV host; +#endif +#ifdef USE_OTG_MODE + OTG_DEV otg; +#endif +} +USB_OTG_CORE_HANDLE , *PUSB_OTG_CORE_HANDLE; + +/** + * @} + */ + + +/** @defgroup USB_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_FunctionsPrototype + * @{ + */ + + +USB_OTG_STS USB_OTG_CoreInit (USB_OTG_CORE_HANDLE *pdev); +USB_OTG_STS USB_OTG_SelectCore (USB_OTG_CORE_HANDLE *pdev, + USB_OTG_CORE_ID_TypeDef coreID); +USB_OTG_STS USB_OTG_EnableGlobalInt (USB_OTG_CORE_HANDLE *pdev); +USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev); +void* USB_OTG_ReadPacket (USB_OTG_CORE_HANDLE *pdev , + uint8_t *dest, + uint16_t len); +USB_OTG_STS USB_OTG_WritePacket (USB_OTG_CORE_HANDLE *pdev , + uint8_t *src, + uint8_t ch_ep_num, + uint16_t len); +USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num); +USB_OTG_STS USB_OTG_FlushRxFifo (USB_OTG_CORE_HANDLE *pdev); + +uint32_t USB_OTG_ReadCoreItr (USB_OTG_CORE_HANDLE *pdev); +uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev); +uint8_t USB_OTG_IsHostMode (USB_OTG_CORE_HANDLE *pdev); +uint8_t USB_OTG_IsDeviceMode (USB_OTG_CORE_HANDLE *pdev); +uint32_t USB_OTG_GetMode (USB_OTG_CORE_HANDLE *pdev); +USB_OTG_STS USB_OTG_PhyInit (USB_OTG_CORE_HANDLE *pdev); +USB_OTG_STS USB_OTG_SetCurrentMode (USB_OTG_CORE_HANDLE *pdev, + uint8_t mode); + +/*********************** HOST APIs ********************************************/ +#ifdef USE_HOST_MODE +USB_OTG_STS USB_OTG_CoreInitHost (USB_OTG_CORE_HANDLE *pdev); +USB_OTG_STS USB_OTG_EnableHostInt (USB_OTG_CORE_HANDLE *pdev); +USB_OTG_STS USB_OTG_HC_Init (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); +USB_OTG_STS USB_OTG_HC_Halt (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); +USB_OTG_STS USB_OTG_HC_StartXfer (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); +USB_OTG_STS USB_OTG_HC_DoPing (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num); +uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev); +uint32_t USB_OTG_ResetPort (USB_OTG_CORE_HANDLE *pdev); +uint32_t USB_OTG_ReadHPRT0 (USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state); +void USB_OTG_InitFSLSPClkSel (USB_OTG_CORE_HANDLE *pdev ,uint8_t freq); +uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) ; +void USB_OTG_StopHost (USB_OTG_CORE_HANDLE *pdev); +#endif +/********************* DEVICE APIs ********************************************/ +#ifdef USE_DEVICE_MODE +USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev); +USB_OTG_STS USB_OTG_EnableDevInt (USB_OTG_CORE_HANDLE *pdev); +uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev); +enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev); +USB_OTG_STS USB_OTG_EP0Activate (USB_OTG_CORE_HANDLE *pdev); +USB_OTG_STS USB_OTG_EPActivate (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); +USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); +USB_OTG_STS USB_OTG_EPStartXfer (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); +USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); +USB_OTG_STS USB_OTG_EPSetStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); +USB_OTG_STS USB_OTG_EPClearStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); +uint32_t USB_OTG_ReadDevAllOutEp_itr (USB_OTG_CORE_HANDLE *pdev); +uint32_t USB_OTG_ReadDevOutEP_itr (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); +uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_InitDevSpeed (USB_OTG_CORE_HANDLE *pdev , uint8_t speed); +uint8_t USBH_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev); +void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status); +uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep); +#endif +/** + * @} + */ + +#endif /* __USB_CORE_H__ */ + + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd.h index d8ae590b..6bfd8993 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd.h @@ -1,158 +1,158 @@ -/** - ****************************************************************************** - * @file usb_dcd.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Peripheral Driver Header file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __DCD_H__ -#define __DCD_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_core.h" - - -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_DCD -* @brief This file is the -* @{ -*/ - - -/** @defgroup USB_DCD_Exported_Defines -* @{ -*/ -#define USB_OTG_EP_CONTROL 0 -#define USB_OTG_EP_ISOC 1 -#define USB_OTG_EP_BULK 2 -#define USB_OTG_EP_INT 3 -#define USB_OTG_EP_MASK 3 - -/* Device Status */ -#define USB_OTG_DEFAULT 1 -#define USB_OTG_ADDRESSED 2 -#define USB_OTG_CONFIGURED 3 -#define USB_OTG_SUSPENDED 4 - -/** -* @} -*/ - - -/** @defgroup USB_DCD_Exported_Types -* @{ -*/ -/******************************************************************************** -Data structure type -********************************************************************************/ -typedef struct -{ - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bEndpointAddress; - uint8_t bmAttributes; - uint16_t wMaxPacketSize; - uint8_t bInterval; -} -EP_DESCRIPTOR , *PEP_DESCRIPTOR; - -/** -* @} -*/ - - -/** @defgroup USB_DCD_Exported_Macros -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USB_DCD_Exported_Variables -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USB_DCD_Exported_FunctionsPrototype -* @{ -*/ -/******************************************************************************** -EXPORTED FUNCTION FROM THE USB-OTG LAYER -********************************************************************************/ -void DCD_Init(USB_OTG_CORE_HANDLE *pdev , - USB_OTG_CORE_ID_TypeDef coreID); - -void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev); -void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev); -void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev, - uint8_t address); -uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev , - uint8_t ep_addr, - uint16_t ep_mps, - uint8_t ep_type); - -uint32_t DCD_EP_Close (USB_OTG_CORE_HANDLE *pdev, - uint8_t ep_addr); - - -uint32_t DCD_EP_PrepareRx ( USB_OTG_CORE_HANDLE *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint16_t buf_len); - -uint32_t DCD_EP_Tx (USB_OTG_CORE_HANDLE *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint32_t buf_len); -uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); -uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); -uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); -uint32_t DCD_Handle_ISR(USB_OTG_CORE_HANDLE *pdev); - -uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev , - uint8_t epnum); - -void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , - uint8_t epnum , - uint32_t Status); - -/** -* @} -*/ - - -#endif //__DCD_H__ - - -/** -* @} -*/ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_dcd.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Peripheral Driver Header file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __DCD_H__ +#define __DCD_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_core.h" + + +/** @addtogroup USB_OTG_DRIVER +* @{ +*/ + +/** @defgroup USB_DCD +* @brief This file is the +* @{ +*/ + + +/** @defgroup USB_DCD_Exported_Defines +* @{ +*/ +#define USB_OTG_EP_CONTROL 0 +#define USB_OTG_EP_ISOC 1 +#define USB_OTG_EP_BULK 2 +#define USB_OTG_EP_INT 3 +#define USB_OTG_EP_MASK 3 + +/* Device Status */ +#define USB_OTG_DEFAULT 1 +#define USB_OTG_ADDRESSED 2 +#define USB_OTG_CONFIGURED 3 +#define USB_OTG_SUSPENDED 4 + +/** +* @} +*/ + + +/** @defgroup USB_DCD_Exported_Types +* @{ +*/ +/******************************************************************************** +Data structure type +********************************************************************************/ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} +EP_DESCRIPTOR , *PEP_DESCRIPTOR; + +/** +* @} +*/ + + +/** @defgroup USB_DCD_Exported_Macros +* @{ +*/ +/** +* @} +*/ + +/** @defgroup USB_DCD_Exported_Variables +* @{ +*/ +/** +* @} +*/ + +/** @defgroup USB_DCD_Exported_FunctionsPrototype +* @{ +*/ +/******************************************************************************** +EXPORTED FUNCTION FROM THE USB-OTG LAYER +********************************************************************************/ +void DCD_Init(USB_OTG_CORE_HANDLE *pdev , + USB_OTG_CORE_ID_TypeDef coreID); + +void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev); +void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev); +void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev, + uint8_t address); +uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev , + uint8_t ep_addr, + uint16_t ep_mps, + uint8_t ep_type); + +uint32_t DCD_EP_Close (USB_OTG_CORE_HANDLE *pdev, + uint8_t ep_addr); + + +uint32_t DCD_EP_PrepareRx ( USB_OTG_CORE_HANDLE *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t buf_len); + +uint32_t DCD_EP_Tx (USB_OTG_CORE_HANDLE *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint32_t buf_len); +uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev, + uint8_t epnum); +uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev, + uint8_t epnum); +uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev, + uint8_t epnum); +uint32_t DCD_Handle_ISR(USB_OTG_CORE_HANDLE *pdev); + +uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev , + uint8_t epnum); + +void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , + uint8_t epnum , + uint32_t Status); + +/** +* @} +*/ + + +#endif //__DCD_H__ + + +/** +* @} +*/ + +/** +* @} +*/ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h index cb449828..9df1a417 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h @@ -1,121 +1,121 @@ -/** - ****************************************************************************** - * @file usb_dcd_int.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Peripheral Device Interface Layer - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef USB_DCD_INT_H__ -#define USB_DCD_INT_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_dcd.h" - - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_DCD_INT - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_DCD_INT_Exported_Defines - * @{ - */ - -typedef struct _USBD_DCD_INT -{ - uint8_t (* DataOutStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); - uint8_t (* DataInStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); - uint8_t (* SetupStage) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* Reset) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* Suspend) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* Resume) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* IsoINIncomplete) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* IsoOUTIncomplete) (USB_OTG_CORE_HANDLE *pdev); - - uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev); - -}USBD_DCD_INT_cb_TypeDef; - -extern USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops; -/** - * @} - */ - - -/** @defgroup USB_DCD_INT_Exported_Types - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_DCD_INT_Exported_Macros - * @{ - */ - -#define CLEAR_IN_EP_INTR(epnum,intr) \ - diepint.d32=0; \ - diepint.b.intr = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT,diepint.d32); - -#define CLEAR_OUT_EP_INTR(epnum,intr) \ - doepint.d32=0; \ - doepint.b.intr = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT,doepint.d32); - -/** - * @} - */ - -/** @defgroup USB_DCD_INT_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_DCD_INT_Exported_FunctionsPrototype - * @{ - */ - -uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev); - -/** - * @} - */ - - -#endif // USB_DCD_INT_H__ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_dcd_int.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Peripheral Device Interface Layer + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef USB_DCD_INT_H__ +#define USB_DCD_INT_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_dcd.h" + + + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_DCD_INT + * @brief This file is the + * @{ + */ + + +/** @defgroup USB_DCD_INT_Exported_Defines + * @{ + */ + +typedef struct _USBD_DCD_INT +{ + uint8_t (* DataOutStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); + uint8_t (* DataInStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); + uint8_t (* SetupStage) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* Reset) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* Suspend) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* Resume) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* IsoINIncomplete) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* IsoOUTIncomplete) (USB_OTG_CORE_HANDLE *pdev); + + uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev); + uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev); + +}USBD_DCD_INT_cb_TypeDef; + +extern USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops; +/** + * @} + */ + + +/** @defgroup USB_DCD_INT_Exported_Types + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_DCD_INT_Exported_Macros + * @{ + */ + +#define CLEAR_IN_EP_INTR(epnum,intr) \ + diepint.d32=0; \ + diepint.b.intr = 1; \ + USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT,diepint.d32); + +#define CLEAR_OUT_EP_INTR(epnum,intr) \ + doepint.d32=0; \ + doepint.b.intr = 1; \ + USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT,doepint.d32); + +/** + * @} + */ + +/** @defgroup USB_DCD_INT_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_DCD_INT_Exported_FunctionsPrototype + * @{ + */ + +uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev); + +/** + * @} + */ + + +#endif // USB_DCD_INT_H__ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_defines.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_defines.h index 87c25bab..8c23d72d 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_defines.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_defines.h @@ -1,244 +1,244 @@ -/** - ****************************************************************************** - * @file usb_defines.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header of the Core Layer - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_DEF_H__ -#define __USB_DEF_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_conf.h" - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_DEFINES - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_DEFINES_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup _CORE_DEFINES_ - * @{ - */ - -#define USB_OTG_SPEED_PARAM_HIGH 0 -#define USB_OTG_SPEED_PARAM_HIGH_IN_FULL 1 -#define USB_OTG_SPEED_PARAM_FULL 3 - -#define USB_OTG_SPEED_HIGH 0 -#define USB_OTG_SPEED_FULL 1 - -#define USB_OTG_ULPI_PHY 1 -#define USB_OTG_EMBEDDED_PHY 2 -#define USB_OTG_I2C_PHY 3 - -/** - * @} - */ - - -/** @defgroup _GLOBAL_DEFINES_ - * @{ - */ -#define GAHBCFG_TXFEMPTYLVL_EMPTY 1 -#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0 -#define GAHBCFG_GLBINT_ENABLE 1 -#define GAHBCFG_INT_DMA_BURST_SINGLE 0 -#define GAHBCFG_INT_DMA_BURST_INCR 1 -#define GAHBCFG_INT_DMA_BURST_INCR4 3 -#define GAHBCFG_INT_DMA_BURST_INCR8 5 -#define GAHBCFG_INT_DMA_BURST_INCR16 7 -#define GAHBCFG_DMAENABLE 1 -#define GAHBCFG_TXFEMPTYLVL_EMPTY 1 -#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0 -#define GRXSTS_PKTSTS_IN 2 -#define GRXSTS_PKTSTS_IN_XFER_COMP 3 -#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5 -#define GRXSTS_PKTSTS_CH_HALTED 7 -/** - * @} - */ - - -/** @defgroup _OnTheGo_DEFINES_ - * @{ - */ -#define MODE_HNP_SRP_CAPABLE 0 -#define MODE_SRP_ONLY_CAPABLE 1 -#define MODE_NO_HNP_SRP_CAPABLE 2 -#define MODE_SRP_CAPABLE_DEVICE 3 -#define MODE_NO_SRP_CAPABLE_DEVICE 4 -#define MODE_SRP_CAPABLE_HOST 5 -#define MODE_NO_SRP_CAPABLE_HOST 6 -#define A_HOST 1 -#define A_SUSPEND 2 -#define A_PERIPHERAL 3 -#define B_PERIPHERAL 4 -#define B_HOST 5 -#define DEVICE_MODE 0 -#define HOST_MODE 1 -#define OTG_MODE 2 -/** - * @} - */ - - -/** @defgroup __DEVICE_DEFINES_ - * @{ - */ -#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0 -#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1 -#define DSTS_ENUMSPD_LS_PHY_6MHZ 2 -#define DSTS_ENUMSPD_FS_PHY_48MHZ 3 - -#define DCFG_FRAME_INTERVAL_80 0 -#define DCFG_FRAME_INTERVAL_85 1 -#define DCFG_FRAME_INTERVAL_90 2 -#define DCFG_FRAME_INTERVAL_95 3 - -#define DEP0CTL_MPS_64 0 -#define DEP0CTL_MPS_32 1 -#define DEP0CTL_MPS_16 2 -#define DEP0CTL_MPS_8 3 - -#define EP_SPEED_LOW 0 -#define EP_SPEED_FULL 1 -#define EP_SPEED_HIGH 2 - -#define EP_TYPE_CTRL 0 -#define EP_TYPE_ISOC 1 -#define EP_TYPE_BULK 2 -#define EP_TYPE_INTR 3 -#define EP_TYPE_MSK 3 - -#define STS_GOUT_NAK 1 -#define STS_DATA_UPDT 2 -#define STS_XFER_COMP 3 -#define STS_SETUP_COMP 4 -#define STS_SETUP_UPDT 6 -/** - * @} - */ - - -/** @defgroup __HOST_DEFINES_ - * @{ - */ -#define HC_PID_DATA0 0 -#define HC_PID_DATA2 1 -#define HC_PID_DATA1 2 -#define HC_PID_SETUP 3 - -#define HPRT0_PRTSPD_HIGH_SPEED 0 -#define HPRT0_PRTSPD_FULL_SPEED 1 -#define HPRT0_PRTSPD_LOW_SPEED 2 - -#define HCFG_30_60_MHZ 0 -#define HCFG_48_MHZ 1 -#define HCFG_6_MHZ 2 - -#define HCCHAR_CTRL 0 -#define HCCHAR_ISOC 1 -#define HCCHAR_BULK 2 -#define HCCHAR_INTR 3 - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -/** - * @} - */ - - -/** @defgroup USB_DEFINES_Exported_Types - * @{ - */ - -typedef enum -{ - USB_OTG_HS_CORE_ID = 0, - USB_OTG_FS_CORE_ID = 1 -}USB_OTG_CORE_ID_TypeDef; -/** - * @} - */ - - -/** @defgroup USB_DEFINES_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_DEFINES_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_DEFINES_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -/** @defgroup Internal_Macro's - * @{ - */ -#define USB_OTG_READ_REG32(reg) (*(__IO uint32_t *)(reg)) -#define USB_OTG_WRITE_REG32(reg,value) (*(__IO uint32_t *)(reg) = value) -#define USB_OTG_MODIFY_REG32(reg,clear_mask,set_mask) \ - USB_OTG_WRITE_REG32(reg, (((USB_OTG_READ_REG32(reg)) & ~clear_mask) | set_mask ) ) - -/******************************************************************************** - ENUMERATION TYPE -********************************************************************************/ -enum USB_OTG_SPEED { - USB_SPEED_UNKNOWN = 0, - USB_SPEED_LOW, - USB_SPEED_FULL, - USB_SPEED_HIGH -}; - -#endif //__USB_DEFINES__H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_defines.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Header of the Core Layer + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_DEF_H__ +#define __USB_DEF_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_conf.h" + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_DEFINES + * @brief This file is the + * @{ + */ + + +/** @defgroup USB_DEFINES_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup _CORE_DEFINES_ + * @{ + */ + +#define USB_OTG_SPEED_PARAM_HIGH 0 +#define USB_OTG_SPEED_PARAM_HIGH_IN_FULL 1 +#define USB_OTG_SPEED_PARAM_FULL 3 + +#define USB_OTG_SPEED_HIGH 0 +#define USB_OTG_SPEED_FULL 1 + +#define USB_OTG_ULPI_PHY 1 +#define USB_OTG_EMBEDDED_PHY 2 +#define USB_OTG_I2C_PHY 3 + +/** + * @} + */ + + +/** @defgroup _GLOBAL_DEFINES_ + * @{ + */ +#define GAHBCFG_TXFEMPTYLVL_EMPTY 1 +#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0 +#define GAHBCFG_GLBINT_ENABLE 1 +#define GAHBCFG_INT_DMA_BURST_SINGLE 0 +#define GAHBCFG_INT_DMA_BURST_INCR 1 +#define GAHBCFG_INT_DMA_BURST_INCR4 3 +#define GAHBCFG_INT_DMA_BURST_INCR8 5 +#define GAHBCFG_INT_DMA_BURST_INCR16 7 +#define GAHBCFG_DMAENABLE 1 +#define GAHBCFG_TXFEMPTYLVL_EMPTY 1 +#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0 +#define GRXSTS_PKTSTS_IN 2 +#define GRXSTS_PKTSTS_IN_XFER_COMP 3 +#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5 +#define GRXSTS_PKTSTS_CH_HALTED 7 +/** + * @} + */ + + +/** @defgroup _OnTheGo_DEFINES_ + * @{ + */ +#define MODE_HNP_SRP_CAPABLE 0 +#define MODE_SRP_ONLY_CAPABLE 1 +#define MODE_NO_HNP_SRP_CAPABLE 2 +#define MODE_SRP_CAPABLE_DEVICE 3 +#define MODE_NO_SRP_CAPABLE_DEVICE 4 +#define MODE_SRP_CAPABLE_HOST 5 +#define MODE_NO_SRP_CAPABLE_HOST 6 +#define A_HOST 1 +#define A_SUSPEND 2 +#define A_PERIPHERAL 3 +#define B_PERIPHERAL 4 +#define B_HOST 5 +#define DEVICE_MODE 0 +#define HOST_MODE 1 +#define OTG_MODE 2 +/** + * @} + */ + + +/** @defgroup __DEVICE_DEFINES_ + * @{ + */ +#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0 +#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1 +#define DSTS_ENUMSPD_LS_PHY_6MHZ 2 +#define DSTS_ENUMSPD_FS_PHY_48MHZ 3 + +#define DCFG_FRAME_INTERVAL_80 0 +#define DCFG_FRAME_INTERVAL_85 1 +#define DCFG_FRAME_INTERVAL_90 2 +#define DCFG_FRAME_INTERVAL_95 3 + +#define DEP0CTL_MPS_64 0 +#define DEP0CTL_MPS_32 1 +#define DEP0CTL_MPS_16 2 +#define DEP0CTL_MPS_8 3 + +#define EP_SPEED_LOW 0 +#define EP_SPEED_FULL 1 +#define EP_SPEED_HIGH 2 + +#define EP_TYPE_CTRL 0 +#define EP_TYPE_ISOC 1 +#define EP_TYPE_BULK 2 +#define EP_TYPE_INTR 3 +#define EP_TYPE_MSK 3 + +#define STS_GOUT_NAK 1 +#define STS_DATA_UPDT 2 +#define STS_XFER_COMP 3 +#define STS_SETUP_COMP 4 +#define STS_SETUP_UPDT 6 +/** + * @} + */ + + +/** @defgroup __HOST_DEFINES_ + * @{ + */ +#define HC_PID_DATA0 0 +#define HC_PID_DATA2 1 +#define HC_PID_DATA1 2 +#define HC_PID_SETUP 3 + +#define HPRT0_PRTSPD_HIGH_SPEED 0 +#define HPRT0_PRTSPD_FULL_SPEED 1 +#define HPRT0_PRTSPD_LOW_SPEED 2 + +#define HCFG_30_60_MHZ 0 +#define HCFG_48_MHZ 1 +#define HCFG_6_MHZ 2 + +#define HCCHAR_CTRL 0 +#define HCCHAR_ISOC 1 +#define HCCHAR_BULK 2 +#define HCCHAR_INTR 3 + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +/** + * @} + */ + + +/** @defgroup USB_DEFINES_Exported_Types + * @{ + */ + +typedef enum +{ + USB_OTG_HS_CORE_ID = 0, + USB_OTG_FS_CORE_ID = 1 +}USB_OTG_CORE_ID_TypeDef; +/** + * @} + */ + + +/** @defgroup USB_DEFINES_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_DEFINES_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_DEFINES_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + + +/** @defgroup Internal_Macro's + * @{ + */ +#define USB_OTG_READ_REG32(reg) (*(__IO uint32_t *)(reg)) +#define USB_OTG_WRITE_REG32(reg,value) (*(__IO uint32_t *)(reg) = value) +#define USB_OTG_MODIFY_REG32(reg,clear_mask,set_mask) \ + USB_OTG_WRITE_REG32(reg, (((USB_OTG_READ_REG32(reg)) & ~clear_mask) | set_mask ) ) + +/******************************************************************************** + ENUMERATION TYPE +********************************************************************************/ +enum USB_OTG_SPEED { + USB_SPEED_UNKNOWN = 0, + USB_SPEED_LOW, + USB_SPEED_FULL, + USB_SPEED_HIGH +}; + +#endif //__USB_DEFINES__H__ + + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd.h index db976779..15e8ab16 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd.h @@ -1,102 +1,102 @@ -/** - ****************************************************************************** - * @file usb_hcd.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Host layer Header file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_HCD_H__ -#define __USB_HCD_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_regs.h" -#include "usb_core.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_HCD - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_HCD_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_HCD_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_HCD_Exported_FunctionsPrototype - * @{ - */ -uint32_t HCD_Init (USB_OTG_CORE_HANDLE *pdev , - USB_OTG_CORE_ID_TypeDef coreID); -uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev , - uint8_t hc_num); -uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev , - uint8_t hc_num) ; -uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev); -uint32_t HCD_ResetPort (USB_OTG_CORE_HANDLE *pdev); -uint32_t HCD_IsDeviceConnected (USB_OTG_CORE_HANDLE *pdev); -uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev) ; -URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num); -uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num); -HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num) ; -/** - * @} - */ - -#endif //__USB_HCD_H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_hcd.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Host layer Header file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_HCD_H__ +#define __USB_HCD_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_regs.h" +#include "usb_core.h" + + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_HCD + * @brief This file is the + * @{ + */ + + +/** @defgroup USB_HCD_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_HCD_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_HCD_Exported_FunctionsPrototype + * @{ + */ +uint32_t HCD_Init (USB_OTG_CORE_HANDLE *pdev , + USB_OTG_CORE_ID_TypeDef coreID); +uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev , + uint8_t hc_num); +uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev , + uint8_t hc_num) ; +uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev); +uint32_t HCD_ResetPort (USB_OTG_CORE_HANDLE *pdev); +uint32_t HCD_IsDeviceConnected (USB_OTG_CORE_HANDLE *pdev); +uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev) ; +URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num); +uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num); +HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num) ; +/** + * @} + */ + +#endif //__USB_HCD_H__ + + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h index a405e366..c95c59f8 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h @@ -1,126 +1,126 @@ -/** - ****************************************************************************** - * @file usb_hcd_int.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Peripheral Device Interface Layer - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __HCD_INT_H__ -#define __HCD_INT_H__ - - -/* Includes ------------------------------------------------------------------*/ -#include "usb_hcd.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_HCD_INT - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_HCD_INT_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Exported_Macros - * @{ - */ - -#define CLEAR_HC_INT(HC_REGS, intr) \ - {\ - USB_OTG_HCINTn_TypeDef hcint_clear; \ - hcint_clear.d32 = 0; \ - hcint_clear.b.intr = 1; \ - USB_OTG_WRITE_REG32(&((HC_REGS)->HCINT), hcint_clear.d32);\ - }\ - -#define MASK_HOST_INT_CHH(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.chhltd = 0; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -#define UNMASK_HOST_INT_CHH(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.chhltd = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -#define MASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.ack = 0; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -#define UNMASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.ack = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -/** - * @} - */ - -/** @defgroup USB_HCD_INT_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_HCD_INT_Exported_FunctionsPrototype - * @{ - */ -/* Callbacks handler */ -void ConnectCallback_Handler(USB_OTG_CORE_HANDLE *pdev); -void Disconnect_Callback_Handler(USB_OTG_CORE_HANDLE *pdev); -void Overcurrent_Callback_Handler(USB_OTG_CORE_HANDLE *pdev); -uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev); - -/** - * @} - */ - - - -#endif //__HCD_INT_H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_hcd_int.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Peripheral Device Interface Layer + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __HCD_INT_H__ +#define __HCD_INT_H__ + + +/* Includes ------------------------------------------------------------------*/ +#include "usb_hcd.h" + + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_HCD_INT + * @brief This file is the + * @{ + */ + + +/** @defgroup USB_HCD_INT_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_INT_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_INT_Exported_Macros + * @{ + */ + +#define CLEAR_HC_INT(HC_REGS, intr) \ + {\ + USB_OTG_HCINTn_TypeDef hcint_clear; \ + hcint_clear.d32 = 0; \ + hcint_clear.b.intr = 1; \ + USB_OTG_WRITE_REG32(&((HC_REGS)->HCINT), hcint_clear.d32);\ + }\ + +#define MASK_HOST_INT_CHH(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ + GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ + GINTMSK.b.chhltd = 0; \ + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} + +#define UNMASK_HOST_INT_CHH(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ + GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ + GINTMSK.b.chhltd = 1; \ + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} + +#define MASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ + GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ + GINTMSK.b.ack = 0; \ + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} + +#define UNMASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ + GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ + GINTMSK.b.ack = 1; \ + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} + +/** + * @} + */ + +/** @defgroup USB_HCD_INT_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_HCD_INT_Exported_FunctionsPrototype + * @{ + */ +/* Callbacks handler */ +void ConnectCallback_Handler(USB_OTG_CORE_HANDLE *pdev); +void Disconnect_Callback_Handler(USB_OTG_CORE_HANDLE *pdev); +void Overcurrent_Callback_Handler(USB_OTG_CORE_HANDLE *pdev); +uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev); + +/** + * @} + */ + + + +#endif //__HCD_INT_H__ + + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_otg.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_otg.h index ffbd34ef..54d61b82 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_otg.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_otg.h @@ -1,94 +1,94 @@ -/** - ****************************************************************************** - * @file usb_otg.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief OTG Core Header - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_OTG__ -#define __USB_OTG__ - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_OTG - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_OTG_Exported_Defines - * @{ - */ - - -void USB_OTG_InitiateSRP(void); -void USB_OTG_InitiateHNP(uint8_t state , uint8_t mode); -void USB_OTG_Switchback (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev); - -uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev); -/** - * @} - */ - - -/** @defgroup USB_OTG_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_OTG_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_OTG_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_OTG_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USB_OTG__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_otg.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief OTG Core Header + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_OTG__ +#define __USB_OTG__ + + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_OTG + * @brief This file is the + * @{ + */ + + +/** @defgroup USB_OTG_Exported_Defines + * @{ + */ + + +void USB_OTG_InitiateSRP(void); +void USB_OTG_InitiateHNP(uint8_t state , uint8_t mode); +void USB_OTG_Switchback (USB_OTG_CORE_HANDLE *pdev); +uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev); + +uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev); +/** + * @} + */ + + +/** @defgroup USB_OTG_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_OTG_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_OTG_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_OTG_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + + +#endif //__USB_OTG__ + + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_regs.h b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_regs.h index d12e05d7..cd71ddfa 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_regs.h +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/inc/usb_regs.h @@ -1,1206 +1,1206 @@ -/** - ****************************************************************************** - * @file usb_regs.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief hardware registers - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_OTG_REGS_H__ -#define __USB_OTG_REGS_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_conf.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_REGS - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_REGS_Exported_Defines - * @{ - */ - -#define USB_OTG_HS_BASE_ADDR 0x40040000 -#define USB_OTG_FS_BASE_ADDR 0x50000000 - -#define USB_OTG_CORE_GLOBAL_REGS_OFFSET 0x000 -#define USB_OTG_DEV_GLOBAL_REG_OFFSET 0x800 -#define USB_OTG_DEV_IN_EP_REG_OFFSET 0x900 -#define USB_OTG_EP_REG_OFFSET 0x20 -#define USB_OTG_DEV_OUT_EP_REG_OFFSET 0xB00 -#define USB_OTG_HOST_GLOBAL_REG_OFFSET 0x400 -#define USB_OTG_HOST_PORT_REGS_OFFSET 0x440 -#define USB_OTG_HOST_CHAN_REGS_OFFSET 0x500 -#define USB_OTG_CHAN_REGS_OFFSET 0x20 -#define USB_OTG_PCGCCTL_OFFSET 0xE00 -#define USB_OTG_DATA_FIFO_OFFSET 0x1000 -#define USB_OTG_DATA_FIFO_SIZE 0x1000 - - -#define USB_OTG_MAX_TX_FIFOS 15 - -#define USB_OTG_HS_MAX_PACKET_SIZE 512 -#define USB_OTG_FS_MAX_PACKET_SIZE 64 -#define USB_OTG_MAX_EP0_SIZE 64 -/** - * @} - */ - -/** @defgroup USB_REGS_Exported_Types - * @{ - */ - -/** @defgroup __USB_OTG_Core_register - * @{ - */ -typedef struct _USB_OTG_GREGS //000h -{ - __IO uint32_t GOTGCTL; /* USB_OTG Control and Status Register 000h*/ - __IO uint32_t GOTGINT; /* USB_OTG Interrupt Register 004h*/ - __IO uint32_t GAHBCFG; /* Core AHB Configuration Register 008h*/ - __IO uint32_t GUSBCFG; /* Core USB Configuration Register 00Ch*/ - __IO uint32_t GRSTCTL; /* Core Reset Register 010h*/ - __IO uint32_t GINTSTS; /* Core Interrupt Register 014h*/ - __IO uint32_t GINTMSK; /* Core Interrupt Mask Register 018h*/ - __IO uint32_t GRXSTSR; /* Receive Sts Q Read Register 01Ch*/ - __IO uint32_t GRXSTSP; /* Receive Sts Q Read & POP Register 020h*/ - __IO uint32_t GRXFSIZ; /* Receive FIFO Size Register 024h*/ - __IO uint32_t DIEPTXF0_HNPTXFSIZ; /* EP0 / Non Periodic Tx FIFO Size Register 028h*/ - __IO uint32_t HNPTXSTS; /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/ - __IO uint32_t GI2CCTL; /* I2C Access Register 030h*/ - uint32_t Reserved34; /* PHY Vendor Control Register 034h*/ - __IO uint32_t GCCFG; /* General Purpose IO Register 038h*/ - __IO uint32_t CID; /* User ID Register 03Ch*/ - uint32_t Reserved40[48]; /* Reserved 040h-0FFh*/ - __IO uint32_t HPTXFSIZ; /* Host Periodic Tx FIFO Size Reg 100h*/ - __IO uint32_t DIEPTXF[USB_OTG_MAX_TX_FIFOS];/* dev Periodic Transmit FIFO */ -} -USB_OTG_GREGS; -/** - * @} - */ - - -/** @defgroup __device_Registers - * @{ - */ -typedef struct _USB_OTG_DREGS // 800h -{ - __IO uint32_t DCFG; /* dev Configuration Register 800h*/ - __IO uint32_t DCTL; /* dev Control Register 804h*/ - __IO uint32_t DSTS; /* dev Status Register (RO) 808h*/ - uint32_t Reserved0C; /* Reserved 80Ch*/ - __IO uint32_t DIEPMSK; /* dev IN Endpoint Mask 810h*/ - __IO uint32_t DOEPMSK; /* dev OUT Endpoint Mask 814h*/ - __IO uint32_t DAINT; /* dev All Endpoints Itr Reg 818h*/ - __IO uint32_t DAINTMSK; /* dev All Endpoints Itr Mask 81Ch*/ - uint32_t Reserved20; /* Reserved 820h*/ - uint32_t Reserved9; /* Reserved 824h*/ - __IO uint32_t DVBUSDIS; /* dev VBUS discharge Register 828h*/ - __IO uint32_t DVBUSPULSE; /* dev VBUS Pulse Register 82Ch*/ - __IO uint32_t DTHRCTL; /* dev thr 830h*/ - __IO uint32_t DIEPEMPMSK; /* dev empty msk 834h*/ - __IO uint32_t DEACHINT; /* dedicated EP interrupt 838h*/ - __IO uint32_t DEACHMSK; /* dedicated EP msk 83Ch*/ - uint32_t Reserved40; /* dedicated EP mask 840h*/ - __IO uint32_t DINEP1MSK; /* dedicated EP mask 844h*/ - uint32_t Reserved44[15]; /* Reserved 844-87Ch*/ - __IO uint32_t DOUTEP1MSK; /* dedicated EP msk 884h*/ -} -USB_OTG_DREGS; -/** - * @} - */ - - -/** @defgroup __IN_Endpoint-Specific_Register - * @{ - */ -typedef struct _USB_OTG_INEPREGS -{ - __IO uint32_t DIEPCTL; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/ - uint32_t Reserved04; /* Reserved 900h + (ep_num * 20h) + 04h*/ - __IO uint32_t DIEPINT; /* dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /* Reserved 900h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DIEPTSIZ; /* IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h*/ - __IO uint32_t DIEPDMA; /* IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h*/ - __IO uint32_t DTXFSTS;/*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/ - uint32_t Reserved18; /* Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/ -} -USB_OTG_INEPREGS; -/** - * @} - */ - - -/** @defgroup __OUT_Endpoint-Specific_Registers - * @{ - */ -typedef struct _USB_OTG_OUTEPREGS -{ - __IO uint32_t DOEPCTL; /* dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ - __IO uint32_t DOUTEPFRM; /* dev OUT Endpoint Frame number B00h + (ep_num * 20h) + 04h*/ - __IO uint32_t DOEPINT; /* dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /* Reserved B00h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DOEPTSIZ; /* dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ - __IO uint32_t DOEPDMA; /* dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/ - uint32_t Reserved18[2]; /* Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/ -} -USB_OTG_OUTEPREGS; -/** - * @} - */ - - -/** @defgroup __Host_Mode_Register_Structures - * @{ - */ -typedef struct _USB_OTG_HREGS -{ - __IO uint32_t HCFG; /* Host Configuration Register 400h*/ - __IO uint32_t HFIR; /* Host Frame Interval Register 404h*/ - __IO uint32_t HFNUM; /* Host Frame Nbr/Frame Remaining 408h*/ - uint32_t Reserved40C; /* Reserved 40Ch*/ - __IO uint32_t HPTXSTS; /* Host Periodic Tx FIFO/ Queue Status 410h*/ - __IO uint32_t HAINT; /* Host All Channels Interrupt Register 414h*/ - __IO uint32_t HAINTMSK; /* Host All Channels Interrupt Mask 418h*/ -} -USB_OTG_HREGS; -/** - * @} - */ - - -/** @defgroup __Host_Channel_Specific_Registers - * @{ - */ -typedef struct _USB_OTG_HC_REGS -{ - __IO uint32_t HCCHAR; - __IO uint32_t HCSPLT; - __IO uint32_t HCINT; - __IO uint32_t HCGINTMSK; - __IO uint32_t HCTSIZ; - __IO uint32_t HCDMA; - uint32_t Reserved[2]; -} -USB_OTG_HC_REGS; -/** - * @} - */ - - -/** @defgroup __otg_Core_registers - * @{ - */ -typedef struct USB_OTG_core_regs //000h -{ - USB_OTG_GREGS *GREGS; - USB_OTG_DREGS *DREGS; - USB_OTG_HREGS *HREGS; - USB_OTG_INEPREGS *INEP_REGS[USB_OTG_MAX_TX_FIFOS]; - USB_OTG_OUTEPREGS *OUTEP_REGS[USB_OTG_MAX_TX_FIFOS]; - USB_OTG_HC_REGS *HC_REGS[USB_OTG_MAX_TX_FIFOS]; - __IO uint32_t *HPRT0; - __IO uint32_t *DFIFO[USB_OTG_MAX_TX_FIFOS]; - __IO uint32_t *PCGCCTL; -} -USB_OTG_CORE_REGS , *PUSB_OTG_CORE_REGS; -typedef union _USB_OTG_OTGCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t sesreqscs : - 1; -uint32_t sesreq : - 1; -uint32_t Reserved2_7 : - 6; -uint32_t hstnegscs : - 1; -uint32_t hnpreq : - 1; -uint32_t hstsethnpen : - 1; -uint32_t devhnpen : - 1; -uint32_t Reserved12_15 : - 4; -uint32_t conidsts : - 1; -uint32_t Reserved17 : - 1; -uint32_t asesvld : - 1; -uint32_t bsesvld : - 1; -uint32_t currmod : - 1; -uint32_t Reserved21_31 : - 11; - } - b; -} USB_OTG_OTGCTL_TypeDef ; -typedef union _USB_OTG_GOTGINT_TypeDef -{ - uint32_t d32; - struct - { -uint32_t Reserved0_1 : - 2; -uint32_t sesenddet : - 1; -uint32_t Reserved3_7 : - 5; -uint32_t sesreqsucstschng : - 1; -uint32_t hstnegsucstschng : - 1; -uint32_t reserver10_16 : - 7; -uint32_t hstnegdet : - 1; -uint32_t adevtoutchng : - 1; -uint32_t debdone : - 1; -uint32_t Reserved31_20 : - 12; - } - b; -} USB_OTG_GOTGINT_TypeDef ; -typedef union _USB_OTG_GAHBCFG_TypeDef -{ - uint32_t d32; - struct - { -uint32_t glblintrmsk : - 1; -uint32_t hburstlen : - 4; -uint32_t dmaenable : - 1; -uint32_t Reserved : - 1; -uint32_t nptxfemplvl_txfemplvl : - 1; -uint32_t ptxfemplvl : - 1; -uint32_t Reserved9_31 : - 23; - } - b; -} USB_OTG_GAHBCFG_TypeDef ; -typedef union _USB_OTG_GUSBCFG_TypeDef -{ - uint32_t d32; - struct - { -uint32_t toutcal : - 3; -uint32_t phyif : - 1; -uint32_t ulpi_utmi_sel : - 1; -uint32_t fsintf : - 1; -uint32_t physel : - 1; -uint32_t ddrsel : - 1; -uint32_t srpcap : - 1; -uint32_t hnpcap : - 1; -uint32_t usbtrdtim : - 4; -uint32_t nptxfrwnden : - 1; -uint32_t phylpwrclksel : - 1; -uint32_t otgutmifssel : - 1; -uint32_t ulpi_fsls : - 1; -uint32_t ulpi_auto_res : - 1; -uint32_t ulpi_clk_sus_m : - 1; -uint32_t ulpi_ext_vbus_drv : - 1; -uint32_t ulpi_int_vbus_indicator : - 1; -uint32_t term_sel_dl_pulse : - 1; -uint32_t Reserved : - 6; -uint32_t force_host : - 1; -uint32_t force_dev : - 1; -uint32_t corrupt_tx : - 1; - } - b; -} USB_OTG_GUSBCFG_TypeDef ; -typedef union _USB_OTG_GRSTCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t csftrst : - 1; -uint32_t hsftrst : - 1; -uint32_t hstfrm : - 1; -uint32_t intknqflsh : - 1; -uint32_t rxfflsh : - 1; -uint32_t txfflsh : - 1; -uint32_t txfnum : - 5; -uint32_t Reserved11_29 : - 19; -uint32_t dmareq : - 1; -uint32_t ahbidle : - 1; - } - b; -} USB_OTG_GRSTCTL_TypeDef ; -typedef union _USB_OTG_GINTMSK_TypeDef -{ - uint32_t d32; - struct - { -uint32_t Reserved0 : - 1; -uint32_t modemismatch : - 1; -uint32_t otgintr : - 1; -uint32_t sofintr : - 1; -uint32_t rxstsqlvl : - 1; -uint32_t nptxfempty : - 1; -uint32_t ginnakeff : - 1; -uint32_t goutnakeff : - 1; -uint32_t Reserved8 : - 1; -uint32_t i2cintr : - 1; -uint32_t erlysuspend : - 1; -uint32_t usbsuspend : - 1; -uint32_t usbreset : - 1; -uint32_t enumdone : - 1; -uint32_t isooutdrop : - 1; -uint32_t eopframe : - 1; -uint32_t Reserved16 : - 1; -uint32_t epmismatch : - 1; -uint32_t inepintr : - 1; -uint32_t outepintr : - 1; -uint32_t incomplisoin : - 1; -uint32_t incomplisoout : - 1; -uint32_t Reserved22_23 : - 2; -uint32_t portintr : - 1; -uint32_t hcintr : - 1; -uint32_t ptxfempty : - 1; -uint32_t Reserved27 : - 1; -uint32_t conidstschng : - 1; -uint32_t disconnect : - 1; -uint32_t sessreqintr : - 1; -uint32_t wkupintr : - 1; - } - b; -} USB_OTG_GINTMSK_TypeDef ; -typedef union _USB_OTG_GINTSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t curmode : - 1; -uint32_t modemismatch : - 1; -uint32_t otgintr : - 1; -uint32_t sofintr : - 1; -uint32_t rxstsqlvl : - 1; -uint32_t nptxfempty : - 1; -uint32_t ginnakeff : - 1; -uint32_t goutnakeff : - 1; -uint32_t Reserved8 : - 1; -uint32_t i2cintr : - 1; -uint32_t erlysuspend : - 1; -uint32_t usbsuspend : - 1; -uint32_t usbreset : - 1; -uint32_t enumdone : - 1; -uint32_t isooutdrop : - 1; -uint32_t eopframe : - 1; -uint32_t intimerrx : - 1; -uint32_t epmismatch : - 1; -uint32_t inepint: - 1; -uint32_t outepintr : - 1; -uint32_t incomplisoin : - 1; -uint32_t incomplisoout : - 1; -uint32_t Reserved22_23 : - 2; -uint32_t portintr : - 1; -uint32_t hcintr : - 1; -uint32_t ptxfempty : - 1; -uint32_t Reserved27 : - 1; -uint32_t conidstschng : - 1; -uint32_t disconnect : - 1; -uint32_t sessreqintr : - 1; -uint32_t wkupintr : - 1; - } - b; -} USB_OTG_GINTSTS_TypeDef ; -typedef union _USB_OTG_DRXSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t epnum : - 4; -uint32_t bcnt : - 11; -uint32_t dpid : - 2; -uint32_t pktsts : - 4; -uint32_t fn : - 4; -uint32_t Reserved : - 7; - } - b; -} USB_OTG_DRXSTS_TypeDef ; -typedef union _USB_OTG_GRXSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t chnum : - 4; -uint32_t bcnt : - 11; -uint32_t dpid : - 2; -uint32_t pktsts : - 4; -uint32_t Reserved : - 11; - } - b; -} USB_OTG_GRXFSTS_TypeDef ; -typedef union _USB_OTG_FSIZ_TypeDef -{ - uint32_t d32; - struct - { -uint32_t startaddr : - 16; -uint32_t depth : - 16; - } - b; -} USB_OTG_FSIZ_TypeDef ; -typedef union _USB_OTG_HNPTXSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t nptxfspcavail : - 16; -uint32_t nptxqspcavail : - 8; -uint32_t nptxqtop_terminate : - 1; -uint32_t nptxqtop_timer : - 2; -uint32_t nptxqtop : - 2; -uint32_t chnum : - 2; -uint32_t Reserved : - 1; - } - b; -} USB_OTG_HNPTXSTS_TypeDef ; -typedef union _USB_OTG_DTXFSTSn_TypeDef -{ - uint32_t d32; - struct - { -uint32_t txfspcavail : - 16; -uint32_t Reserved : - 16; - } - b; -} USB_OTG_DTXFSTSn_TypeDef ; -typedef union _USB_OTG_GI2CCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t rwdata : - 8; -uint32_t regaddr : - 8; -uint32_t addr : - 7; -uint32_t i2cen : - 1; -uint32_t ack : - 1; -uint32_t i2csuspctl : - 1; -uint32_t i2cdevaddr : - 2; -uint32_t dat_se0: - 1; -uint32_t Reserved : - 1; -uint32_t rw : - 1; -uint32_t bsydne : - 1; - } - b; -} USB_OTG_GI2CCTL_TypeDef ; -typedef union _USB_OTG_GCCFG_TypeDef -{ - uint32_t d32; - struct - { -uint32_t Reserved_in : - 16; -uint32_t pwdn : - 1; -uint32_t i2cifen : - 1; -uint32_t vbussensingA : - 1; -uint32_t vbussensingB : - 1; -uint32_t sofouten : - 1; -uint32_t disablevbussensing : - 1; -uint32_t Reserved_out : - 10; - } - b; -} USB_OTG_GCCFG_TypeDef ; - -typedef union _USB_OTG_DCFG_TypeDef -{ - uint32_t d32; - struct - { -uint32_t devspd : - 2; -uint32_t nzstsouthshk : - 1; -uint32_t Reserved3 : - 1; -uint32_t devaddr : - 7; -uint32_t perfrint : - 2; -uint32_t Reserved13_17 : - 5; -uint32_t epmscnt : - 4; - } - b; -} USB_OTG_DCFG_TypeDef ; -typedef union _USB_OTG_DCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t rmtwkupsig : - 1; -uint32_t sftdiscon : - 1; -uint32_t gnpinnaksts : - 1; -uint32_t goutnaksts : - 1; -uint32_t tstctl : - 3; -uint32_t sgnpinnak : - 1; -uint32_t cgnpinnak : - 1; -uint32_t sgoutnak : - 1; -uint32_t cgoutnak : - 1; -uint32_t Reserved : - 21; - } - b; -} USB_OTG_DCTL_TypeDef ; -typedef union _USB_OTG_DSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t suspsts : - 1; -uint32_t enumspd : - 2; -uint32_t errticerr : - 1; -uint32_t Reserved4_7: - 4; -uint32_t soffn : - 14; -uint32_t Reserved22_31 : - 10; - } - b; -} USB_OTG_DSTS_TypeDef ; -typedef union _USB_OTG_DIEPINTn_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfercompl : - 1; -uint32_t epdisabled : - 1; -uint32_t ahberr : - 1; -uint32_t timeout : - 1; -uint32_t intktxfemp : - 1; -uint32_t intknepmis : - 1; -uint32_t inepnakeff : - 1; -uint32_t emptyintr : - 1; -uint32_t txfifoundrn : - 1; -uint32_t Reserved08_31 : - 23; - } - b; -} USB_OTG_DIEPINTn_TypeDef ; -typedef union _USB_OTG_DIEPINTn_TypeDef USB_OTG_DIEPMSK_TypeDef ; -typedef union _USB_OTG_DOEPINTn_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfercompl : - 1; -uint32_t epdisabled : - 1; -uint32_t ahberr : - 1; -uint32_t setup : - 1; -uint32_t Reserved04_31 : - 28; - } - b; -} USB_OTG_DOEPINTn_TypeDef ; -typedef union _USB_OTG_DOEPINTn_TypeDef USB_OTG_DOEPMSK_TypeDef ; - -typedef union _USB_OTG_DAINT_TypeDef -{ - uint32_t d32; - struct - { -uint32_t in : - 16; -uint32_t out : - 16; - } - ep; -} USB_OTG_DAINT_TypeDef ; - -typedef union _USB_OTG_DTHRCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t non_iso_thr_en : - 1; -uint32_t iso_thr_en : - 1; -uint32_t tx_thr_len : - 9; -uint32_t Reserved11_15 : - 5; -uint32_t rx_thr_en : - 1; -uint32_t rx_thr_len : - 9; -uint32_t Reserved26_31 : - 6; - } - b; -} USB_OTG_DTHRCTL_TypeDef ; -typedef union _USB_OTG_DEPCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t mps : - 11; -uint32_t reserved : - 4; -uint32_t usbactep : - 1; -uint32_t dpid : - 1; -uint32_t naksts : - 1; -uint32_t eptype : - 2; -uint32_t snp : - 1; -uint32_t stall : - 1; -uint32_t txfnum : - 4; -uint32_t cnak : - 1; -uint32_t snak : - 1; -uint32_t setd0pid : - 1; -uint32_t setd1pid : - 1; -uint32_t epdis : - 1; -uint32_t epena : - 1; - } - b; -} USB_OTG_DEPCTL_TypeDef ; -typedef union _USB_OTG_DEPXFRSIZ_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfersize : - 19; -uint32_t pktcnt : - 10; -uint32_t mc : - 2; -uint32_t Reserved : - 1; - } - b; -} USB_OTG_DEPXFRSIZ_TypeDef ; -typedef union _USB_OTG_DEP0XFRSIZ_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfersize : - 7; -uint32_t Reserved7_18 : - 12; -uint32_t pktcnt : - 2; -uint32_t Reserved20_28 : - 9; -uint32_t supcnt : - 2; - uint32_t Reserved31; - } - b; -} USB_OTG_DEP0XFRSIZ_TypeDef ; -typedef union _USB_OTG_HCFG_TypeDef -{ - uint32_t d32; - struct - { -uint32_t fslspclksel : - 2; -uint32_t fslssupp : - 1; - } - b; -} USB_OTG_HCFG_TypeDef ; -typedef union _USB_OTG_HFRMINTRVL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t frint : - 16; -uint32_t Reserved : - 16; - } - b; -} USB_OTG_HFRMINTRVL_TypeDef ; - -typedef union _USB_OTG_HFNUM_TypeDef -{ - uint32_t d32; - struct - { -uint32_t frnum : - 16; -uint32_t frrem : - 16; - } - b; -} USB_OTG_HFNUM_TypeDef ; -typedef union _USB_OTG_HPTXSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t ptxfspcavail : - 16; -uint32_t ptxqspcavail : - 8; -uint32_t ptxqtop_terminate : - 1; -uint32_t ptxqtop_timer : - 2; -uint32_t ptxqtop : - 2; -uint32_t chnum : - 2; -uint32_t ptxqtop_odd : - 1; - } - b; -} USB_OTG_HPTXSTS_TypeDef ; -typedef union _USB_OTG_HPRT0_TypeDef -{ - uint32_t d32; - struct - { -uint32_t prtconnsts : - 1; -uint32_t prtconndet : - 1; -uint32_t prtena : - 1; -uint32_t prtenchng : - 1; -uint32_t prtovrcurract : - 1; -uint32_t prtovrcurrchng : - 1; -uint32_t prtres : - 1; -uint32_t prtsusp : - 1; -uint32_t prtrst : - 1; -uint32_t Reserved9 : - 1; -uint32_t prtlnsts : - 2; -uint32_t prtpwr : - 1; -uint32_t prttstctl : - 4; -uint32_t prtspd : - 2; -uint32_t Reserved19_31 : - 13; - } - b; -} USB_OTG_HPRT0_TypeDef ; -typedef union _USB_OTG_HAINT_TypeDef -{ - uint32_t d32; - struct - { -uint32_t chint : - 16; -uint32_t Reserved : - 16; - } - b; -} USB_OTG_HAINT_TypeDef ; -typedef union _USB_OTG_HAINTMSK_TypeDef -{ - uint32_t d32; - struct - { -uint32_t chint : - 16; -uint32_t Reserved : - 16; - } - b; -} USB_OTG_HAINTMSK_TypeDef ; -typedef union _USB_OTG_HCCHAR_TypeDef -{ - uint32_t d32; - struct - { -uint32_t mps : - 11; -uint32_t epnum : - 4; -uint32_t epdir : - 1; -uint32_t Reserved : - 1; -uint32_t lspddev : - 1; -uint32_t eptype : - 2; -uint32_t multicnt : - 2; -uint32_t devaddr : - 7; -uint32_t oddfrm : - 1; -uint32_t chdis : - 1; -uint32_t chen : - 1; - } - b; -} USB_OTG_HCCHAR_TypeDef ; -typedef union _USB_OTG_HCSPLT_TypeDef -{ - uint32_t d32; - struct - { -uint32_t prtaddr : - 7; -uint32_t hubaddr : - 7; -uint32_t xactpos : - 2; -uint32_t compsplt : - 1; -uint32_t Reserved : - 14; -uint32_t spltena : - 1; - } - b; -} USB_OTG_HCSPLT_TypeDef ; -typedef union _USB_OTG_HCINTn_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfercompl : - 1; -uint32_t chhltd : - 1; -uint32_t ahberr : - 1; -uint32_t stall : - 1; -uint32_t nak : - 1; -uint32_t ack : - 1; -uint32_t nyet : - 1; -uint32_t xacterr : - 1; -uint32_t bblerr : - 1; -uint32_t frmovrun : - 1; -uint32_t datatglerr : - 1; -uint32_t Reserved : - 21; - } - b; -} USB_OTG_HCINTn_TypeDef ; -typedef union _USB_OTG_HCTSIZn_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfersize : - 19; -uint32_t pktcnt : - 10; -uint32_t pid : - 2; -uint32_t dopng : - 1; - } - b; -} USB_OTG_HCTSIZn_TypeDef ; -typedef union _USB_OTG_HCGINTMSK_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfercompl : - 1; -uint32_t chhltd : - 1; -uint32_t ahberr : - 1; -uint32_t stall : - 1; -uint32_t nak : - 1; -uint32_t ack : - 1; -uint32_t nyet : - 1; -uint32_t xacterr : - 1; -uint32_t bblerr : - 1; -uint32_t frmovrun : - 1; -uint32_t datatglerr : - 1; -uint32_t Reserved : - 21; - } - b; -} USB_OTG_HCGINTMSK_TypeDef ; -typedef union _USB_OTG_PCGCCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t stoppclk : - 1; -uint32_t gatehclk : - 1; -uint32_t Reserved : - 30; - } - b; -} USB_OTG_PCGCCTL_TypeDef ; - -/** - * @} - */ - - -/** @defgroup USB_REGS_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_REGS_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_REGS_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USB_OTG_REGS_H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_regs.h + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief hardware registers + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_OTG_REGS_H__ +#define __USB_OTG_REGS_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_conf.h" + + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_REGS + * @brief This file is the + * @{ + */ + + +/** @defgroup USB_REGS_Exported_Defines + * @{ + */ + +#define USB_OTG_HS_BASE_ADDR 0x40040000 +#define USB_OTG_FS_BASE_ADDR 0x50000000 + +#define USB_OTG_CORE_GLOBAL_REGS_OFFSET 0x000 +#define USB_OTG_DEV_GLOBAL_REG_OFFSET 0x800 +#define USB_OTG_DEV_IN_EP_REG_OFFSET 0x900 +#define USB_OTG_EP_REG_OFFSET 0x20 +#define USB_OTG_DEV_OUT_EP_REG_OFFSET 0xB00 +#define USB_OTG_HOST_GLOBAL_REG_OFFSET 0x400 +#define USB_OTG_HOST_PORT_REGS_OFFSET 0x440 +#define USB_OTG_HOST_CHAN_REGS_OFFSET 0x500 +#define USB_OTG_CHAN_REGS_OFFSET 0x20 +#define USB_OTG_PCGCCTL_OFFSET 0xE00 +#define USB_OTG_DATA_FIFO_OFFSET 0x1000 +#define USB_OTG_DATA_FIFO_SIZE 0x1000 + + +#define USB_OTG_MAX_TX_FIFOS 15 + +#define USB_OTG_HS_MAX_PACKET_SIZE 512 +#define USB_OTG_FS_MAX_PACKET_SIZE 64 +#define USB_OTG_MAX_EP0_SIZE 64 +/** + * @} + */ + +/** @defgroup USB_REGS_Exported_Types + * @{ + */ + +/** @defgroup __USB_OTG_Core_register + * @{ + */ +typedef struct _USB_OTG_GREGS //000h +{ + __IO uint32_t GOTGCTL; /* USB_OTG Control and Status Register 000h*/ + __IO uint32_t GOTGINT; /* USB_OTG Interrupt Register 004h*/ + __IO uint32_t GAHBCFG; /* Core AHB Configuration Register 008h*/ + __IO uint32_t GUSBCFG; /* Core USB Configuration Register 00Ch*/ + __IO uint32_t GRSTCTL; /* Core Reset Register 010h*/ + __IO uint32_t GINTSTS; /* Core Interrupt Register 014h*/ + __IO uint32_t GINTMSK; /* Core Interrupt Mask Register 018h*/ + __IO uint32_t GRXSTSR; /* Receive Sts Q Read Register 01Ch*/ + __IO uint32_t GRXSTSP; /* Receive Sts Q Read & POP Register 020h*/ + __IO uint32_t GRXFSIZ; /* Receive FIFO Size Register 024h*/ + __IO uint32_t DIEPTXF0_HNPTXFSIZ; /* EP0 / Non Periodic Tx FIFO Size Register 028h*/ + __IO uint32_t HNPTXSTS; /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/ + __IO uint32_t GI2CCTL; /* I2C Access Register 030h*/ + uint32_t Reserved34; /* PHY Vendor Control Register 034h*/ + __IO uint32_t GCCFG; /* General Purpose IO Register 038h*/ + __IO uint32_t CID; /* User ID Register 03Ch*/ + uint32_t Reserved40[48]; /* Reserved 040h-0FFh*/ + __IO uint32_t HPTXFSIZ; /* Host Periodic Tx FIFO Size Reg 100h*/ + __IO uint32_t DIEPTXF[USB_OTG_MAX_TX_FIFOS];/* dev Periodic Transmit FIFO */ +} +USB_OTG_GREGS; +/** + * @} + */ + + +/** @defgroup __device_Registers + * @{ + */ +typedef struct _USB_OTG_DREGS // 800h +{ + __IO uint32_t DCFG; /* dev Configuration Register 800h*/ + __IO uint32_t DCTL; /* dev Control Register 804h*/ + __IO uint32_t DSTS; /* dev Status Register (RO) 808h*/ + uint32_t Reserved0C; /* Reserved 80Ch*/ + __IO uint32_t DIEPMSK; /* dev IN Endpoint Mask 810h*/ + __IO uint32_t DOEPMSK; /* dev OUT Endpoint Mask 814h*/ + __IO uint32_t DAINT; /* dev All Endpoints Itr Reg 818h*/ + __IO uint32_t DAINTMSK; /* dev All Endpoints Itr Mask 81Ch*/ + uint32_t Reserved20; /* Reserved 820h*/ + uint32_t Reserved9; /* Reserved 824h*/ + __IO uint32_t DVBUSDIS; /* dev VBUS discharge Register 828h*/ + __IO uint32_t DVBUSPULSE; /* dev VBUS Pulse Register 82Ch*/ + __IO uint32_t DTHRCTL; /* dev thr 830h*/ + __IO uint32_t DIEPEMPMSK; /* dev empty msk 834h*/ + __IO uint32_t DEACHINT; /* dedicated EP interrupt 838h*/ + __IO uint32_t DEACHMSK; /* dedicated EP msk 83Ch*/ + uint32_t Reserved40; /* dedicated EP mask 840h*/ + __IO uint32_t DINEP1MSK; /* dedicated EP mask 844h*/ + uint32_t Reserved44[15]; /* Reserved 844-87Ch*/ + __IO uint32_t DOUTEP1MSK; /* dedicated EP msk 884h*/ +} +USB_OTG_DREGS; +/** + * @} + */ + + +/** @defgroup __IN_Endpoint-Specific_Register + * @{ + */ +typedef struct _USB_OTG_INEPREGS +{ + __IO uint32_t DIEPCTL; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/ + uint32_t Reserved04; /* Reserved 900h + (ep_num * 20h) + 04h*/ + __IO uint32_t DIEPINT; /* dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h*/ + uint32_t Reserved0C; /* Reserved 900h + (ep_num * 20h) + 0Ch*/ + __IO uint32_t DIEPTSIZ; /* IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h*/ + __IO uint32_t DIEPDMA; /* IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h*/ + __IO uint32_t DTXFSTS;/*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/ + uint32_t Reserved18; /* Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/ +} +USB_OTG_INEPREGS; +/** + * @} + */ + + +/** @defgroup __OUT_Endpoint-Specific_Registers + * @{ + */ +typedef struct _USB_OTG_OUTEPREGS +{ + __IO uint32_t DOEPCTL; /* dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ + __IO uint32_t DOUTEPFRM; /* dev OUT Endpoint Frame number B00h + (ep_num * 20h) + 04h*/ + __IO uint32_t DOEPINT; /* dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ + uint32_t Reserved0C; /* Reserved B00h + (ep_num * 20h) + 0Ch*/ + __IO uint32_t DOEPTSIZ; /* dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ + __IO uint32_t DOEPDMA; /* dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/ + uint32_t Reserved18[2]; /* Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/ +} +USB_OTG_OUTEPREGS; +/** + * @} + */ + + +/** @defgroup __Host_Mode_Register_Structures + * @{ + */ +typedef struct _USB_OTG_HREGS +{ + __IO uint32_t HCFG; /* Host Configuration Register 400h*/ + __IO uint32_t HFIR; /* Host Frame Interval Register 404h*/ + __IO uint32_t HFNUM; /* Host Frame Nbr/Frame Remaining 408h*/ + uint32_t Reserved40C; /* Reserved 40Ch*/ + __IO uint32_t HPTXSTS; /* Host Periodic Tx FIFO/ Queue Status 410h*/ + __IO uint32_t HAINT; /* Host All Channels Interrupt Register 414h*/ + __IO uint32_t HAINTMSK; /* Host All Channels Interrupt Mask 418h*/ +} +USB_OTG_HREGS; +/** + * @} + */ + + +/** @defgroup __Host_Channel_Specific_Registers + * @{ + */ +typedef struct _USB_OTG_HC_REGS +{ + __IO uint32_t HCCHAR; + __IO uint32_t HCSPLT; + __IO uint32_t HCINT; + __IO uint32_t HCGINTMSK; + __IO uint32_t HCTSIZ; + __IO uint32_t HCDMA; + uint32_t Reserved[2]; +} +USB_OTG_HC_REGS; +/** + * @} + */ + + +/** @defgroup __otg_Core_registers + * @{ + */ +typedef struct USB_OTG_core_regs //000h +{ + USB_OTG_GREGS *GREGS; + USB_OTG_DREGS *DREGS; + USB_OTG_HREGS *HREGS; + USB_OTG_INEPREGS *INEP_REGS[USB_OTG_MAX_TX_FIFOS]; + USB_OTG_OUTEPREGS *OUTEP_REGS[USB_OTG_MAX_TX_FIFOS]; + USB_OTG_HC_REGS *HC_REGS[USB_OTG_MAX_TX_FIFOS]; + __IO uint32_t *HPRT0; + __IO uint32_t *DFIFO[USB_OTG_MAX_TX_FIFOS]; + __IO uint32_t *PCGCCTL; +} +USB_OTG_CORE_REGS , *PUSB_OTG_CORE_REGS; +typedef union _USB_OTG_OTGCTL_TypeDef +{ + uint32_t d32; + struct + { +uint32_t sesreqscs : + 1; +uint32_t sesreq : + 1; +uint32_t Reserved2_7 : + 6; +uint32_t hstnegscs : + 1; +uint32_t hnpreq : + 1; +uint32_t hstsethnpen : + 1; +uint32_t devhnpen : + 1; +uint32_t Reserved12_15 : + 4; +uint32_t conidsts : + 1; +uint32_t Reserved17 : + 1; +uint32_t asesvld : + 1; +uint32_t bsesvld : + 1; +uint32_t currmod : + 1; +uint32_t Reserved21_31 : + 11; + } + b; +} USB_OTG_OTGCTL_TypeDef ; +typedef union _USB_OTG_GOTGINT_TypeDef +{ + uint32_t d32; + struct + { +uint32_t Reserved0_1 : + 2; +uint32_t sesenddet : + 1; +uint32_t Reserved3_7 : + 5; +uint32_t sesreqsucstschng : + 1; +uint32_t hstnegsucstschng : + 1; +uint32_t reserver10_16 : + 7; +uint32_t hstnegdet : + 1; +uint32_t adevtoutchng : + 1; +uint32_t debdone : + 1; +uint32_t Reserved31_20 : + 12; + } + b; +} USB_OTG_GOTGINT_TypeDef ; +typedef union _USB_OTG_GAHBCFG_TypeDef +{ + uint32_t d32; + struct + { +uint32_t glblintrmsk : + 1; +uint32_t hburstlen : + 4; +uint32_t dmaenable : + 1; +uint32_t Reserved : + 1; +uint32_t nptxfemplvl_txfemplvl : + 1; +uint32_t ptxfemplvl : + 1; +uint32_t Reserved9_31 : + 23; + } + b; +} USB_OTG_GAHBCFG_TypeDef ; +typedef union _USB_OTG_GUSBCFG_TypeDef +{ + uint32_t d32; + struct + { +uint32_t toutcal : + 3; +uint32_t phyif : + 1; +uint32_t ulpi_utmi_sel : + 1; +uint32_t fsintf : + 1; +uint32_t physel : + 1; +uint32_t ddrsel : + 1; +uint32_t srpcap : + 1; +uint32_t hnpcap : + 1; +uint32_t usbtrdtim : + 4; +uint32_t nptxfrwnden : + 1; +uint32_t phylpwrclksel : + 1; +uint32_t otgutmifssel : + 1; +uint32_t ulpi_fsls : + 1; +uint32_t ulpi_auto_res : + 1; +uint32_t ulpi_clk_sus_m : + 1; +uint32_t ulpi_ext_vbus_drv : + 1; +uint32_t ulpi_int_vbus_indicator : + 1; +uint32_t term_sel_dl_pulse : + 1; +uint32_t Reserved : + 6; +uint32_t force_host : + 1; +uint32_t force_dev : + 1; +uint32_t corrupt_tx : + 1; + } + b; +} USB_OTG_GUSBCFG_TypeDef ; +typedef union _USB_OTG_GRSTCTL_TypeDef +{ + uint32_t d32; + struct + { +uint32_t csftrst : + 1; +uint32_t hsftrst : + 1; +uint32_t hstfrm : + 1; +uint32_t intknqflsh : + 1; +uint32_t rxfflsh : + 1; +uint32_t txfflsh : + 1; +uint32_t txfnum : + 5; +uint32_t Reserved11_29 : + 19; +uint32_t dmareq : + 1; +uint32_t ahbidle : + 1; + } + b; +} USB_OTG_GRSTCTL_TypeDef ; +typedef union _USB_OTG_GINTMSK_TypeDef +{ + uint32_t d32; + struct + { +uint32_t Reserved0 : + 1; +uint32_t modemismatch : + 1; +uint32_t otgintr : + 1; +uint32_t sofintr : + 1; +uint32_t rxstsqlvl : + 1; +uint32_t nptxfempty : + 1; +uint32_t ginnakeff : + 1; +uint32_t goutnakeff : + 1; +uint32_t Reserved8 : + 1; +uint32_t i2cintr : + 1; +uint32_t erlysuspend : + 1; +uint32_t usbsuspend : + 1; +uint32_t usbreset : + 1; +uint32_t enumdone : + 1; +uint32_t isooutdrop : + 1; +uint32_t eopframe : + 1; +uint32_t Reserved16 : + 1; +uint32_t epmismatch : + 1; +uint32_t inepintr : + 1; +uint32_t outepintr : + 1; +uint32_t incomplisoin : + 1; +uint32_t incomplisoout : + 1; +uint32_t Reserved22_23 : + 2; +uint32_t portintr : + 1; +uint32_t hcintr : + 1; +uint32_t ptxfempty : + 1; +uint32_t Reserved27 : + 1; +uint32_t conidstschng : + 1; +uint32_t disconnect : + 1; +uint32_t sessreqintr : + 1; +uint32_t wkupintr : + 1; + } + b; +} USB_OTG_GINTMSK_TypeDef ; +typedef union _USB_OTG_GINTSTS_TypeDef +{ + uint32_t d32; + struct + { +uint32_t curmode : + 1; +uint32_t modemismatch : + 1; +uint32_t otgintr : + 1; +uint32_t sofintr : + 1; +uint32_t rxstsqlvl : + 1; +uint32_t nptxfempty : + 1; +uint32_t ginnakeff : + 1; +uint32_t goutnakeff : + 1; +uint32_t Reserved8 : + 1; +uint32_t i2cintr : + 1; +uint32_t erlysuspend : + 1; +uint32_t usbsuspend : + 1; +uint32_t usbreset : + 1; +uint32_t enumdone : + 1; +uint32_t isooutdrop : + 1; +uint32_t eopframe : + 1; +uint32_t intimerrx : + 1; +uint32_t epmismatch : + 1; +uint32_t inepint: + 1; +uint32_t outepintr : + 1; +uint32_t incomplisoin : + 1; +uint32_t incomplisoout : + 1; +uint32_t Reserved22_23 : + 2; +uint32_t portintr : + 1; +uint32_t hcintr : + 1; +uint32_t ptxfempty : + 1; +uint32_t Reserved27 : + 1; +uint32_t conidstschng : + 1; +uint32_t disconnect : + 1; +uint32_t sessreqintr : + 1; +uint32_t wkupintr : + 1; + } + b; +} USB_OTG_GINTSTS_TypeDef ; +typedef union _USB_OTG_DRXSTS_TypeDef +{ + uint32_t d32; + struct + { +uint32_t epnum : + 4; +uint32_t bcnt : + 11; +uint32_t dpid : + 2; +uint32_t pktsts : + 4; +uint32_t fn : + 4; +uint32_t Reserved : + 7; + } + b; +} USB_OTG_DRXSTS_TypeDef ; +typedef union _USB_OTG_GRXSTS_TypeDef +{ + uint32_t d32; + struct + { +uint32_t chnum : + 4; +uint32_t bcnt : + 11; +uint32_t dpid : + 2; +uint32_t pktsts : + 4; +uint32_t Reserved : + 11; + } + b; +} USB_OTG_GRXFSTS_TypeDef ; +typedef union _USB_OTG_FSIZ_TypeDef +{ + uint32_t d32; + struct + { +uint32_t startaddr : + 16; +uint32_t depth : + 16; + } + b; +} USB_OTG_FSIZ_TypeDef ; +typedef union _USB_OTG_HNPTXSTS_TypeDef +{ + uint32_t d32; + struct + { +uint32_t nptxfspcavail : + 16; +uint32_t nptxqspcavail : + 8; +uint32_t nptxqtop_terminate : + 1; +uint32_t nptxqtop_timer : + 2; +uint32_t nptxqtop : + 2; +uint32_t chnum : + 2; +uint32_t Reserved : + 1; + } + b; +} USB_OTG_HNPTXSTS_TypeDef ; +typedef union _USB_OTG_DTXFSTSn_TypeDef +{ + uint32_t d32; + struct + { +uint32_t txfspcavail : + 16; +uint32_t Reserved : + 16; + } + b; +} USB_OTG_DTXFSTSn_TypeDef ; +typedef union _USB_OTG_GI2CCTL_TypeDef +{ + uint32_t d32; + struct + { +uint32_t rwdata : + 8; +uint32_t regaddr : + 8; +uint32_t addr : + 7; +uint32_t i2cen : + 1; +uint32_t ack : + 1; +uint32_t i2csuspctl : + 1; +uint32_t i2cdevaddr : + 2; +uint32_t dat_se0: + 1; +uint32_t Reserved : + 1; +uint32_t rw : + 1; +uint32_t bsydne : + 1; + } + b; +} USB_OTG_GI2CCTL_TypeDef ; +typedef union _USB_OTG_GCCFG_TypeDef +{ + uint32_t d32; + struct + { +uint32_t Reserved_in : + 16; +uint32_t pwdn : + 1; +uint32_t i2cifen : + 1; +uint32_t vbussensingA : + 1; +uint32_t vbussensingB : + 1; +uint32_t sofouten : + 1; +uint32_t disablevbussensing : + 1; +uint32_t Reserved_out : + 10; + } + b; +} USB_OTG_GCCFG_TypeDef ; + +typedef union _USB_OTG_DCFG_TypeDef +{ + uint32_t d32; + struct + { +uint32_t devspd : + 2; +uint32_t nzstsouthshk : + 1; +uint32_t Reserved3 : + 1; +uint32_t devaddr : + 7; +uint32_t perfrint : + 2; +uint32_t Reserved13_17 : + 5; +uint32_t epmscnt : + 4; + } + b; +} USB_OTG_DCFG_TypeDef ; +typedef union _USB_OTG_DCTL_TypeDef +{ + uint32_t d32; + struct + { +uint32_t rmtwkupsig : + 1; +uint32_t sftdiscon : + 1; +uint32_t gnpinnaksts : + 1; +uint32_t goutnaksts : + 1; +uint32_t tstctl : + 3; +uint32_t sgnpinnak : + 1; +uint32_t cgnpinnak : + 1; +uint32_t sgoutnak : + 1; +uint32_t cgoutnak : + 1; +uint32_t Reserved : + 21; + } + b; +} USB_OTG_DCTL_TypeDef ; +typedef union _USB_OTG_DSTS_TypeDef +{ + uint32_t d32; + struct + { +uint32_t suspsts : + 1; +uint32_t enumspd : + 2; +uint32_t errticerr : + 1; +uint32_t Reserved4_7: + 4; +uint32_t soffn : + 14; +uint32_t Reserved22_31 : + 10; + } + b; +} USB_OTG_DSTS_TypeDef ; +typedef union _USB_OTG_DIEPINTn_TypeDef +{ + uint32_t d32; + struct + { +uint32_t xfercompl : + 1; +uint32_t epdisabled : + 1; +uint32_t ahberr : + 1; +uint32_t timeout : + 1; +uint32_t intktxfemp : + 1; +uint32_t intknepmis : + 1; +uint32_t inepnakeff : + 1; +uint32_t emptyintr : + 1; +uint32_t txfifoundrn : + 1; +uint32_t Reserved08_31 : + 23; + } + b; +} USB_OTG_DIEPINTn_TypeDef ; +typedef union _USB_OTG_DIEPINTn_TypeDef USB_OTG_DIEPMSK_TypeDef ; +typedef union _USB_OTG_DOEPINTn_TypeDef +{ + uint32_t d32; + struct + { +uint32_t xfercompl : + 1; +uint32_t epdisabled : + 1; +uint32_t ahberr : + 1; +uint32_t setup : + 1; +uint32_t Reserved04_31 : + 28; + } + b; +} USB_OTG_DOEPINTn_TypeDef ; +typedef union _USB_OTG_DOEPINTn_TypeDef USB_OTG_DOEPMSK_TypeDef ; + +typedef union _USB_OTG_DAINT_TypeDef +{ + uint32_t d32; + struct + { +uint32_t in : + 16; +uint32_t out : + 16; + } + ep; +} USB_OTG_DAINT_TypeDef ; + +typedef union _USB_OTG_DTHRCTL_TypeDef +{ + uint32_t d32; + struct + { +uint32_t non_iso_thr_en : + 1; +uint32_t iso_thr_en : + 1; +uint32_t tx_thr_len : + 9; +uint32_t Reserved11_15 : + 5; +uint32_t rx_thr_en : + 1; +uint32_t rx_thr_len : + 9; +uint32_t Reserved26_31 : + 6; + } + b; +} USB_OTG_DTHRCTL_TypeDef ; +typedef union _USB_OTG_DEPCTL_TypeDef +{ + uint32_t d32; + struct + { +uint32_t mps : + 11; +uint32_t reserved : + 4; +uint32_t usbactep : + 1; +uint32_t dpid : + 1; +uint32_t naksts : + 1; +uint32_t eptype : + 2; +uint32_t snp : + 1; +uint32_t stall : + 1; +uint32_t txfnum : + 4; +uint32_t cnak : + 1; +uint32_t snak : + 1; +uint32_t setd0pid : + 1; +uint32_t setd1pid : + 1; +uint32_t epdis : + 1; +uint32_t epena : + 1; + } + b; +} USB_OTG_DEPCTL_TypeDef ; +typedef union _USB_OTG_DEPXFRSIZ_TypeDef +{ + uint32_t d32; + struct + { +uint32_t xfersize : + 19; +uint32_t pktcnt : + 10; +uint32_t mc : + 2; +uint32_t Reserved : + 1; + } + b; +} USB_OTG_DEPXFRSIZ_TypeDef ; +typedef union _USB_OTG_DEP0XFRSIZ_TypeDef +{ + uint32_t d32; + struct + { +uint32_t xfersize : + 7; +uint32_t Reserved7_18 : + 12; +uint32_t pktcnt : + 2; +uint32_t Reserved20_28 : + 9; +uint32_t supcnt : + 2; + uint32_t Reserved31; + } + b; +} USB_OTG_DEP0XFRSIZ_TypeDef ; +typedef union _USB_OTG_HCFG_TypeDef +{ + uint32_t d32; + struct + { +uint32_t fslspclksel : + 2; +uint32_t fslssupp : + 1; + } + b; +} USB_OTG_HCFG_TypeDef ; +typedef union _USB_OTG_HFRMINTRVL_TypeDef +{ + uint32_t d32; + struct + { +uint32_t frint : + 16; +uint32_t Reserved : + 16; + } + b; +} USB_OTG_HFRMINTRVL_TypeDef ; + +typedef union _USB_OTG_HFNUM_TypeDef +{ + uint32_t d32; + struct + { +uint32_t frnum : + 16; +uint32_t frrem : + 16; + } + b; +} USB_OTG_HFNUM_TypeDef ; +typedef union _USB_OTG_HPTXSTS_TypeDef +{ + uint32_t d32; + struct + { +uint32_t ptxfspcavail : + 16; +uint32_t ptxqspcavail : + 8; +uint32_t ptxqtop_terminate : + 1; +uint32_t ptxqtop_timer : + 2; +uint32_t ptxqtop : + 2; +uint32_t chnum : + 2; +uint32_t ptxqtop_odd : + 1; + } + b; +} USB_OTG_HPTXSTS_TypeDef ; +typedef union _USB_OTG_HPRT0_TypeDef +{ + uint32_t d32; + struct + { +uint32_t prtconnsts : + 1; +uint32_t prtconndet : + 1; +uint32_t prtena : + 1; +uint32_t prtenchng : + 1; +uint32_t prtovrcurract : + 1; +uint32_t prtovrcurrchng : + 1; +uint32_t prtres : + 1; +uint32_t prtsusp : + 1; +uint32_t prtrst : + 1; +uint32_t Reserved9 : + 1; +uint32_t prtlnsts : + 2; +uint32_t prtpwr : + 1; +uint32_t prttstctl : + 4; +uint32_t prtspd : + 2; +uint32_t Reserved19_31 : + 13; + } + b; +} USB_OTG_HPRT0_TypeDef ; +typedef union _USB_OTG_HAINT_TypeDef +{ + uint32_t d32; + struct + { +uint32_t chint : + 16; +uint32_t Reserved : + 16; + } + b; +} USB_OTG_HAINT_TypeDef ; +typedef union _USB_OTG_HAINTMSK_TypeDef +{ + uint32_t d32; + struct + { +uint32_t chint : + 16; +uint32_t Reserved : + 16; + } + b; +} USB_OTG_HAINTMSK_TypeDef ; +typedef union _USB_OTG_HCCHAR_TypeDef +{ + uint32_t d32; + struct + { +uint32_t mps : + 11; +uint32_t epnum : + 4; +uint32_t epdir : + 1; +uint32_t Reserved : + 1; +uint32_t lspddev : + 1; +uint32_t eptype : + 2; +uint32_t multicnt : + 2; +uint32_t devaddr : + 7; +uint32_t oddfrm : + 1; +uint32_t chdis : + 1; +uint32_t chen : + 1; + } + b; +} USB_OTG_HCCHAR_TypeDef ; +typedef union _USB_OTG_HCSPLT_TypeDef +{ + uint32_t d32; + struct + { +uint32_t prtaddr : + 7; +uint32_t hubaddr : + 7; +uint32_t xactpos : + 2; +uint32_t compsplt : + 1; +uint32_t Reserved : + 14; +uint32_t spltena : + 1; + } + b; +} USB_OTG_HCSPLT_TypeDef ; +typedef union _USB_OTG_HCINTn_TypeDef +{ + uint32_t d32; + struct + { +uint32_t xfercompl : + 1; +uint32_t chhltd : + 1; +uint32_t ahberr : + 1; +uint32_t stall : + 1; +uint32_t nak : + 1; +uint32_t ack : + 1; +uint32_t nyet : + 1; +uint32_t xacterr : + 1; +uint32_t bblerr : + 1; +uint32_t frmovrun : + 1; +uint32_t datatglerr : + 1; +uint32_t Reserved : + 21; + } + b; +} USB_OTG_HCINTn_TypeDef ; +typedef union _USB_OTG_HCTSIZn_TypeDef +{ + uint32_t d32; + struct + { +uint32_t xfersize : + 19; +uint32_t pktcnt : + 10; +uint32_t pid : + 2; +uint32_t dopng : + 1; + } + b; +} USB_OTG_HCTSIZn_TypeDef ; +typedef union _USB_OTG_HCGINTMSK_TypeDef +{ + uint32_t d32; + struct + { +uint32_t xfercompl : + 1; +uint32_t chhltd : + 1; +uint32_t ahberr : + 1; +uint32_t stall : + 1; +uint32_t nak : + 1; +uint32_t ack : + 1; +uint32_t nyet : + 1; +uint32_t xacterr : + 1; +uint32_t bblerr : + 1; +uint32_t frmovrun : + 1; +uint32_t datatglerr : + 1; +uint32_t Reserved : + 21; + } + b; +} USB_OTG_HCGINTMSK_TypeDef ; +typedef union _USB_OTG_PCGCCTL_TypeDef +{ + uint32_t d32; + struct + { +uint32_t stoppclk : + 1; +uint32_t gatehclk : + 1; +uint32_t Reserved : + 30; + } + b; +} USB_OTG_PCGCCTL_TypeDef ; + +/** + * @} + */ + + +/** @defgroup USB_REGS_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_REGS_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_REGS_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + + +#endif //__USB_OTG_REGS_H__ + + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_bsp_template.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_bsp_template.c index a32f872e..c3f515bc 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_bsp_template.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_bsp_template.c @@ -1,200 +1,200 @@ -/** - ****************************************************************************** - * @file usb_bsp.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file is responsible to offer board support package and is - * configurable by user. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_bsp.h" - -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_BSP - * @brief This file is responsible to offer board support package - * @{ - */ - -/** @defgroup USB_BSP_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_BSP_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - - - -/** @defgroup USB_BSP_Private_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_BSP_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBH_BSP_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_BSP_Private_Functions - * @{ - */ - - -/** - * @brief USB_OTG_BSP_Init - * Initilizes BSP configurations - * @param None - * @retval None - */ - -void USB_OTG_BSP_Init(void) -{ - -} -/** - * @brief USB_OTG_BSP_EnableInterrupt - * Enabele USB Global interrupt - * @param None - * @retval None - */ -void USB_OTG_BSP_EnableInterrupt(void) -{ - -} - -/** - * @brief BSP_Drive_VBUS - * Drives the Vbus signal through IO - * @param speed : Full, Low - * @param state : VBUS states - * @retval None - */ - -void USB_OTG_BSP_DriveVBUS(uint32_t speed, uint8_t state) -{ - -} - -/** - * @brief USB_OTG_BSP_ConfigVBUS - * Configures the IO for the Vbus and OverCurrent - * @param Speed : Full, Low - * @retval None - */ - -void USB_OTG_BSP_ConfigVBUS(uint32_t speed) -{ - -} - -/** - * @brief USB_OTG_BSP_TimeInit - * Initialises delay unit Systick timer /Timer2 - * @param None - * @retval None - */ -void USB_OTG_BSP_TimeInit ( void ) -{ - -} - -/** - * @brief USB_OTG_BSP_uDelay - * This function provides delay time in micro sec - * @param usec : Value of delay required in micro sec - * @retval None - */ -void USB_OTG_BSP_uDelay (const uint32_t usec) -{ - - uint32_t count = 0; - const uint32_t utime = (120 * usec / 7); - do - { - if ( ++count > utime ) - { - return ; - } - } - while (1); - -} - - -/** - * @brief USB_OTG_BSP_mDelay - * This function provides delay time in milli sec - * @param msec : Value of delay required in milli sec - * @retval None - */ -void USB_OTG_BSP_mDelay (const uint32_t msec) -{ - - USB_OTG_BSP_uDelay(msec * 1000); - -} - - -/** - * @brief USB_OTG_BSP_TimerIRQ - * Time base IRQ - * @param None - * @retval None - */ - -void USB_OTG_BSP_TimerIRQ (void) -{ - -} - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usb_bsp.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief This file is responsible to offer board support package and is + * configurable by user. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_bsp.h" + +/** @addtogroup USB_OTG_DRIVER +* @{ +*/ + +/** @defgroup USB_BSP + * @brief This file is responsible to offer board support package + * @{ + */ + +/** @defgroup USB_BSP_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_BSP_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + + + +/** @defgroup USB_BSP_Private_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_BSP_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBH_BSP_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_BSP_Private_Functions + * @{ + */ + + +/** + * @brief USB_OTG_BSP_Init + * Initilizes BSP configurations + * @param None + * @retval None + */ + +void USB_OTG_BSP_Init(void) +{ + +} +/** + * @brief USB_OTG_BSP_EnableInterrupt + * Enabele USB Global interrupt + * @param None + * @retval None + */ +void USB_OTG_BSP_EnableInterrupt(void) +{ + +} + +/** + * @brief BSP_Drive_VBUS + * Drives the Vbus signal through IO + * @param speed : Full, Low + * @param state : VBUS states + * @retval None + */ + +void USB_OTG_BSP_DriveVBUS(uint32_t speed, uint8_t state) +{ + +} + +/** + * @brief USB_OTG_BSP_ConfigVBUS + * Configures the IO for the Vbus and OverCurrent + * @param Speed : Full, Low + * @retval None + */ + +void USB_OTG_BSP_ConfigVBUS(uint32_t speed) +{ + +} + +/** + * @brief USB_OTG_BSP_TimeInit + * Initialises delay unit Systick timer /Timer2 + * @param None + * @retval None + */ +void USB_OTG_BSP_TimeInit ( void ) +{ + +} + +/** + * @brief USB_OTG_BSP_uDelay + * This function provides delay time in micro sec + * @param usec : Value of delay required in micro sec + * @retval None + */ +void USB_OTG_BSP_uDelay (const uint32_t usec) +{ + + uint32_t count = 0; + const uint32_t utime = (120 * usec / 7); + do + { + if ( ++count > utime ) + { + return ; + } + } + while (1); + +} + + +/** + * @brief USB_OTG_BSP_mDelay + * This function provides delay time in milli sec + * @param msec : Value of delay required in milli sec + * @retval None + */ +void USB_OTG_BSP_mDelay (const uint32_t msec) +{ + + USB_OTG_BSP_uDelay(msec * 1000); + +} + + +/** + * @brief USB_OTG_BSP_TimerIRQ + * Time base IRQ + * @param None + * @retval None + */ + +void USB_OTG_BSP_TimerIRQ (void) +{ + +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_core.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_core.c index 738329c5..cb9eabc8 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_core.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_core.c @@ -1,2189 +1,2189 @@ -/** - ****************************************************************************** - * @file usb_core.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief USB-OTG Core Layer - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_bsp.h" -#include "usb_core.h" - - -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_CORE -* @brief This file includes the USB-OTG Core Layer -* @{ -*/ - - -/** @defgroup USB_CORE_Private_Defines -* @{ -*/ - -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - - -/** @defgroup USB_CORE_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_Variables -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_FunctionPrototypes -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_Functions -* @{ -*/ - -/** -* @brief USB_OTG_EnableCommonInt -* Initializes the commmon interrupts, used in both device and modes -* @param pdev : Selected device -* @retval None -*/ -static void USB_OTG_EnableCommonInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTMSK_TypeDef int_mask; - - int_mask.d32 = 0; - /* Clear any pending USB_OTG Interrupts */ -#ifndef USE_OTG_MODE - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GOTGINT, 0xFFFFFFFF); -#endif - /* Clear any pending interrupts */ - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); - /* Enable the interrupts in the INTMSK */ - int_mask.b.wkupintr = 1; - int_mask.b.usbsuspend = 1; - -#ifdef USE_OTG_MODE - int_mask.b.otgintr = 1; - int_mask.b.sessreqintr = 1; - int_mask.b.conidstschng = 1; -#endif - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32); -} - -/** -* @brief USB_OTG_CoreReset : Soft reset of the core -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -static USB_OTG_STS USB_OTG_CoreReset(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - __IO USB_OTG_GRSTCTL_TypeDef greset; - uint32_t count = 0; - - greset.d32 = 0; - /* Wait for AHB master IDLE state. */ - do - { - USB_OTG_BSP_uDelay(3); - greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - return USB_OTG_OK; - } - } - while (greset.b.ahbidle == 0); - /* Core Soft Reset */ - count = 0; - greset.b.csftrst = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRSTCTL, greset.d32 ); - do - { - greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - break; - } - } - while (greset.b.csftrst == 1); - /* Wait for 3 PHY Clocks*/ - USB_OTG_BSP_uDelay(3); - return status; -} - -/** -* @brief USB_OTG_WritePacket : Writes a packet into the Tx FIFO associated -* with the EP -* @param pdev : Selected device -* @param src : source pointer -* @param ch_ep_num : end point number -* @param bytes : No. of bytes -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev, - uint8_t *src, - uint8_t ch_ep_num, - uint16_t len) -{ - USB_OTG_STS status = USB_OTG_OK; - if (pdev->cfg.dma_enable == 0) - { - uint32_t count32b= 0 , i= 0; - __IO uint32_t *fifo; - - count32b = (len + 3) / 4; - fifo = pdev->regs.DFIFO[ch_ep_num]; - for (i = 0; i < count32b; i++, src+=4) - { - USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) ); - } - } - return status; -} - - -/** -* @brief USB_OTG_ReadPacket : Reads a packet from the Rx FIFO -* @param pdev : Selected device -* @param dest : Destination Pointer -* @param bytes : No. of bytes -* @retval None -*/ -void *USB_OTG_ReadPacket(USB_OTG_CORE_HANDLE *pdev, - uint8_t *dest, - uint16_t len) -{ - uint32_t i=0; - uint32_t count32b = (len + 3) / 4; - - __IO uint32_t *fifo = pdev->regs.DFIFO[0]; - - for ( i = 0; i < count32b; i++, dest += 4 ) - { - *(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo); - - } - return ((void *)dest); -} - -/** -* @brief USB_OTG_SelectCore -* Initialize core registers address. -* @param pdev : Selected device -* @param coreID : USB OTG Core ID -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_SelectCore(USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID) -{ - uint32_t i , baseAddress = 0; - USB_OTG_STS status = USB_OTG_OK; - - pdev->cfg.dma_enable = 0; - - /* at startup the core is in FS mode */ - pdev->cfg.speed = USB_OTG_SPEED_FULL; - pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; - - /* initialize device cfg following its address */ - if (coreID == USB_OTG_FS_CORE_ID) - { - baseAddress = USB_OTG_FS_BASE_ADDR; - pdev->cfg.coreID = USB_OTG_FS_CORE_ID; - pdev->cfg.host_channels = 8 ; - pdev->cfg.dev_endpoints = 4 ; - pdev->cfg.TotalFifoSize = 320; /* in 32-bits */ - pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY; - -#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED - pdev->cfg.Sof_output = 1; -#endif - -#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - pdev->cfg.low_power = 1; -#endif - } - else if (coreID == USB_OTG_HS_CORE_ID) - { - baseAddress = USB_OTG_HS_BASE_ADDR; - pdev->cfg.coreID = USB_OTG_HS_CORE_ID; - pdev->cfg.host_channels = 12 ; - pdev->cfg.dev_endpoints = 6 ; - pdev->cfg.TotalFifoSize = 1280;/* in 32-bits */ - -#ifdef USB_OTG_ULPI_PHY_ENABLED - pdev->cfg.phy_itface = USB_OTG_ULPI_PHY; -#else - #ifdef USB_OTG_EMBEDDED_PHY_ENABLED - pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY; - #else - #ifdef USB_OTG_I2C_PHY_ENABLED - pdev->cfg.phy_itface = USB_OTG_I2C_PHY; - #endif - #endif -#endif - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - pdev->cfg.dma_enable = 1; -#endif - -#ifdef USB_OTG_HS_SOF_OUTPUT_ENABLED - pdev->cfg.Sof_output = 1; -#endif - -#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT - pdev->cfg.low_power = 1; -#endif - - } - - pdev->regs.GREGS = (USB_OTG_GREGS *)(baseAddress + \ - USB_OTG_CORE_GLOBAL_REGS_OFFSET); - pdev->regs.DREGS = (USB_OTG_DREGS *) (baseAddress + \ - USB_OTG_DEV_GLOBAL_REG_OFFSET); - - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - pdev->regs.INEP_REGS[i] = (USB_OTG_INEPREGS *) \ - (baseAddress + USB_OTG_DEV_IN_EP_REG_OFFSET + \ - (i * USB_OTG_EP_REG_OFFSET)); - pdev->regs.OUTEP_REGS[i] = (USB_OTG_OUTEPREGS *) \ - (baseAddress + USB_OTG_DEV_OUT_EP_REG_OFFSET + \ - (i * USB_OTG_EP_REG_OFFSET)); - } - pdev->regs.HREGS = (USB_OTG_HREGS *)(baseAddress + \ - USB_OTG_HOST_GLOBAL_REG_OFFSET); - pdev->regs.HPRT0 = (uint32_t *)(baseAddress + USB_OTG_HOST_PORT_REGS_OFFSET); - - for (i = 0; i < pdev->cfg.host_channels; i++) - { - pdev->regs.HC_REGS[i] = (USB_OTG_HC_REGS *)(baseAddress + \ - USB_OTG_HOST_CHAN_REGS_OFFSET + \ - (i * USB_OTG_CHAN_REGS_OFFSET)); - } - for (i = 0; i < pdev->cfg.host_channels; i++) - { - pdev->regs.DFIFO[i] = (uint32_t *)(baseAddress + USB_OTG_DATA_FIFO_OFFSET +\ - (i * USB_OTG_DATA_FIFO_SIZE)); - } - pdev->regs.PCGCCTL = (uint32_t *)(baseAddress + USB_OTG_PCGCCTL_OFFSET); - - return status; -} - - -/** -* @brief USB_OTG_CoreInit -* Initializes the USB_OTG controller registers and prepares the core -* device mode or host mode operation. -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GUSBCFG_TypeDef usbcfg; - USB_OTG_GCCFG_TypeDef gccfg; - USB_OTG_GI2CCTL_TypeDef i2cctl; - USB_OTG_GAHBCFG_TypeDef ahbcfg; - - usbcfg.d32 = 0; - gccfg.d32 = 0; - ahbcfg.d32 = 0; - - - - if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) - { - gccfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GCCFG); - gccfg.b.pwdn = 0; - - if (pdev->cfg.Sof_output) - { - gccfg.b.sofouten = 1; - } - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32); - - /* Init The ULPI Interface */ - usbcfg.d32 = 0; - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - usbcfg.b.physel = 0; /* HS Interface */ -#ifdef USB_OTG_INTERNAL_VBUS_ENABLED - usbcfg.b.ulpi_ext_vbus_drv = 0; /* Use internal VBUS */ -#else - #ifdef USB_OTG_EXTERNAL_VBUS_ENABLED - usbcfg.b.ulpi_ext_vbus_drv = 1; /* Use external VBUS */ - #endif -#endif - usbcfg.b.term_sel_dl_pulse = 0; /* Data line pulsing using utmi_txvalid */ - usbcfg.b.ulpi_utmi_sel = 1; /* ULPI seleInterfacect */ - - usbcfg.b.phyif = 0; /* 8 bits */ - usbcfg.b.ddrsel = 0; /* single data rate */ - - usbcfg.b.ulpi_fsls = 0; - usbcfg.b.ulpi_clk_sus_m = 0; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - - /* Reset after a PHY select */ - USB_OTG_CoreReset(pdev); - - if(pdev->cfg.dma_enable == 1) - { - - ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/ - ahbcfg.b.dmaenable = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32); - - } - } - else /* FS interface (embedded Phy or I2C Phy) */ - { - - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);; - usbcfg.b.physel = 1; /* FS Interface */ - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - /* Reset after a PHY select and set Host mode */ - USB_OTG_CoreReset(pdev); - /* Enable the I2C interface and deactivate the power down*/ - gccfg.d32 = 0; - gccfg.b.pwdn = 1; - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - gccfg.b.i2cifen = 1; - } - gccfg.b.vbussensingA = 1 ; - gccfg.b.vbussensingB = 1 ; -#ifndef VBUS_SENSING_ENABLED - gccfg.b.disablevbussensing = 1; -#endif - - if(pdev->cfg.Sof_output) - { - gccfg.b.sofouten = 1; - } - - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32); - USB_OTG_BSP_mDelay(20); - /* Program GUSBCFG.OtgUtmifsSel to I2C*/ - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - usbcfg.b.otgutmifssel = 1; - } - - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - /*Program GI2CCTL.I2CEn*/ - i2cctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GI2CCTL); - i2cctl.b.i2cdevaddr = 1; - i2cctl.b.i2cen = 0; - i2cctl.b.dat_se0 = 1; - i2cctl.b.addr = 0x2D; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32); - - USB_OTG_BSP_mDelay(200); - - i2cctl.b.i2cen = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32); - USB_OTG_BSP_mDelay(200); - } - } - /* case the HS core is working in FS mode */ - if(pdev->cfg.dma_enable == 1) - { - - ahbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GAHBCFG); - ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/ - ahbcfg.b.dmaenable = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32); - - } - /* initialize OTG features */ -#ifdef USE_OTG_MODE - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - usbcfg.b.hnpcap = 1; - usbcfg.b.srpcap = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - USB_OTG_EnableCommonInt(pdev); -#endif - return status; -} -/** -* @brief USB_OTG_EnableGlobalInt -* Enables the controller's Global Int in the AHB Config reg -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EnableGlobalInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GAHBCFG_TypeDef ahbcfg; - - ahbcfg.d32 = 0; - ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, 0, ahbcfg.d32); - return status; -} - - -/** -* @brief USB_OTG_DisableGlobalInt -* Enables the controller's Global Int in the AHB Config reg -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GAHBCFG_TypeDef ahbcfg; - ahbcfg.d32 = 0; - ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32, 0); - return status; -} - - -/** -* @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO -* @param pdev : Selected device -* @param num : FO num -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num ) -{ - USB_OTG_STS status = USB_OTG_OK; - __IO USB_OTG_GRSTCTL_TypeDef greset; - - uint32_t count = 0; - greset.d32 = 0; - greset.b.txfflsh = 1; - greset.b.txfnum = num; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 ); - do - { - greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - break; - } - } - while (greset.b.txfflsh == 1); - /* Wait for 3 PHY Clocks*/ - USB_OTG_BSP_uDelay(3); - return status; -} - - -/** -* @brief USB_OTG_FlushRxFifo : Flush a Rx FIFO -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_FlushRxFifo( USB_OTG_CORE_HANDLE *pdev ) -{ - USB_OTG_STS status = USB_OTG_OK; - __IO USB_OTG_GRSTCTL_TypeDef greset; - uint32_t count = 0; - - greset.d32 = 0; - greset.b.rxfflsh = 1; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 ); - do - { - greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - break; - } - } - while (greset.b.rxfflsh == 1); - /* Wait for 3 PHY Clocks*/ - USB_OTG_BSP_uDelay(3); - return status; -} - - -/** -* @brief USB_OTG_SetCurrentMode : Set ID line -* @param pdev : Selected device -* @param mode : (Host/device) -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_SetCurrentMode(USB_OTG_CORE_HANDLE *pdev , uint8_t mode) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GUSBCFG_TypeDef usbcfg; - - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - usbcfg.b.force_host = 0; - usbcfg.b.force_dev = 0; - - if ( mode == HOST_MODE) - { - usbcfg.b.force_host = 1; - } - else if ( mode == DEVICE_MODE) - { - usbcfg.b.force_dev = 1; - } - - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - USB_OTG_BSP_mDelay(50); - return status; -} - - -/** -* @brief USB_OTG_GetMode : Get current mode -* @param pdev : Selected device -* @retval current mode -*/ -uint32_t USB_OTG_GetMode(USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS ) & 0x1); -} - - -/** -* @brief USB_OTG_IsDeviceMode : Check if it is device mode -* @param pdev : Selected device -* @retval num_in_ep -*/ -uint8_t USB_OTG_IsDeviceMode(USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_GetMode(pdev) != HOST_MODE); -} - - -/** -* @brief USB_OTG_IsHostMode : Check if it is host mode -* @param pdev : Selected device -* @retval num_in_ep -*/ -uint8_t USB_OTG_IsHostMode(USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_GetMode(pdev) == HOST_MODE); -} - - -/** -* @brief USB_OTG_ReadCoreItr : returns the Core Interrupt register -* @param pdev : Selected device -* @retval Status -*/ -uint32_t USB_OTG_ReadCoreItr(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t v = 0; - v = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS); - v &= USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK); - return v; -} - - -/** -* @brief USB_OTG_ReadOtgItr : returns the USB_OTG Interrupt register -* @param pdev : Selected device -* @retval Status -*/ -uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32 (&pdev->regs.GREGS->GOTGINT)); -} - -#ifdef USE_HOST_MODE -/** -* @brief USB_OTG_CoreInitHost : Initializes USB_OTG controller for host mode -* @param pdev : Selected device -* @retval status -*/ -USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_FSIZ_TypeDef nptxfifosize; - USB_OTG_FSIZ_TypeDef ptxfifosize; - USB_OTG_HCFG_TypeDef hcfg; - -#ifdef USE_OTG_MODE - USB_OTG_OTGCTL_TypeDef gotgctl; -#endif - - uint32_t i = 0; - - nptxfifosize.d32 = 0; - ptxfifosize.d32 = 0; -#ifdef USE_OTG_MODE - gotgctl.d32 = 0; -#endif - hcfg.d32 = 0; - - - /* configure charge pump IO */ - USB_OTG_BSP_ConfigVBUS(pdev); - - /* Restart the Phy Clock */ - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0); - - /* Initialize Host Configuration Register */ - USB_OTG_InitFSLSPClkSel(pdev , HCFG_48_MHZ); /* in init phase */ - - hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); - hcfg.b.fslssupp = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32); - - /* Configure data FIFO sizes */ - /* Rx FIFO */ -#ifdef USB_OTG_FS_CORE - if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID) - { - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE); - nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE; - nptxfifosize.b.depth = TXH_NP_FS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32); - - ptxfifosize.b.startaddr = RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ; - ptxfifosize.b.depth = TXH_P_FS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32); - } -#endif -#ifdef USB_OTG_HS_CORE - if (pdev->cfg.coreID == USB_OTG_HS_CORE_ID) - { - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE); - nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE; - nptxfifosize.b.depth = TXH_NP_HS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32); - - ptxfifosize.b.startaddr = RX_FIFO_HS_SIZE + TXH_NP_HS_FIFOSIZ; - ptxfifosize.b.depth = TXH_P_HS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32); - } -#endif - -#ifdef USE_OTG_MODE - /* Clear Host Set HNP Enable in the USB_OTG Control Register */ - gotgctl.b.hstsethnpen = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GOTGCTL, gotgctl.d32, 0); -#endif - - /* Make sure the FIFOs are flushed. */ - USB_OTG_FlushTxFifo(pdev, 0x10 ); /* all Tx FIFOs */ - USB_OTG_FlushRxFifo(pdev); - - - /* Clear all pending HC Interrupts */ - for (i = 0; i < pdev->cfg.host_channels; i++) - { - USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINT, 0xFFFFFFFF ); - USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCGINTMSK, 0 ); - } -#ifndef USE_OTG_MODE - USB_OTG_DriveVbus(pdev, 1); -#endif - - USB_OTG_EnableHostInt(pdev); - return status; -} - -/** -* @brief USB_OTG_IsEvenFrame -* This function returns the frame number for sof packet -* @param pdev : Selected device -* @retval Frame number -*/ -uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) -{ - return !(USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0x1); -} - -/** -* @brief USB_OTG_DriveVbus : set/reset vbus -* @param pdev : Selected device -* @param state : VBUS state -* @retval None -*/ -void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state) -{ - USB_OTG_HPRT0_TypeDef hprt0; - - hprt0.d32 = 0; - - /* enable disable the external charge pump */ - USB_OTG_BSP_DriveVBUS(pdev, state); - - /* Turn on the Host port power. */ - hprt0.d32 = USB_OTG_ReadHPRT0(pdev); - if ((hprt0.b.prtpwr == 0 ) && (state == 1 )) - { - hprt0.b.prtpwr = 1; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - } - if ((hprt0.b.prtpwr == 1 ) && (state == 0 )) - { - hprt0.b.prtpwr = 0; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - } - - USB_OTG_BSP_mDelay(200); -} -/** -* @brief USB_OTG_EnableHostInt: Enables the Host mode interrupts -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EnableHostInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GINTMSK_TypeDef intmsk; - intmsk.d32 = 0; - /* Disable all interrupts. */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTMSK, 0); - - /* Clear any pending interrupts. */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); - - /* Enable the common interrupts */ - USB_OTG_EnableCommonInt(pdev); - - if (pdev->cfg.dma_enable == 0) - { - intmsk.b.rxstsqlvl = 1; - } - intmsk.b.portintr = 1; - intmsk.b.hcintr = 1; - intmsk.b.disconnect = 1; - intmsk.b.sofintr = 1; - intmsk.b.incomplisoout = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32); - return status; -} - -/** -* @brief USB_OTG_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the -* HCFG register on the PHY type -* @param pdev : Selected device -* @param freq : clock frequency -* @retval None -*/ -void USB_OTG_InitFSLSPClkSel(USB_OTG_CORE_HANDLE *pdev , uint8_t freq) -{ - USB_OTG_HCFG_TypeDef hcfg; - - hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); - hcfg.b.fslspclksel = freq; - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32); -} - - -/** -* @brief USB_OTG_ReadHPRT0 : Reads HPRT0 to modify later -* @param pdev : Selected device -* @retval HPRT0 value -*/ -uint32_t USB_OTG_ReadHPRT0(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HPRT0_TypeDef hprt0; - - hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); - hprt0.b.prtena = 0; - hprt0.b.prtconndet = 0; - hprt0.b.prtenchng = 0; - hprt0.b.prtovrcurrchng = 0; - return hprt0.d32; -} - - -/** -* @brief USB_OTG_ReadHostAllChannels_intr : Register PCD Callbacks -* @param pdev : Selected device -* @retval Status -*/ -uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32 (&pdev->regs.HREGS->HAINT)); -} - - -/** -* @brief USB_OTG_ResetPort : Reset Host Port -* @param pdev : Selected device -* @retval status -* @note : (1)The application must wait at least 10 ms (+ 10 ms security) -* before clearing the reset bit. -*/ -uint32_t USB_OTG_ResetPort(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HPRT0_TypeDef hprt0; - - hprt0.d32 = USB_OTG_ReadHPRT0(pdev); - hprt0.b.prtrst = 1; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - USB_OTG_BSP_mDelay (10); /* See Note #1 */ - hprt0.b.prtrst = 0; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - USB_OTG_BSP_mDelay (20); - return 1; -} - - -/** -* @brief USB_OTG_HC_Init : Prepares a host channel for transferring packets -* @param pdev : Selected device -* @param hc_num : channel number -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_HC_Init(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - uint32_t intr_enable = 0; - USB_OTG_HCGINTMSK_TypeDef hcintmsk; - USB_OTG_GINTMSK_TypeDef gintmsk; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCINTn_TypeDef hcint; - - - gintmsk.d32 = 0; - hcintmsk.d32 = 0; - hcchar.d32 = 0; - - /* Clear old interrupt conditions for this host channel. */ - hcint.d32 = 0xFFFFFFFF; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINT, hcint.d32); - - /* Enable channel interrupts required for this transfer. */ - hcintmsk.d32 = 0; - - if (pdev->cfg.dma_enable == 1) - { - hcintmsk.b.ahberr = 1; - } - - switch (pdev->host.hc[hc_num].ep_type) - { - case EP_TYPE_CTRL: - case EP_TYPE_BULK: - hcintmsk.b.xfercompl = 1; - hcintmsk.b.stall = 1; - hcintmsk.b.xacterr = 1; - hcintmsk.b.datatglerr = 1; - hcintmsk.b.nak = 1; - if (pdev->host.hc[hc_num].ep_is_in) - { - hcintmsk.b.bblerr = 1; - } - else - { - hcintmsk.b.nyet = 1; - if (pdev->host.hc[hc_num].do_ping) - { - hcintmsk.b.ack = 1; - } - } - break; - case EP_TYPE_INTR: - hcintmsk.b.xfercompl = 1; - hcintmsk.b.nak = 1; - hcintmsk.b.stall = 1; - hcintmsk.b.xacterr = 1; - hcintmsk.b.datatglerr = 1; - hcintmsk.b.frmovrun = 1; - - if (pdev->host.hc[hc_num].ep_is_in) - { - hcintmsk.b.bblerr = 1; - } - - break; - case EP_TYPE_ISOC: - hcintmsk.b.xfercompl = 1; - hcintmsk.b.frmovrun = 1; - hcintmsk.b.ack = 1; - - if (pdev->host.hc[hc_num].ep_is_in) - { - hcintmsk.b.xacterr = 1; - hcintmsk.b.bblerr = 1; - } - break; - } - - - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, hcintmsk.d32); - - - /* Enable the top level host channel interrupt. */ - intr_enable = (1 << hc_num); - USB_OTG_MODIFY_REG32(&pdev->regs.HREGS->HAINTMSK, 0, intr_enable); - - /* Make sure host channel interrupts are enabled. */ - gintmsk.b.hcintr = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, gintmsk.d32); - - /* Program the HCCHAR register */ - hcchar.d32 = 0; - hcchar.b.devaddr = pdev->host.hc[hc_num].dev_addr; - hcchar.b.epnum = pdev->host.hc[hc_num].ep_num; - hcchar.b.epdir = pdev->host.hc[hc_num].ep_is_in; - hcchar.b.lspddev = (pdev->host.hc[hc_num].speed == HPRT0_PRTSPD_LOW_SPEED); - hcchar.b.eptype = pdev->host.hc[hc_num].ep_type; - hcchar.b.mps = pdev->host.hc[hc_num].max_packet; - if (pdev->host.hc[hc_num].ep_type == HCCHAR_INTR) - { - hcchar.b.oddfrm = 1; - } - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - return status; -} - - -/** -* @brief USB_OTG_HC_StartXfer : Start transfer -* @param pdev : Selected device -* @param hc_num : channel number -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_HC_StartXfer(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCTSIZn_TypeDef hctsiz; - USB_OTG_HNPTXSTS_TypeDef hnptxsts; - USB_OTG_HPTXSTS_TypeDef hptxsts; - USB_OTG_GINTMSK_TypeDef intmsk; - uint16_t len_words = 0; - - uint16_t num_packets; - uint16_t max_hc_pkt_count; - - max_hc_pkt_count = 256; - hctsiz.d32 = 0; - hcchar.d32 = 0; - intmsk.d32 = 0; - - /* Compute the expected number of packets associated to the transfer */ - if (pdev->host.hc[hc_num].xfer_len > 0) - { - num_packets = (pdev->host.hc[hc_num].xfer_len + \ - pdev->host.hc[hc_num].max_packet - 1) / pdev->host.hc[hc_num].max_packet; - - if (num_packets > max_hc_pkt_count) - { - num_packets = max_hc_pkt_count; - pdev->host.hc[hc_num].xfer_len = num_packets * \ - pdev->host.hc[hc_num].max_packet; - } - } - else - { - num_packets = 1; - } - if (pdev->host.hc[hc_num].ep_is_in) - { - pdev->host.hc[hc_num].xfer_len = num_packets * \ - pdev->host.hc[hc_num].max_packet; - } - /* Initialize the HCTSIZn register */ - hctsiz.b.xfersize = pdev->host.hc[hc_num].xfer_len; - hctsiz.b.pktcnt = num_packets; - hctsiz.b.pid = pdev->host.hc[hc_num].data_pid; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCDMA, (unsigned int)pdev->host.hc[hc_num].xfer_buff); - } - - - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); - hcchar.b.oddfrm = USB_OTG_IsEvenFrame(pdev); - - /* Set host channel enable */ - hcchar.b.chen = 1; - hcchar.b.chdis = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - - if (pdev->cfg.dma_enable == 0) /* Slave mode */ - { - if((pdev->host.hc[hc_num].ep_is_in == 0) && - (pdev->host.hc[hc_num].xfer_len > 0)) - { - switch(pdev->host.hc[hc_num].ep_type) - { - /* Non periodic transfer */ - case EP_TYPE_CTRL: - case EP_TYPE_BULK: - - hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); - len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4; - - /* check if there is enough space in FIFO space */ - if(len_words > hnptxsts.b.nptxfspcavail) - { - /* need to process data in nptxfempty interrupt */ - intmsk.b.nptxfempty = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); - } - - break; - /* Periodic transfer */ - case EP_TYPE_INTR: - case EP_TYPE_ISOC: - hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); - len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4; - /* check if there is enough space in FIFO space */ - if(len_words > hptxsts.b.ptxfspcavail) /* split the transfer */ - { - /* need to process data in ptxfempty interrupt */ - intmsk.b.ptxfempty = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); - } - break; - - default: - break; - } - - /* Write packet into the Tx FIFO. */ - USB_OTG_WritePacket(pdev, - pdev->host.hc[hc_num].xfer_buff , - hc_num, pdev->host.hc[hc_num].xfer_len); - } - } - return status; -} - - -/** -* @brief USB_OTG_HC_Halt : Halt channel -* @param pdev : Selected device -* @param hc_num : channel number -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_HC_Halt(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_HNPTXSTS_TypeDef nptxsts; - USB_OTG_HPTXSTS_TypeDef hptxsts; - USB_OTG_HCCHAR_TypeDef hcchar; - - nptxsts.d32 = 0; - hptxsts.d32 = 0; - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); - hcchar.b.chen = 1; - hcchar.b.chdis = 1; - - /* Check for space in the request queue to issue the halt. */ - if (hcchar.b.eptype == HCCHAR_CTRL || hcchar.b.eptype == HCCHAR_BULK) - { - nptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); - if (nptxsts.b.nptxqspcavail == 0) - { - hcchar.b.chen = 0; - } - } - else - { - hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); - if (hptxsts.b.ptxqspcavail == 0) - { - hcchar.b.chen = 0; - } - } - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - return status; -} - -/** -* @brief Issue a ping token -* @param None -* @retval : None -*/ -USB_OTG_STS USB_OTG_HC_DoPing(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCTSIZn_TypeDef hctsiz; - - hctsiz.d32 = 0; - hctsiz.b.dopng = 1; - hctsiz.b.pktcnt = 1; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32); - - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); - hcchar.b.chen = 1; - hcchar.b.chdis = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - return status; -} - -/** -* @brief Stop the device and clean up fifo's -* @param None -* @retval : None -*/ -void USB_OTG_StopHost(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HCCHAR_TypeDef hcchar; - uint32_t i; - - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINTMSK , 0); - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINT, 0xFFFFFFFF); - /* Flush out any leftover queued requests. */ - - for (i = 0; i < pdev->cfg.host_channels; i++) - { - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR); - hcchar.b.chen = 0; - hcchar.b.chdis = 1; - hcchar.b.epdir = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[i]->HCCHAR, hcchar.d32); - } - - /* Flush the FIFO */ - USB_OTG_FlushRxFifo(pdev); - USB_OTG_FlushTxFifo(pdev , 0x10 ); -} -#endif -#ifdef USE_DEVICE_MODE -/* PCD Core Layer */ - -/** -* @brief USB_OTG_InitDevSpeed :Initializes the DevSpd field of DCFG register -* depending the PHY type and the enumeration speed of the device. -* @param pdev : Selected device -* @retval : None -*/ -void USB_OTG_InitDevSpeed(USB_OTG_CORE_HANDLE *pdev , uint8_t speed) -{ - USB_OTG_DCFG_TypeDef dcfg; - - dcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCFG); - dcfg.b.devspd = speed; - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCFG, dcfg.d32); -} - - -/** -* @brief USB_OTG_CoreInitDev : Initializes the USB_OTG controller registers -* for device mode -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - uint32_t i; - USB_OTG_DCFG_TypeDef dcfg; - USB_OTG_FSIZ_TypeDef nptxfifosize; - USB_OTG_FSIZ_TypeDef txfifosize; - USB_OTG_DIEPMSK_TypeDef msk; - USB_OTG_DTHRCTL_TypeDef dthrctl; - - depctl.d32 = 0; - dcfg.d32 = 0; - nptxfifosize.d32 = 0; - txfifosize.d32 = 0; - msk.d32 = 0; - - /* Restart the Phy Clock */ - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0); - /* Device configuration register */ - dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG); - dcfg.b.perfrint = DCFG_FRAME_INTERVAL_80; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32 ); - -#ifdef USB_OTG_FS_CORE - if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID ) - { - - /* Set Full speed phy */ - USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_FULL); - - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE); - - /* EP0 TX*/ - nptxfifosize.b.depth = TX0_FIFO_FS_SIZE; - nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 ); - - - /* EP1 TX*/ - txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth; - txfifosize.b.depth = TX1_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 ); - - - /* EP2 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX2_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 ); - - - /* EP3 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX3_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 ); - } -#endif -#ifdef USB_OTG_HS_CORE - if(pdev->cfg.coreID == USB_OTG_HS_CORE_ID ) - { - - /* Set High speed phy */ - - if(pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) - { - USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH); - } - else /* set High speed phy in Full speed mode */ - { - USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH_IN_FULL); - } - - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE); - - /* EP0 TX*/ - nptxfifosize.b.depth = TX0_FIFO_HS_SIZE; - nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 ); - - - /* EP1 TX*/ - txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth; - txfifosize.b.depth = TX1_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 ); - - - /* EP2 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX2_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 ); - - - /* EP3 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX3_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 ); - - /* EP4 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX4_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[3], txfifosize.d32 ); - - - /* EP5 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX5_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[4], txfifosize.d32 ); - } -#endif - /* Flush the FIFOs */ - USB_OTG_FlushTxFifo(pdev , 0x10); /* all Tx FIFOs */ - USB_OTG_FlushRxFifo(pdev); - /* Clear all pending Device Interrupts */ - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 ); - - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[i]->DIEPCTL); - if (depctl.b.epena) - { - depctl.d32 = 0; - depctl.b.epdis = 1; - depctl.b.snak = 1; - } - else - { - depctl.d32 = 0; - } - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPCTL, depctl.d32); - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPTSIZ, 0); - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); - } - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - USB_OTG_DEPCTL_TypeDef depctl; - depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[i]->DOEPCTL); - if (depctl.b.epena) - { - depctl.d32 = 0; - depctl.b.epdis = 1; - depctl.b.snak = 1; - } - else - { - depctl.d32 = 0; - } - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPCTL, depctl.d32); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPTSIZ, 0); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); - } - msk.d32 = 0; - msk.b.txfifoundrn = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPMSK, msk.d32, msk.d32); - - if (pdev->cfg.dma_enable == 1) - { - dthrctl.d32 = 0; - dthrctl.b.non_iso_thr_en = 1; - dthrctl.b.iso_thr_en = 1; - dthrctl.b.tx_thr_len = 64; - dthrctl.b.rx_thr_en = 1; - dthrctl.b.rx_thr_len = 64; - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DTHRCTL, dthrctl.d32); - } - USB_OTG_EnableDevInt(pdev); - return status; -} - - -/** -* @brief USB_OTG_EnableDevInt : Enables the Device mode interrupts -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EnableDevInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GINTMSK_TypeDef intmsk; - - intmsk.d32 = 0; - - /* Disable all interrupts. */ - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, 0); - /* Clear any pending interrupts */ - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); - /* Enable the common interrupts */ - USB_OTG_EnableCommonInt(pdev); - - if (pdev->cfg.dma_enable == 0) - { - intmsk.b.rxstsqlvl = 1; - } - - /* Enable interrupts matching to the Device mode ONLY */ - intmsk.b.usbsuspend = 1; - intmsk.b.usbreset = 1; - intmsk.b.enumdone = 1; - intmsk.b.inepintr = 1; - intmsk.b.outepintr = 1; - intmsk.b.sofintr = 1; - - intmsk.b.incomplisoin = 1; - intmsk.b.incomplisoout = 1; -#ifdef VBUS_SENSING_ENABLED - intmsk.b.sessreqintr = 1; - intmsk.b.otgintr = 1; -#endif - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32); - return status; -} - - -/** -* @brief USB_OTG_GetDeviceSpeed -* Get the device speed from the device status register -* @param None -* @retval status -*/ -enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_DSTS_TypeDef dsts; - enum USB_OTG_SPEED speed = USB_SPEED_UNKNOWN; - - - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - switch (dsts.b.enumspd) - { - case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: - speed = USB_SPEED_HIGH; - break; - case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: - case DSTS_ENUMSPD_FS_PHY_48MHZ: - speed = USB_SPEED_FULL; - break; - - case DSTS_ENUMSPD_LS_PHY_6MHZ: - speed = USB_SPEED_LOW; - break; - } - - return speed; -} -/** -* @brief enables EP0 OUT to receive SETUP packets and configures EP0 -* for transmitting packets -* @param None -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EP0Activate(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DSTS_TypeDef dsts; - USB_OTG_DEPCTL_TypeDef diepctl; - USB_OTG_DCTL_TypeDef dctl; - - dctl.d32 = 0; - /* Read the Device Status and Endpoint 0 Control registers */ - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - diepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL); - /* Set the MPS of the IN EP based on the enumeration speed */ - switch (dsts.b.enumspd) - { - case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: - case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: - case DSTS_ENUMSPD_FS_PHY_48MHZ: - diepctl.b.mps = DEP0CTL_MPS_64; - break; - case DSTS_ENUMSPD_LS_PHY_6MHZ: - diepctl.b.mps = DEP0CTL_MPS_8; - break; - } - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL, diepctl.d32); - dctl.b.cgnpinnak = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, dctl.d32); - return status; -} - - -/** -* @brief USB_OTG_EPActivate : Activates an EP -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPActivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DAINT_TypeDef daintmsk; - __IO uint32_t *addr; - - - depctl.d32 = 0; - daintmsk.d32 = 0; - /* Read DEPCTLn register */ - if (ep->is_in == 1) - { - addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL; - daintmsk.ep.in = 1 << ep->num; - } - else - { - addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL; - daintmsk.ep.out = 1 << ep->num; - } - /* If the EP is already active don't change the EP Control - * register. */ - depctl.d32 = USB_OTG_READ_REG32(addr); - if (!depctl.b.usbactep) - { - depctl.b.mps = ep->maxpacket; - depctl.b.eptype = ep->type; - depctl.b.txfnum = ep->tx_fifo_num; - depctl.b.setd0pid = 1; - depctl.b.usbactep = 1; - USB_OTG_WRITE_REG32(addr, depctl.d32); - } - /* Enable the Interrupt for this EP */ -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID)) - { - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, 0, daintmsk.d32); - } - else -#endif - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, 0, daintmsk.d32); - return status; -} - - -/** -* @brief USB_OTG_EPDeactivate : Deactivates an EP -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DAINT_TypeDef daintmsk; - __IO uint32_t *addr; - - depctl.d32 = 0; - daintmsk.d32 = 0; - /* Read DEPCTLn register */ - if (ep->is_in == 1) - { - addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL; - daintmsk.ep.in = 1 << ep->num; - } - else - { - addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL; - daintmsk.ep.out = 1 << ep->num; - } - depctl.b.usbactep = 0; - USB_OTG_WRITE_REG32(addr, depctl.d32); - /* Disable the Interrupt for this EP */ - -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID)) - { - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, daintmsk.d32, 0); - } - else -#endif - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, daintmsk.d32, 0); - return status; -} - - -/** -* @brief USB_OTG_EPStartXfer : Handle the setup for data xfer for an EP and -* starts the xfer -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DEPXFRSIZ_TypeDef deptsiz; - USB_OTG_DSTS_TypeDef dsts; - uint32_t fifoemptymsk = 0; - - depctl.d32 = 0; - deptsiz.d32 = 0; - /* IN endpoint */ - if (ep->is_in == 1) - { - depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPCTL)); - deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ)); - /* Zero Length Packet? */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = 0; - deptsiz.b.pktcnt = 1; - } - else - { - /* Program the transfer size and packet count - * as follows: xfersize = N * maxpacket + - * short_packet pktcnt = N + (short_packet - * exist ? 1 : 0) - */ - deptsiz.b.xfersize = ep->xfer_len; - deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket; - - if (ep->type == EP_TYPE_ISOC) - { - deptsiz.b.mc = 1; - } - } - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ, deptsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr); - } - else - { - if (ep->type != EP_TYPE_ISOC) - { - /* Enable the Tx FIFO Empty Interrupt for this EP */ - if (ep->xfer_len > 0) - { - fifoemptymsk = 1 << ep->num; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk); - } - } - } - - - if (ep->type == EP_TYPE_ISOC) - { - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - if (((dsts.b.soffn)&0x1) == 0) - { - depctl.b.setd1pid = 1; - } - else - { - depctl.b.setd0pid = 1; - } - } - - /* EP enable, IN data in FIFO */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPCTL, depctl.d32); - - if (ep->type == EP_TYPE_ISOC) - { - USB_OTG_WritePacket(pdev, ep->xfer_buff, ep->num, ep->xfer_len); - } - } - else - { - /* OUT endpoint */ - depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL)); - deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ)); - /* Program the transfer size and packet count as follows: - * pktcnt = N - * xfersize = N * maxpacket - */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = ep->maxpacket; - deptsiz.b.pktcnt = 1; - } - else - { - deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket; - deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; - } - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr); - } - - if (ep->type == EP_TYPE_ISOC) - { - if (ep->even_odd_frame) - { - depctl.b.setd1pid = 1; - } - else - { - depctl.b.setd0pid = 1; - } - } - /* EP enable */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL, depctl.d32); - } - return status; -} - - -/** -* @brief USB_OTG_EP0StartXfer : Handle the setup for a data xfer for EP0 and -* starts the xfer -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DEP0XFRSIZ_TypeDef deptsiz; - USB_OTG_INEPREGS *in_regs; - uint32_t fifoemptymsk = 0; - - depctl.d32 = 0; - deptsiz.d32 = 0; - /* IN endpoint */ - if (ep->is_in == 1) - { - in_regs = pdev->regs.INEP_REGS[0]; - depctl.d32 = USB_OTG_READ_REG32(&in_regs->DIEPCTL); - deptsiz.d32 = USB_OTG_READ_REG32(&in_regs->DIEPTSIZ); - /* Zero Length Packet? */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = 0; - deptsiz.b.pktcnt = 1; - - } - else - { - if (ep->xfer_len > ep->maxpacket) - { - ep->xfer_len = ep->maxpacket; - deptsiz.b.xfersize = ep->maxpacket; - } - else - { - deptsiz.b.xfersize = ep->xfer_len; - } - deptsiz.b.pktcnt = 1; - } - USB_OTG_WRITE_REG32(&in_regs->DIEPTSIZ, deptsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr); - } - - /* EP enable, IN data in FIFO */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32(&in_regs->DIEPCTL, depctl.d32); - - - - if (pdev->cfg.dma_enable == 0) - { - /* Enable the Tx FIFO Empty Interrupt for this EP */ - if (ep->xfer_len > 0) - { - { - fifoemptymsk |= 1 << ep->num; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk); - } - } - } - } - else - { - /* OUT endpoint */ - depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - deptsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ); - /* Program the transfer size and packet count as follows: - * xfersize = N * (maxpacket + 4 - (maxpacket % 4)) - * pktcnt = N */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = ep->maxpacket; - deptsiz.b.pktcnt = 1; - } - else - { - ep->xfer_len = ep->maxpacket; - deptsiz.b.xfersize = ep->maxpacket; - deptsiz.b.pktcnt = 1; - } - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32); - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr); - } - /* EP enable */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32 (&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL), depctl.d32); - - } - return status; -} - - -/** -* @brief USB_OTG_EPSetStall : Set the EP STALL -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPSetStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - - depctl.d32 = 0; - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - /* set the disable and stall bits */ - if (depctl.b.epena) - { - depctl.b.epdis = 1; - } - depctl.b.stall = 1; - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); - } - else - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - /* set the stall bit */ - depctl.b.stall = 1; - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); - } - return status; -} - - -/** -* @brief Clear the EP STALL -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPClearStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - - depctl.d32 = 0; - - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - } - else - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - } - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - /* clear the stall bits */ - depctl.b.stall = 0; - if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) - { - depctl.b.setd0pid = 1; /* DATA0 */ - } - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); - return status; -} - - -/** -* @brief USB_OTG_ReadDevAllOutEp_itr : returns OUT endpoint interrupt bits -* @param pdev : Selected device -* @retval OUT endpoint interrupt bits -*/ -uint32_t USB_OTG_ReadDevAllOutEp_itr(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t v; - v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT); - v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK); - return ((v & 0xffff0000) >> 16); -} - - -/** -* @brief USB_OTG_ReadDevOutEP_itr : returns Device OUT EP Interrupt register -* @param pdev : Selected device -* @param ep : end point number -* @retval Device OUT EP Interrupt register -*/ -uint32_t USB_OTG_ReadDevOutEP_itr(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - uint32_t v; - v = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT); - v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOEPMSK); - return v; -} - - -/** -* @brief USB_OTG_ReadDevAllInEPItr : Get int status register -* @param pdev : Selected device -* @retval int status register -*/ -uint32_t USB_OTG_ReadDevAllInEPItr(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t v; - v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT); - v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK); - return (v & 0xffff); -} - -/** -* @brief configures EPO to receive SETUP packets -* @param None -* @retval : None -*/ -void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_DEP0XFRSIZ_TypeDef doeptsize0; - doeptsize0.d32 = 0; - doeptsize0.b.supcnt = 3; - doeptsize0.b.pktcnt = 1; - doeptsize0.b.xfersize = 8 * 3; - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPTSIZ, doeptsize0.d32 ); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_DEPCTL_TypeDef doepctl; - doepctl.d32 = 0; - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPDMA, - (uint32_t)&pdev->dev.setup_packet); - - /* EP enable */ - doepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[0]->DOEPCTL); - doepctl.b.epena = 1; - doepctl.d32 = 0x80008000; - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPCTL, doepctl.d32); - } -} - -/** -* @brief USB_OTG_RemoteWakeup : active remote wakeup signalling -* @param None -* @retval : None -*/ -void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_DCTL_TypeDef dctl; - USB_OTG_DSTS_TypeDef dsts; - USB_OTG_PCGCCTL_TypeDef power; - - if (pdev->dev.DevRemoteWakeup) - { - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - if(dsts.b.suspsts == 1) - { - if(pdev->cfg.low_power) - { - /* un-gate USB Core clock */ - //power.d32 = USB_OTG_READ_REG32(&(pdev->regs.PCGCCTL)); - power.d32 = USB_OTG_READ_REG32((pdev->regs.PCGCCTL)); // ala42 - power.b.gatehclk = 0; - power.b.stoppclk = 0; - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); - } - /* active Remote wakeup signaling */ - dctl.d32 = 0; - dctl.b.rmtwkupsig = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, 0, dctl.d32); - USB_OTG_BSP_mDelay(5); - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 ); - } - } -} - - -/** -* @brief USB_OTG_UngateClock : active USB Core clock -* @param None -* @retval : None -*/ -void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev) -{ - if(pdev->cfg.low_power) - { - - USB_OTG_DSTS_TypeDef dsts; - USB_OTG_PCGCCTL_TypeDef power; - - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - if(dsts.b.suspsts == 1) - { - /* un-gate USB Core clock */ - //power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); - power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL); // ala42 - power.b.gatehclk = 0; - power.b.stoppclk = 0; - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); - - } - } -} - -/** -* @brief Stop the device and clean up fifo's -* @param None -* @retval : None -*/ -void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t i; - - pdev->dev.device_status = 1; - - for (i = 0; i < pdev->cfg.dev_endpoints ; i++) - { - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); - } - - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); - - /* Flush the FIFO */ - USB_OTG_FlushRxFifo(pdev); - USB_OTG_FlushTxFifo(pdev , 0x10 ); -} - -/** -* @brief returns the EP Status -* @param pdev : Selected device -* ep : endpoint structure -* @retval : EP status -*/ - -uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep) -{ - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - uint32_t Status = 0; - - depctl.d32 = 0; - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - - if (depctl.b.stall == 1) - Status = USB_OTG_EP_TX_STALL; - else if (depctl.b.naksts == 1) - Status = USB_OTG_EP_TX_NAK; - else - Status = USB_OTG_EP_TX_VALID; - - } - else - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - if (depctl.b.stall == 1) - Status = USB_OTG_EP_RX_STALL; - else if (depctl.b.naksts == 1) - Status = USB_OTG_EP_RX_NAK; - else - Status = USB_OTG_EP_RX_VALID; - } - - /* Return the current status */ - return Status; -} - -/** -* @brief Set the EP Status -* @param pdev : Selected device -* Status : new Status -* ep : EP structure -* @retval : None -*/ -void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status) -{ - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - - depctl.d32 = 0; - - /* Process for IN endpoint */ - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - - if (Status == USB_OTG_EP_TX_STALL) - { - USB_OTG_EPSetStall(pdev, ep); return; - } - else if (Status == USB_OTG_EP_TX_NAK) - depctl.b.snak = 1; - else if (Status == USB_OTG_EP_TX_VALID) - { - if (depctl.b.stall == 1) - { - ep->even_odd_frame = 0; - USB_OTG_EPClearStall(pdev, ep); - return; - } - depctl.b.cnak = 1; - depctl.b.usbactep = 1; - depctl.b.epena = 1; - } - else if (Status == USB_OTG_EP_TX_DIS) - depctl.b.usbactep = 0; - } - else /* Process for OUT endpoint */ - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - - if (Status == USB_OTG_EP_RX_STALL) { - depctl.b.stall = 1; - } - else if (Status == USB_OTG_EP_RX_NAK) - depctl.b.snak = 1; - else if (Status == USB_OTG_EP_RX_VALID) - { - if (depctl.b.stall == 1) - { - ep->even_odd_frame = 0; - USB_OTG_EPClearStall(pdev, ep); - return; - } - depctl.b.cnak = 1; - depctl.b.usbactep = 1; - depctl.b.epena = 1; - } - else if (Status == USB_OTG_EP_RX_DIS) - { - depctl.b.usbactep = 0; - } - } - - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); -} - -#endif -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usb_core.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief USB-OTG Core Layer + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_bsp.h" +#include "usb_core.h" + + +/** @addtogroup USB_OTG_DRIVER +* @{ +*/ + +/** @defgroup USB_CORE +* @brief This file includes the USB-OTG Core Layer +* @{ +*/ + + +/** @defgroup USB_CORE_Private_Defines +* @{ +*/ + +/** +* @} +*/ + + +/** @defgroup USB_CORE_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + + +/** @defgroup USB_CORE_Private_Macros +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USB_CORE_Private_Variables +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USB_CORE_Private_FunctionPrototypes +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USB_CORE_Private_Functions +* @{ +*/ + +/** +* @brief USB_OTG_EnableCommonInt +* Initializes the commmon interrupts, used in both device and modes +* @param pdev : Selected device +* @retval None +*/ +static void USB_OTG_EnableCommonInt(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTMSK_TypeDef int_mask; + + int_mask.d32 = 0; + /* Clear any pending USB_OTG Interrupts */ +#ifndef USE_OTG_MODE + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GOTGINT, 0xFFFFFFFF); +#endif + /* Clear any pending interrupts */ + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); + /* Enable the interrupts in the INTMSK */ + int_mask.b.wkupintr = 1; + int_mask.b.usbsuspend = 1; + +#ifdef USE_OTG_MODE + int_mask.b.otgintr = 1; + int_mask.b.sessreqintr = 1; + int_mask.b.conidstschng = 1; +#endif + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32); +} + +/** +* @brief USB_OTG_CoreReset : Soft reset of the core +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +static USB_OTG_STS USB_OTG_CoreReset(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_STS status = USB_OTG_OK; + __IO USB_OTG_GRSTCTL_TypeDef greset; + uint32_t count = 0; + + greset.d32 = 0; + /* Wait for AHB master IDLE state. */ + do + { + USB_OTG_BSP_uDelay(3); + greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL); + if (++count > 200000) + { + return USB_OTG_OK; + } + } + while (greset.b.ahbidle == 0); + /* Core Soft Reset */ + count = 0; + greset.b.csftrst = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRSTCTL, greset.d32 ); + do + { + greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL); + if (++count > 200000) + { + break; + } + } + while (greset.b.csftrst == 1); + /* Wait for 3 PHY Clocks*/ + USB_OTG_BSP_uDelay(3); + return status; +} + +/** +* @brief USB_OTG_WritePacket : Writes a packet into the Tx FIFO associated +* with the EP +* @param pdev : Selected device +* @param src : source pointer +* @param ch_ep_num : end point number +* @param bytes : No. of bytes +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev, + uint8_t *src, + uint8_t ch_ep_num, + uint16_t len) +{ + USB_OTG_STS status = USB_OTG_OK; + if (pdev->cfg.dma_enable == 0) + { + uint32_t count32b= 0 , i= 0; + __IO uint32_t *fifo; + + count32b = (len + 3) / 4; + fifo = pdev->regs.DFIFO[ch_ep_num]; + for (i = 0; i < count32b; i++, src+=4) + { + USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) ); + } + } + return status; +} + + +/** +* @brief USB_OTG_ReadPacket : Reads a packet from the Rx FIFO +* @param pdev : Selected device +* @param dest : Destination Pointer +* @param bytes : No. of bytes +* @retval None +*/ +void *USB_OTG_ReadPacket(USB_OTG_CORE_HANDLE *pdev, + uint8_t *dest, + uint16_t len) +{ + uint32_t i=0; + uint32_t count32b = (len + 3) / 4; + + __IO uint32_t *fifo = pdev->regs.DFIFO[0]; + + for ( i = 0; i < count32b; i++, dest += 4 ) + { + *(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo); + + } + return ((void *)dest); +} + +/** +* @brief USB_OTG_SelectCore +* Initialize core registers address. +* @param pdev : Selected device +* @param coreID : USB OTG Core ID +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_SelectCore(USB_OTG_CORE_HANDLE *pdev, + USB_OTG_CORE_ID_TypeDef coreID) +{ + uint32_t i , baseAddress = 0; + USB_OTG_STS status = USB_OTG_OK; + + pdev->cfg.dma_enable = 0; + + /* at startup the core is in FS mode */ + pdev->cfg.speed = USB_OTG_SPEED_FULL; + pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; + + /* initialize device cfg following its address */ + if (coreID == USB_OTG_FS_CORE_ID) + { + baseAddress = USB_OTG_FS_BASE_ADDR; + pdev->cfg.coreID = USB_OTG_FS_CORE_ID; + pdev->cfg.host_channels = 8 ; + pdev->cfg.dev_endpoints = 4 ; + pdev->cfg.TotalFifoSize = 320; /* in 32-bits */ + pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY; + +#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED + pdev->cfg.Sof_output = 1; +#endif + +#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT + pdev->cfg.low_power = 1; +#endif + } + else if (coreID == USB_OTG_HS_CORE_ID) + { + baseAddress = USB_OTG_HS_BASE_ADDR; + pdev->cfg.coreID = USB_OTG_HS_CORE_ID; + pdev->cfg.host_channels = 12 ; + pdev->cfg.dev_endpoints = 6 ; + pdev->cfg.TotalFifoSize = 1280;/* in 32-bits */ + +#ifdef USB_OTG_ULPI_PHY_ENABLED + pdev->cfg.phy_itface = USB_OTG_ULPI_PHY; +#else + #ifdef USB_OTG_EMBEDDED_PHY_ENABLED + pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY; + #else + #ifdef USB_OTG_I2C_PHY_ENABLED + pdev->cfg.phy_itface = USB_OTG_I2C_PHY; + #endif + #endif +#endif + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + pdev->cfg.dma_enable = 1; +#endif + +#ifdef USB_OTG_HS_SOF_OUTPUT_ENABLED + pdev->cfg.Sof_output = 1; +#endif + +#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT + pdev->cfg.low_power = 1; +#endif + + } + + pdev->regs.GREGS = (USB_OTG_GREGS *)(baseAddress + \ + USB_OTG_CORE_GLOBAL_REGS_OFFSET); + pdev->regs.DREGS = (USB_OTG_DREGS *) (baseAddress + \ + USB_OTG_DEV_GLOBAL_REG_OFFSET); + + for (i = 0; i < pdev->cfg.dev_endpoints; i++) + { + pdev->regs.INEP_REGS[i] = (USB_OTG_INEPREGS *) \ + (baseAddress + USB_OTG_DEV_IN_EP_REG_OFFSET + \ + (i * USB_OTG_EP_REG_OFFSET)); + pdev->regs.OUTEP_REGS[i] = (USB_OTG_OUTEPREGS *) \ + (baseAddress + USB_OTG_DEV_OUT_EP_REG_OFFSET + \ + (i * USB_OTG_EP_REG_OFFSET)); + } + pdev->regs.HREGS = (USB_OTG_HREGS *)(baseAddress + \ + USB_OTG_HOST_GLOBAL_REG_OFFSET); + pdev->regs.HPRT0 = (uint32_t *)(baseAddress + USB_OTG_HOST_PORT_REGS_OFFSET); + + for (i = 0; i < pdev->cfg.host_channels; i++) + { + pdev->regs.HC_REGS[i] = (USB_OTG_HC_REGS *)(baseAddress + \ + USB_OTG_HOST_CHAN_REGS_OFFSET + \ + (i * USB_OTG_CHAN_REGS_OFFSET)); + } + for (i = 0; i < pdev->cfg.host_channels; i++) + { + pdev->regs.DFIFO[i] = (uint32_t *)(baseAddress + USB_OTG_DATA_FIFO_OFFSET +\ + (i * USB_OTG_DATA_FIFO_SIZE)); + } + pdev->regs.PCGCCTL = (uint32_t *)(baseAddress + USB_OTG_PCGCCTL_OFFSET); + + return status; +} + + +/** +* @brief USB_OTG_CoreInit +* Initializes the USB_OTG controller registers and prepares the core +* device mode or host mode operation. +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_GUSBCFG_TypeDef usbcfg; + USB_OTG_GCCFG_TypeDef gccfg; + USB_OTG_GI2CCTL_TypeDef i2cctl; + USB_OTG_GAHBCFG_TypeDef ahbcfg; + + usbcfg.d32 = 0; + gccfg.d32 = 0; + ahbcfg.d32 = 0; + + + + if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) + { + gccfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GCCFG); + gccfg.b.pwdn = 0; + + if (pdev->cfg.Sof_output) + { + gccfg.b.sofouten = 1; + } + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32); + + /* Init The ULPI Interface */ + usbcfg.d32 = 0; + usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); + + usbcfg.b.physel = 0; /* HS Interface */ +#ifdef USB_OTG_INTERNAL_VBUS_ENABLED + usbcfg.b.ulpi_ext_vbus_drv = 0; /* Use internal VBUS */ +#else + #ifdef USB_OTG_EXTERNAL_VBUS_ENABLED + usbcfg.b.ulpi_ext_vbus_drv = 1; /* Use external VBUS */ + #endif +#endif + usbcfg.b.term_sel_dl_pulse = 0; /* Data line pulsing using utmi_txvalid */ + usbcfg.b.ulpi_utmi_sel = 1; /* ULPI seleInterfacect */ + + usbcfg.b.phyif = 0; /* 8 bits */ + usbcfg.b.ddrsel = 0; /* single data rate */ + + usbcfg.b.ulpi_fsls = 0; + usbcfg.b.ulpi_clk_sus_m = 0; + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); + + /* Reset after a PHY select */ + USB_OTG_CoreReset(pdev); + + if(pdev->cfg.dma_enable == 1) + { + + ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/ + ahbcfg.b.dmaenable = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32); + + } + } + else /* FS interface (embedded Phy or I2C Phy) */ + { + + usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);; + usbcfg.b.physel = 1; /* FS Interface */ + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); + /* Reset after a PHY select and set Host mode */ + USB_OTG_CoreReset(pdev); + /* Enable the I2C interface and deactivate the power down*/ + gccfg.d32 = 0; + gccfg.b.pwdn = 1; + + if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) + { + gccfg.b.i2cifen = 1; + } + gccfg.b.vbussensingA = 1 ; + gccfg.b.vbussensingB = 1 ; +#ifndef VBUS_SENSING_ENABLED + gccfg.b.disablevbussensing = 1; +#endif + + if(pdev->cfg.Sof_output) + { + gccfg.b.sofouten = 1; + } + + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32); + USB_OTG_BSP_mDelay(20); + /* Program GUSBCFG.OtgUtmifsSel to I2C*/ + usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); + + if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) + { + usbcfg.b.otgutmifssel = 1; + } + + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); + + if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) + { + /*Program GI2CCTL.I2CEn*/ + i2cctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GI2CCTL); + i2cctl.b.i2cdevaddr = 1; + i2cctl.b.i2cen = 0; + i2cctl.b.dat_se0 = 1; + i2cctl.b.addr = 0x2D; + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32); + + USB_OTG_BSP_mDelay(200); + + i2cctl.b.i2cen = 1; + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32); + USB_OTG_BSP_mDelay(200); + } + } + /* case the HS core is working in FS mode */ + if(pdev->cfg.dma_enable == 1) + { + + ahbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GAHBCFG); + ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/ + ahbcfg.b.dmaenable = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32); + + } + /* initialize OTG features */ +#ifdef USE_OTG_MODE + usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); + usbcfg.b.hnpcap = 1; + usbcfg.b.srpcap = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); + USB_OTG_EnableCommonInt(pdev); +#endif + return status; +} +/** +* @brief USB_OTG_EnableGlobalInt +* Enables the controller's Global Int in the AHB Config reg +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_EnableGlobalInt(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_GAHBCFG_TypeDef ahbcfg; + + ahbcfg.d32 = 0; + ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ + USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, 0, ahbcfg.d32); + return status; +} + + +/** +* @brief USB_OTG_DisableGlobalInt +* Enables the controller's Global Int in the AHB Config reg +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_GAHBCFG_TypeDef ahbcfg; + ahbcfg.d32 = 0; + ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ + USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32, 0); + return status; +} + + +/** +* @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO +* @param pdev : Selected device +* @param num : FO num +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num ) +{ + USB_OTG_STS status = USB_OTG_OK; + __IO USB_OTG_GRSTCTL_TypeDef greset; + + uint32_t count = 0; + greset.d32 = 0; + greset.b.txfflsh = 1; + greset.b.txfnum = num; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 ); + do + { + greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL); + if (++count > 200000) + { + break; + } + } + while (greset.b.txfflsh == 1); + /* Wait for 3 PHY Clocks*/ + USB_OTG_BSP_uDelay(3); + return status; +} + + +/** +* @brief USB_OTG_FlushRxFifo : Flush a Rx FIFO +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_FlushRxFifo( USB_OTG_CORE_HANDLE *pdev ) +{ + USB_OTG_STS status = USB_OTG_OK; + __IO USB_OTG_GRSTCTL_TypeDef greset; + uint32_t count = 0; + + greset.d32 = 0; + greset.b.rxfflsh = 1; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 ); + do + { + greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL); + if (++count > 200000) + { + break; + } + } + while (greset.b.rxfflsh == 1); + /* Wait for 3 PHY Clocks*/ + USB_OTG_BSP_uDelay(3); + return status; +} + + +/** +* @brief USB_OTG_SetCurrentMode : Set ID line +* @param pdev : Selected device +* @param mode : (Host/device) +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_SetCurrentMode(USB_OTG_CORE_HANDLE *pdev , uint8_t mode) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_GUSBCFG_TypeDef usbcfg; + + usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); + + usbcfg.b.force_host = 0; + usbcfg.b.force_dev = 0; + + if ( mode == HOST_MODE) + { + usbcfg.b.force_host = 1; + } + else if ( mode == DEVICE_MODE) + { + usbcfg.b.force_dev = 1; + } + + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); + USB_OTG_BSP_mDelay(50); + return status; +} + + +/** +* @brief USB_OTG_GetMode : Get current mode +* @param pdev : Selected device +* @retval current mode +*/ +uint32_t USB_OTG_GetMode(USB_OTG_CORE_HANDLE *pdev) +{ + return (USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS ) & 0x1); +} + + +/** +* @brief USB_OTG_IsDeviceMode : Check if it is device mode +* @param pdev : Selected device +* @retval num_in_ep +*/ +uint8_t USB_OTG_IsDeviceMode(USB_OTG_CORE_HANDLE *pdev) +{ + return (USB_OTG_GetMode(pdev) != HOST_MODE); +} + + +/** +* @brief USB_OTG_IsHostMode : Check if it is host mode +* @param pdev : Selected device +* @retval num_in_ep +*/ +uint8_t USB_OTG_IsHostMode(USB_OTG_CORE_HANDLE *pdev) +{ + return (USB_OTG_GetMode(pdev) == HOST_MODE); +} + + +/** +* @brief USB_OTG_ReadCoreItr : returns the Core Interrupt register +* @param pdev : Selected device +* @retval Status +*/ +uint32_t USB_OTG_ReadCoreItr(USB_OTG_CORE_HANDLE *pdev) +{ + uint32_t v = 0; + v = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS); + v &= USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK); + return v; +} + + +/** +* @brief USB_OTG_ReadOtgItr : returns the USB_OTG Interrupt register +* @param pdev : Selected device +* @retval Status +*/ +uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev) +{ + return (USB_OTG_READ_REG32 (&pdev->regs.GREGS->GOTGINT)); +} + +#ifdef USE_HOST_MODE +/** +* @brief USB_OTG_CoreInitHost : Initializes USB_OTG controller for host mode +* @param pdev : Selected device +* @retval status +*/ +USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_FSIZ_TypeDef nptxfifosize; + USB_OTG_FSIZ_TypeDef ptxfifosize; + USB_OTG_HCFG_TypeDef hcfg; + +#ifdef USE_OTG_MODE + USB_OTG_OTGCTL_TypeDef gotgctl; +#endif + + uint32_t i = 0; + + nptxfifosize.d32 = 0; + ptxfifosize.d32 = 0; +#ifdef USE_OTG_MODE + gotgctl.d32 = 0; +#endif + hcfg.d32 = 0; + + + /* configure charge pump IO */ + USB_OTG_BSP_ConfigVBUS(pdev); + + /* Restart the Phy Clock */ + USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0); + + /* Initialize Host Configuration Register */ + USB_OTG_InitFSLSPClkSel(pdev , HCFG_48_MHZ); /* in init phase */ + + hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); + hcfg.b.fslssupp = 0; + USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32); + + /* Configure data FIFO sizes */ + /* Rx FIFO */ +#ifdef USB_OTG_FS_CORE + if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID) + { + /* set Rx FIFO size */ + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE); + nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE; + nptxfifosize.b.depth = TXH_NP_FS_FIFOSIZ; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32); + + ptxfifosize.b.startaddr = RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ; + ptxfifosize.b.depth = TXH_P_FS_FIFOSIZ; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32); + } +#endif +#ifdef USB_OTG_HS_CORE + if (pdev->cfg.coreID == USB_OTG_HS_CORE_ID) + { + /* set Rx FIFO size */ + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE); + nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE; + nptxfifosize.b.depth = TXH_NP_HS_FIFOSIZ; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32); + + ptxfifosize.b.startaddr = RX_FIFO_HS_SIZE + TXH_NP_HS_FIFOSIZ; + ptxfifosize.b.depth = TXH_P_HS_FIFOSIZ; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32); + } +#endif + +#ifdef USE_OTG_MODE + /* Clear Host Set HNP Enable in the USB_OTG Control Register */ + gotgctl.b.hstsethnpen = 1; + USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GOTGCTL, gotgctl.d32, 0); +#endif + + /* Make sure the FIFOs are flushed. */ + USB_OTG_FlushTxFifo(pdev, 0x10 ); /* all Tx FIFOs */ + USB_OTG_FlushRxFifo(pdev); + + + /* Clear all pending HC Interrupts */ + for (i = 0; i < pdev->cfg.host_channels; i++) + { + USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINT, 0xFFFFFFFF ); + USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCGINTMSK, 0 ); + } +#ifndef USE_OTG_MODE + USB_OTG_DriveVbus(pdev, 1); +#endif + + USB_OTG_EnableHostInt(pdev); + return status; +} + +/** +* @brief USB_OTG_IsEvenFrame +* This function returns the frame number for sof packet +* @param pdev : Selected device +* @retval Frame number +*/ +uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) +{ + return !(USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0x1); +} + +/** +* @brief USB_OTG_DriveVbus : set/reset vbus +* @param pdev : Selected device +* @param state : VBUS state +* @retval None +*/ +void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state) +{ + USB_OTG_HPRT0_TypeDef hprt0; + + hprt0.d32 = 0; + + /* enable disable the external charge pump */ + USB_OTG_BSP_DriveVBUS(pdev, state); + + /* Turn on the Host port power. */ + hprt0.d32 = USB_OTG_ReadHPRT0(pdev); + if ((hprt0.b.prtpwr == 0 ) && (state == 1 )) + { + hprt0.b.prtpwr = 1; + USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); + } + if ((hprt0.b.prtpwr == 1 ) && (state == 0 )) + { + hprt0.b.prtpwr = 0; + USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); + } + + USB_OTG_BSP_mDelay(200); +} +/** +* @brief USB_OTG_EnableHostInt: Enables the Host mode interrupts +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_EnableHostInt(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_GINTMSK_TypeDef intmsk; + intmsk.d32 = 0; + /* Disable all interrupts. */ + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTMSK, 0); + + /* Clear any pending interrupts. */ + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); + + /* Enable the common interrupts */ + USB_OTG_EnableCommonInt(pdev); + + if (pdev->cfg.dma_enable == 0) + { + intmsk.b.rxstsqlvl = 1; + } + intmsk.b.portintr = 1; + intmsk.b.hcintr = 1; + intmsk.b.disconnect = 1; + intmsk.b.sofintr = 1; + intmsk.b.incomplisoout = 1; + USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32); + return status; +} + +/** +* @brief USB_OTG_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the +* HCFG register on the PHY type +* @param pdev : Selected device +* @param freq : clock frequency +* @retval None +*/ +void USB_OTG_InitFSLSPClkSel(USB_OTG_CORE_HANDLE *pdev , uint8_t freq) +{ + USB_OTG_HCFG_TypeDef hcfg; + + hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); + hcfg.b.fslspclksel = freq; + USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32); +} + + +/** +* @brief USB_OTG_ReadHPRT0 : Reads HPRT0 to modify later +* @param pdev : Selected device +* @retval HPRT0 value +*/ +uint32_t USB_OTG_ReadHPRT0(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_HPRT0_TypeDef hprt0; + + hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); + hprt0.b.prtena = 0; + hprt0.b.prtconndet = 0; + hprt0.b.prtenchng = 0; + hprt0.b.prtovrcurrchng = 0; + return hprt0.d32; +} + + +/** +* @brief USB_OTG_ReadHostAllChannels_intr : Register PCD Callbacks +* @param pdev : Selected device +* @retval Status +*/ +uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev) +{ + return (USB_OTG_READ_REG32 (&pdev->regs.HREGS->HAINT)); +} + + +/** +* @brief USB_OTG_ResetPort : Reset Host Port +* @param pdev : Selected device +* @retval status +* @note : (1)The application must wait at least 10 ms (+ 10 ms security) +* before clearing the reset bit. +*/ +uint32_t USB_OTG_ResetPort(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_HPRT0_TypeDef hprt0; + + hprt0.d32 = USB_OTG_ReadHPRT0(pdev); + hprt0.b.prtrst = 1; + USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); + USB_OTG_BSP_mDelay (10); /* See Note #1 */ + hprt0.b.prtrst = 0; + USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); + USB_OTG_BSP_mDelay (20); + return 1; +} + + +/** +* @brief USB_OTG_HC_Init : Prepares a host channel for transferring packets +* @param pdev : Selected device +* @param hc_num : channel number +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_HC_Init(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) +{ + USB_OTG_STS status = USB_OTG_OK; + uint32_t intr_enable = 0; + USB_OTG_HCGINTMSK_TypeDef hcintmsk; + USB_OTG_GINTMSK_TypeDef gintmsk; + USB_OTG_HCCHAR_TypeDef hcchar; + USB_OTG_HCINTn_TypeDef hcint; + + + gintmsk.d32 = 0; + hcintmsk.d32 = 0; + hcchar.d32 = 0; + + /* Clear old interrupt conditions for this host channel. */ + hcint.d32 = 0xFFFFFFFF; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINT, hcint.d32); + + /* Enable channel interrupts required for this transfer. */ + hcintmsk.d32 = 0; + + if (pdev->cfg.dma_enable == 1) + { + hcintmsk.b.ahberr = 1; + } + + switch (pdev->host.hc[hc_num].ep_type) + { + case EP_TYPE_CTRL: + case EP_TYPE_BULK: + hcintmsk.b.xfercompl = 1; + hcintmsk.b.stall = 1; + hcintmsk.b.xacterr = 1; + hcintmsk.b.datatglerr = 1; + hcintmsk.b.nak = 1; + if (pdev->host.hc[hc_num].ep_is_in) + { + hcintmsk.b.bblerr = 1; + } + else + { + hcintmsk.b.nyet = 1; + if (pdev->host.hc[hc_num].do_ping) + { + hcintmsk.b.ack = 1; + } + } + break; + case EP_TYPE_INTR: + hcintmsk.b.xfercompl = 1; + hcintmsk.b.nak = 1; + hcintmsk.b.stall = 1; + hcintmsk.b.xacterr = 1; + hcintmsk.b.datatglerr = 1; + hcintmsk.b.frmovrun = 1; + + if (pdev->host.hc[hc_num].ep_is_in) + { + hcintmsk.b.bblerr = 1; + } + + break; + case EP_TYPE_ISOC: + hcintmsk.b.xfercompl = 1; + hcintmsk.b.frmovrun = 1; + hcintmsk.b.ack = 1; + + if (pdev->host.hc[hc_num].ep_is_in) + { + hcintmsk.b.xacterr = 1; + hcintmsk.b.bblerr = 1; + } + break; + } + + + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, hcintmsk.d32); + + + /* Enable the top level host channel interrupt. */ + intr_enable = (1 << hc_num); + USB_OTG_MODIFY_REG32(&pdev->regs.HREGS->HAINTMSK, 0, intr_enable); + + /* Make sure host channel interrupts are enabled. */ + gintmsk.b.hcintr = 1; + USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, gintmsk.d32); + + /* Program the HCCHAR register */ + hcchar.d32 = 0; + hcchar.b.devaddr = pdev->host.hc[hc_num].dev_addr; + hcchar.b.epnum = pdev->host.hc[hc_num].ep_num; + hcchar.b.epdir = pdev->host.hc[hc_num].ep_is_in; + hcchar.b.lspddev = (pdev->host.hc[hc_num].speed == HPRT0_PRTSPD_LOW_SPEED); + hcchar.b.eptype = pdev->host.hc[hc_num].ep_type; + hcchar.b.mps = pdev->host.hc[hc_num].max_packet; + if (pdev->host.hc[hc_num].ep_type == HCCHAR_INTR) + { + hcchar.b.oddfrm = 1; + } + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); + return status; +} + + +/** +* @brief USB_OTG_HC_StartXfer : Start transfer +* @param pdev : Selected device +* @param hc_num : channel number +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_HC_StartXfer(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_HCCHAR_TypeDef hcchar; + USB_OTG_HCTSIZn_TypeDef hctsiz; + USB_OTG_HNPTXSTS_TypeDef hnptxsts; + USB_OTG_HPTXSTS_TypeDef hptxsts; + USB_OTG_GINTMSK_TypeDef intmsk; + uint16_t len_words = 0; + + uint16_t num_packets; + uint16_t max_hc_pkt_count; + + max_hc_pkt_count = 256; + hctsiz.d32 = 0; + hcchar.d32 = 0; + intmsk.d32 = 0; + + /* Compute the expected number of packets associated to the transfer */ + if (pdev->host.hc[hc_num].xfer_len > 0) + { + num_packets = (pdev->host.hc[hc_num].xfer_len + \ + pdev->host.hc[hc_num].max_packet - 1) / pdev->host.hc[hc_num].max_packet; + + if (num_packets > max_hc_pkt_count) + { + num_packets = max_hc_pkt_count; + pdev->host.hc[hc_num].xfer_len = num_packets * \ + pdev->host.hc[hc_num].max_packet; + } + } + else + { + num_packets = 1; + } + if (pdev->host.hc[hc_num].ep_is_in) + { + pdev->host.hc[hc_num].xfer_len = num_packets * \ + pdev->host.hc[hc_num].max_packet; + } + /* Initialize the HCTSIZn register */ + hctsiz.b.xfersize = pdev->host.hc[hc_num].xfer_len; + hctsiz.b.pktcnt = num_packets; + hctsiz.b.pid = pdev->host.hc[hc_num].data_pid; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32); + + if (pdev->cfg.dma_enable == 1) + { + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCDMA, (unsigned int)pdev->host.hc[hc_num].xfer_buff); + } + + + hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); + hcchar.b.oddfrm = USB_OTG_IsEvenFrame(pdev); + + /* Set host channel enable */ + hcchar.b.chen = 1; + hcchar.b.chdis = 0; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); + + if (pdev->cfg.dma_enable == 0) /* Slave mode */ + { + if((pdev->host.hc[hc_num].ep_is_in == 0) && + (pdev->host.hc[hc_num].xfer_len > 0)) + { + switch(pdev->host.hc[hc_num].ep_type) + { + /* Non periodic transfer */ + case EP_TYPE_CTRL: + case EP_TYPE_BULK: + + hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); + len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4; + + /* check if there is enough space in FIFO space */ + if(len_words > hnptxsts.b.nptxfspcavail) + { + /* need to process data in nptxfempty interrupt */ + intmsk.b.nptxfempty = 1; + USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); + } + + break; + /* Periodic transfer */ + case EP_TYPE_INTR: + case EP_TYPE_ISOC: + hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); + len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4; + /* check if there is enough space in FIFO space */ + if(len_words > hptxsts.b.ptxfspcavail) /* split the transfer */ + { + /* need to process data in ptxfempty interrupt */ + intmsk.b.ptxfempty = 1; + USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); + } + break; + + default: + break; + } + + /* Write packet into the Tx FIFO. */ + USB_OTG_WritePacket(pdev, + pdev->host.hc[hc_num].xfer_buff , + hc_num, pdev->host.hc[hc_num].xfer_len); + } + } + return status; +} + + +/** +* @brief USB_OTG_HC_Halt : Halt channel +* @param pdev : Selected device +* @param hc_num : channel number +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_HC_Halt(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_HNPTXSTS_TypeDef nptxsts; + USB_OTG_HPTXSTS_TypeDef hptxsts; + USB_OTG_HCCHAR_TypeDef hcchar; + + nptxsts.d32 = 0; + hptxsts.d32 = 0; + hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); + hcchar.b.chen = 1; + hcchar.b.chdis = 1; + + /* Check for space in the request queue to issue the halt. */ + if (hcchar.b.eptype == HCCHAR_CTRL || hcchar.b.eptype == HCCHAR_BULK) + { + nptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); + if (nptxsts.b.nptxqspcavail == 0) + { + hcchar.b.chen = 0; + } + } + else + { + hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); + if (hptxsts.b.ptxqspcavail == 0) + { + hcchar.b.chen = 0; + } + } + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); + return status; +} + +/** +* @brief Issue a ping token +* @param None +* @retval : None +*/ +USB_OTG_STS USB_OTG_HC_DoPing(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_HCCHAR_TypeDef hcchar; + USB_OTG_HCTSIZn_TypeDef hctsiz; + + hctsiz.d32 = 0; + hctsiz.b.dopng = 1; + hctsiz.b.pktcnt = 1; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32); + + hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); + hcchar.b.chen = 1; + hcchar.b.chdis = 0; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); + return status; +} + +/** +* @brief Stop the device and clean up fifo's +* @param None +* @retval : None +*/ +void USB_OTG_StopHost(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_HCCHAR_TypeDef hcchar; + uint32_t i; + + USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINTMSK , 0); + USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINT, 0xFFFFFFFF); + /* Flush out any leftover queued requests. */ + + for (i = 0; i < pdev->cfg.host_channels; i++) + { + hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR); + hcchar.b.chen = 0; + hcchar.b.chdis = 1; + hcchar.b.epdir = 0; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[i]->HCCHAR, hcchar.d32); + } + + /* Flush the FIFO */ + USB_OTG_FlushRxFifo(pdev); + USB_OTG_FlushTxFifo(pdev , 0x10 ); +} +#endif +#ifdef USE_DEVICE_MODE +/* PCD Core Layer */ + +/** +* @brief USB_OTG_InitDevSpeed :Initializes the DevSpd field of DCFG register +* depending the PHY type and the enumeration speed of the device. +* @param pdev : Selected device +* @retval : None +*/ +void USB_OTG_InitDevSpeed(USB_OTG_CORE_HANDLE *pdev , uint8_t speed) +{ + USB_OTG_DCFG_TypeDef dcfg; + + dcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCFG); + dcfg.b.devspd = speed; + USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCFG, dcfg.d32); +} + + +/** +* @brief USB_OTG_CoreInitDev : Initializes the USB_OTG controller registers +* for device mode +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_DEPCTL_TypeDef depctl; + uint32_t i; + USB_OTG_DCFG_TypeDef dcfg; + USB_OTG_FSIZ_TypeDef nptxfifosize; + USB_OTG_FSIZ_TypeDef txfifosize; + USB_OTG_DIEPMSK_TypeDef msk; + USB_OTG_DTHRCTL_TypeDef dthrctl; + + depctl.d32 = 0; + dcfg.d32 = 0; + nptxfifosize.d32 = 0; + txfifosize.d32 = 0; + msk.d32 = 0; + + /* Restart the Phy Clock */ + USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0); + /* Device configuration register */ + dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG); + dcfg.b.perfrint = DCFG_FRAME_INTERVAL_80; + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32 ); + +#ifdef USB_OTG_FS_CORE + if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID ) + { + + /* Set Full speed phy */ + USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_FULL); + + /* set Rx FIFO size */ + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE); + + /* EP0 TX*/ + nptxfifosize.b.depth = TX0_FIFO_FS_SIZE; + nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 ); + + + /* EP1 TX*/ + txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth; + txfifosize.b.depth = TX1_FIFO_FS_SIZE; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 ); + + + /* EP2 TX*/ + txfifosize.b.startaddr += txfifosize.b.depth; + txfifosize.b.depth = TX2_FIFO_FS_SIZE; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 ); + + + /* EP3 TX*/ + txfifosize.b.startaddr += txfifosize.b.depth; + txfifosize.b.depth = TX3_FIFO_FS_SIZE; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 ); + } +#endif +#ifdef USB_OTG_HS_CORE + if(pdev->cfg.coreID == USB_OTG_HS_CORE_ID ) + { + + /* Set High speed phy */ + + if(pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) + { + USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH); + } + else /* set High speed phy in Full speed mode */ + { + USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH_IN_FULL); + } + + /* set Rx FIFO size */ + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE); + + /* EP0 TX*/ + nptxfifosize.b.depth = TX0_FIFO_HS_SIZE; + nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 ); + + + /* EP1 TX*/ + txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth; + txfifosize.b.depth = TX1_FIFO_HS_SIZE; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 ); + + + /* EP2 TX*/ + txfifosize.b.startaddr += txfifosize.b.depth; + txfifosize.b.depth = TX2_FIFO_HS_SIZE; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 ); + + + /* EP3 TX*/ + txfifosize.b.startaddr += txfifosize.b.depth; + txfifosize.b.depth = TX3_FIFO_HS_SIZE; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 ); + + /* EP4 TX*/ + txfifosize.b.startaddr += txfifosize.b.depth; + txfifosize.b.depth = TX4_FIFO_HS_SIZE; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[3], txfifosize.d32 ); + + + /* EP5 TX*/ + txfifosize.b.startaddr += txfifosize.b.depth; + txfifosize.b.depth = TX5_FIFO_HS_SIZE; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[4], txfifosize.d32 ); + } +#endif + /* Flush the FIFOs */ + USB_OTG_FlushTxFifo(pdev , 0x10); /* all Tx FIFOs */ + USB_OTG_FlushRxFifo(pdev); + /* Clear all pending Device Interrupts */ + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 ); + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 ); + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 ); + + for (i = 0; i < pdev->cfg.dev_endpoints; i++) + { + depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[i]->DIEPCTL); + if (depctl.b.epena) + { + depctl.d32 = 0; + depctl.b.epdis = 1; + depctl.b.snak = 1; + } + else + { + depctl.d32 = 0; + } + USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPCTL, depctl.d32); + USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPTSIZ, 0); + USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); + } + for (i = 0; i < pdev->cfg.dev_endpoints; i++) + { + USB_OTG_DEPCTL_TypeDef depctl; + depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[i]->DOEPCTL); + if (depctl.b.epena) + { + depctl.d32 = 0; + depctl.b.epdis = 1; + depctl.b.snak = 1; + } + else + { + depctl.d32 = 0; + } + USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPCTL, depctl.d32); + USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPTSIZ, 0); + USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); + } + msk.d32 = 0; + msk.b.txfifoundrn = 1; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPMSK, msk.d32, msk.d32); + + if (pdev->cfg.dma_enable == 1) + { + dthrctl.d32 = 0; + dthrctl.b.non_iso_thr_en = 1; + dthrctl.b.iso_thr_en = 1; + dthrctl.b.tx_thr_len = 64; + dthrctl.b.rx_thr_en = 1; + dthrctl.b.rx_thr_len = 64; + USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DTHRCTL, dthrctl.d32); + } + USB_OTG_EnableDevInt(pdev); + return status; +} + + +/** +* @brief USB_OTG_EnableDevInt : Enables the Device mode interrupts +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_EnableDevInt(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_GINTMSK_TypeDef intmsk; + + intmsk.d32 = 0; + + /* Disable all interrupts. */ + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, 0); + /* Clear any pending interrupts */ + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); + /* Enable the common interrupts */ + USB_OTG_EnableCommonInt(pdev); + + if (pdev->cfg.dma_enable == 0) + { + intmsk.b.rxstsqlvl = 1; + } + + /* Enable interrupts matching to the Device mode ONLY */ + intmsk.b.usbsuspend = 1; + intmsk.b.usbreset = 1; + intmsk.b.enumdone = 1; + intmsk.b.inepintr = 1; + intmsk.b.outepintr = 1; + intmsk.b.sofintr = 1; + + intmsk.b.incomplisoin = 1; + intmsk.b.incomplisoout = 1; +#ifdef VBUS_SENSING_ENABLED + intmsk.b.sessreqintr = 1; + intmsk.b.otgintr = 1; +#endif + USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32); + return status; +} + + +/** +* @brief USB_OTG_GetDeviceSpeed +* Get the device speed from the device status register +* @param None +* @retval status +*/ +enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_DSTS_TypeDef dsts; + enum USB_OTG_SPEED speed = USB_SPEED_UNKNOWN; + + + dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); + + switch (dsts.b.enumspd) + { + case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: + speed = USB_SPEED_HIGH; + break; + case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: + case DSTS_ENUMSPD_FS_PHY_48MHZ: + speed = USB_SPEED_FULL; + break; + + case DSTS_ENUMSPD_LS_PHY_6MHZ: + speed = USB_SPEED_LOW; + break; + } + + return speed; +} +/** +* @brief enables EP0 OUT to receive SETUP packets and configures EP0 +* for transmitting packets +* @param None +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_EP0Activate(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_DSTS_TypeDef dsts; + USB_OTG_DEPCTL_TypeDef diepctl; + USB_OTG_DCTL_TypeDef dctl; + + dctl.d32 = 0; + /* Read the Device Status and Endpoint 0 Control registers */ + dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); + diepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL); + /* Set the MPS of the IN EP based on the enumeration speed */ + switch (dsts.b.enumspd) + { + case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: + case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: + case DSTS_ENUMSPD_FS_PHY_48MHZ: + diepctl.b.mps = DEP0CTL_MPS_64; + break; + case DSTS_ENUMSPD_LS_PHY_6MHZ: + diepctl.b.mps = DEP0CTL_MPS_8; + break; + } + USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL, diepctl.d32); + dctl.b.cgnpinnak = 1; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, dctl.d32); + return status; +} + + +/** +* @brief USB_OTG_EPActivate : Activates an EP +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_EPActivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_DEPCTL_TypeDef depctl; + USB_OTG_DAINT_TypeDef daintmsk; + __IO uint32_t *addr; + + + depctl.d32 = 0; + daintmsk.d32 = 0; + /* Read DEPCTLn register */ + if (ep->is_in == 1) + { + addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL; + daintmsk.ep.in = 1 << ep->num; + } + else + { + addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL; + daintmsk.ep.out = 1 << ep->num; + } + /* If the EP is already active don't change the EP Control + * register. */ + depctl.d32 = USB_OTG_READ_REG32(addr); + if (!depctl.b.usbactep) + { + depctl.b.mps = ep->maxpacket; + depctl.b.eptype = ep->type; + depctl.b.txfnum = ep->tx_fifo_num; + depctl.b.setd0pid = 1; + depctl.b.usbactep = 1; + USB_OTG_WRITE_REG32(addr, depctl.d32); + } + /* Enable the Interrupt for this EP */ +#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED + if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID)) + { + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, 0, daintmsk.d32); + } + else +#endif + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, 0, daintmsk.d32); + return status; +} + + +/** +* @brief USB_OTG_EPDeactivate : Deactivates an EP +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_DEPCTL_TypeDef depctl; + USB_OTG_DAINT_TypeDef daintmsk; + __IO uint32_t *addr; + + depctl.d32 = 0; + daintmsk.d32 = 0; + /* Read DEPCTLn register */ + if (ep->is_in == 1) + { + addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL; + daintmsk.ep.in = 1 << ep->num; + } + else + { + addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL; + daintmsk.ep.out = 1 << ep->num; + } + depctl.b.usbactep = 0; + USB_OTG_WRITE_REG32(addr, depctl.d32); + /* Disable the Interrupt for this EP */ + +#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED + if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID)) + { + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, daintmsk.d32, 0); + } + else +#endif + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, daintmsk.d32, 0); + return status; +} + + +/** +* @brief USB_OTG_EPStartXfer : Handle the setup for data xfer for an EP and +* starts the xfer +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_DEPCTL_TypeDef depctl; + USB_OTG_DEPXFRSIZ_TypeDef deptsiz; + USB_OTG_DSTS_TypeDef dsts; + uint32_t fifoemptymsk = 0; + + depctl.d32 = 0; + deptsiz.d32 = 0; + /* IN endpoint */ + if (ep->is_in == 1) + { + depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPCTL)); + deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ)); + /* Zero Length Packet? */ + if (ep->xfer_len == 0) + { + deptsiz.b.xfersize = 0; + deptsiz.b.pktcnt = 1; + } + else + { + /* Program the transfer size and packet count + * as follows: xfersize = N * maxpacket + + * short_packet pktcnt = N + (short_packet + * exist ? 1 : 0) + */ + deptsiz.b.xfersize = ep->xfer_len; + deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket; + + if (ep->type == EP_TYPE_ISOC) + { + deptsiz.b.mc = 1; + } + } + USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ, deptsiz.d32); + + if (pdev->cfg.dma_enable == 1) + { + USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr); + } + else + { + if (ep->type != EP_TYPE_ISOC) + { + /* Enable the Tx FIFO Empty Interrupt for this EP */ + if (ep->xfer_len > 0) + { + fifoemptymsk = 1 << ep->num; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk); + } + } + } + + + if (ep->type == EP_TYPE_ISOC) + { + dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); + + if (((dsts.b.soffn)&0x1) == 0) + { + depctl.b.setd1pid = 1; + } + else + { + depctl.b.setd0pid = 1; + } + } + + /* EP enable, IN data in FIFO */ + depctl.b.cnak = 1; + depctl.b.epena = 1; + USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPCTL, depctl.d32); + + if (ep->type == EP_TYPE_ISOC) + { + USB_OTG_WritePacket(pdev, ep->xfer_buff, ep->num, ep->xfer_len); + } + } + else + { + /* OUT endpoint */ + depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL)); + deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ)); + /* Program the transfer size and packet count as follows: + * pktcnt = N + * xfersize = N * maxpacket + */ + if (ep->xfer_len == 0) + { + deptsiz.b.xfersize = ep->maxpacket; + deptsiz.b.pktcnt = 1; + } + else + { + deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket; + deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; + } + USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32); + + if (pdev->cfg.dma_enable == 1) + { + USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr); + } + + if (ep->type == EP_TYPE_ISOC) + { + if (ep->even_odd_frame) + { + depctl.b.setd1pid = 1; + } + else + { + depctl.b.setd0pid = 1; + } + } + /* EP enable */ + depctl.b.cnak = 1; + depctl.b.epena = 1; + USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL, depctl.d32); + } + return status; +} + + +/** +* @brief USB_OTG_EP0StartXfer : Handle the setup for a data xfer for EP0 and +* starts the xfer +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_DEPCTL_TypeDef depctl; + USB_OTG_DEP0XFRSIZ_TypeDef deptsiz; + USB_OTG_INEPREGS *in_regs; + uint32_t fifoemptymsk = 0; + + depctl.d32 = 0; + deptsiz.d32 = 0; + /* IN endpoint */ + if (ep->is_in == 1) + { + in_regs = pdev->regs.INEP_REGS[0]; + depctl.d32 = USB_OTG_READ_REG32(&in_regs->DIEPCTL); + deptsiz.d32 = USB_OTG_READ_REG32(&in_regs->DIEPTSIZ); + /* Zero Length Packet? */ + if (ep->xfer_len == 0) + { + deptsiz.b.xfersize = 0; + deptsiz.b.pktcnt = 1; + + } + else + { + if (ep->xfer_len > ep->maxpacket) + { + ep->xfer_len = ep->maxpacket; + deptsiz.b.xfersize = ep->maxpacket; + } + else + { + deptsiz.b.xfersize = ep->xfer_len; + } + deptsiz.b.pktcnt = 1; + } + USB_OTG_WRITE_REG32(&in_regs->DIEPTSIZ, deptsiz.d32); + + if (pdev->cfg.dma_enable == 1) + { + USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr); + } + + /* EP enable, IN data in FIFO */ + depctl.b.cnak = 1; + depctl.b.epena = 1; + USB_OTG_WRITE_REG32(&in_regs->DIEPCTL, depctl.d32); + + + + if (pdev->cfg.dma_enable == 0) + { + /* Enable the Tx FIFO Empty Interrupt for this EP */ + if (ep->xfer_len > 0) + { + { + fifoemptymsk |= 1 << ep->num; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk); + } + } + } + } + else + { + /* OUT endpoint */ + depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); + deptsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ); + /* Program the transfer size and packet count as follows: + * xfersize = N * (maxpacket + 4 - (maxpacket % 4)) + * pktcnt = N */ + if (ep->xfer_len == 0) + { + deptsiz.b.xfersize = ep->maxpacket; + deptsiz.b.pktcnt = 1; + } + else + { + ep->xfer_len = ep->maxpacket; + deptsiz.b.xfersize = ep->maxpacket; + deptsiz.b.pktcnt = 1; + } + USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32); + if (pdev->cfg.dma_enable == 1) + { + USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr); + } + /* EP enable */ + depctl.b.cnak = 1; + depctl.b.epena = 1; + USB_OTG_WRITE_REG32 (&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL), depctl.d32); + + } + return status; +} + + +/** +* @brief USB_OTG_EPSetStall : Set the EP STALL +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_EPSetStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_DEPCTL_TypeDef depctl; + __IO uint32_t *depctl_addr; + + depctl.d32 = 0; + if (ep->is_in == 1) + { + depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); + depctl.d32 = USB_OTG_READ_REG32(depctl_addr); + /* set the disable and stall bits */ + if (depctl.b.epena) + { + depctl.b.epdis = 1; + } + depctl.b.stall = 1; + USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); + } + else + { + depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); + depctl.d32 = USB_OTG_READ_REG32(depctl_addr); + /* set the stall bit */ + depctl.b.stall = 1; + USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); + } + return status; +} + + +/** +* @brief Clear the EP STALL +* @param pdev : Selected device +* @retval USB_OTG_STS : status +*/ +USB_OTG_STS USB_OTG_EPClearStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) +{ + USB_OTG_STS status = USB_OTG_OK; + USB_OTG_DEPCTL_TypeDef depctl; + __IO uint32_t *depctl_addr; + + depctl.d32 = 0; + + if (ep->is_in == 1) + { + depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); + } + else + { + depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); + } + depctl.d32 = USB_OTG_READ_REG32(depctl_addr); + /* clear the stall bits */ + depctl.b.stall = 0; + if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) + { + depctl.b.setd0pid = 1; /* DATA0 */ + } + USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); + return status; +} + + +/** +* @brief USB_OTG_ReadDevAllOutEp_itr : returns OUT endpoint interrupt bits +* @param pdev : Selected device +* @retval OUT endpoint interrupt bits +*/ +uint32_t USB_OTG_ReadDevAllOutEp_itr(USB_OTG_CORE_HANDLE *pdev) +{ + uint32_t v; + v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT); + v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK); + return ((v & 0xffff0000) >> 16); +} + + +/** +* @brief USB_OTG_ReadDevOutEP_itr : returns Device OUT EP Interrupt register +* @param pdev : Selected device +* @param ep : end point number +* @retval Device OUT EP Interrupt register +*/ +uint32_t USB_OTG_ReadDevOutEP_itr(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) +{ + uint32_t v; + v = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT); + v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOEPMSK); + return v; +} + + +/** +* @brief USB_OTG_ReadDevAllInEPItr : Get int status register +* @param pdev : Selected device +* @retval int status register +*/ +uint32_t USB_OTG_ReadDevAllInEPItr(USB_OTG_CORE_HANDLE *pdev) +{ + uint32_t v; + v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT); + v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK); + return (v & 0xffff); +} + +/** +* @brief configures EPO to receive SETUP packets +* @param None +* @retval : None +*/ +void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_DEP0XFRSIZ_TypeDef doeptsize0; + doeptsize0.d32 = 0; + doeptsize0.b.supcnt = 3; + doeptsize0.b.pktcnt = 1; + doeptsize0.b.xfersize = 8 * 3; + USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPTSIZ, doeptsize0.d32 ); + + if (pdev->cfg.dma_enable == 1) + { + USB_OTG_DEPCTL_TypeDef doepctl; + doepctl.d32 = 0; + USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPDMA, + (uint32_t)&pdev->dev.setup_packet); + + /* EP enable */ + doepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[0]->DOEPCTL); + doepctl.b.epena = 1; + doepctl.d32 = 0x80008000; + USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPCTL, doepctl.d32); + } +} + +/** +* @brief USB_OTG_RemoteWakeup : active remote wakeup signalling +* @param None +* @retval : None +*/ +void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev) +{ + + USB_OTG_DCTL_TypeDef dctl; + USB_OTG_DSTS_TypeDef dsts; + USB_OTG_PCGCCTL_TypeDef power; + + if (pdev->dev.DevRemoteWakeup) + { + dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); + if(dsts.b.suspsts == 1) + { + if(pdev->cfg.low_power) + { + /* un-gate USB Core clock */ + //power.d32 = USB_OTG_READ_REG32(&(pdev->regs.PCGCCTL)); + power.d32 = USB_OTG_READ_REG32((pdev->regs.PCGCCTL)); // ala42 + power.b.gatehclk = 0; + power.b.stoppclk = 0; + USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); + } + /* active Remote wakeup signaling */ + dctl.d32 = 0; + dctl.b.rmtwkupsig = 1; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, 0, dctl.d32); + USB_OTG_BSP_mDelay(5); + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 ); + } + } +} + + +/** +* @brief USB_OTG_UngateClock : active USB Core clock +* @param None +* @retval : None +*/ +void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev) +{ + if(pdev->cfg.low_power) + { + + USB_OTG_DSTS_TypeDef dsts; + USB_OTG_PCGCCTL_TypeDef power; + + dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); + + if(dsts.b.suspsts == 1) + { + /* un-gate USB Core clock */ + //power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); + power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL); // ala42 + power.b.gatehclk = 0; + power.b.stoppclk = 0; + USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); + + } + } +} + +/** +* @brief Stop the device and clean up fifo's +* @param None +* @retval : None +*/ +void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev) +{ + uint32_t i; + + pdev->dev.device_status = 1; + + for (i = 0; i < pdev->cfg.dev_endpoints ; i++) + { + USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); + USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); + } + + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 ); + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 ); + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 ); + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); + + /* Flush the FIFO */ + USB_OTG_FlushRxFifo(pdev); + USB_OTG_FlushTxFifo(pdev , 0x10 ); +} + +/** +* @brief returns the EP Status +* @param pdev : Selected device +* ep : endpoint structure +* @retval : EP status +*/ + +uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep) +{ + USB_OTG_DEPCTL_TypeDef depctl; + __IO uint32_t *depctl_addr; + uint32_t Status = 0; + + depctl.d32 = 0; + if (ep->is_in == 1) + { + depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); + depctl.d32 = USB_OTG_READ_REG32(depctl_addr); + + if (depctl.b.stall == 1) + Status = USB_OTG_EP_TX_STALL; + else if (depctl.b.naksts == 1) + Status = USB_OTG_EP_TX_NAK; + else + Status = USB_OTG_EP_TX_VALID; + + } + else + { + depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); + depctl.d32 = USB_OTG_READ_REG32(depctl_addr); + if (depctl.b.stall == 1) + Status = USB_OTG_EP_RX_STALL; + else if (depctl.b.naksts == 1) + Status = USB_OTG_EP_RX_NAK; + else + Status = USB_OTG_EP_RX_VALID; + } + + /* Return the current status */ + return Status; +} + +/** +* @brief Set the EP Status +* @param pdev : Selected device +* Status : new Status +* ep : EP structure +* @retval : None +*/ +void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status) +{ + USB_OTG_DEPCTL_TypeDef depctl; + __IO uint32_t *depctl_addr; + + depctl.d32 = 0; + + /* Process for IN endpoint */ + if (ep->is_in == 1) + { + depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); + depctl.d32 = USB_OTG_READ_REG32(depctl_addr); + + if (Status == USB_OTG_EP_TX_STALL) + { + USB_OTG_EPSetStall(pdev, ep); return; + } + else if (Status == USB_OTG_EP_TX_NAK) + depctl.b.snak = 1; + else if (Status == USB_OTG_EP_TX_VALID) + { + if (depctl.b.stall == 1) + { + ep->even_odd_frame = 0; + USB_OTG_EPClearStall(pdev, ep); + return; + } + depctl.b.cnak = 1; + depctl.b.usbactep = 1; + depctl.b.epena = 1; + } + else if (Status == USB_OTG_EP_TX_DIS) + depctl.b.usbactep = 0; + } + else /* Process for OUT endpoint */ + { + depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); + depctl.d32 = USB_OTG_READ_REG32(depctl_addr); + + if (Status == USB_OTG_EP_RX_STALL) { + depctl.b.stall = 1; + } + else if (Status == USB_OTG_EP_RX_NAK) + depctl.b.snak = 1; + else if (Status == USB_OTG_EP_RX_VALID) + { + if (depctl.b.stall == 1) + { + ep->even_odd_frame = 0; + USB_OTG_EPClearStall(pdev, ep); + return; + } + depctl.b.cnak = 1; + depctl.b.usbactep = 1; + depctl.b.epena = 1; + } + else if (Status == USB_OTG_EP_RX_DIS) + { + depctl.b.usbactep = 0; + } + } + + USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); +} + +#endif +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c index 3afb0250..c3336cb8 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd.c @@ -1,472 +1,472 @@ -/** - ****************************************************************************** - * @file usb_dcd.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Peripheral Device Interface Layer - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_dcd.h" -#include "usb_bsp.h" - - -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_DCD -* @brief This file is the interface between EFSL ans Host mass-storage class -* @{ -*/ - - -/** @defgroup USB_DCD_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - - -/** @defgroup USB_DCD_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_Private_Variables -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_Private_FunctionPrototypes -* @{ -*/ - -/** -* @} -*/ - - -/** @defgroup USB_DCD_Private_Functions -* @{ -*/ - - - -void DCD_Init(USB_OTG_CORE_HANDLE *pdev , - USB_OTG_CORE_ID_TypeDef coreID) -{ - uint32_t i; - USB_OTG_EP *ep; - - USB_OTG_SelectCore (pdev , coreID); - - pdev->dev.device_status = USB_OTG_DEFAULT; - pdev->dev.device_address = 0; - - /* Init ep structure */ - for (i = 0; i < pdev->cfg.dev_endpoints ; i++) - { - ep = &pdev->dev.in_ep[i]; - /* Init ep structure */ - ep->is_in = 1; - ep->num = i; - ep->tx_fifo_num = i; - /* Control until ep is actvated */ - ep->type = EP_TYPE_CTRL; - ep->maxpacket = USB_OTG_MAX_EP0_SIZE; - ep->xfer_buff = 0; - ep->xfer_len = 0; - } - - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - ep = &pdev->dev.out_ep[i]; - /* Init ep structure */ - ep->is_in = 0; - ep->num = i; - ep->tx_fifo_num = i; - /* Control until ep is activated */ - ep->type = EP_TYPE_CTRL; - ep->maxpacket = USB_OTG_MAX_EP0_SIZE; - ep->xfer_buff = 0; - ep->xfer_len = 0; - } - - USB_OTG_DisableGlobalInt(pdev); - - /*Init the Core (common init.) */ - USB_OTG_CoreInit(pdev); - - - /* Force Device Mode*/ - USB_OTG_SetCurrentMode(pdev, DEVICE_MODE); - - /* Init Device */ - USB_OTG_CoreInitDev(pdev); - - - /* Enable USB Global interrupt */ - USB_OTG_EnableGlobalInt(pdev); -} - - -/** -* @brief Configure an EP -* @param pdev : Device instance -* @param epdesc : Endpoint Descriptor -* @retval : status -*/ -uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev , - uint8_t ep_addr, - uint16_t ep_mps, - uint8_t ep_type) -{ - USB_OTG_EP *ep; - - if ((ep_addr & 0x80) == 0x80) - { - ep = &pdev->dev.in_ep[ep_addr & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[ep_addr & 0x7F]; - } - ep->num = ep_addr & 0x7F; - - ep->is_in = (0x80 & ep_addr) != 0; - ep->maxpacket = ep_mps; - ep->type = ep_type; - if (ep->is_in) - { - /* Assign a Tx FIFO */ - ep->tx_fifo_num = ep->num; - } - /* Set initial data PID. */ - if (ep_type == USB_OTG_EP_BULK ) - { - ep->data_pid_start = 0; - } - USB_OTG_EPActivate(pdev , ep ); - return 0; -} -/** -* @brief called when an EP is disabled -* @param pdev: device instance -* @param ep_addr: endpoint address -* @retval : status -*/ -uint32_t DCD_EP_Close(USB_OTG_CORE_HANDLE *pdev , uint8_t ep_addr) -{ - USB_OTG_EP *ep; - - if ((ep_addr&0x80) == 0x80) - { - ep = &pdev->dev.in_ep[ep_addr & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[ep_addr & 0x7F]; - } - ep->num = ep_addr & 0x7F; - ep->is_in = (0x80 & ep_addr) != 0; - USB_OTG_EPDeactivate(pdev , ep ); - return 0; -} - - -/** -* @brief DCD_EP_PrepareRx -* @param pdev: device instance -* @param ep_addr: endpoint address -* @param pbuf: pointer to Rx buffer -* @param buf_len: data length -* @retval : status -*/ -uint32_t DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint16_t buf_len) -{ - USB_OTG_EP *ep; - - ep = &pdev->dev.out_ep[ep_addr & 0x7F]; - - /*setup and start the Xfer */ - ep->xfer_buff = pbuf; - ep->xfer_len = buf_len; - ep->xfer_count = 0; - ep->is_in = 0; - ep->num = ep_addr & 0x7F; - - if (pdev->cfg.dma_enable == 1) - { - ep->dma_addr = (uint32_t)pbuf; - } - - if ( ep->num == 0 ) - { - USB_OTG_EP0StartXfer(pdev , ep); - } - else - { - USB_OTG_EPStartXfer(pdev, ep ); - } - return 0; -} - -/** -* @brief Transmit data over USB -* @param pdev: device instance -* @param ep_addr: endpoint address -* @param pbuf: pointer to Tx buffer -* @param buf_len: data length -* @retval : status -*/ -uint32_t DCD_EP_Tx ( USB_OTG_CORE_HANDLE *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint32_t buf_len) -{ - USB_OTG_EP *ep; - - ep = &pdev->dev.in_ep[ep_addr & 0x7F]; - - /* Setup and start the Transfer */ - ep->is_in = 1; - ep->num = ep_addr & 0x7F; - ep->xfer_buff = pbuf; - ep->dma_addr = (uint32_t)pbuf; - ep->xfer_count = 0; - ep->xfer_len = buf_len; - - if ( ep->num == 0 ) - { - USB_OTG_EP0StartXfer(pdev , ep); - } - else - { - USB_OTG_EPStartXfer(pdev, ep ); - } - return 0; -} - - -/** -* @brief Stall an endpoint. -* @param pdev: device instance -* @param epnum: endpoint address -* @retval : status -*/ -uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) -{ - USB_OTG_EP *ep; - if ((0x80 & epnum) == 0x80) - { - ep = &pdev->dev.in_ep[epnum & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[epnum]; - } - - ep->is_stall = 1; - ep->num = epnum & 0x7F; - ep->is_in = ((epnum & 0x80) == 0x80); - - USB_OTG_EPSetStall(pdev , ep); - return (0); -} - - -/** -* @brief Clear stall condition on endpoints. -* @param pdev: device instance -* @param epnum: endpoint address -* @retval : status -*/ -uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) -{ - USB_OTG_EP *ep; - if ((0x80 & epnum) == 0x80) - { - ep = &pdev->dev.in_ep[epnum & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[epnum]; - } - - ep->is_stall = 0; - ep->num = epnum & 0x7F; - ep->is_in = ((epnum & 0x80) == 0x80); - - USB_OTG_EPClearStall(pdev , ep); - return (0); -} - - -/** -* @brief This Function flushes the FIFOs. -* @param pdev: device instance -* @param epnum: endpoint address -* @retval : status -*/ -uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - - if ((epnum & 0x80) == 0x80) - { - USB_OTG_FlushTxFifo(pdev, epnum & 0x7F); - } - else - { - USB_OTG_FlushRxFifo(pdev); - } - - return (0); -} - - -/** -* @brief This Function set USB device address -* @param pdev: device instance -* @param address: new device address -* @retval : status -*/ -void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev, uint8_t address) -{ - USB_OTG_DCFG_TypeDef dcfg; - dcfg.d32 = 0; - dcfg.b.devaddr = address; - USB_OTG_MODIFY_REG32( &pdev->regs.DREGS->DCFG, 0, dcfg.d32); -} - -/** -* @brief Connect device (enable internal pull-up) -* @param pdev: device instance -* @retval : None -*/ -void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev) -{ -#ifndef USE_OTG_MODE - USB_OTG_DCTL_TypeDef dctl; - dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); - /* Connect device */ - dctl.b.sftdiscon = 0; - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); - USB_OTG_BSP_mDelay(3); -#endif -} - - -/** -* @brief Disconnect device (disable internal pull-up) -* @param pdev: device instance -* @retval : None -*/ -void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev) -{ -#ifndef USE_OTG_MODE - USB_OTG_DCTL_TypeDef dctl; - dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); - /* Disconnect device for 3ms */ - dctl.b.sftdiscon = 1; - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); - USB_OTG_BSP_mDelay(3); -#endif -} - - -/** -* @brief returns the EP Status -* @param pdev : Selected device -* epnum : endpoint address -* @retval : EP status -*/ - -uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,uint8_t epnum) -{ - USB_OTG_EP *ep; - uint32_t Status = 0; - - if ((0x80 & epnum) == 0x80) - { - ep = &pdev->dev.in_ep[epnum & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[epnum]; - } - - Status = USB_OTG_GetEPStatus(pdev ,ep); - - /* Return the current status */ - return Status; -} - -/** -* @brief Set the EP Status -* @param pdev : Selected device -* Status : new Status -* epnum : EP address -* @retval : None -*/ -void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum , uint32_t Status) -{ - USB_OTG_EP *ep; - - if ((0x80 & epnum) == 0x80) - { - ep = &pdev->dev.in_ep[epnum & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[epnum]; - } - - USB_OTG_SetEPStatus(pdev ,ep , Status); -} - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usb_dcd.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Peripheral Device Interface Layer + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_dcd.h" +#include "usb_bsp.h" + + +/** @addtogroup USB_OTG_DRIVER +* @{ +*/ + +/** @defgroup USB_DCD +* @brief This file is the interface between EFSL ans Host mass-storage class +* @{ +*/ + + +/** @defgroup USB_DCD_Private_Defines +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USB_DCD_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + + +/** @defgroup USB_DCD_Private_Macros +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USB_DCD_Private_Variables +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USB_DCD_Private_FunctionPrototypes +* @{ +*/ + +/** +* @} +*/ + + +/** @defgroup USB_DCD_Private_Functions +* @{ +*/ + + + +void DCD_Init(USB_OTG_CORE_HANDLE *pdev , + USB_OTG_CORE_ID_TypeDef coreID) +{ + uint32_t i; + USB_OTG_EP *ep; + + USB_OTG_SelectCore (pdev , coreID); + + pdev->dev.device_status = USB_OTG_DEFAULT; + pdev->dev.device_address = 0; + + /* Init ep structure */ + for (i = 0; i < pdev->cfg.dev_endpoints ; i++) + { + ep = &pdev->dev.in_ep[i]; + /* Init ep structure */ + ep->is_in = 1; + ep->num = i; + ep->tx_fifo_num = i; + /* Control until ep is actvated */ + ep->type = EP_TYPE_CTRL; + ep->maxpacket = USB_OTG_MAX_EP0_SIZE; + ep->xfer_buff = 0; + ep->xfer_len = 0; + } + + for (i = 0; i < pdev->cfg.dev_endpoints; i++) + { + ep = &pdev->dev.out_ep[i]; + /* Init ep structure */ + ep->is_in = 0; + ep->num = i; + ep->tx_fifo_num = i; + /* Control until ep is activated */ + ep->type = EP_TYPE_CTRL; + ep->maxpacket = USB_OTG_MAX_EP0_SIZE; + ep->xfer_buff = 0; + ep->xfer_len = 0; + } + + USB_OTG_DisableGlobalInt(pdev); + + /*Init the Core (common init.) */ + USB_OTG_CoreInit(pdev); + + + /* Force Device Mode*/ + USB_OTG_SetCurrentMode(pdev, DEVICE_MODE); + + /* Init Device */ + USB_OTG_CoreInitDev(pdev); + + + /* Enable USB Global interrupt */ + USB_OTG_EnableGlobalInt(pdev); +} + + +/** +* @brief Configure an EP +* @param pdev : Device instance +* @param epdesc : Endpoint Descriptor +* @retval : status +*/ +uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev , + uint8_t ep_addr, + uint16_t ep_mps, + uint8_t ep_type) +{ + USB_OTG_EP *ep; + + if ((ep_addr & 0x80) == 0x80) + { + ep = &pdev->dev.in_ep[ep_addr & 0x7F]; + } + else + { + ep = &pdev->dev.out_ep[ep_addr & 0x7F]; + } + ep->num = ep_addr & 0x7F; + + ep->is_in = (0x80 & ep_addr) != 0; + ep->maxpacket = ep_mps; + ep->type = ep_type; + if (ep->is_in) + { + /* Assign a Tx FIFO */ + ep->tx_fifo_num = ep->num; + } + /* Set initial data PID. */ + if (ep_type == USB_OTG_EP_BULK ) + { + ep->data_pid_start = 0; + } + USB_OTG_EPActivate(pdev , ep ); + return 0; +} +/** +* @brief called when an EP is disabled +* @param pdev: device instance +* @param ep_addr: endpoint address +* @retval : status +*/ +uint32_t DCD_EP_Close(USB_OTG_CORE_HANDLE *pdev , uint8_t ep_addr) +{ + USB_OTG_EP *ep; + + if ((ep_addr&0x80) == 0x80) + { + ep = &pdev->dev.in_ep[ep_addr & 0x7F]; + } + else + { + ep = &pdev->dev.out_ep[ep_addr & 0x7F]; + } + ep->num = ep_addr & 0x7F; + ep->is_in = (0x80 & ep_addr) != 0; + USB_OTG_EPDeactivate(pdev , ep ); + return 0; +} + + +/** +* @brief DCD_EP_PrepareRx +* @param pdev: device instance +* @param ep_addr: endpoint address +* @param pbuf: pointer to Rx buffer +* @param buf_len: data length +* @retval : status +*/ +uint32_t DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t buf_len) +{ + USB_OTG_EP *ep; + + ep = &pdev->dev.out_ep[ep_addr & 0x7F]; + + /*setup and start the Xfer */ + ep->xfer_buff = pbuf; + ep->xfer_len = buf_len; + ep->xfer_count = 0; + ep->is_in = 0; + ep->num = ep_addr & 0x7F; + + if (pdev->cfg.dma_enable == 1) + { + ep->dma_addr = (uint32_t)pbuf; + } + + if ( ep->num == 0 ) + { + USB_OTG_EP0StartXfer(pdev , ep); + } + else + { + USB_OTG_EPStartXfer(pdev, ep ); + } + return 0; +} + +/** +* @brief Transmit data over USB +* @param pdev: device instance +* @param ep_addr: endpoint address +* @param pbuf: pointer to Tx buffer +* @param buf_len: data length +* @retval : status +*/ +uint32_t DCD_EP_Tx ( USB_OTG_CORE_HANDLE *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint32_t buf_len) +{ + USB_OTG_EP *ep; + + ep = &pdev->dev.in_ep[ep_addr & 0x7F]; + + /* Setup and start the Transfer */ + ep->is_in = 1; + ep->num = ep_addr & 0x7F; + ep->xfer_buff = pbuf; + ep->dma_addr = (uint32_t)pbuf; + ep->xfer_count = 0; + ep->xfer_len = buf_len; + + if ( ep->num == 0 ) + { + USB_OTG_EP0StartXfer(pdev , ep); + } + else + { + USB_OTG_EPStartXfer(pdev, ep ); + } + return 0; +} + + +/** +* @brief Stall an endpoint. +* @param pdev: device instance +* @param epnum: endpoint address +* @retval : status +*/ +uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) +{ + USB_OTG_EP *ep; + if ((0x80 & epnum) == 0x80) + { + ep = &pdev->dev.in_ep[epnum & 0x7F]; + } + else + { + ep = &pdev->dev.out_ep[epnum]; + } + + ep->is_stall = 1; + ep->num = epnum & 0x7F; + ep->is_in = ((epnum & 0x80) == 0x80); + + USB_OTG_EPSetStall(pdev , ep); + return (0); +} + + +/** +* @brief Clear stall condition on endpoints. +* @param pdev: device instance +* @param epnum: endpoint address +* @retval : status +*/ +uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) +{ + USB_OTG_EP *ep; + if ((0x80 & epnum) == 0x80) + { + ep = &pdev->dev.in_ep[epnum & 0x7F]; + } + else + { + ep = &pdev->dev.out_ep[epnum]; + } + + ep->is_stall = 0; + ep->num = epnum & 0x7F; + ep->is_in = ((epnum & 0x80) == 0x80); + + USB_OTG_EPClearStall(pdev , ep); + return (0); +} + + +/** +* @brief This Function flushes the FIFOs. +* @param pdev: device instance +* @param epnum: endpoint address +* @retval : status +*/ +uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) +{ + + if ((epnum & 0x80) == 0x80) + { + USB_OTG_FlushTxFifo(pdev, epnum & 0x7F); + } + else + { + USB_OTG_FlushRxFifo(pdev); + } + + return (0); +} + + +/** +* @brief This Function set USB device address +* @param pdev: device instance +* @param address: new device address +* @retval : status +*/ +void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev, uint8_t address) +{ + USB_OTG_DCFG_TypeDef dcfg; + dcfg.d32 = 0; + dcfg.b.devaddr = address; + USB_OTG_MODIFY_REG32( &pdev->regs.DREGS->DCFG, 0, dcfg.d32); +} + +/** +* @brief Connect device (enable internal pull-up) +* @param pdev: device instance +* @retval : None +*/ +void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev) +{ +#ifndef USE_OTG_MODE + USB_OTG_DCTL_TypeDef dctl; + dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); + /* Connect device */ + dctl.b.sftdiscon = 0; + USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); + USB_OTG_BSP_mDelay(3); +#endif +} + + +/** +* @brief Disconnect device (disable internal pull-up) +* @param pdev: device instance +* @retval : None +*/ +void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev) +{ +#ifndef USE_OTG_MODE + USB_OTG_DCTL_TypeDef dctl; + dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); + /* Disconnect device for 3ms */ + dctl.b.sftdiscon = 1; + USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); + USB_OTG_BSP_mDelay(3); +#endif +} + + +/** +* @brief returns the EP Status +* @param pdev : Selected device +* epnum : endpoint address +* @retval : EP status +*/ + +uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,uint8_t epnum) +{ + USB_OTG_EP *ep; + uint32_t Status = 0; + + if ((0x80 & epnum) == 0x80) + { + ep = &pdev->dev.in_ep[epnum & 0x7F]; + } + else + { + ep = &pdev->dev.out_ep[epnum]; + } + + Status = USB_OTG_GetEPStatus(pdev ,ep); + + /* Return the current status */ + return Status; +} + +/** +* @brief Set the EP Status +* @param pdev : Selected device +* Status : new Status +* epnum : EP address +* @retval : None +*/ +void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum , uint32_t Status) +{ + USB_OTG_EP *ep; + + if ((0x80 & epnum) == 0x80) + { + ep = &pdev->dev.in_ep[epnum & 0x7F]; + } + else + { + ep = &pdev->dev.out_ep[epnum]; + } + + USB_OTG_SetEPStatus(pdev ,ep , Status); +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd_int.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd_int.c index 51d16576..3a49ede2 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd_int.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_dcd_int.c @@ -1,900 +1,900 @@ -/** - ****************************************************************************** - * @file usb_dcd_int.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Peripheral Device interrupt subroutines - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_dcd_int.h" - -typedef int IRQn_Type; -#define __NVIC_PRIO_BITS 4 -#define __Vendor_SysTickConfig 1 -#include - - -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_DCD_INT -* @brief This file contains the interrupt subroutines for the Device mode. -* @{ -*/ - - -/** @defgroup USB_DCD_INT_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_INT_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - - -/** @defgroup USB_DCD_INT_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_INT_Private_Variables -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_INT_Private_FunctionPrototypes -* @{ -*/ -/* static functions */ -static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum); - -/* Interrupt Handlers */ -static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev); - -static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev , uint32_t epnum); - -static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev); - -static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev); -#ifdef VBUS_SENSING_ENABLED -static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev); -#endif - -/** -* @} -*/ - - -/** @defgroup USB_DCD_INT_Private_Functions -* @{ -*/ - - -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED -/** -* @brief USBD_OTG_EP1OUT_ISR_Handler -* handles all USB Interrupts -* @param pdev: device instance -* @retval status -*/ -uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_DOEPINTn_TypeDef doepint; - USB_OTG_DEPXFRSIZ_TypeDef deptsiz; - - doepint.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[1]->DOEPINT); - doepint.d32&= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOUTEP1MSK); - - /* Transfer complete */ - if ( doepint.b.xfercompl ) - { - /* Clear the bit in DOEPINTn for this interrupt */ - CLEAR_OUT_EP_INTR(1, xfercompl); - if (pdev->cfg.dma_enable == 1) - { - deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ)); - /*ToDo : handle more than one single MPS size packet */ - pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].maxpacket - \ - deptsiz.b.xfersize; - } - /* Inform upper layer: data ready */ - /* RX COMPLETE */ - USBD_DCD_INT_fops->DataOutStage(pdev , 1); - - } - - /* Endpoint disable */ - if ( doepint.b.epdisabled ) - { - /* Clear the bit in DOEPINTn for this interrupt */ - CLEAR_OUT_EP_INTR(1, epdisabled); - } - /* AHB Error */ - if ( doepint.b.ahberr ) - { - CLEAR_OUT_EP_INTR(1, ahberr); - } - return 1; -} - -/** -* @brief USBD_OTG_EP1IN_ISR_Handler -* handles all USB Interrupts -* @param pdev: device instance -* @retval status -*/ -uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_DIEPINTn_TypeDef diepint; - uint32_t fifoemptymsk, msk, emp; - - msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK); - emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK); - msk |= ((emp >> 1 ) & 0x1) << 7; - diepint.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk; - - if ( diepint.b.xfercompl ) - { - fifoemptymsk = 0x1 << 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); - CLEAR_IN_EP_INTR(1, xfercompl); - /* TX COMPLETE */ - USBD_DCD_INT_fops->DataInStage(pdev , 1); - } - if ( diepint.b.ahberr ) - { - CLEAR_IN_EP_INTR(1, ahberr); - } - if ( diepint.b.epdisabled ) - { - CLEAR_IN_EP_INTR(1, epdisabled); - } - if ( diepint.b.timeout ) - { - CLEAR_IN_EP_INTR(1, timeout); - } - if (diepint.b.intktxfemp) - { - CLEAR_IN_EP_INTR(1, intktxfemp); - } - if (diepint.b.intknepmis) - { - CLEAR_IN_EP_INTR(1, intknepmis); - } - if (diepint.b.inepnakeff) - { - CLEAR_IN_EP_INTR(1, inepnakeff); - } - if (diepint.b.emptyintr) - { - DCD_WriteEmptyTxFifo(pdev , 1); - CLEAR_IN_EP_INTR(1, emptyintr); - } - return 1; -} -#endif - -/** -* @brief STM32_USBF_OTG_ISR_Handler -* handles all USB Interrupts -* @param pdev: device instance -* @retval status -*/ -uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintr_status; - uint32_t retval = 0; - - if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */ - { - gintr_status.d32 = USB_OTG_ReadCoreItr(pdev); - if (!gintr_status.d32) /* avoid spurious interrupt */ - { - return 0; - } - - if (gintr_status.b.outepintr) - { - retval |= DCD_HandleOutEP_ISR(pdev); - } - - if (gintr_status.b.inepint) - { - retval |= DCD_HandleInEP_ISR(pdev); - } - - if (gintr_status.b.modemismatch) - { - USB_OTG_GINTSTS_TypeDef gintsts; - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.modemismatch = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - } - - if (gintr_status.b.wkupintr) - { - retval |= DCD_HandleResume_ISR(pdev); - } - - if (gintr_status.b.usbsuspend) - { - retval |= DCD_HandleUSBSuspend_ISR(pdev); - } - if (gintr_status.b.sofintr) - { - retval |= DCD_HandleSof_ISR(pdev); - - } - - if (gintr_status.b.rxstsqlvl) - { - retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev); - - } - - if (gintr_status.b.usbreset) - { - retval |= DCD_HandleUsbReset_ISR(pdev); - - } - if (gintr_status.b.enumdone) - { - retval |= DCD_HandleEnumDone_ISR(pdev); - } - - if (gintr_status.b.incomplisoin) - { - retval |= DCD_IsoINIncomplete_ISR(pdev); - } - - if (gintr_status.b.incomplisoout) - { - retval |= DCD_IsoOUTIncomplete_ISR(pdev); - } -#ifdef VBUS_SENSING_ENABLED - if (gintr_status.b.sessreqintr) - { - retval |= DCD_SessionRequest_ISR(pdev); - } - - if (gintr_status.b.otgintr) - { - retval |= DCD_OTG_ISR(pdev); - } -#endif - } - return retval; -} - -#ifdef VBUS_SENSING_ENABLED -/** -* @brief DCD_SessionRequest_ISR -* Indicates that the USB_OTG controller has detected a connection -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - USBD_DCD_INT_fops->DevConnected (pdev); - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.sessreqintr = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); - return 1; -} - -/** -* @brief DCD_OTG_ISR -* Indicates that the USB_OTG controller has detected an OTG event: -* used to detect the end of session i.e. disconnection -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_GOTGINT_TypeDef gotgint; - - gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT); - - if (gotgint.b.sesenddet) - { - USBD_DCD_INT_fops->DevDisconnected (pdev); - } - /* Clear OTG interrupt */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32); - return 1; -} -#endif -/** -* @brief DCD_HandleResume_ISR -* Indicates that the USB_OTG controller has detected a resume or -* remote Wake-up sequence -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - USB_OTG_DCTL_TypeDef devctl; - USB_OTG_PCGCCTL_TypeDef power; - - if(pdev->cfg.low_power) - { - /* un-gate USB Core clock */ - //power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); - power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL); // ala42 - power.b.gatehclk = 0; - power.b.stoppclk = 0; - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); - } - - /* Clear the Remote Wake-up Signaling */ - devctl.d32 = 0; - devctl.b.rmtwkupsig = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, devctl.d32, 0); - - /* Inform upper layer by the Resume Event */ - USBD_DCD_INT_fops->Resume (pdev); - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.wkupintr = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); - return 1; -} - -/** -* @brief USB_OTG_HandleUSBSuspend_ISR -* Indicates that SUSPEND state has been detected on the USB -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - USB_OTG_PCGCCTL_TypeDef power; - USB_OTG_DSTS_TypeDef dsts; - - USBD_DCD_INT_fops->Suspend (pdev); - - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.usbsuspend = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - if((pdev->cfg.low_power) && (dsts.b.suspsts == 1)) - { - /* switch-off the clocks */ - power.d32 = 0; - power.b.stoppclk = 1; - USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32); - - power.b.gatehclk = 1; - USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32); - - /* Request to enter Sleep mode after exit from current ISR */ - SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk); - } - return 1; -} - -/** -* @brief DCD_HandleInEP_ISR -* Indicates that an IN EP has a pending Interrupt -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_DIEPINTn_TypeDef diepint; - - uint32_t ep_intr; - uint32_t epnum = 0; - uint32_t fifoemptymsk; - diepint.d32 = 0; - ep_intr = USB_OTG_ReadDevAllInEPItr(pdev); - - while ( ep_intr ) - { - if (ep_intr&0x1) /* In ITR */ - { - diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */ - if ( diepint.b.xfercompl ) - { - fifoemptymsk = 0x1 << epnum; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); - CLEAR_IN_EP_INTR(epnum, xfercompl); - /* TX COMPLETE */ - USBD_DCD_INT_fops->DataInStage(pdev , epnum); - - if (pdev->cfg.dma_enable == 1) - { - if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN)) - { - /* prepare to rx more setup packets */ - USB_OTG_EP0_OutStart(pdev); - } - } - } - if ( diepint.b.ahberr ) - { - CLEAR_IN_EP_INTR(epnum, ahberr); - } - if ( diepint.b.timeout ) - { - CLEAR_IN_EP_INTR(epnum, timeout); - } - if (diepint.b.intktxfemp) - { - CLEAR_IN_EP_INTR(epnum, intktxfemp); - } - if (diepint.b.intknepmis) - { - CLEAR_IN_EP_INTR(epnum, intknepmis); - } - if (diepint.b.inepnakeff) - { - CLEAR_IN_EP_INTR(epnum, inepnakeff); - } - if ( diepint.b.epdisabled ) - { - CLEAR_IN_EP_INTR(epnum, epdisabled); - } - if (diepint.b.emptyintr) - { - - DCD_WriteEmptyTxFifo(pdev , epnum); - - CLEAR_IN_EP_INTR(epnum, emptyintr); - } - } - epnum++; - ep_intr >>= 1; - } - - return 1; -} - -/** -* @brief DCD_HandleOutEP_ISR -* Indicates that an OUT EP has a pending Interrupt -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t ep_intr; - USB_OTG_DOEPINTn_TypeDef doepint; - USB_OTG_DEPXFRSIZ_TypeDef deptsiz; - uint32_t epnum = 0; - - doepint.d32 = 0; - - /* Read in the device interrupt bits */ - ep_intr = USB_OTG_ReadDevAllOutEp_itr(pdev); - - while ( ep_intr ) - { - if (ep_intr&0x1) - { - - doepint.d32 = USB_OTG_ReadDevOutEP_itr(pdev, epnum); - - /* Transfer complete */ - if ( doepint.b.xfercompl ) - { - /* Clear the bit in DOEPINTn for this interrupt */ - CLEAR_OUT_EP_INTR(epnum, xfercompl); - if (pdev->cfg.dma_enable == 1) - { - deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[epnum]->DOEPTSIZ)); - /*ToDo : handle more than one single MPS size packet */ - pdev->dev.out_ep[epnum].xfer_count = pdev->dev.out_ep[epnum].maxpacket - \ - deptsiz.b.xfersize; - } - /* Inform upper layer: data ready */ - /* RX COMPLETE */ - USBD_DCD_INT_fops->DataOutStage(pdev , epnum); - - if (pdev->cfg.dma_enable == 1) - { - if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_OUT)) - { - /* prepare to rx more setup packets */ - USB_OTG_EP0_OutStart(pdev); - } - } - } - /* Endpoint disable */ - if ( doepint.b.epdisabled ) - { - /* Clear the bit in DOEPINTn for this interrupt */ - CLEAR_OUT_EP_INTR(epnum, epdisabled); - } - /* AHB Error */ - if ( doepint.b.ahberr ) - { - CLEAR_OUT_EP_INTR(epnum, ahberr); - } - /* Setup Phase Done (control EPs) */ - if ( doepint.b.setup ) - { - - /* inform the upper layer that a setup packet is available */ - /* SETUP COMPLETE */ - USBD_DCD_INT_fops->SetupStage(pdev); - CLEAR_OUT_EP_INTR(epnum, setup); - } - } - epnum++; - ep_intr >>= 1; - } - return 1; -} - -/** -* @brief DCD_HandleSof_ISR -* Handles the SOF Interrupts -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef GINTSTS; - - - USBD_DCD_INT_fops->SOF(pdev); - - /* Clear interrupt */ - GINTSTS.d32 = 0; - GINTSTS.b.sofintr = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, GINTSTS.d32); - - return 1; -} - -/** -* @brief DCD_HandleRxStatusQueueLevel_ISR -* Handles the Rx Status Queue Level Interrupt -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTMSK_TypeDef int_mask; - USB_OTG_DRXSTS_TypeDef status; - USB_OTG_EP *ep; - - /* Disable the Rx Status Queue Level interrupt */ - int_mask.d32 = 0; - int_mask.b.rxstsqlvl = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0); - - /* Get the Status from the top of the FIFO */ - status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP ); - - ep = &pdev->dev.out_ep[status.b.epnum]; - - switch (status.b.pktsts) - { - case STS_GOUT_NAK: - break; - case STS_DATA_UPDT: - if (status.b.bcnt) - { - USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt); - ep->xfer_buff += status.b.bcnt; - ep->xfer_count += status.b.bcnt; - } - break; - case STS_XFER_COMP: - break; - case STS_SETUP_COMP: - break; - case STS_SETUP_UPDT: - /* Copy the setup packet received in FIFO into the setup buffer in RAM */ - USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8); - ep->xfer_count += status.b.bcnt; - break; - default: - break; - } - - /* Enable the Rx Status Queue Level interrupt */ - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32); - - return 1; -} - -/** -* @brief DCD_WriteEmptyTxFifo -* check FIFO for the next packet to be loaded -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum) -{ - USB_OTG_DTXFSTSn_TypeDef txstatus; - USB_OTG_EP *ep; - uint32_t len = 0; - uint32_t len32b; - txstatus.d32 = 0; - - ep = &pdev->dev.in_ep[epnum]; - - len = ep->xfer_len - ep->xfer_count; - - if (len > ep->maxpacket) - { - len = ep->maxpacket; - } - - len32b = (len + 3) / 4; - txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS); - - - - while (txstatus.b.txfspcavail > len32b && - ep->xfer_count < ep->xfer_len && - ep->xfer_len != 0) - { - /* Write the FIFO */ - len = ep->xfer_len - ep->xfer_count; - - if (len > ep->maxpacket) - { - len = ep->maxpacket; - } - len32b = (len + 3) / 4; - - USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len); - - ep->xfer_buff += len; - ep->xfer_count += len; - - if( ep->xfer_count >= ep->xfer_len){ - uint32_t fifoemptymsk = 1 << ep->num; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); - break; - } - - txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS); - } - - return 1; -} - -/** -* @brief DCD_HandleUsbReset_ISR -* This interrupt occurs when a USB Reset is detected -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_DAINT_TypeDef daintmsk; - USB_OTG_DOEPMSK_TypeDef doepmsk; - USB_OTG_DIEPMSK_TypeDef diepmsk; - USB_OTG_DCFG_TypeDef dcfg; - USB_OTG_DCTL_TypeDef dctl; - USB_OTG_GINTSTS_TypeDef gintsts; - uint32_t i; - - dctl.d32 = 0; - daintmsk.d32 = 0; - doepmsk.d32 = 0; - diepmsk.d32 = 0; - dcfg.d32 = 0; - gintsts.d32 = 0; - - /* Clear the Remote Wake-up Signaling */ - dctl.b.rmtwkupsig = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 ); - - /* Flush the Tx FIFO */ - USB_OTG_FlushTxFifo(pdev , 0 ); - - for (i = 0; i < pdev->cfg.dev_endpoints ; i++) - { - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); - } - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); - - daintmsk.ep.in = 1; - daintmsk.ep.out = 1; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, daintmsk.d32 ); - - doepmsk.b.setup = 1; - doepmsk.b.xfercompl = 1; - doepmsk.b.ahberr = 1; - doepmsk.b.epdisabled = 1; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 ); -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOUTEP1MSK, doepmsk.d32 ); -#endif - diepmsk.b.xfercompl = 1; - diepmsk.b.timeout = 1; - diepmsk.b.epdisabled = 1; - diepmsk.b.ahberr = 1; - diepmsk.b.intknepmis = 1; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 ); -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 ); -#endif - /* Reset Device Address */ - dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG); - dcfg.b.devaddr = 0; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32); - - - /* setup EP0 to receive SETUP packets */ - USB_OTG_EP0_OutStart(pdev); - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.usbreset = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - /*Reset internal state machine */ - USBD_DCD_INT_fops->Reset(pdev); - return 1; -} - -/** -* @brief DCD_HandleEnumDone_ISR -* Read the device status register and set the device speed -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - USB_OTG_GUSBCFG_TypeDef gusbcfg; - - USB_OTG_EP0Activate(pdev); - - /* Set USB turn-around time based on device speed and PHY interface. */ - gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - /* Full or High speed */ - if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH) - { - pdev->cfg.speed = USB_OTG_SPEED_HIGH; - pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ; - gusbcfg.b.usbtrdtim = 9; - } - else - { - pdev->cfg.speed = USB_OTG_SPEED_FULL; - pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; - gusbcfg.b.usbtrdtim = 5; - } - - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32); - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.enumdone = 1; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 ); - return 1; -} - - -/** -* @brief DCD_IsoINIncomplete_ISR -* handle the ISO IN incomplete interrupt -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - - gintsts.d32 = 0; - - USBD_DCD_INT_fops->IsoINIncomplete (pdev); - - /* Clear interrupt */ - gintsts.b.incomplisoin = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - return 1; -} - -/** -* @brief DCD_IsoOUTIncomplete_ISR -* handle the ISO OUT incomplete interrupt -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - - gintsts.d32 = 0; - - USBD_DCD_INT_fops->IsoOUTIncomplete (pdev); - - /* Clear interrupt */ - gintsts.b.incomplisoout = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - return 1; -} -/** -* @brief DCD_ReadDevInEP -* Reads ep flags -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) -{ - uint32_t v, msk, emp; - msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPMSK); - emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK); - msk |= ((emp >> epnum) & 0x1) << 7; - v = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT) & msk; - return v; -} - - - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usb_dcd_int.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Peripheral Device interrupt subroutines + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_dcd_int.h" + +typedef int IRQn_Type; +#define __NVIC_PRIO_BITS 4 +#define __Vendor_SysTickConfig 1 +#include + + +/** @addtogroup USB_OTG_DRIVER +* @{ +*/ + +/** @defgroup USB_DCD_INT +* @brief This file contains the interrupt subroutines for the Device mode. +* @{ +*/ + + +/** @defgroup USB_DCD_INT_Private_Defines +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USB_DCD_INT_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + + +/** @defgroup USB_DCD_INT_Private_Macros +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USB_DCD_INT_Private_Variables +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USB_DCD_INT_Private_FunctionPrototypes +* @{ +*/ +/* static functions */ +static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum); + +/* Interrupt Handlers */ +static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev); +static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev); +static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev); + +static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev); +static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev , uint32_t epnum); + +static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev); +static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev); +static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev); +static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev); + +static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev); +static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev); +#ifdef VBUS_SENSING_ENABLED +static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev); +static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev); +#endif + +/** +* @} +*/ + + +/** @defgroup USB_DCD_INT_Private_Functions +* @{ +*/ + + +#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED +/** +* @brief USBD_OTG_EP1OUT_ISR_Handler +* handles all USB Interrupts +* @param pdev: device instance +* @retval status +*/ +uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) +{ + + USB_OTG_DOEPINTn_TypeDef doepint; + USB_OTG_DEPXFRSIZ_TypeDef deptsiz; + + doepint.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[1]->DOEPINT); + doepint.d32&= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOUTEP1MSK); + + /* Transfer complete */ + if ( doepint.b.xfercompl ) + { + /* Clear the bit in DOEPINTn for this interrupt */ + CLEAR_OUT_EP_INTR(1, xfercompl); + if (pdev->cfg.dma_enable == 1) + { + deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ)); + /*ToDo : handle more than one single MPS size packet */ + pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].maxpacket - \ + deptsiz.b.xfersize; + } + /* Inform upper layer: data ready */ + /* RX COMPLETE */ + USBD_DCD_INT_fops->DataOutStage(pdev , 1); + + } + + /* Endpoint disable */ + if ( doepint.b.epdisabled ) + { + /* Clear the bit in DOEPINTn for this interrupt */ + CLEAR_OUT_EP_INTR(1, epdisabled); + } + /* AHB Error */ + if ( doepint.b.ahberr ) + { + CLEAR_OUT_EP_INTR(1, ahberr); + } + return 1; +} + +/** +* @brief USBD_OTG_EP1IN_ISR_Handler +* handles all USB Interrupts +* @param pdev: device instance +* @retval status +*/ +uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) +{ + + USB_OTG_DIEPINTn_TypeDef diepint; + uint32_t fifoemptymsk, msk, emp; + + msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK); + emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK); + msk |= ((emp >> 1 ) & 0x1) << 7; + diepint.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk; + + if ( diepint.b.xfercompl ) + { + fifoemptymsk = 0x1 << 1; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); + CLEAR_IN_EP_INTR(1, xfercompl); + /* TX COMPLETE */ + USBD_DCD_INT_fops->DataInStage(pdev , 1); + } + if ( diepint.b.ahberr ) + { + CLEAR_IN_EP_INTR(1, ahberr); + } + if ( diepint.b.epdisabled ) + { + CLEAR_IN_EP_INTR(1, epdisabled); + } + if ( diepint.b.timeout ) + { + CLEAR_IN_EP_INTR(1, timeout); + } + if (diepint.b.intktxfemp) + { + CLEAR_IN_EP_INTR(1, intktxfemp); + } + if (diepint.b.intknepmis) + { + CLEAR_IN_EP_INTR(1, intknepmis); + } + if (diepint.b.inepnakeff) + { + CLEAR_IN_EP_INTR(1, inepnakeff); + } + if (diepint.b.emptyintr) + { + DCD_WriteEmptyTxFifo(pdev , 1); + CLEAR_IN_EP_INTR(1, emptyintr); + } + return 1; +} +#endif + +/** +* @brief STM32_USBF_OTG_ISR_Handler +* handles all USB Interrupts +* @param pdev: device instance +* @retval status +*/ +uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintr_status; + uint32_t retval = 0; + + if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */ + { + gintr_status.d32 = USB_OTG_ReadCoreItr(pdev); + if (!gintr_status.d32) /* avoid spurious interrupt */ + { + return 0; + } + + if (gintr_status.b.outepintr) + { + retval |= DCD_HandleOutEP_ISR(pdev); + } + + if (gintr_status.b.inepint) + { + retval |= DCD_HandleInEP_ISR(pdev); + } + + if (gintr_status.b.modemismatch) + { + USB_OTG_GINTSTS_TypeDef gintsts; + + /* Clear interrupt */ + gintsts.d32 = 0; + gintsts.b.modemismatch = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); + } + + if (gintr_status.b.wkupintr) + { + retval |= DCD_HandleResume_ISR(pdev); + } + + if (gintr_status.b.usbsuspend) + { + retval |= DCD_HandleUSBSuspend_ISR(pdev); + } + if (gintr_status.b.sofintr) + { + retval |= DCD_HandleSof_ISR(pdev); + + } + + if (gintr_status.b.rxstsqlvl) + { + retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev); + + } + + if (gintr_status.b.usbreset) + { + retval |= DCD_HandleUsbReset_ISR(pdev); + + } + if (gintr_status.b.enumdone) + { + retval |= DCD_HandleEnumDone_ISR(pdev); + } + + if (gintr_status.b.incomplisoin) + { + retval |= DCD_IsoINIncomplete_ISR(pdev); + } + + if (gintr_status.b.incomplisoout) + { + retval |= DCD_IsoOUTIncomplete_ISR(pdev); + } +#ifdef VBUS_SENSING_ENABLED + if (gintr_status.b.sessreqintr) + { + retval |= DCD_SessionRequest_ISR(pdev); + } + + if (gintr_status.b.otgintr) + { + retval |= DCD_OTG_ISR(pdev); + } +#endif + } + return retval; +} + +#ifdef VBUS_SENSING_ENABLED +/** +* @brief DCD_SessionRequest_ISR +* Indicates that the USB_OTG controller has detected a connection +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + USBD_DCD_INT_fops->DevConnected (pdev); + + /* Clear interrupt */ + gintsts.d32 = 0; + gintsts.b.sessreqintr = 1; + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); + return 1; +} + +/** +* @brief DCD_OTG_ISR +* Indicates that the USB_OTG controller has detected an OTG event: +* used to detect the end of session i.e. disconnection +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + + USB_OTG_GOTGINT_TypeDef gotgint; + + gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT); + + if (gotgint.b.sesenddet) + { + USBD_DCD_INT_fops->DevDisconnected (pdev); + } + /* Clear OTG interrupt */ + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32); + return 1; +} +#endif +/** +* @brief DCD_HandleResume_ISR +* Indicates that the USB_OTG controller has detected a resume or +* remote Wake-up sequence +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + USB_OTG_DCTL_TypeDef devctl; + USB_OTG_PCGCCTL_TypeDef power; + + if(pdev->cfg.low_power) + { + /* un-gate USB Core clock */ + //power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); + power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL); // ala42 + power.b.gatehclk = 0; + power.b.stoppclk = 0; + USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); + } + + /* Clear the Remote Wake-up Signaling */ + devctl.d32 = 0; + devctl.b.rmtwkupsig = 1; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, devctl.d32, 0); + + /* Inform upper layer by the Resume Event */ + USBD_DCD_INT_fops->Resume (pdev); + + /* Clear interrupt */ + gintsts.d32 = 0; + gintsts.b.wkupintr = 1; + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); + return 1; +} + +/** +* @brief USB_OTG_HandleUSBSuspend_ISR +* Indicates that SUSPEND state has been detected on the USB +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + USB_OTG_PCGCCTL_TypeDef power; + USB_OTG_DSTS_TypeDef dsts; + + USBD_DCD_INT_fops->Suspend (pdev); + + dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); + + /* Clear interrupt */ + gintsts.d32 = 0; + gintsts.b.usbsuspend = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); + + if((pdev->cfg.low_power) && (dsts.b.suspsts == 1)) + { + /* switch-off the clocks */ + power.d32 = 0; + power.b.stoppclk = 1; + USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32); + + power.b.gatehclk = 1; + USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32); + + /* Request to enter Sleep mode after exit from current ISR */ + SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk); + } + return 1; +} + +/** +* @brief DCD_HandleInEP_ISR +* Indicates that an IN EP has a pending Interrupt +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_DIEPINTn_TypeDef diepint; + + uint32_t ep_intr; + uint32_t epnum = 0; + uint32_t fifoemptymsk; + diepint.d32 = 0; + ep_intr = USB_OTG_ReadDevAllInEPItr(pdev); + + while ( ep_intr ) + { + if (ep_intr&0x1) /* In ITR */ + { + diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */ + if ( diepint.b.xfercompl ) + { + fifoemptymsk = 0x1 << epnum; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); + CLEAR_IN_EP_INTR(epnum, xfercompl); + /* TX COMPLETE */ + USBD_DCD_INT_fops->DataInStage(pdev , epnum); + + if (pdev->cfg.dma_enable == 1) + { + if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN)) + { + /* prepare to rx more setup packets */ + USB_OTG_EP0_OutStart(pdev); + } + } + } + if ( diepint.b.ahberr ) + { + CLEAR_IN_EP_INTR(epnum, ahberr); + } + if ( diepint.b.timeout ) + { + CLEAR_IN_EP_INTR(epnum, timeout); + } + if (diepint.b.intktxfemp) + { + CLEAR_IN_EP_INTR(epnum, intktxfemp); + } + if (diepint.b.intknepmis) + { + CLEAR_IN_EP_INTR(epnum, intknepmis); + } + if (diepint.b.inepnakeff) + { + CLEAR_IN_EP_INTR(epnum, inepnakeff); + } + if ( diepint.b.epdisabled ) + { + CLEAR_IN_EP_INTR(epnum, epdisabled); + } + if (diepint.b.emptyintr) + { + + DCD_WriteEmptyTxFifo(pdev , epnum); + + CLEAR_IN_EP_INTR(epnum, emptyintr); + } + } + epnum++; + ep_intr >>= 1; + } + + return 1; +} + +/** +* @brief DCD_HandleOutEP_ISR +* Indicates that an OUT EP has a pending Interrupt +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + uint32_t ep_intr; + USB_OTG_DOEPINTn_TypeDef doepint; + USB_OTG_DEPXFRSIZ_TypeDef deptsiz; + uint32_t epnum = 0; + + doepint.d32 = 0; + + /* Read in the device interrupt bits */ + ep_intr = USB_OTG_ReadDevAllOutEp_itr(pdev); + + while ( ep_intr ) + { + if (ep_intr&0x1) + { + + doepint.d32 = USB_OTG_ReadDevOutEP_itr(pdev, epnum); + + /* Transfer complete */ + if ( doepint.b.xfercompl ) + { + /* Clear the bit in DOEPINTn for this interrupt */ + CLEAR_OUT_EP_INTR(epnum, xfercompl); + if (pdev->cfg.dma_enable == 1) + { + deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[epnum]->DOEPTSIZ)); + /*ToDo : handle more than one single MPS size packet */ + pdev->dev.out_ep[epnum].xfer_count = pdev->dev.out_ep[epnum].maxpacket - \ + deptsiz.b.xfersize; + } + /* Inform upper layer: data ready */ + /* RX COMPLETE */ + USBD_DCD_INT_fops->DataOutStage(pdev , epnum); + + if (pdev->cfg.dma_enable == 1) + { + if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_OUT)) + { + /* prepare to rx more setup packets */ + USB_OTG_EP0_OutStart(pdev); + } + } + } + /* Endpoint disable */ + if ( doepint.b.epdisabled ) + { + /* Clear the bit in DOEPINTn for this interrupt */ + CLEAR_OUT_EP_INTR(epnum, epdisabled); + } + /* AHB Error */ + if ( doepint.b.ahberr ) + { + CLEAR_OUT_EP_INTR(epnum, ahberr); + } + /* Setup Phase Done (control EPs) */ + if ( doepint.b.setup ) + { + + /* inform the upper layer that a setup packet is available */ + /* SETUP COMPLETE */ + USBD_DCD_INT_fops->SetupStage(pdev); + CLEAR_OUT_EP_INTR(epnum, setup); + } + } + epnum++; + ep_intr >>= 1; + } + return 1; +} + +/** +* @brief DCD_HandleSof_ISR +* Handles the SOF Interrupts +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef GINTSTS; + + + USBD_DCD_INT_fops->SOF(pdev); + + /* Clear interrupt */ + GINTSTS.d32 = 0; + GINTSTS.b.sofintr = 1; + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, GINTSTS.d32); + + return 1; +} + +/** +* @brief DCD_HandleRxStatusQueueLevel_ISR +* Handles the Rx Status Queue Level Interrupt +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTMSK_TypeDef int_mask; + USB_OTG_DRXSTS_TypeDef status; + USB_OTG_EP *ep; + + /* Disable the Rx Status Queue Level interrupt */ + int_mask.d32 = 0; + int_mask.b.rxstsqlvl = 1; + USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0); + + /* Get the Status from the top of the FIFO */ + status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP ); + + ep = &pdev->dev.out_ep[status.b.epnum]; + + switch (status.b.pktsts) + { + case STS_GOUT_NAK: + break; + case STS_DATA_UPDT: + if (status.b.bcnt) + { + USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt); + ep->xfer_buff += status.b.bcnt; + ep->xfer_count += status.b.bcnt; + } + break; + case STS_XFER_COMP: + break; + case STS_SETUP_COMP: + break; + case STS_SETUP_UPDT: + /* Copy the setup packet received in FIFO into the setup buffer in RAM */ + USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8); + ep->xfer_count += status.b.bcnt; + break; + default: + break; + } + + /* Enable the Rx Status Queue Level interrupt */ + USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32); + + return 1; +} + +/** +* @brief DCD_WriteEmptyTxFifo +* check FIFO for the next packet to be loaded +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum) +{ + USB_OTG_DTXFSTSn_TypeDef txstatus; + USB_OTG_EP *ep; + uint32_t len = 0; + uint32_t len32b; + txstatus.d32 = 0; + + ep = &pdev->dev.in_ep[epnum]; + + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->maxpacket) + { + len = ep->maxpacket; + } + + len32b = (len + 3) / 4; + txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS); + + + + while (txstatus.b.txfspcavail > len32b && + ep->xfer_count < ep->xfer_len && + ep->xfer_len != 0) + { + /* Write the FIFO */ + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->maxpacket) + { + len = ep->maxpacket; + } + len32b = (len + 3) / 4; + + USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len); + + ep->xfer_buff += len; + ep->xfer_count += len; + + if( ep->xfer_count >= ep->xfer_len){ + uint32_t fifoemptymsk = 1 << ep->num; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); + break; + } + + txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS); + } + + return 1; +} + +/** +* @brief DCD_HandleUsbReset_ISR +* This interrupt occurs when a USB Reset is detected +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_DAINT_TypeDef daintmsk; + USB_OTG_DOEPMSK_TypeDef doepmsk; + USB_OTG_DIEPMSK_TypeDef diepmsk; + USB_OTG_DCFG_TypeDef dcfg; + USB_OTG_DCTL_TypeDef dctl; + USB_OTG_GINTSTS_TypeDef gintsts; + uint32_t i; + + dctl.d32 = 0; + daintmsk.d32 = 0; + doepmsk.d32 = 0; + diepmsk.d32 = 0; + dcfg.d32 = 0; + gintsts.d32 = 0; + + /* Clear the Remote Wake-up Signaling */ + dctl.b.rmtwkupsig = 1; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 ); + + /* Flush the Tx FIFO */ + USB_OTG_FlushTxFifo(pdev , 0 ); + + for (i = 0; i < pdev->cfg.dev_endpoints ; i++) + { + USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); + USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); + } + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); + + daintmsk.ep.in = 1; + daintmsk.ep.out = 1; + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, daintmsk.d32 ); + + doepmsk.b.setup = 1; + doepmsk.b.xfercompl = 1; + doepmsk.b.ahberr = 1; + doepmsk.b.epdisabled = 1; + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 ); +#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOUTEP1MSK, doepmsk.d32 ); +#endif + diepmsk.b.xfercompl = 1; + diepmsk.b.timeout = 1; + diepmsk.b.epdisabled = 1; + diepmsk.b.ahberr = 1; + diepmsk.b.intknepmis = 1; + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 ); +#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 ); +#endif + /* Reset Device Address */ + dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG); + dcfg.b.devaddr = 0; + USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32); + + + /* setup EP0 to receive SETUP packets */ + USB_OTG_EP0_OutStart(pdev); + + /* Clear interrupt */ + gintsts.d32 = 0; + gintsts.b.usbreset = 1; + USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); + + /*Reset internal state machine */ + USBD_DCD_INT_fops->Reset(pdev); + return 1; +} + +/** +* @brief DCD_HandleEnumDone_ISR +* Read the device status register and set the device speed +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + USB_OTG_GUSBCFG_TypeDef gusbcfg; + + USB_OTG_EP0Activate(pdev); + + /* Set USB turn-around time based on device speed and PHY interface. */ + gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); + + /* Full or High speed */ + if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH) + { + pdev->cfg.speed = USB_OTG_SPEED_HIGH; + pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ; + gusbcfg.b.usbtrdtim = 9; + } + else + { + pdev->cfg.speed = USB_OTG_SPEED_FULL; + pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; + gusbcfg.b.usbtrdtim = 5; + } + + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32); + + /* Clear interrupt */ + gintsts.d32 = 0; + gintsts.b.enumdone = 1; + USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 ); + return 1; +} + + +/** +* @brief DCD_IsoINIncomplete_ISR +* handle the ISO IN incomplete interrupt +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + + gintsts.d32 = 0; + + USBD_DCD_INT_fops->IsoINIncomplete (pdev); + + /* Clear interrupt */ + gintsts.b.incomplisoin = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); + + return 1; +} + +/** +* @brief DCD_IsoOUTIncomplete_ISR +* handle the ISO OUT incomplete interrupt +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + + gintsts.d32 = 0; + + USBD_DCD_INT_fops->IsoOUTIncomplete (pdev); + + /* Clear interrupt */ + gintsts.b.incomplisoout = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); + return 1; +} +/** +* @brief DCD_ReadDevInEP +* Reads ep flags +* @param pdev: device instance +* @retval status +*/ +static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) +{ + uint32_t v, msk, emp; + msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPMSK); + emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK); + msk |= ((emp >> epnum) & 0x1) << 7; + v = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT) & msk; + return v; +} + + + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_hcd.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_hcd.c index fe6e60fe..689d061a 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_hcd.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_hcd.c @@ -1,256 +1,256 @@ -/** - ****************************************************************************** - * @file usb_hcd.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Host Interface Layer - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_core.h" -#include "usb_hcd.h" -#include "usb_conf.h" -#include "usb_bsp.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_HCD - * @brief This file is the interface between EFSL ans Host mass-storage class - * @{ - */ - - -/** @defgroup USB_HCD_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USB_HCD_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Private_Variables - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Private_Functions - * @{ - */ - -/** - * @brief HCD_Init - * Initialize the HOST portion of the driver. - * @param pdev: Selected device - * @param base_address: OTG base address - * @retval Status - */ -uint32_t HCD_Init(USB_OTG_CORE_HANDLE *pdev , - USB_OTG_CORE_ID_TypeDef coreID) -{ - uint8_t i = 0; - pdev->host.ConnSts = 0; - - for (i= 0; i< USB_OTG_MAX_TX_FIFOS; i++) - { - pdev->host.ErrCnt[i] = 0; - pdev->host.XferCnt[i] = 0; - pdev->host.HC_Status[i] = HC_IDLE; - } - pdev->host.hc[0].max_packet = 8; - - USB_OTG_SelectCore(pdev, coreID); -#ifndef DUAL_ROLE_MODE_ENABLED - USB_OTG_DisableGlobalInt(pdev); - USB_OTG_CoreInit(pdev); - - /* Force Host Mode*/ - USB_OTG_SetCurrentMode(pdev , HOST_MODE); - USB_OTG_CoreInitHost(pdev); - USB_OTG_EnableGlobalInt(pdev); -#endif - - return 0; -} - - -/** - * @brief HCD_GetCurrentSpeed - * Get Current device Speed. - * @param pdev : Selected device - * @retval Status - */ - -uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HPRT0_TypeDef HPRT0; - HPRT0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); - - return HPRT0.b.prtspd; -} - -/** - * @brief HCD_ResetPort - * Issues the reset command to device - * @param pdev : Selected device - * @retval Status - */ -uint32_t HCD_ResetPort(USB_OTG_CORE_HANDLE *pdev) -{ - /* - Before starting to drive a USB reset, the application waits for the OTG - interrupt triggered by the debounce done bit (DBCDNE bit in OTG_FS_GOTGINT), - which indicates that the bus is stable again after the electrical debounce - caused by the attachment of a pull-up resistor on DP (FS) or DM (LS). - */ - - USB_OTG_ResetPort(pdev); - return 0; -} - -/** - * @brief HCD_IsDeviceConnected - * Check if the device is connected. - * @param pdev : Selected device - * @retval Device connection status. 1 -> connected and 0 -> disconnected - * - */ -uint32_t HCD_IsDeviceConnected(USB_OTG_CORE_HANDLE *pdev) -{ - return (pdev->host.ConnSts); -} - -/** - * @brief HCD_GetCurrentFrame - * This function returns the frame number for sof packet - * @param pdev : Selected device - * @retval Frame number - * - */ -uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0xFFFF) ; -} - -/** - * @brief HCD_GetURB_State - * This function returns the last URBstate - * @param pdev: Selected device - * @retval URB_STATE - * - */ -URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num) -{ - return pdev->host.URB_State[ch_num] ; -} - -/** - * @brief HCD_GetXferCnt - * This function returns the last URBstate - * @param pdev: Selected device - * @retval No. of data bytes transferred - * - */ -uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num) -{ - return pdev->host.XferCnt[ch_num] ; -} - - - -/** - * @brief HCD_GetHCState - * This function returns the HC Status - * @param pdev: Selected device - * @retval HC_STATUS - * - */ -HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num) -{ - return pdev->host.HC_Status[ch_num] ; -} - -/** - * @brief HCD_HC_Init - * This function prepare a HC and start a transfer - * @param pdev: Selected device - * @param hc_num: Channel number - * @retval status - */ -uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - return USB_OTG_HC_Init(pdev, hc_num); -} - -/** - * @brief HCD_SubmitRequest - * This function prepare a HC and start a transfer - * @param pdev: Selected device - * @param hc_num: Channel number - * @retval status - */ -uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - - pdev->host.URB_State[hc_num] = URB_IDLE; - pdev->host.hc[hc_num].xfer_count = 0 ; - return USB_OTG_HC_StartXfer(pdev, hc_num); -} - - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usb_hcd.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Host Interface Layer + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_core.h" +#include "usb_hcd.h" +#include "usb_conf.h" +#include "usb_bsp.h" + + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_HCD + * @brief This file is the interface between EFSL ans Host mass-storage class + * @{ + */ + + +/** @defgroup USB_HCD_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USB_HCD_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_Private_Variables + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_Private_Functions + * @{ + */ + +/** + * @brief HCD_Init + * Initialize the HOST portion of the driver. + * @param pdev: Selected device + * @param base_address: OTG base address + * @retval Status + */ +uint32_t HCD_Init(USB_OTG_CORE_HANDLE *pdev , + USB_OTG_CORE_ID_TypeDef coreID) +{ + uint8_t i = 0; + pdev->host.ConnSts = 0; + + for (i= 0; i< USB_OTG_MAX_TX_FIFOS; i++) + { + pdev->host.ErrCnt[i] = 0; + pdev->host.XferCnt[i] = 0; + pdev->host.HC_Status[i] = HC_IDLE; + } + pdev->host.hc[0].max_packet = 8; + + USB_OTG_SelectCore(pdev, coreID); +#ifndef DUAL_ROLE_MODE_ENABLED + USB_OTG_DisableGlobalInt(pdev); + USB_OTG_CoreInit(pdev); + + /* Force Host Mode*/ + USB_OTG_SetCurrentMode(pdev , HOST_MODE); + USB_OTG_CoreInitHost(pdev); + USB_OTG_EnableGlobalInt(pdev); +#endif + + return 0; +} + + +/** + * @brief HCD_GetCurrentSpeed + * Get Current device Speed. + * @param pdev : Selected device + * @retval Status + */ + +uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_HPRT0_TypeDef HPRT0; + HPRT0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); + + return HPRT0.b.prtspd; +} + +/** + * @brief HCD_ResetPort + * Issues the reset command to device + * @param pdev : Selected device + * @retval Status + */ +uint32_t HCD_ResetPort(USB_OTG_CORE_HANDLE *pdev) +{ + /* + Before starting to drive a USB reset, the application waits for the OTG + interrupt triggered by the debounce done bit (DBCDNE bit in OTG_FS_GOTGINT), + which indicates that the bus is stable again after the electrical debounce + caused by the attachment of a pull-up resistor on DP (FS) or DM (LS). + */ + + USB_OTG_ResetPort(pdev); + return 0; +} + +/** + * @brief HCD_IsDeviceConnected + * Check if the device is connected. + * @param pdev : Selected device + * @retval Device connection status. 1 -> connected and 0 -> disconnected + * + */ +uint32_t HCD_IsDeviceConnected(USB_OTG_CORE_HANDLE *pdev) +{ + return (pdev->host.ConnSts); +} + +/** + * @brief HCD_GetCurrentFrame + * This function returns the frame number for sof packet + * @param pdev : Selected device + * @retval Frame number + * + */ +uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev) +{ + return (USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0xFFFF) ; +} + +/** + * @brief HCD_GetURB_State + * This function returns the last URBstate + * @param pdev: Selected device + * @retval URB_STATE + * + */ +URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num) +{ + return pdev->host.URB_State[ch_num] ; +} + +/** + * @brief HCD_GetXferCnt + * This function returns the last URBstate + * @param pdev: Selected device + * @retval No. of data bytes transferred + * + */ +uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num) +{ + return pdev->host.XferCnt[ch_num] ; +} + + + +/** + * @brief HCD_GetHCState + * This function returns the HC Status + * @param pdev: Selected device + * @retval HC_STATUS + * + */ +HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num) +{ + return pdev->host.HC_Status[ch_num] ; +} + +/** + * @brief HCD_HC_Init + * This function prepare a HC and start a transfer + * @param pdev: Selected device + * @param hc_num: Channel number + * @retval status + */ +uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) +{ + return USB_OTG_HC_Init(pdev, hc_num); +} + +/** + * @brief HCD_SubmitRequest + * This function prepare a HC and start a transfer + * @param pdev: Selected device + * @param hc_num: Channel number + * @retval status + */ +uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) +{ + + pdev->host.URB_State[hc_num] = URB_IDLE; + pdev->host.hc[hc_num].xfer_count = 0 ; + return USB_OTG_HC_StartXfer(pdev, hc_num); +} + + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_hcd_int.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_hcd_int.c index 8ad0f353..bd4081fb 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_hcd_int.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_hcd_int.c @@ -1,832 +1,832 @@ -/** - ****************************************************************************** - * @file usb_hcd_int.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Host driver interrupt subroutines - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_core.h" -#include "usb_defines.h" -#include "usb_hcd_int.h" - -#if defined (__CC_ARM) /*!< ARM Compiler */ - #pragma O0 -#elif defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma O0 -#elif defined (__GNUC__) /*!< GNU Compiler */ - #pragma GCC optimize ("O0") -#elif defined (__TASKING__) /*!< TASKING Compiler */ - #pragma optimize=0 - -#endif /* __CC_ARM */ - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_HCD_INT - * @brief This file contains the interrupt subroutines for the Host mode. - * @{ - */ - - -/** @defgroup USB_HCD_INT_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USB_HCD_INT_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Private_Variables - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Private_FunctionPrototypes - * @{ - */ - -static uint32_t USB_OTG_USBH_handle_sof_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_port_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , - uint32_t num); -static uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , - uint32_t num); -static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev); - -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Private_Functions - * @{ - */ - -/** - * @brief HOST_Handle_ISR - * This function handles all USB Host Interrupts - * @param pdev: Selected device - * @retval status - */ - -uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - uint32_t retval = 0; - - gintsts.d32 = 0; - - /* Check if HOST Mode */ - if (USB_OTG_IsHostMode(pdev)) - { - gintsts.d32 = USB_OTG_ReadCoreItr(pdev); - if (!gintsts.d32) - { - return 0; - } - - if (gintsts.b.sofintr) - { - retval |= USB_OTG_USBH_handle_sof_ISR (pdev); - } - - if (gintsts.b.rxstsqlvl) - { - retval |= USB_OTG_USBH_handle_rx_qlvl_ISR (pdev); - } - - if (gintsts.b.nptxfempty) - { - retval |= USB_OTG_USBH_handle_nptxfempty_ISR (pdev); - } - - if (gintsts.b.ptxfempty) - { - retval |= USB_OTG_USBH_handle_ptxfempty_ISR (pdev); - } - - if (gintsts.b.hcintr) - { - retval |= USB_OTG_USBH_handle_hc_ISR (pdev); - } - - if (gintsts.b.portintr) - { - retval |= USB_OTG_USBH_handle_port_ISR (pdev); - } - - if (gintsts.b.disconnect) - { - retval |= USB_OTG_USBH_handle_Disconnect_ISR (pdev); - - } - - if (gintsts.b.incomplisoout) - { - retval |= USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (pdev); - } - - - } - return retval; -} - -/** - * @brief USB_OTG_USBH_handle_hc_ISR - * This function indicates that one or more host channels has a pending - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HAINT_TypeDef haint; - USB_OTG_HCCHAR_TypeDef hcchar; - uint32_t i = 0; - uint32_t retval = 0; - - /* Clear appropriate bits in HCINTn to clear the interrupt bit in - * GINTSTS */ - - haint.d32 = USB_OTG_ReadHostAllChannels_intr(pdev); - - for (i = 0; i < pdev->cfg.host_channels ; i++) - { - if (haint.b.chint & (1 << i)) - { - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR); - - if (hcchar.b.epdir) - { - retval |= USB_OTG_USBH_handle_hc_n_In_ISR (pdev, i); - } - else - { - retval |= USB_OTG_USBH_handle_hc_n_Out_ISR (pdev, i); - } - } - } - - return retval; -} - -/** - * @brief USB_OTG_otg_hcd_handle_sof_intr - * Handles the start-of-frame interrupt in host mode. - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_sof_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - - - gintsts.d32 = 0; - /* Clear interrupt */ - gintsts.b.sofintr = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_Disconnect_ISR - * Handles disconnect event. - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - - pdev->host.ConnSts = 0; - gintsts.d32 = 0; - - pdev->host.port_cb->Disconnect(pdev); - - /* Clear interrupt */ - gintsts.b.disconnect = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_nptxfempty_ISR - * Handles non periodic tx fifo empty. - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTMSK_TypeDef intmsk; - USB_OTG_HNPTXSTS_TypeDef hnptxsts; - uint16_t len_words , len; - - hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); - - len_words = (pdev->host.hc[hnptxsts.b.chnum].xfer_len + 3) / 4; - - while ((hnptxsts.b.nptxfspcavail > len_words)&& - (pdev->host.hc[hnptxsts.b.chnum].xfer_len != 0)) - { - - len = hnptxsts.b.nptxfspcavail * 4; - - if (len > pdev->host.hc[hnptxsts.b.chnum].xfer_len) - { - /* Last packet */ - len = pdev->host.hc[hnptxsts.b.chnum].xfer_len; - - intmsk.d32 = 0; - intmsk.b.nptxfempty = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0); - } - - len_words = (pdev->host.hc[hnptxsts.b.chnum].xfer_len + 3) / 4; - - USB_OTG_WritePacket (pdev , pdev->host.hc[hnptxsts.b.chnum].xfer_buff, hnptxsts.b.chnum, len); - - pdev->host.hc[hnptxsts.b.chnum].xfer_buff += len; - pdev->host.hc[hnptxsts.b.chnum].xfer_len -= len; - pdev->host.hc[hnptxsts.b.chnum].xfer_count += len; - - hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); - } - - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_ptxfempty_ISR - * Handles periodic tx fifo empty - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTMSK_TypeDef intmsk; - USB_OTG_HPTXSTS_TypeDef hptxsts; - uint16_t len_words , len; - - hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); - - len_words = (pdev->host.hc[hptxsts.b.chnum].xfer_len + 3) / 4; - - while ((hptxsts.b.ptxfspcavail > len_words)&& - (pdev->host.hc[hptxsts.b.chnum].xfer_len != 0)) - { - - len = hptxsts.b.ptxfspcavail * 4; - - if (len > pdev->host.hc[hptxsts.b.chnum].xfer_len) - { - len = pdev->host.hc[hptxsts.b.chnum].xfer_len; - /* Last packet */ - intmsk.d32 = 0; - intmsk.b.ptxfempty = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0); - } - - len_words = (pdev->host.hc[hptxsts.b.chnum].xfer_len + 3) / 4; - - USB_OTG_WritePacket (pdev , pdev->host.hc[hptxsts.b.chnum].xfer_buff, hptxsts.b.chnum, len); - - pdev->host.hc[hptxsts.b.chnum].xfer_buff += len; - pdev->host.hc[hptxsts.b.chnum].xfer_len -= len; - pdev->host.hc[hptxsts.b.chnum].xfer_count += len; - - hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); - } - - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_port_ISR - * This function determines which interrupt conditions have occurred - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_port_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HPRT0_TypeDef hprt0; - USB_OTG_HPRT0_TypeDef hprt0_dup; - USB_OTG_HCFG_TypeDef hcfg; - uint32_t do_reset = 0; - uint32_t retval = 0; - - hcfg.d32 = 0; - hprt0.d32 = 0; - hprt0_dup.d32 = 0; - - hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); - hprt0_dup.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); - - /* Clear the interrupt bits in GINTSTS */ - - hprt0_dup.b.prtena = 0; - hprt0_dup.b.prtconndet = 0; - hprt0_dup.b.prtenchng = 0; - hprt0_dup.b.prtovrcurrchng = 0; - - /* Port Connect Detected */ - if (hprt0.b.prtconndet) - { - pdev->host.port_cb->Connect(pdev); - hprt0_dup.b.prtconndet = 1; - do_reset = 1; - retval |= 1; - } - - /* Port Enable Changed */ - if (hprt0.b.prtenchng) - { - hprt0_dup.b.prtenchng = 1; - if (hprt0.b.prtena == 1) - { - pdev->host.ConnSts = 1; - - if ((hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) || - (hprt0.b.prtspd == HPRT0_PRTSPD_FULL_SPEED)) - { - - hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); - - if (hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) - { - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 6000 ); - if (hcfg.b.fslspclksel != HCFG_6_MHZ) - { - if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID) - { - USB_OTG_InitFSLSPClkSel(pdev ,HCFG_6_MHZ ); - } - do_reset = 1; - } - } - else - { - - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 48000 ); - if (hcfg.b.fslspclksel != HCFG_48_MHZ) - { - USB_OTG_InitFSLSPClkSel(pdev ,HCFG_48_MHZ ); - do_reset = 1; - } - } - } - else - { - do_reset = 1; - } - } - } - /* Overcurrent Change Interrupt */ - if (hprt0.b.prtovrcurrchng) - { - hprt0_dup.b.prtovrcurrchng = 1; - retval |= 1; - } - if (do_reset) - { - USB_OTG_ResetPort(pdev); - - } - /* Clear Port Interrupts */ - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0_dup.d32); - - return retval; -} - -/** - * @brief USB_OTG_USBH_handle_hc_n_Out_ISR - * Handles interrupt for a specific Host Channel - * @param pdev: Selected device - * @param hc_num: Channel number - * @retval status - */ -uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num) -{ - - USB_OTG_HCINTn_TypeDef hcint; - USB_OTG_HCGINTMSK_TypeDef hcintmsk; - USB_OTG_HC_REGS *hcreg; - USB_OTG_HCCHAR_TypeDef hcchar; - - hcreg = pdev->regs.HC_REGS[num]; - hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT); - hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCGINTMSK); - hcint.d32 = hcint.d32 & hcintmsk.d32; - - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR); - - if (hcint.b.ahberr) - { - CLEAR_HC_INT(hcreg ,ahberr); - UNMASK_HOST_INT_CHH (num); - } - else if (hcint.b.ack) - { - CLEAR_HC_INT(hcreg , ack); - } - - else if (hcint.b.xfercompl) - { - pdev->host.ErrCnt[num] = 0; - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , xfercompl); - pdev->host.HC_Status[num] = HC_XFRC; - } - - else if (hcint.b.stall) - { - CLEAR_HC_INT(hcreg , stall); - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - pdev->host.HC_Status[num] = HC_STALL; - } - - else if (hcint.b.nak) - { - pdev->host.ErrCnt[num] = 0; - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nak); - pdev->host.HC_Status[num] = HC_NAK; - } - - else if (hcint.b.xacterr) - { - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - pdev->host.ErrCnt[num] ++; - pdev->host.HC_Status[num] = HC_XACTERR; - CLEAR_HC_INT(hcreg , xacterr); - } - else if (hcint.b.nyet) - { - pdev->host.ErrCnt[num] = 0; - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nyet); - pdev->host.HC_Status[num] = HC_NYET; - } - else if (hcint.b.datatglerr) - { - - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nak); - pdev->host.HC_Status[num] = HC_DATATGLERR; - - CLEAR_HC_INT(hcreg , datatglerr); - } - else if (hcint.b.chhltd) - { - MASK_HOST_INT_CHH (num); - - if(pdev->host.HC_Status[num] == HC_XFRC) - { - pdev->host.URB_State[num] = URB_DONE; - - if (hcchar.b.eptype == EP_TYPE_BULK) - { - pdev->host.hc[num].toggle_out ^= 1; - } - } - else if(pdev->host.HC_Status[num] == HC_NAK) - { - pdev->host.URB_State[num] = URB_NOTREADY; - } - else if(pdev->host.HC_Status[num] == HC_NYET) - { - if(pdev->host.hc[num].do_ping == 1) - { - USB_OTG_HC_DoPing(pdev, num); - } - pdev->host.URB_State[num] = URB_NOTREADY; - } - else if(pdev->host.HC_Status[num] == HC_STALL) - { - pdev->host.URB_State[num] = URB_STALL; - } - else if(pdev->host.HC_Status[num] == HC_XACTERR) - { - if (pdev->host.ErrCnt[num] == 3) - { - pdev->host.URB_State[num] = URB_ERROR; - pdev->host.ErrCnt[num] = 0; - } - } - CLEAR_HC_INT(hcreg , chhltd); - } - - - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_hc_n_In_ISR - * Handles interrupt for a specific Host Channel - * @param pdev: Selected device - * @param hc_num: Channel number - * @retval status - */ -uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num) -{ - USB_OTG_HCINTn_TypeDef hcint; - USB_OTG_HCGINTMSK_TypeDef hcintmsk; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCTSIZn_TypeDef hctsiz; - USB_OTG_HC_REGS *hcreg; - - - hcreg = pdev->regs.HC_REGS[num]; - hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT); - hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCGINTMSK); - hcint.d32 = hcint.d32 & hcintmsk.d32; - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR); - hcintmsk.d32 = 0; - - - if (hcint.b.ahberr) - { - CLEAR_HC_INT(hcreg ,ahberr); - UNMASK_HOST_INT_CHH (num); - } - else if (hcint.b.ack) - { - CLEAR_HC_INT(hcreg ,ack); - } - - else if (hcint.b.stall) - { - UNMASK_HOST_INT_CHH (num); - pdev->host.HC_Status[num] = HC_STALL; - CLEAR_HC_INT(hcreg , nak); /* Clear the NAK Condition */ - CLEAR_HC_INT(hcreg , stall); /* Clear the STALL Condition */ - hcint.b.nak = 0; /* NOTE: When there is a 'stall', reset also nak, - else, the pdev->host.HC_Status = HC_STALL - will be overwritten by 'nak' in code below */ - USB_OTG_HC_Halt(pdev, num); - } - else if (hcint.b.datatglerr) - { - - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nak); - pdev->host.HC_Status[num] = HC_DATATGLERR; - CLEAR_HC_INT(hcreg , datatglerr); - } - - if (hcint.b.frmovrun) - { - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg ,frmovrun); - } - - else if (hcint.b.xfercompl) - { - - if (pdev->cfg.dma_enable == 1) - { - hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCTSIZ); - pdev->host.XferCnt[num] = pdev->host.hc[num].xfer_len - hctsiz.b.xfersize; - } - - pdev->host.HC_Status[num] = HC_XFRC; - pdev->host.ErrCnt [num]= 0; - CLEAR_HC_INT(hcreg , xfercompl); - - if ((hcchar.b.eptype == EP_TYPE_CTRL)|| - (hcchar.b.eptype == EP_TYPE_BULK)) - { - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nak); - pdev->host.hc[num].toggle_in ^= 1; - - } - else if(hcchar.b.eptype == EP_TYPE_INTR) - { - hcchar.b.oddfrm = 1; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); - pdev->host.URB_State[num] = URB_DONE; - } - - } - else if (hcint.b.chhltd) - { - MASK_HOST_INT_CHH (num); - - if(pdev->host.HC_Status[num] == HC_XFRC) - { - pdev->host.URB_State[num] = URB_DONE; - } - - else if (pdev->host.HC_Status[num] == HC_STALL) - { - pdev->host.URB_State[num] = URB_STALL; - } - - else if((pdev->host.HC_Status[num] == HC_XACTERR) || - (pdev->host.HC_Status[num] == HC_DATATGLERR)) - { - pdev->host.ErrCnt[num] = 0; - pdev->host.URB_State[num] = URB_ERROR; - - } - else if(hcchar.b.eptype == EP_TYPE_INTR) - { - pdev->host.hc[num].toggle_in ^= 1; - } - - CLEAR_HC_INT(hcreg , chhltd); - - } - else if (hcint.b.xacterr) - { - UNMASK_HOST_INT_CHH (num); - pdev->host.ErrCnt[num] ++; - pdev->host.HC_Status[num] = HC_XACTERR; - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , xacterr); - - } - else if (hcint.b.nak) - { - if(hcchar.b.eptype == EP_TYPE_INTR) - { - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nak); - } - else if ((hcchar.b.eptype == EP_TYPE_CTRL)|| - (hcchar.b.eptype == EP_TYPE_BULK)) - { - /* re-activate the channel */ - hcchar.b.chen = 1; - hcchar.b.chdis = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); - } - pdev->host.HC_Status[num] = HC_NAK; - } - - - return 1; - -} - -/** - * @brief USB_OTG_USBH_handle_rx_qlvl_ISR - * Handles the Rx Status Queue Level Interrupt - * @param pdev: Selected device - * @retval status - */ - -static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GRXFSTS_TypeDef grxsts; - USB_OTG_GINTMSK_TypeDef intmsk; - USB_OTG_HCTSIZn_TypeDef hctsiz; - USB_OTG_HCCHAR_TypeDef hcchar; - __IO uint8_t channelnum =0; - uint32_t count; - - /* Disable the Rx Status Queue Level interrupt */ - intmsk.d32 = 0; - intmsk.b.rxstsqlvl = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0); - - grxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRXSTSP); - channelnum = grxsts.b.chnum; - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR); - - switch (grxsts.b.pktsts) - { - case GRXSTS_PKTSTS_IN: - /* Read the data into the host buffer. */ - if ((grxsts.b.bcnt > 0) && (pdev->host.hc[channelnum].xfer_buff != (void *)0)) - { - - USB_OTG_ReadPacket(pdev, pdev->host.hc[channelnum].xfer_buff, grxsts.b.bcnt); - /*manage multiple Xfer */ - pdev->host.hc[grxsts.b.chnum].xfer_buff += grxsts.b.bcnt; - pdev->host.hc[grxsts.b.chnum].xfer_count += grxsts.b.bcnt; - - - count = pdev->host.hc[channelnum].xfer_count; - pdev->host.XferCnt[channelnum] = count; - - hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCTSIZ); - if(hctsiz.b.pktcnt > 0) - { - /* re-activate the channel when more packets are expected */ - hcchar.b.chen = 1; - hcchar.b.chdis = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR, hcchar.d32); - } - } - break; - - case GRXSTS_PKTSTS_IN_XFER_COMP: - - case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: - case GRXSTS_PKTSTS_CH_HALTED: - default: - break; - } - - /* Enable the Rx Status Queue Level interrupt */ - intmsk.b.rxstsqlvl = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR - * Handles the incomplete Periodic transfer Interrupt - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_GINTSTS_TypeDef gintsts; - USB_OTG_HCCHAR_TypeDef hcchar; - - - - - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[0]->HCCHAR); - hcchar.b.chen = 1; - hcchar.b.chdis = 1; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[0]->HCCHAR, hcchar.d32); - - gintsts.d32 = 0; - /* Clear interrupt */ - gintsts.b.incomplisoout = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - return 1; -} - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_hcd_int.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief Host driver interrupt subroutines + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_core.h" +#include "usb_defines.h" +#include "usb_hcd_int.h" + +#if defined (__CC_ARM) /*!< ARM Compiler */ + #pragma O0 +#elif defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma O0 +#elif defined (__GNUC__) /*!< GNU Compiler */ + #pragma GCC optimize ("O0") +#elif defined (__TASKING__) /*!< TASKING Compiler */ + #pragma optimize=0 + +#endif /* __CC_ARM */ + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_HCD_INT + * @brief This file contains the interrupt subroutines for the Host mode. + * @{ + */ + + +/** @defgroup USB_HCD_INT_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_INT_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USB_HCD_INT_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_INT_Private_Variables + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_HCD_INT_Private_FunctionPrototypes + * @{ + */ + +static uint32_t USB_OTG_USBH_handle_sof_ISR(USB_OTG_CORE_HANDLE *pdev); +static uint32_t USB_OTG_USBH_handle_port_ISR(USB_OTG_CORE_HANDLE *pdev); +static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev); +static uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , + uint32_t num); +static uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , + uint32_t num); +static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev); +static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev); +static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev); +static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev); +static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev); + +/** + * @} + */ + + +/** @defgroup USB_HCD_INT_Private_Functions + * @{ + */ + +/** + * @brief HOST_Handle_ISR + * This function handles all USB Host Interrupts + * @param pdev: Selected device + * @retval status + */ + +uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + uint32_t retval = 0; + + gintsts.d32 = 0; + + /* Check if HOST Mode */ + if (USB_OTG_IsHostMode(pdev)) + { + gintsts.d32 = USB_OTG_ReadCoreItr(pdev); + if (!gintsts.d32) + { + return 0; + } + + if (gintsts.b.sofintr) + { + retval |= USB_OTG_USBH_handle_sof_ISR (pdev); + } + + if (gintsts.b.rxstsqlvl) + { + retval |= USB_OTG_USBH_handle_rx_qlvl_ISR (pdev); + } + + if (gintsts.b.nptxfempty) + { + retval |= USB_OTG_USBH_handle_nptxfempty_ISR (pdev); + } + + if (gintsts.b.ptxfempty) + { + retval |= USB_OTG_USBH_handle_ptxfempty_ISR (pdev); + } + + if (gintsts.b.hcintr) + { + retval |= USB_OTG_USBH_handle_hc_ISR (pdev); + } + + if (gintsts.b.portintr) + { + retval |= USB_OTG_USBH_handle_port_ISR (pdev); + } + + if (gintsts.b.disconnect) + { + retval |= USB_OTG_USBH_handle_Disconnect_ISR (pdev); + + } + + if (gintsts.b.incomplisoout) + { + retval |= USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (pdev); + } + + + } + return retval; +} + +/** + * @brief USB_OTG_USBH_handle_hc_ISR + * This function indicates that one or more host channels has a pending + * @param pdev: Selected device + * @retval status + */ +static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_HAINT_TypeDef haint; + USB_OTG_HCCHAR_TypeDef hcchar; + uint32_t i = 0; + uint32_t retval = 0; + + /* Clear appropriate bits in HCINTn to clear the interrupt bit in + * GINTSTS */ + + haint.d32 = USB_OTG_ReadHostAllChannels_intr(pdev); + + for (i = 0; i < pdev->cfg.host_channels ; i++) + { + if (haint.b.chint & (1 << i)) + { + hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR); + + if (hcchar.b.epdir) + { + retval |= USB_OTG_USBH_handle_hc_n_In_ISR (pdev, i); + } + else + { + retval |= USB_OTG_USBH_handle_hc_n_Out_ISR (pdev, i); + } + } + } + + return retval; +} + +/** + * @brief USB_OTG_otg_hcd_handle_sof_intr + * Handles the start-of-frame interrupt in host mode. + * @param pdev: Selected device + * @retval status + */ +static uint32_t USB_OTG_USBH_handle_sof_ISR (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + + + gintsts.d32 = 0; + /* Clear interrupt */ + gintsts.b.sofintr = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); + + return 1; +} + +/** + * @brief USB_OTG_USBH_handle_Disconnect_ISR + * Handles disconnect event. + * @param pdev: Selected device + * @retval status + */ +static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + + pdev->host.ConnSts = 0; + gintsts.d32 = 0; + + pdev->host.port_cb->Disconnect(pdev); + + /* Clear interrupt */ + gintsts.b.disconnect = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); + + return 1; +} + +/** + * @brief USB_OTG_USBH_handle_nptxfempty_ISR + * Handles non periodic tx fifo empty. + * @param pdev: Selected device + * @retval status + */ +static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTMSK_TypeDef intmsk; + USB_OTG_HNPTXSTS_TypeDef hnptxsts; + uint16_t len_words , len; + + hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); + + len_words = (pdev->host.hc[hnptxsts.b.chnum].xfer_len + 3) / 4; + + while ((hnptxsts.b.nptxfspcavail > len_words)&& + (pdev->host.hc[hnptxsts.b.chnum].xfer_len != 0)) + { + + len = hnptxsts.b.nptxfspcavail * 4; + + if (len > pdev->host.hc[hnptxsts.b.chnum].xfer_len) + { + /* Last packet */ + len = pdev->host.hc[hnptxsts.b.chnum].xfer_len; + + intmsk.d32 = 0; + intmsk.b.nptxfempty = 1; + USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0); + } + + len_words = (pdev->host.hc[hnptxsts.b.chnum].xfer_len + 3) / 4; + + USB_OTG_WritePacket (pdev , pdev->host.hc[hnptxsts.b.chnum].xfer_buff, hnptxsts.b.chnum, len); + + pdev->host.hc[hnptxsts.b.chnum].xfer_buff += len; + pdev->host.hc[hnptxsts.b.chnum].xfer_len -= len; + pdev->host.hc[hnptxsts.b.chnum].xfer_count += len; + + hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); + } + + return 1; +} + +/** + * @brief USB_OTG_USBH_handle_ptxfempty_ISR + * Handles periodic tx fifo empty + * @param pdev: Selected device + * @retval status + */ +static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTMSK_TypeDef intmsk; + USB_OTG_HPTXSTS_TypeDef hptxsts; + uint16_t len_words , len; + + hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); + + len_words = (pdev->host.hc[hptxsts.b.chnum].xfer_len + 3) / 4; + + while ((hptxsts.b.ptxfspcavail > len_words)&& + (pdev->host.hc[hptxsts.b.chnum].xfer_len != 0)) + { + + len = hptxsts.b.ptxfspcavail * 4; + + if (len > pdev->host.hc[hptxsts.b.chnum].xfer_len) + { + len = pdev->host.hc[hptxsts.b.chnum].xfer_len; + /* Last packet */ + intmsk.d32 = 0; + intmsk.b.ptxfempty = 1; + USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0); + } + + len_words = (pdev->host.hc[hptxsts.b.chnum].xfer_len + 3) / 4; + + USB_OTG_WritePacket (pdev , pdev->host.hc[hptxsts.b.chnum].xfer_buff, hptxsts.b.chnum, len); + + pdev->host.hc[hptxsts.b.chnum].xfer_buff += len; + pdev->host.hc[hptxsts.b.chnum].xfer_len -= len; + pdev->host.hc[hptxsts.b.chnum].xfer_count += len; + + hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); + } + + return 1; +} + +/** + * @brief USB_OTG_USBH_handle_port_ISR + * This function determines which interrupt conditions have occurred + * @param pdev: Selected device + * @retval status + */ +static uint32_t USB_OTG_USBH_handle_port_ISR (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_HPRT0_TypeDef hprt0; + USB_OTG_HPRT0_TypeDef hprt0_dup; + USB_OTG_HCFG_TypeDef hcfg; + uint32_t do_reset = 0; + uint32_t retval = 0; + + hcfg.d32 = 0; + hprt0.d32 = 0; + hprt0_dup.d32 = 0; + + hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); + hprt0_dup.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); + + /* Clear the interrupt bits in GINTSTS */ + + hprt0_dup.b.prtena = 0; + hprt0_dup.b.prtconndet = 0; + hprt0_dup.b.prtenchng = 0; + hprt0_dup.b.prtovrcurrchng = 0; + + /* Port Connect Detected */ + if (hprt0.b.prtconndet) + { + pdev->host.port_cb->Connect(pdev); + hprt0_dup.b.prtconndet = 1; + do_reset = 1; + retval |= 1; + } + + /* Port Enable Changed */ + if (hprt0.b.prtenchng) + { + hprt0_dup.b.prtenchng = 1; + if (hprt0.b.prtena == 1) + { + pdev->host.ConnSts = 1; + + if ((hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) || + (hprt0.b.prtspd == HPRT0_PRTSPD_FULL_SPEED)) + { + + hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); + + if (hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) + { + USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 6000 ); + if (hcfg.b.fslspclksel != HCFG_6_MHZ) + { + if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID) + { + USB_OTG_InitFSLSPClkSel(pdev ,HCFG_6_MHZ ); + } + do_reset = 1; + } + } + else + { + + USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 48000 ); + if (hcfg.b.fslspclksel != HCFG_48_MHZ) + { + USB_OTG_InitFSLSPClkSel(pdev ,HCFG_48_MHZ ); + do_reset = 1; + } + } + } + else + { + do_reset = 1; + } + } + } + /* Overcurrent Change Interrupt */ + if (hprt0.b.prtovrcurrchng) + { + hprt0_dup.b.prtovrcurrchng = 1; + retval |= 1; + } + if (do_reset) + { + USB_OTG_ResetPort(pdev); + + } + /* Clear Port Interrupts */ + USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0_dup.d32); + + return retval; +} + +/** + * @brief USB_OTG_USBH_handle_hc_n_Out_ISR + * Handles interrupt for a specific Host Channel + * @param pdev: Selected device + * @param hc_num: Channel number + * @retval status + */ +uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num) +{ + + USB_OTG_HCINTn_TypeDef hcint; + USB_OTG_HCGINTMSK_TypeDef hcintmsk; + USB_OTG_HC_REGS *hcreg; + USB_OTG_HCCHAR_TypeDef hcchar; + + hcreg = pdev->regs.HC_REGS[num]; + hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT); + hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCGINTMSK); + hcint.d32 = hcint.d32 & hcintmsk.d32; + + hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR); + + if (hcint.b.ahberr) + { + CLEAR_HC_INT(hcreg ,ahberr); + UNMASK_HOST_INT_CHH (num); + } + else if (hcint.b.ack) + { + CLEAR_HC_INT(hcreg , ack); + } + + else if (hcint.b.xfercompl) + { + pdev->host.ErrCnt[num] = 0; + UNMASK_HOST_INT_CHH (num); + USB_OTG_HC_Halt(pdev, num); + CLEAR_HC_INT(hcreg , xfercompl); + pdev->host.HC_Status[num] = HC_XFRC; + } + + else if (hcint.b.stall) + { + CLEAR_HC_INT(hcreg , stall); + UNMASK_HOST_INT_CHH (num); + USB_OTG_HC_Halt(pdev, num); + pdev->host.HC_Status[num] = HC_STALL; + } + + else if (hcint.b.nak) + { + pdev->host.ErrCnt[num] = 0; + UNMASK_HOST_INT_CHH (num); + USB_OTG_HC_Halt(pdev, num); + CLEAR_HC_INT(hcreg , nak); + pdev->host.HC_Status[num] = HC_NAK; + } + + else if (hcint.b.xacterr) + { + UNMASK_HOST_INT_CHH (num); + USB_OTG_HC_Halt(pdev, num); + pdev->host.ErrCnt[num] ++; + pdev->host.HC_Status[num] = HC_XACTERR; + CLEAR_HC_INT(hcreg , xacterr); + } + else if (hcint.b.nyet) + { + pdev->host.ErrCnt[num] = 0; + UNMASK_HOST_INT_CHH (num); + USB_OTG_HC_Halt(pdev, num); + CLEAR_HC_INT(hcreg , nyet); + pdev->host.HC_Status[num] = HC_NYET; + } + else if (hcint.b.datatglerr) + { + + UNMASK_HOST_INT_CHH (num); + USB_OTG_HC_Halt(pdev, num); + CLEAR_HC_INT(hcreg , nak); + pdev->host.HC_Status[num] = HC_DATATGLERR; + + CLEAR_HC_INT(hcreg , datatglerr); + } + else if (hcint.b.chhltd) + { + MASK_HOST_INT_CHH (num); + + if(pdev->host.HC_Status[num] == HC_XFRC) + { + pdev->host.URB_State[num] = URB_DONE; + + if (hcchar.b.eptype == EP_TYPE_BULK) + { + pdev->host.hc[num].toggle_out ^= 1; + } + } + else if(pdev->host.HC_Status[num] == HC_NAK) + { + pdev->host.URB_State[num] = URB_NOTREADY; + } + else if(pdev->host.HC_Status[num] == HC_NYET) + { + if(pdev->host.hc[num].do_ping == 1) + { + USB_OTG_HC_DoPing(pdev, num); + } + pdev->host.URB_State[num] = URB_NOTREADY; + } + else if(pdev->host.HC_Status[num] == HC_STALL) + { + pdev->host.URB_State[num] = URB_STALL; + } + else if(pdev->host.HC_Status[num] == HC_XACTERR) + { + if (pdev->host.ErrCnt[num] == 3) + { + pdev->host.URB_State[num] = URB_ERROR; + pdev->host.ErrCnt[num] = 0; + } + } + CLEAR_HC_INT(hcreg , chhltd); + } + + + return 1; +} + +/** + * @brief USB_OTG_USBH_handle_hc_n_In_ISR + * Handles interrupt for a specific Host Channel + * @param pdev: Selected device + * @param hc_num: Channel number + * @retval status + */ +uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num) +{ + USB_OTG_HCINTn_TypeDef hcint; + USB_OTG_HCGINTMSK_TypeDef hcintmsk; + USB_OTG_HCCHAR_TypeDef hcchar; + USB_OTG_HCTSIZn_TypeDef hctsiz; + USB_OTG_HC_REGS *hcreg; + + + hcreg = pdev->regs.HC_REGS[num]; + hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT); + hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCGINTMSK); + hcint.d32 = hcint.d32 & hcintmsk.d32; + hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR); + hcintmsk.d32 = 0; + + + if (hcint.b.ahberr) + { + CLEAR_HC_INT(hcreg ,ahberr); + UNMASK_HOST_INT_CHH (num); + } + else if (hcint.b.ack) + { + CLEAR_HC_INT(hcreg ,ack); + } + + else if (hcint.b.stall) + { + UNMASK_HOST_INT_CHH (num); + pdev->host.HC_Status[num] = HC_STALL; + CLEAR_HC_INT(hcreg , nak); /* Clear the NAK Condition */ + CLEAR_HC_INT(hcreg , stall); /* Clear the STALL Condition */ + hcint.b.nak = 0; /* NOTE: When there is a 'stall', reset also nak, + else, the pdev->host.HC_Status = HC_STALL + will be overwritten by 'nak' in code below */ + USB_OTG_HC_Halt(pdev, num); + } + else if (hcint.b.datatglerr) + { + + UNMASK_HOST_INT_CHH (num); + USB_OTG_HC_Halt(pdev, num); + CLEAR_HC_INT(hcreg , nak); + pdev->host.HC_Status[num] = HC_DATATGLERR; + CLEAR_HC_INT(hcreg , datatglerr); + } + + if (hcint.b.frmovrun) + { + UNMASK_HOST_INT_CHH (num); + USB_OTG_HC_Halt(pdev, num); + CLEAR_HC_INT(hcreg ,frmovrun); + } + + else if (hcint.b.xfercompl) + { + + if (pdev->cfg.dma_enable == 1) + { + hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCTSIZ); + pdev->host.XferCnt[num] = pdev->host.hc[num].xfer_len - hctsiz.b.xfersize; + } + + pdev->host.HC_Status[num] = HC_XFRC; + pdev->host.ErrCnt [num]= 0; + CLEAR_HC_INT(hcreg , xfercompl); + + if ((hcchar.b.eptype == EP_TYPE_CTRL)|| + (hcchar.b.eptype == EP_TYPE_BULK)) + { + UNMASK_HOST_INT_CHH (num); + USB_OTG_HC_Halt(pdev, num); + CLEAR_HC_INT(hcreg , nak); + pdev->host.hc[num].toggle_in ^= 1; + + } + else if(hcchar.b.eptype == EP_TYPE_INTR) + { + hcchar.b.oddfrm = 1; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); + pdev->host.URB_State[num] = URB_DONE; + } + + } + else if (hcint.b.chhltd) + { + MASK_HOST_INT_CHH (num); + + if(pdev->host.HC_Status[num] == HC_XFRC) + { + pdev->host.URB_State[num] = URB_DONE; + } + + else if (pdev->host.HC_Status[num] == HC_STALL) + { + pdev->host.URB_State[num] = URB_STALL; + } + + else if((pdev->host.HC_Status[num] == HC_XACTERR) || + (pdev->host.HC_Status[num] == HC_DATATGLERR)) + { + pdev->host.ErrCnt[num] = 0; + pdev->host.URB_State[num] = URB_ERROR; + + } + else if(hcchar.b.eptype == EP_TYPE_INTR) + { + pdev->host.hc[num].toggle_in ^= 1; + } + + CLEAR_HC_INT(hcreg , chhltd); + + } + else if (hcint.b.xacterr) + { + UNMASK_HOST_INT_CHH (num); + pdev->host.ErrCnt[num] ++; + pdev->host.HC_Status[num] = HC_XACTERR; + USB_OTG_HC_Halt(pdev, num); + CLEAR_HC_INT(hcreg , xacterr); + + } + else if (hcint.b.nak) + { + if(hcchar.b.eptype == EP_TYPE_INTR) + { + UNMASK_HOST_INT_CHH (num); + USB_OTG_HC_Halt(pdev, num); + CLEAR_HC_INT(hcreg , nak); + } + else if ((hcchar.b.eptype == EP_TYPE_CTRL)|| + (hcchar.b.eptype == EP_TYPE_BULK)) + { + /* re-activate the channel */ + hcchar.b.chen = 1; + hcchar.b.chdis = 0; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); + } + pdev->host.HC_Status[num] = HC_NAK; + } + + + return 1; + +} + +/** + * @brief USB_OTG_USBH_handle_rx_qlvl_ISR + * Handles the Rx Status Queue Level Interrupt + * @param pdev: Selected device + * @retval status + */ + +static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GRXFSTS_TypeDef grxsts; + USB_OTG_GINTMSK_TypeDef intmsk; + USB_OTG_HCTSIZn_TypeDef hctsiz; + USB_OTG_HCCHAR_TypeDef hcchar; + __IO uint8_t channelnum =0; + uint32_t count; + + /* Disable the Rx Status Queue Level interrupt */ + intmsk.d32 = 0; + intmsk.b.rxstsqlvl = 1; + USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0); + + grxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRXSTSP); + channelnum = grxsts.b.chnum; + hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR); + + switch (grxsts.b.pktsts) + { + case GRXSTS_PKTSTS_IN: + /* Read the data into the host buffer. */ + if ((grxsts.b.bcnt > 0) && (pdev->host.hc[channelnum].xfer_buff != (void *)0)) + { + + USB_OTG_ReadPacket(pdev, pdev->host.hc[channelnum].xfer_buff, grxsts.b.bcnt); + /*manage multiple Xfer */ + pdev->host.hc[grxsts.b.chnum].xfer_buff += grxsts.b.bcnt; + pdev->host.hc[grxsts.b.chnum].xfer_count += grxsts.b.bcnt; + + + count = pdev->host.hc[channelnum].xfer_count; + pdev->host.XferCnt[channelnum] = count; + + hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCTSIZ); + if(hctsiz.b.pktcnt > 0) + { + /* re-activate the channel when more packets are expected */ + hcchar.b.chen = 1; + hcchar.b.chdis = 0; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR, hcchar.d32); + } + } + break; + + case GRXSTS_PKTSTS_IN_XFER_COMP: + + case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: + case GRXSTS_PKTSTS_CH_HALTED: + default: + break; + } + + /* Enable the Rx Status Queue Level interrupt */ + intmsk.b.rxstsqlvl = 1; + USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); + return 1; +} + +/** + * @brief USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR + * Handles the incomplete Periodic transfer Interrupt + * @param pdev: Selected device + * @retval status + */ +static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev) +{ + + USB_OTG_GINTSTS_TypeDef gintsts; + USB_OTG_HCCHAR_TypeDef hcchar; + + + + + hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[0]->HCCHAR); + hcchar.b.chen = 1; + hcchar.b.chdis = 1; + USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[0]->HCCHAR, hcchar.d32); + + gintsts.d32 = 0; + /* Clear interrupt */ + gintsts.b.incomplisoout = 1; + USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); + + return 1; +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_otg.c b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_otg.c index f9cabf5e..fbb71ecb 100644 --- a/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_otg.c +++ b/Libmaple/libmaple/libmaple/usbF4/STM32_USB_OTG_Driver/src/usb_otg.c @@ -1,175 +1,175 @@ -/** - ****************************************************************************** - * @file usb_otg.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief OTG Core Layer - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_defines.h" -#include "usb_regs.h" -#include "usb_core.h" -#include "usb_otg.h" - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_OTG - * @brief This file is the interface between EFSL ans Host mass-storage class - * @{ - */ - - -/** @defgroup USB_OTG_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_OTG_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USB_OTG_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_OTG_Private_Variables - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_OTG_Private_FunctionPrototypes - * @{ - */ - -static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev); - -/** - * @} - */ - - -/** @defgroup USB_OTG_Private_Functions - * @{ - */ - - -/* OTG Interrupt Handler */ - - -/** - * @brief STM32_USBO_OTG_ISR_Handler - * - * @param None - * @retval : None - */ -uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t retval = 0; - USB_OTG_GINTSTS_TypeDef gintsts ; - gintsts.d32 = 0; - - gintsts.d32 = USB_OTG_Read_itr(pdev); - if (gintsts.d32 == 0) - { - return 0; - } - if (gintsts.b.otgintr) - { - retval |= 1;//USB_OTG_HandleOTG_ISR(pdev); - } - if (gintsts.b.conidstschng) - { - retval |= 2;//USB_OTG_HandleConnectorIDStatusChange_ISR(pdev); - } - if (gintsts.b.sessreqintr) - { - retval |= 3;//USB_OTG_HandleSessionRequest_ISR(pdev); - } - return retval; -} - - -/** - * @brief USB_OTG_Read_itr - * returns the Core Interrupt register - * @param None - * @retval : status - */ -static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - USB_OTG_GINTMSK_TypeDef gintmsk; - USB_OTG_GINTMSK_TypeDef gintmsk_common; - - - gintsts.d32 = 0; - gintmsk.d32 = 0; - gintmsk_common.d32 = 0; - - /* OTG interrupts */ - gintmsk_common.b.sessreqintr = 1; - gintmsk_common.b.conidstschng = 1; - gintmsk_common.b.otgintr = 1; - - gintsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS); - gintmsk.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK); - return ((gintsts.d32 & gintmsk.d32 ) & gintmsk_common.d32); -} - - -/** - * @brief USB_OTG_GetCurrentState - * Return current OTG State - * @param None - * @retval : None - */ -uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev) -{ - return pdev->otg.OTG_State; -} - - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usb_otg.c + * @author MCD Application Team + * @version V2.0.0 + * @date 22-July-2011 + * @brief OTG Core Layer + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_defines.h" +#include "usb_regs.h" +#include "usb_core.h" +#include "usb_otg.h" + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_OTG + * @brief This file is the interface between EFSL ans Host mass-storage class + * @{ + */ + + +/** @defgroup USB_OTG_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_OTG_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USB_OTG_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_OTG_Private_Variables + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_OTG_Private_FunctionPrototypes + * @{ + */ + +static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev); + +/** + * @} + */ + + +/** @defgroup USB_OTG_Private_Functions + * @{ + */ + + +/* OTG Interrupt Handler */ + + +/** + * @brief STM32_USBO_OTG_ISR_Handler + * + * @param None + * @retval : None + */ +uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev) +{ + uint32_t retval = 0; + USB_OTG_GINTSTS_TypeDef gintsts ; + gintsts.d32 = 0; + + gintsts.d32 = USB_OTG_Read_itr(pdev); + if (gintsts.d32 == 0) + { + return 0; + } + if (gintsts.b.otgintr) + { + retval |= 1;//USB_OTG_HandleOTG_ISR(pdev); + } + if (gintsts.b.conidstschng) + { + retval |= 2;//USB_OTG_HandleConnectorIDStatusChange_ISR(pdev); + } + if (gintsts.b.sessreqintr) + { + retval |= 3;//USB_OTG_HandleSessionRequest_ISR(pdev); + } + return retval; +} + + +/** + * @brief USB_OTG_Read_itr + * returns the Core Interrupt register + * @param None + * @retval : status + */ +static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev) +{ + USB_OTG_GINTSTS_TypeDef gintsts; + USB_OTG_GINTMSK_TypeDef gintmsk; + USB_OTG_GINTMSK_TypeDef gintmsk_common; + + + gintsts.d32 = 0; + gintmsk.d32 = 0; + gintmsk_common.d32 = 0; + + /* OTG interrupts */ + gintmsk_common.b.sessreqintr = 1; + gintmsk_common.b.conidstschng = 1; + gintmsk_common.b.otgintr = 1; + + gintsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS); + gintmsk.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK); + return ((gintsts.d32 & gintmsk.d32 ) & gintmsk_common.d32); +} + + +/** + * @brief USB_OTG_GetCurrentState + * Return current OTG State + * @param None + * @retval : None + */ +uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev) +{ + return pdev->otg.OTG_State; +} + + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/core_cm4.h b/Libmaple/libmaple/libmaple/usbF4/VCP/core_cm4.h index 8e42b81e..443665c7 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/core_cm4.h +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/core_cm4.h @@ -1,1378 +1,1378 @@ -/**************************************************************************//** - * @file core_cm4.h - * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File - * @version V2.10 - * @date 19. July 2011 - * - * @note - * Copyright (C) 2009-2011 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. - * - ******************************************************************************/ -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef __CORE_CM4_H_GENERIC -#define __CORE_CM4_H_GENERIC - - -/** \mainpage CMSIS Cortex-M4 - - This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. - It consists of: - - - Cortex-M Core Register Definitions - - Cortex-M functions - - Cortex-M instructions - - Cortex-M SIMD instructions - - The CMSIS Cortex-M4 Core Peripheral Access Layer contains C and assembly functions that ease - access to the Cortex-M Core - */ - -/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions - CMSIS violates following MISRA-C2004 Rules: - - - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \defgroup CMSIS_core_definitions CMSIS Core Definitions - This file defines all structures and symbols for CMSIS core: - - CMSIS version number - - Cortex-M core - - Cortex-M core Revision Number - @{ - */ - -/* CMSIS CM4 definitions */ -#define __CM4_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ -#define __CM4_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */ -#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | __CM4_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x04) /*!< Cortex core */ - - -#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 available 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 - -/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TASKING__ ) - /* add preprocessor checks to define __FPU_USED */ - #define __FPU_USED 0 -#endif - -#include /*!< standard types definitions */ -#include /*!< Core Instruction Access */ -//#include /*!< Core Function Access */ -//#include /*!< Compiler specific SIMD Intrinsics */ - -#endif /* __CORE_CM4_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM4_H_DEPENDANT -#define __CORE_CM4_H_DEPENDANT - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM4_REV - #define __CM4_REV 0x0000 - #warning "__CM4_REV not defined in device header file; using default!" - #endif - - #ifndef __FPU_PRESENT - #define __FPU_PRESENT 0 - #warning "__FPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0 - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (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 */ - -/*@} end of group CMSIS_core_definitions */ - - - -/******************************************************************************* - * Register Abstraction - ******************************************************************************/ -/** \defgroup CMSIS_core_register CMSIS Core Register - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - - Core FPU Register -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE CMSIS Core - Type definitions for the Cortex-M Core Registers - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ -#else - uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ -#endif - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ -#else - uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ -#endif - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ - uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC CMSIS NVIC - Type definitions for the Cortex-M NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; - __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; - __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; - __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; - __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56]; - __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; - __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB CMSIS SCB - Type definitions for the Cortex-M System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5]; - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control 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_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE 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 Vector Table Offset Register Definitions */ -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << 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_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB CMSIS System Control and ID Register not in the SCB - Type definitions for the Cortex-M System Control and ID Register not in the SCB - @{ - */ - -/** \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ - __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ -#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ -#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ - -#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ -#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ - -#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ - -#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ -#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ - -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick CMSIS SysTick - Type definitions for the Cortex-M System Timer Registers - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) 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_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_ITM CMSIS ITM - Type definitions for the Cortex-M Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __O union - { - __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; - __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15]; - __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; - __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ -} 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_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency 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_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */ -#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA 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 */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -#if (__MPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_MPU CMSIS MPU - Type definitions for the Cortex-M Memory Protection Unit (MPU) - @{ - */ - -/** \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) 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_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field 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_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -#if (__FPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_FPU CMSIS FPU - Type definitions for the Cortex-M Floating Point Unit (FPU) - @{ - */ - -/** \brief Structure type to access the Floating Point Unit (FPU). - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ - __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ - __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ - __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ - __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ -} FPU_Type; - -/* Floating-Point Context Control Register */ -#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ -#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ - -#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ -#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ - -#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ -#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ - -#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ -#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ - -#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ -#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ - -#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ -#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ - -#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ -#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ - -#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ -#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ - -#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ -#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ - -/* Floating-Point Context Address Register */ -#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ -#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ - -/* Floating-Point Default Status Control Register */ -#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ -#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ - -#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ -#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ - -#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ -#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ - -#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ -#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ - -/* Media and FP Feature Register 0 */ -#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ -#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ - -#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ -#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ - -#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ -#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ - -#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ -#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ - -#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ -#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ - -#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ -#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ - -#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ -#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ - -#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ -#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ - -/* Media and FP Feature Register 1 */ -#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ -#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ - -#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ -#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ - -#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ -#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ - -#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ -#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ - -/*@} end of group CMSIS_FPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug CMSIS Core Debug - Type definitions for the Cortex-M Core Debug Registers - @{ - */ - -/** \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) 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_CoreDebug */ - - -/** \ingroup CMSIS_core_register - @{ - */ - -/* Memory mapping of Cortex-M4 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#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 (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -#if (__FPU_PRESENT == 1) - #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ - #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions - @{ - */ - -/** \brief Set Priority Grouping - - This function sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup 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. - - \param [in] PriorityGroup Priority grouping field - */ -static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)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 | - ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** \brief Get Priority Grouping - - This function gets the priority grouping from NVIC Interrupt Controller. - Priority grouping is SCB->AIRCR [10:8] PRIGROUP field. - - \return Priority grouping 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 External Interrupt - - This function enables a device specific interrupt in the NVIC interrupt controller. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the external interrupt to enable - */ -static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ -/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ - NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ -} - - -/** \brief Disable External Interrupt - - This function disables a device specific interrupt in the NVIC interrupt controller. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the external interrupt to disable - */ -static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ -} - - -/** \brief Get Pending Interrupt - - This function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Number of the interrupt for get pending - \return 0 Interrupt status is not pending - \return 1 Interrupt status is pending - */ -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 Pending Interrupt - - This function sets the pending bit for the specified interrupt. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the interrupt for set pending - */ -static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ -} - - -/** \brief Clear Pending Interrupt - - This function clears the pending bit for the specified interrupt. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the interrupt for clear pending - */ -static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ -} - - -/** \brief Get Active Interrupt - - This function reads the active register in NVIC and returns the active bit. - \param [in] IRQn Number of the interrupt for get active - \return 0 Interrupt status is not active - \return 1 Interrupt status is active - */ -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 Interrupt Priority - - This function sets 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. - - \param [in] IRQn Number of the interrupt for set priority - \param [in] priority Priority to set - */ -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-M System Interrupts */ - else { - NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ -} - - -/** \brief Get Interrupt Priority - - This function reads 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. - - \param [in] IRQn Number of the interrupt for get priority - \return Interrupt Priority - */ -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-M system interrupts */ - else { - return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ -} - - -/** \brief Encode Priority - - This function encodes 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 - - \param [in] PriorityGroup Used priority group - \param [in] PreemptPriority Preemptive priority value (starting from 0) - \param [in] SubPriority Sub priority value (starting from 0) - \return Encoded priority for the interrupt - */ -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 Priority - - This function decodes 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 - - \param [in] Priority Priority value - \param [in] PriorityGroup Used priority group - \param [out] pPreemptPriority Preemptive priority value (starting from 0) - \param [out] pSubPriority Sub priority value (starting from 0) - */ -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); -} - - -/** \brief System Reset - - This function initiate a system reset request to reset the MCU. - */ -static __INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - 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 CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - This function initialises the system tick timer and its interrupt and start the system tick timer. - Counter is in free running mode to generate periodical interrupts. - - \param [in] ticks Number of ticks between two interrupts - \return 0 Function succeeded - \return 1 Function failed - */ -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 - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions CMSIS Core Debug Functions - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< external variable to receive characters */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */ - - -/** \brief ITM Send Character - - This function transmits a character via the ITM channel 0. - It just 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. - - \param [in] ch Character to transmit - \return Character to transmit - */ -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 ITM Receive Character - - This function inputs a character via external variable ITM_RxBuffer. - It just 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 Received character - \return -1 No character received - */ -static __INLINE int32_t ITM_ReceiveChar (void) { - int32_t 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 ITM Check Character - - This function checks external variable ITM_RxBuffer whether a character is available or not. - It returns '1' if a character is available and '0' if no character is available. - - \return 0 No character available - \return 1 Character available - */ -static __INLINE int32_t ITM_CheckChar (void) { - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { - return (0); /* no character available */ - } else { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - -#endif /* __CORE_CM4_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ - -#ifdef __cplusplus -} -#endif +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2009-2011 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. + * + ******************************************************************************/ +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + + +/** \mainpage CMSIS Cortex-M4 + + This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. + It consists of: + + - Cortex-M Core Register Definitions + - Cortex-M functions + - Cortex-M instructions + - Cortex-M SIMD instructions + + The CMSIS Cortex-M4 Core Peripheral Access Layer contains C and assembly functions that ease + access to the Cortex-M Core + */ + +/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions + CMSIS violates following MISRA-C2004 Rules: + + - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \defgroup CMSIS_core_definitions CMSIS Core Definitions + This file defines all structures and symbols for CMSIS core: + - CMSIS version number + - Cortex-M core + - Cortex-M core Revision Number + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | __CM4_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04) /*!< Cortex core */ + + +#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 available 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 + +/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TASKING__ ) + /* add preprocessor checks to define __FPU_USED */ + #define __FPU_USED 0 +#endif + +#include /*!< standard types definitions */ +#include /*!< Core Instruction Access */ +//#include /*!< Core Function Access */ +//#include /*!< Compiler specific SIMD Intrinsics */ + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000 + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0 + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (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 */ + +/*@} end of group CMSIS_core_definitions */ + + + +/******************************************************************************* + * Register Abstraction + ******************************************************************************/ +/** \defgroup CMSIS_core_register CMSIS Core Register + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE CMSIS Core + Type definitions for the Cortex-M Core Registers + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC CMSIS NVIC + Type definitions for the Cortex-M NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB CMSIS SCB + Type definitions for the Cortex-M System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control 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_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE 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 Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << 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_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB CMSIS System Control and ID Register not in the SCB + Type definitions for the Cortex-M System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick CMSIS SysTick + Type definitions for the Cortex-M System Timer Registers + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) 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_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM CMSIS ITM + Type definitions for the Cortex-M Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ +} 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_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency 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_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */ +#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA 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 */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU CMSIS MPU + Type definitions for the Cortex-M Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) 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_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field 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_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_FPU CMSIS FPU + Type definitions for the Cortex-M Floating Point Unit (FPU) + @{ + */ + +/** \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register */ +#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register */ +#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register */ +#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug CMSIS Core Debug + Type definitions for the Cortex-M Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) 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_CoreDebug */ + + +/** \ingroup CMSIS_core_register + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#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 (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions + @{ + */ + +/** \brief Set Priority Grouping + + This function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup 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. + + \param [in] PriorityGroup Priority grouping field + */ +static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)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 | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + This function gets the priority grouping from NVIC Interrupt Controller. + Priority grouping is SCB->AIRCR [10:8] PRIGROUP field. + + \return Priority grouping 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 External Interrupt + + This function enables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to enable + */ +static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ +/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + This function disables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to disable + */ +static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + This function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Number of the interrupt for get pending + \return 0 Interrupt status is not pending + \return 1 Interrupt status is pending + */ +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 Pending Interrupt + + This function sets the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for set pending + */ +static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + This function clears the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for clear pending + */ +static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + This function reads the active register in NVIC and returns the active bit. + \param [in] IRQn Number of the interrupt for get active + \return 0 Interrupt status is not active + \return 1 Interrupt status is active + */ +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 Interrupt Priority + + This function sets 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. + + \param [in] IRQn Number of the interrupt for set priority + \param [in] priority Priority to set + */ +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-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + This function reads 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. + + \param [in] IRQn Number of the interrupt for get priority + \return Interrupt Priority + */ +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-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + This function encodes 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 + + \param [in] PriorityGroup Used priority group + \param [in] PreemptPriority Preemptive priority value (starting from 0) + \param [in] SubPriority Sub priority value (starting from 0) + \return Encoded priority for the interrupt + */ +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 Priority + + This function decodes 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 + + \param [in] Priority Priority value + \param [in] PriorityGroup Used priority group + \param [out] pPreemptPriority Preemptive priority value (starting from 0) + \param [out] pSubPriority Sub priority value (starting from 0) + */ +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); +} + + +/** \brief System Reset + + This function initiate a system reset request to reset the MCU. + */ +static __INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + 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 CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + This function initialises the system tick timer and its interrupt and start the system tick timer. + Counter is in free running mode to generate periodical interrupts. + + \param [in] ticks Number of ticks between two interrupts + \return 0 Function succeeded + \return 1 Function failed + */ +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 + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions CMSIS Core Debug Functions + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< external variable to receive characters */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */ + + +/** \brief ITM Send Character + + This function transmits a character via the ITM channel 0. + It just 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. + + \param [in] ch Character to transmit + \return Character to transmit + */ +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 ITM Receive Character + + This function inputs a character via external variable ITM_RxBuffer. + It just 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 Received character + \return -1 No character received + */ +static __INLINE int32_t ITM_ReceiveChar (void) { + int32_t 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 ITM Check Character + + This function checks external variable ITM_RxBuffer whether a character is available or not. + It returns '1' if a character is available and '0' if no character is available. + + \return 0 No character available + \return 1 Character available + */ +static __INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/core_cmInstr.h b/Libmaple/libmaple/libmaple/usbF4/VCP/core_cmInstr.h index ceb4f875..78d2ef80 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/core_cmInstr.h +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/core_cmInstr.h @@ -1,585 +1,585 @@ -/**************************************************************************//** - * @file core_cmInstr.h - * @brief CMSIS Cortex-M Core Instruction Access Header File - * @version V2.10 - * @date 19. July 2011 - * - * @note - * Copyright (C) 2009-2011 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 __CORE_CMINSTR_H -#define __CORE_CMINSTR_H - - -/* ########################## Core Instruction Access ######################### */ -/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface - Access to dedicated instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -#define __NOP __nop - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -#define __WFI __wfi - - -/** \brief Wait For Event - - Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. - */ -#define __WFE __wfe - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -#define __SEV __sev - - -/** \brief Instruction Synchronization Barrier - - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. - */ -#define __ISB() __isb(0xF) - - -/** \brief Data Synchronization Barrier - - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -#define __DSB() __dsb(0xF) - - -/** \brief Data Memory Barrier - - This function ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ -#define __DMB() __dmb(0xF) - - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -#define __REV __rev - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -static __INLINE __ASM uint32_t __REV16(uint32_t value) -{ - rev16 r0, r0 - bx lr -} - - -/** \brief Reverse byte order in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -static __INLINE __ASM int32_t __REVSH(int32_t value) -{ - revsh r0, r0 - bx lr -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Reverse bit order of value - - This function reverses the bit order of the given value. - - \param [in] value Value to reverse - \return Reversed value - */ -#define __RBIT __rbit - - -/** \brief LDR Exclusive (8 bit) - - This function performs a exclusive LDR command for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) - - -/** \brief LDR Exclusive (16 bit) - - This function performs a exclusive LDR command for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) - - -/** \brief LDR Exclusive (32 bit) - - This function performs a exclusive LDR command for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) - - -/** \brief STR Exclusive (8 bit) - - This function performs a exclusive STR command for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXB(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (16 bit) - - This function performs a exclusive STR command for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXH(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (32 bit) - - This function performs a exclusive STR command for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXW(value, ptr) __strex(value, ptr) - - -/** \brief Remove the exclusive lock - - This function removes the exclusive lock which is created by LDREX. - - */ -#define __CLREX __clrex - - -/** \brief Signed Saturate - - This function saturates a signed value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) - \return Saturated value - */ -#define __SSAT __ssat - - -/** \brief Unsigned Saturate - - This function saturates an unsigned value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) - \return Saturated value - */ -#define __USAT __usat - - -/** \brief Count leading zeros - - This function counts the number of leading zeros of a data value. - - \param [in] value Value to count the leading zeros - \return number of leading zeros in value - */ -#define __CLZ __clz - -#endif /* (__CORTEX_M >= 0x03) */ - - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ - -#include - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -__attribute__( ( always_inline ) ) static __INLINE void __NOP(void) -{ - __ASM volatile ("nop"); -} - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -__attribute__( ( always_inline ) ) static __INLINE void __WFI(void) -{ - __ASM volatile ("wfi"); -} - - -/** \brief Wait For Event - - Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. - */ -__attribute__( ( always_inline ) ) static __INLINE void __WFE(void) -{ - __ASM volatile ("wfe"); -} - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -__attribute__( ( always_inline ) ) static __INLINE void __SEV(void) -{ - __ASM volatile ("sev"); -} - - -/** \brief Instruction Synchronization Barrier - - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. - */ -__attribute__( ( always_inline ) ) static __INLINE void __ISB(void) -{ - __ASM volatile ("isb"); -} - - -/** \brief Data Synchronization Barrier - - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -__attribute__( ( always_inline ) ) static __INLINE void __DSB(void) -{ - __ASM volatile ("dsb"); -} - - -/** \brief Data Memory Barrier - - This function ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ -__attribute__( ( always_inline ) ) static __INLINE void __DMB(void) -{ - __ASM volatile ("dmb"); -} - - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief Reverse byte order in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value) -{ - uint32_t result; - - __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Reverse bit order of value - - This function reverses the bit order of the given value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief LDR Exclusive (8 bit) - - This function performs a exclusive LDR command for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr) -{ - uint8_t result; - - __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - - -/** \brief LDR Exclusive (16 bit) - - This function performs a exclusive LDR command for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr) -{ - uint16_t result; - - __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - - -/** \brief LDR Exclusive (32 bit) - - This function performs a exclusive LDR command for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - - -/** \brief STR Exclusive (8 bit) - - This function performs a exclusive STR command for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) -{ - uint32_t result; - - __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -/** \brief STR Exclusive (16 bit) - - This function performs a exclusive STR command for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) -{ - uint32_t result; - - __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -/** \brief STR Exclusive (32 bit) - - This function performs a exclusive STR command for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -/** \brief Remove the exclusive lock - - This function removes the exclusive lock which is created by LDREX. - - */ -__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void) -{ - __ASM volatile ("clrex"); -} - - -/** \brief Signed Saturate - - This function saturates a signed value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) - \return Saturated value - */ -#define __SSAT(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Unsigned Saturate - - This function saturates an unsigned value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) - \return Saturated value - */ -#define __USAT(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Count leading zeros - - This function counts the number of leading zeros of a data value. - - \param [in] value Value to count the leading zeros - \return number of leading zeros in value - */ -__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value) -{ - uint8_t result; - - __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -#endif /* (__CORTEX_M >= 0x03) */ - - - - -#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 intrinsics, - * Including the CMSIS ones. - */ - -#endif - -/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ - -#endif /* __CORE_CMINSTR_H */ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2009-2011 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 __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +static __INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +static __INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +#endif /* (__CORTEX_M >= 0x03) */ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) static __INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) static __INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) static __INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__( ( always_inline ) ) static __INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) static __INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) static __INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value) +{ + uint32_t result; + + __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint8_t result; + + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint16_t result; + + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void) +{ + __ASM volatile ("clrex"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value) +{ + uint8_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + + + +#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 intrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/misc.c b/Libmaple/libmaple/libmaple/usbF4/VCP/misc.c index c0d8705b..9f33150c 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/misc.c +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/misc.c @@ -1,256 +1,256 @@ -/** - ****************************************************************************** - * @file misc.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides all the miscellaneous firmware functions (add-on - * to CMSIS functions). - * - * @verbatim - * - * =================================================================== - * How to configure Interrupts using driver - * =================================================================== - * - * This section provide functions allowing to configure the NVIC interrupts (IRQ). - * The Cortex-M4 exceptions are managed by CMSIS functions. - * - * 1. Configure the NVIC Priority Grouping using NVIC_PriorityGroupConfig() - * function according to the following table. - - * The table below gives the allowed values of the pre-emption priority and subpriority according - * to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function - * ========================================================================================================================== - * NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description - * ========================================================================================================================== - * NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority - * | | | 4 bits for subpriority - * -------------------------------------------------------------------------------------------------------------------------- - * NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority - * | | | 3 bits for subpriority - * -------------------------------------------------------------------------------------------------------------------------- - * NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority - * | | | 2 bits for subpriority - * -------------------------------------------------------------------------------------------------------------------------- - * NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority - * | | | 1 bits for subpriority - * -------------------------------------------------------------------------------------------------------------------------- - * NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority - * | | | 0 bits for subpriority - * ========================================================================================================================== - * - * 2. Enable and Configure the priority of the selected IRQ Channels using NVIC_Init() - * - * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. - * The pending IRQ priority will be managed only by the subpriority. - * - * @note IRQ priority order (sorted by highest to lowest priority): - * - Lowest pre-emption priority - * - Lowest subpriority - * - Lowest hardware priority (IRQ number) - * - * @endverbatim - * - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; -typedef unsigned long uint32_t; -typedef unsigned int u32; -typedef unsigned short uint16_t; -typedef unsigned short u16; -typedef unsigned char uint8_t; -typedef unsigned char u8; -#include "misc.h" -#define assert_param(x) - -typedef int IRQn_Type; -#define __NVIC_PRIO_BITS 4 -#define __Vendor_SysTickConfig 1 -#include - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup MISC - * @brief MISC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup MISC_Private_Functions - * @{ - */ - -/** - * @brief Configures the priority grouping: pre-emption priority and subpriority. - * @param NVIC_PriorityGroup: specifies the priority grouping bits length. - * This parameter can be one of the following values: - * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority - * 4 bits for subpriority - * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority - * 3 bits for subpriority - * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority - * 2 bits for subpriority - * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority - * 1 bits for subpriority - * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority - * 0 bits for subpriority - * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. - * The pending IRQ priority will be managed only by the subpriority. - * @retval None - */ -void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) -{ - /* Check the parameters */ - assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); - - /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ - SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; -} - -/** - * @brief Initializes the NVIC peripheral according to the specified - * parameters in the NVIC_InitStruct. - * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() - * function should be called before. - * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains - * the configuration information for the specified NVIC peripheral. - * @retval None - */ -void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) -{ - uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); - assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); - assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); - - if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) - { - /* Compute the Corresponding IRQ Priority --------------------------------*/ - tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; - tmppre = (0x4 - tmppriority); - tmpsub = tmpsub >> tmppriority; - - tmppriority = NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; - tmppriority |= (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub); - - tmppriority = tmppriority << 0x04; - - NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; - - /* Enable the Selected IRQ Channels --------------------------------------*/ - NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = - (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); - } - else - { - /* Disable the Selected IRQ Channels -------------------------------------*/ - NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = - (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); - } -} - -/** - * @brief Sets the vector table location and Offset. - * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. - * This parameter can be one of the following values: - * @arg NVIC_VectTab_RAM: Vector Table in internal SRAM. - * @arg NVIC_VectTab_FLASH: Vector Table in internal FLASH. - * @param Offset: Vector Table base offset field. This value must be a multiple of 0x200. - * @retval None - */ -void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) -{ - /* Check the parameters */ - assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); - assert_param(IS_NVIC_OFFSET(Offset)); - - SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); -} - -/** - * @brief Selects the condition for the system to enter low power mode. - * @param LowPowerMode: Specifies the new mode for the system to enter low power mode. - * This parameter can be one of the following values: - * @arg NVIC_LP_SEVONPEND: Low Power SEV on Pend. - * @arg NVIC_LP_SLEEPDEEP: Low Power DEEPSLEEP request. - * @arg NVIC_LP_SLEEPONEXIT: Low Power Sleep on Exit. - * @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_NVIC_LP(LowPowerMode)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - SCB->SCR |= LowPowerMode; - } - else - { - SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); - } -} - -/** - * @brief Configures the SysTick clock source. - * @param SysTick_CLKSource: specifies the SysTick clock source. - * This parameter can be one of the following values: - * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. - * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. - * @retval None - */ -void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) -{ - /* Check the parameters */ - assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); - if (SysTick_CLKSource == SysTick_CLKSource_HCLK) - { - SysTick->CTRL |= SysTick_CLKSource_HCLK; - } - else - { - SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file misc.c + * @author MCD Application Team + * @version V1.0.0RC1 + * @date 25-August-2011 + * @brief This file provides all the miscellaneous firmware functions (add-on + * to CMSIS functions). + * + * @verbatim + * + * =================================================================== + * How to configure Interrupts using driver + * =================================================================== + * + * This section provide functions allowing to configure the NVIC interrupts (IRQ). + * The Cortex-M4 exceptions are managed by CMSIS functions. + * + * 1. Configure the NVIC Priority Grouping using NVIC_PriorityGroupConfig() + * function according to the following table. + + * The table below gives the allowed values of the pre-emption priority and subpriority according + * to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function + * ========================================================================================================================== + * NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description + * ========================================================================================================================== + * NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority + * | | | 4 bits for subpriority + * -------------------------------------------------------------------------------------------------------------------------- + * NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority + * | | | 3 bits for subpriority + * -------------------------------------------------------------------------------------------------------------------------- + * NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority + * | | | 2 bits for subpriority + * -------------------------------------------------------------------------------------------------------------------------- + * NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority + * | | | 1 bits for subpriority + * -------------------------------------------------------------------------------------------------------------------------- + * NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority + * | | | 0 bits for subpriority + * ========================================================================================================================== + * + * 2. Enable and Configure the priority of the selected IRQ Channels using NVIC_Init() + * + * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. + * The pending IRQ priority will be managed only by the subpriority. + * + * @note IRQ priority order (sorted by highest to lowest priority): + * - Lowest pre-emption priority + * - Lowest subpriority + * - Lowest hardware priority (IRQ number) + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +typedef unsigned long uint32_t; +typedef unsigned int u32; +typedef unsigned short uint16_t; +typedef unsigned short u16; +typedef unsigned char uint8_t; +typedef unsigned char u8; +#include "misc.h" +#define assert_param(x) + +typedef int IRQn_Type; +#define __NVIC_PRIO_BITS 4 +#define __Vendor_SysTickConfig 1 +#include + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup MISC + * @brief MISC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup MISC_Private_Functions + * @{ + */ + +/** + * @brief Configures the priority grouping: pre-emption priority and subpriority. + * @param NVIC_PriorityGroup: specifies the priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority + * 4 bits for subpriority + * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority + * 3 bits for subpriority + * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority + * 2 bits for subpriority + * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority + * 1 bits for subpriority + * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority + * 0 bits for subpriority + * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. + * The pending IRQ priority will be managed only by the subpriority. + * @retval None + */ +void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); + + /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ + SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; +} + +/** + * @brief Initializes the NVIC peripheral according to the specified + * parameters in the NVIC_InitStruct. + * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() + * function should be called before. + * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains + * the configuration information for the specified NVIC peripheral. + * @retval None + */ +void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) +{ + uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); + assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); + assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); + + if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) + { + /* Compute the Corresponding IRQ Priority --------------------------------*/ + tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; + tmppre = (0x4 - tmppriority); + tmpsub = tmpsub >> tmppriority; + + tmppriority = NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; + tmppriority |= (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub); + + tmppriority = tmppriority << 0x04; + + NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; + + /* Enable the Selected IRQ Channels --------------------------------------*/ + NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } + else + { + /* Disable the Selected IRQ Channels -------------------------------------*/ + NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } +} + +/** + * @brief Sets the vector table location and Offset. + * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. + * This parameter can be one of the following values: + * @arg NVIC_VectTab_RAM: Vector Table in internal SRAM. + * @arg NVIC_VectTab_FLASH: Vector Table in internal FLASH. + * @param Offset: Vector Table base offset field. This value must be a multiple of 0x200. + * @retval None + */ +void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) +{ + /* Check the parameters */ + assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); + assert_param(IS_NVIC_OFFSET(Offset)); + + SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); +} + +/** + * @brief Selects the condition for the system to enter low power mode. + * @param LowPowerMode: Specifies the new mode for the system to enter low power mode. + * This parameter can be one of the following values: + * @arg NVIC_LP_SEVONPEND: Low Power SEV on Pend. + * @arg NVIC_LP_SLEEPDEEP: Low Power DEEPSLEEP request. + * @arg NVIC_LP_SLEEPONEXIT: Low Power Sleep on Exit. + * @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_NVIC_LP(LowPowerMode)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + SCB->SCR |= LowPowerMode; + } + else + { + SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); + } +} + +/** + * @brief Configures the SysTick clock source. + * @param SysTick_CLKSource: specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. + * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. + * @retval None + */ +void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) +{ + /* Check the parameters */ + assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); + if (SysTick_CLKSource == SysTick_CLKSource_HCLK) + { + SysTick->CTRL |= SysTick_CLKSource_HCLK; + } + else + { + SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/misc.h b/Libmaple/libmaple/libmaple/usbF4/VCP/misc.h index a1dcaad8..1f87d1b3 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/misc.h +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/misc.h @@ -1,172 +1,172 @@ -/** - ****************************************************************************** - * @file misc.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the miscellaneous - * firmware library functions (add-on to CMSIS functions). - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MISC_H -#define __MISC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -//#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup MISC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief NVIC Init Structure definition - */ - -typedef struct -{ - uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. - This parameter can be an enumerator of @ref IRQn_Type - enumeration (For the complete STM32 Devices IRQ Channels - list, please refer to stm32f4xx.h file) */ - - uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel - specified in NVIC_IRQChannel. This parameter can be a value - between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table - A lower priority value indicates a higher priority */ - - uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified - in NVIC_IRQChannel. This parameter can be a value - between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table - A lower priority value indicates a higher priority */ - - FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel - will be enabled or disabled. - This parameter can be set either to ENABLE or DISABLE */ -} NVIC_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup MISC_Exported_Constants - * @{ - */ - -/** @defgroup MISC_Vector_Table_Base - * @{ - */ - -#define NVIC_VectTab_RAM ((uint32_t)0x20000000) -#define NVIC_VectTab_FLASH ((uint32_t)0x08000000) -#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ - ((VECTTAB) == NVIC_VectTab_FLASH)) -/** - * @} - */ - -/** @defgroup MISC_System_Low_Power - * @{ - */ - -#define NVIC_LP_SEVONPEND ((uint8_t)0x10) -#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) -#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) -#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ - ((LP) == NVIC_LP_SLEEPDEEP) || \ - ((LP) == NVIC_LP_SLEEPONEXIT)) -/** - * @} - */ - -/** @defgroup MISC_Preemption_Priority_Group - * @{ - */ - -#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority - 4 bits for subpriority */ -#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority - 3 bits for subpriority */ -#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority - 2 bits for subpriority */ -#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority - 1 bits for subpriority */ -#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority - 0 bits for subpriority */ - -#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ - ((GROUP) == NVIC_PriorityGroup_1) || \ - ((GROUP) == NVIC_PriorityGroup_2) || \ - ((GROUP) == NVIC_PriorityGroup_3) || \ - ((GROUP) == NVIC_PriorityGroup_4)) - -#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) - -#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) - -#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF) - -/** - * @} - */ - -/** @defgroup MISC_SysTick_clock_source - * @{ - */ - -#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) -#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) -#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ - ((SOURCE) == SysTick_CLKSource_HCLK_Div8)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); -void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); -void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); -void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); -void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); - -#ifdef __cplusplus -} -#endif - -#endif /* __MISC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file misc.h + * @author MCD Application Team + * @version V1.0.0RC1 + * @date 25-August-2011 + * @brief This file contains all the functions prototypes for the miscellaneous + * firmware library functions (add-on to CMSIS functions). + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MISC_H +#define __MISC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +//#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup MISC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief NVIC Init Structure definition + */ + +typedef struct +{ + uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. + This parameter can be an enumerator of @ref IRQn_Type + enumeration (For the complete STM32 Devices IRQ Channels + list, please refer to stm32f4xx.h file) */ + + uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel + specified in NVIC_IRQChannel. This parameter can be a value + between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table + A lower priority value indicates a higher priority */ + + uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified + in NVIC_IRQChannel. This parameter can be a value + between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table + A lower priority value indicates a higher priority */ + + FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel + will be enabled or disabled. + This parameter can be set either to ENABLE or DISABLE */ +} NVIC_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup MISC_Exported_Constants + * @{ + */ + +/** @defgroup MISC_Vector_Table_Base + * @{ + */ + +#define NVIC_VectTab_RAM ((uint32_t)0x20000000) +#define NVIC_VectTab_FLASH ((uint32_t)0x08000000) +#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ + ((VECTTAB) == NVIC_VectTab_FLASH)) +/** + * @} + */ + +/** @defgroup MISC_System_Low_Power + * @{ + */ + +#define NVIC_LP_SEVONPEND ((uint8_t)0x10) +#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) +#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) +#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ + ((LP) == NVIC_LP_SLEEPDEEP) || \ + ((LP) == NVIC_LP_SLEEPONEXIT)) +/** + * @} + */ + +/** @defgroup MISC_Preemption_Priority_Group + * @{ + */ + +#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority + 4 bits for subpriority */ +#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority + 3 bits for subpriority */ +#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority + 2 bits for subpriority */ +#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority + 1 bits for subpriority */ +#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority + 0 bits for subpriority */ + +#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ + ((GROUP) == NVIC_PriorityGroup_1) || \ + ((GROUP) == NVIC_PriorityGroup_2) || \ + ((GROUP) == NVIC_PriorityGroup_3) || \ + ((GROUP) == NVIC_PriorityGroup_4)) + +#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) + +#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) + +#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF) + +/** + * @} + */ + +/** @defgroup MISC_SysTick_clock_source + * @{ + */ + +#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) +#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) +#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ + ((SOURCE) == SysTick_CLKSource_HCLK_Div8)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); +void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); +void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); +void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); +void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); + +#ifdef __cplusplus +} +#endif + +#endif /* __MISC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/usb_bsp.c b/Libmaple/libmaple/libmaple/usbF4/VCP/usb_bsp.c index 9f677e82..df23ccbd 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/usb_bsp.c +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/usb_bsp.c @@ -1,486 +1,486 @@ -/** - ****************************************************************************** - * @file usb_bsp.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file is responsible to offer board support package and is - * configurable by user. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_bsp.h" -#include "usbd_conf.h" -#include -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; -#define OTG_FS_IRQn 67 -//typedef unsigned char uint8_t; -#include - -//#include "stm32f4_discovery.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY -* @{ -*/ - -/** @defgroup USB_BSP -* @brief This file is responsible to offer board support package -* @{ -*/ - -/** @defgroup USB_BSP_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_BSP_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - - - - -/** @defgroup USB_BSP_Private_Macros -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USBH_BSP_Private_Variables -* @{ -*/ - -/** -* @} -*/ - -/** @defgroup USBH_BSP_Private_FunctionPrototypes -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USB_BSP_Private_Functions -* @{ -*/ - - -/** -* @brief USB_OTG_BSP_Init -* Initilizes BSP configurations -* @param None -* @retval None -*/ - -void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) -{ - // ala42 -#define GPIO_AF_OTG1_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ - gpio_set_mode(GPIOA,11,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ); - gpio_set_mode(GPIOA,12,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ); - gpio_set_af_mode(GPIOA,11,GPIO_AF_OTG1_FS) ; // OTG_FS_DM - gpio_set_af_mode(GPIOA,12,GPIO_AF_OTG1_FS) ; // OTG_FS_DP -#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED - gpio_set_mode(GPIOA, 8,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ); - gpio_set_af_mode(GPIOA, 8,GPIO_AF_OTG1_FS) ; // OTG_FS_SOF -#endif -#ifdef VBUS_SENSING_ENABLED - gpio_set_mode(GPIOA, 9,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ); - gpio_set_af_mode(GPIOA, 9,GPIO_AF_OTG1_FS) ; // OTG_FS_VBUS -#endif - -#ifdef ID_SENSING_ENABLED - gpio_set_mode(GPIOA,10,GPIO_MODE_OUTPUT | GPIO_OTYPE_OD | GPIO_PUPD_INPUT_PU | GPIO_OSPEED_100MHZ); - gpio_set_af_mode(GPIOA,10,GPIO_AF_OTG1_FS) ; // OTG_FS_ID -#endif - rcc_clk_enable(RCC_SYSCFG); - rcc_clk_enable(RCC_USBFS); -} - -void USB_OTG_BSP_DeInit(USB_OTG_CORE_HANDLE *pdev) -{ - // ala42 -#define GPIO_AF0 ((uint8_t)0) /* OTG_FS Alternate Function mapping */ - gpio_set_mode(GPIOA,11, GPIO_MODE_INPUT); - gpio_set_mode(GPIOA,12, GPIO_MODE_INPUT); - gpio_set_af_mode(GPIOA,11,GPIO_AF0) ; // OTG_FS_DM - gpio_set_af_mode(GPIOA,12,GPIO_AF0) ; // OTG_FS_DP -#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED - gpio_set_mode(GPIOA, 8,GPIO_MODE_INPUT); - gpio_set_af_mode(GPIOA, 8,GPIO_AF0) ; // OTG_FS_SOF -#endif -#ifdef VBUS_SENSING_ENABLED - gpio_set_mode(GPIOA, 9,GPIO_MODE_INPUT); - gpio_set_af_mode(GPIOA, 9,GPIO_AF0) ; // OTG_FS_VBUS -#endif - -#ifdef ID_SENSING_ENABLED - gpio_set_mode(GPIOA,10,GPIO_MODE_INPUT); - gpio_set_af_mode(GPIOA,10,GPIO_AF0) ; // OTG_FS_ID -#endif - - rcc_clk_enable(RCC_SYSCFG); - rcc_clk_disable(RCC_USBFS); -} - - -#if 0 -void USB_OTG_BSP_Init_disabled(USB_OTG_CORE_HANDLE *pdev) - { - GPIO_InitTypeDef GPIO_InitStructure; - -#ifndef USE_ULPI_PHY -#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - EXTI_InitTypeDef EXTI_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; -#endif -#endif - - - #ifdef USE_USB_OTG_FS - - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA , ENABLE); - - /* Configure SOF VBUS ID DM DP Pins */ - GPIO_InitStructure.GPIO_Pin = 0 -#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED - | GPIO_Pin_8 -#endif -#ifndef VBUS_SENSING_ENABLED - | GPIO_Pin_9 -#endif - | GPIO_Pin_11 - | GPIO_Pin_12; - - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; - GPIO_Init(GPIOA, &GPIO_InitStructure); - -#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED - GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_OTG1_FS) ; -#endif -#ifndef VBUS_SENSING_ENABLED - GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_OTG1_FS) ; -#endif - GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_OTG1_FS) ; - GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_OTG1_FS) ; - - /* this for ID line debug */ - - -#ifdef ID_SENSING_ENABLED - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_OTG1_FS) ; -#endif - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); - RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE) ; - #else // USE_USB_OTG_HS - - #ifdef USE_ULPI_PHY // ULPI - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | - RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOH | - RCC_AHB1Periph_GPIOI, ENABLE); - - - GPIO_PinAFConfig(GPIOA,GPIO_PinSource3, GPIO_AF_OTG2_HS) ; // D0 - GPIO_PinAFConfig(GPIOA,GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // CLK - GPIO_PinAFConfig(GPIOB,GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // D1 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource1, GPIO_AF_OTG2_HS) ; // D2 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // D7 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_OTG2_HS) ; // D3 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_OTG2_HS) ; // D4 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_OTG2_HS) ; // D5 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_OTG2_HS) ; // D6 - GPIO_PinAFConfig(GPIOH,GPIO_PinSource4, GPIO_AF_OTG2_HS) ; // NXT - GPIO_PinAFConfig(GPIOI,GPIO_PinSource11,GPIO_AF_OTG2_HS) ; // DIR - GPIO_PinAFConfig(GPIOC,GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // STP - - // CLK - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - // D0 - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - - - // D1 D2 D3 D4 D5 D6 D7 - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | - GPIO_Pin_5 | GPIO_Pin_10 | - GPIO_Pin_11| GPIO_Pin_12 | - GPIO_Pin_13 ; - - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - - // STP - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOC, &GPIO_InitStructure); - - //NXT - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOH, &GPIO_InitStructure); - - - //DIR - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOI, &GPIO_InitStructure); - - - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS | - RCC_AHB1Periph_OTG_HS_ULPI, ENABLE) ; - - #else - #ifdef USE_I2C_PHY - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB , ENABLE); - /* Configure RESET INTN SCL SDA (Phy/I2C) Pins */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | - GPIO_Pin_1 | - GPIO_Pin_10 | - GPIO_Pin_11; - - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_OTG2_FS); - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS, ENABLE) ; - - #else - - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE); - - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | - GPIO_Pin_13 | - GPIO_Pin_14 | - GPIO_Pin_15; - - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - GPIO_PinAFConfig(GPIOB,GPIO_PinSource12, GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_OTG2_FS) ; - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS, ENABLE) ; - #endif - #endif // USE_ULPI_PHY - - #endif //USB_OTG_HS - - - /* enable the PWR clock */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); - - /* Configure the Key button in EXTI mode */ - STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI); - -#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - EXTI_ClearITPendingBit(EXTI_Line18); - - EXTI_InitStructure.EXTI_Line = EXTI_Line18; - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; - EXTI_InitStructure.EXTI_LineCmd = ENABLE; - EXTI_Init(&EXTI_InitStructure); - - EXTI_ClearITPendingBit(EXTI_Line18); - - NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_WKUP_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - EXTI_ClearITPendingBit(EXTI_Line18); -#endif - -#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT - EXTI_ClearITPendingBit(EXTI_Line20); - - EXTI_InitStructure.EXTI_Line = EXTI_Line20; - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; - EXTI_InitStructure.EXTI_LineCmd = ENABLE; - EXTI_Init(&EXTI_InitStructure); - - EXTI_ClearITPendingBit(EXTI_Line20); - - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_WKUP_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - EXTI_ClearITPendingBit(EXTI_Line20); -#endif - - EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE); -} -#endif - -/** -* @brief USB_OTG_BSP_EnableInterrupt -* Enabele USB Global interrupt -* @param None -* @retval None -*/ -void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev) -{ -#if 1 - NVIC_InitTypeDef NVIC_InitStructure; - - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); -#ifdef USE_USB_OTG_HS - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_IRQn; -#else - NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn; -#endif - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_OUT_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_IN_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); -#endif -#endif -} - -void USB_OTG_BSP_DisableInterrupt(USB_OTG_CORE_HANDLE *pdev) -{ -#if 1 - NVIC_InitTypeDef NVIC_InitStructure; - - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); -#ifdef USE_USB_OTG_HS - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_IRQn; -#else - NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn; -#endif - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; - NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; - NVIC_Init(&NVIC_InitStructure); -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_OUT_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; - NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; - NVIC_Init(&NVIC_InitStructure); - - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_IN_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; - NVIC_Init(&NVIC_InitStructure); -#endif -#endif -} - -/** -* @brief USB_OTG_BSP_uDelay -* This function provides delay time in micro sec -* @param usec : Value of delay required in micro sec -* @retval None -*/ -void USB_OTG_BSP_uDelay (const uint32_t usec) -{ - uint32_t count = 0; - const uint32_t utime = (120 * usec / 7); - do - { - if ( ++count > utime ) - { - return ; - } - } - while (1); -} - - -/** -* @brief USB_OTG_BSP_mDelay -* This function provides delay time in milli sec -* @param msec : Value of delay required in milli sec -* @retval None -*/ -void USB_OTG_BSP_mDelay (const uint32_t msec) -{ - USB_OTG_BSP_uDelay(msec * 1000); -} -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usb_bsp.c + * @author MCD Application Team + * @version V1.0.0 + * @date 19-September-2011 + * @brief This file is responsible to offer board support package and is + * configurable by user. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_bsp.h" +#include "usbd_conf.h" +#include +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +#define OTG_FS_IRQn 67 +//typedef unsigned char uint8_t; +#include + +//#include "stm32f4_discovery.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY +* @{ +*/ + +/** @defgroup USB_BSP +* @brief This file is responsible to offer board support package +* @{ +*/ + +/** @defgroup USB_BSP_Private_Defines +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USB_BSP_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + + + + +/** @defgroup USB_BSP_Private_Macros +* @{ +*/ +/** +* @} +*/ + +/** @defgroup USBH_BSP_Private_Variables +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup USBH_BSP_Private_FunctionPrototypes +* @{ +*/ +/** +* @} +*/ + +/** @defgroup USB_BSP_Private_Functions +* @{ +*/ + + +/** +* @brief USB_OTG_BSP_Init +* Initilizes BSP configurations +* @param None +* @retval None +*/ + +void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) +{ + // ala42 +#define GPIO_AF_OTG1_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ + gpio_set_mode(GPIOA,11,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ); + gpio_set_mode(GPIOA,12,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ); + gpio_set_af_mode(GPIOA,11,GPIO_AF_OTG1_FS) ; // OTG_FS_DM + gpio_set_af_mode(GPIOA,12,GPIO_AF_OTG1_FS) ; // OTG_FS_DP +#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED + gpio_set_mode(GPIOA, 8,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ); + gpio_set_af_mode(GPIOA, 8,GPIO_AF_OTG1_FS) ; // OTG_FS_SOF +#endif +#ifdef VBUS_SENSING_ENABLED + gpio_set_mode(GPIOA, 9,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ); + gpio_set_af_mode(GPIOA, 9,GPIO_AF_OTG1_FS) ; // OTG_FS_VBUS +#endif + +#ifdef ID_SENSING_ENABLED + gpio_set_mode(GPIOA,10,GPIO_MODE_OUTPUT | GPIO_OTYPE_OD | GPIO_PUPD_INPUT_PU | GPIO_OSPEED_100MHZ); + gpio_set_af_mode(GPIOA,10,GPIO_AF_OTG1_FS) ; // OTG_FS_ID +#endif + rcc_clk_enable(RCC_SYSCFG); + rcc_clk_enable(RCC_USBFS); +} + +void USB_OTG_BSP_DeInit(USB_OTG_CORE_HANDLE *pdev) +{ + // ala42 +#define GPIO_AF0 ((uint8_t)0) /* OTG_FS Alternate Function mapping */ + gpio_set_mode(GPIOA,11, GPIO_MODE_INPUT); + gpio_set_mode(GPIOA,12, GPIO_MODE_INPUT); + gpio_set_af_mode(GPIOA,11,GPIO_AF0) ; // OTG_FS_DM + gpio_set_af_mode(GPIOA,12,GPIO_AF0) ; // OTG_FS_DP +#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED + gpio_set_mode(GPIOA, 8,GPIO_MODE_INPUT); + gpio_set_af_mode(GPIOA, 8,GPIO_AF0) ; // OTG_FS_SOF +#endif +#ifdef VBUS_SENSING_ENABLED + gpio_set_mode(GPIOA, 9,GPIO_MODE_INPUT); + gpio_set_af_mode(GPIOA, 9,GPIO_AF0) ; // OTG_FS_VBUS +#endif + +#ifdef ID_SENSING_ENABLED + gpio_set_mode(GPIOA,10,GPIO_MODE_INPUT); + gpio_set_af_mode(GPIOA,10,GPIO_AF0) ; // OTG_FS_ID +#endif + + rcc_clk_enable(RCC_SYSCFG); + rcc_clk_disable(RCC_USBFS); +} + + +#if 0 +void USB_OTG_BSP_Init_disabled(USB_OTG_CORE_HANDLE *pdev) + { + GPIO_InitTypeDef GPIO_InitStructure; + +#ifndef USE_ULPI_PHY +#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT + EXTI_InitTypeDef EXTI_InitStructure; + NVIC_InitTypeDef NVIC_InitStructure; +#endif +#endif + + + #ifdef USE_USB_OTG_FS + + RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA , ENABLE); + + /* Configure SOF VBUS ID DM DP Pins */ + GPIO_InitStructure.GPIO_Pin = 0 +#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED + | GPIO_Pin_8 +#endif +#ifndef VBUS_SENSING_ENABLED + | GPIO_Pin_9 +#endif + | GPIO_Pin_11 + | GPIO_Pin_12; + + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; + GPIO_Init(GPIOA, &GPIO_InitStructure); + +#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED + GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_OTG1_FS) ; +#endif +#ifndef VBUS_SENSING_ENABLED + GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_OTG1_FS) ; +#endif + GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_OTG1_FS) ; + GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_OTG1_FS) ; + + /* this for ID line debug */ + + +#ifdef ID_SENSING_ENABLED + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_Init(GPIOA, &GPIO_InitStructure); + GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_OTG1_FS) ; +#endif + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); + RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE) ; + #else // USE_USB_OTG_HS + + #ifdef USE_ULPI_PHY // ULPI + RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | + RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOH | + RCC_AHB1Periph_GPIOI, ENABLE); + + + GPIO_PinAFConfig(GPIOA,GPIO_PinSource3, GPIO_AF_OTG2_HS) ; // D0 + GPIO_PinAFConfig(GPIOA,GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // CLK + GPIO_PinAFConfig(GPIOB,GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // D1 + GPIO_PinAFConfig(GPIOB,GPIO_PinSource1, GPIO_AF_OTG2_HS) ; // D2 + GPIO_PinAFConfig(GPIOB,GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // D7 + GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_OTG2_HS) ; // D3 + GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_OTG2_HS) ; // D4 + GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_OTG2_HS) ; // D5 + GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_OTG2_HS) ; // D6 + GPIO_PinAFConfig(GPIOH,GPIO_PinSource4, GPIO_AF_OTG2_HS) ; // NXT + GPIO_PinAFConfig(GPIOI,GPIO_PinSource11,GPIO_AF_OTG2_HS) ; // DIR + GPIO_PinAFConfig(GPIOC,GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // STP + + // CLK + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + // D0 + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + + + // D1 D2 D3 D4 D5 D6 D7 + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | + GPIO_Pin_5 | GPIO_Pin_10 | + GPIO_Pin_11| GPIO_Pin_12 | + GPIO_Pin_13 ; + + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + + // STP + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOC, &GPIO_InitStructure); + + //NXT + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOH, &GPIO_InitStructure); + + + //DIR + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOI, &GPIO_InitStructure); + + + RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS | + RCC_AHB1Periph_OTG_HS_ULPI, ENABLE) ; + + #else + #ifdef USE_I2C_PHY + RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB , ENABLE); + /* Configure RESET INTN SCL SDA (Phy/I2C) Pins */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | + GPIO_Pin_1 | + GPIO_Pin_10 | + GPIO_Pin_11; + + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_OTG2_FS) ; + GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_OTG2_FS) ; + GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_OTG2_FS) ; + GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_OTG2_FS); + RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS, ENABLE) ; + + #else + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | + GPIO_Pin_13 | + GPIO_Pin_14 | + GPIO_Pin_15; + + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + GPIO_PinAFConfig(GPIOB,GPIO_PinSource12, GPIO_AF_OTG2_FS) ; + GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_OTG2_FS) ; + GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_OTG2_FS) ; + GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_OTG2_FS) ; + RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS, ENABLE) ; + #endif + #endif // USE_ULPI_PHY + + #endif //USB_OTG_HS + + + /* enable the PWR clock */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); + + /* Configure the Key button in EXTI mode */ + STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI); + +#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT + EXTI_ClearITPendingBit(EXTI_Line18); + + EXTI_InitStructure.EXTI_Line = EXTI_Line18; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); + + EXTI_ClearITPendingBit(EXTI_Line18); + + NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_WKUP_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + EXTI_ClearITPendingBit(EXTI_Line18); +#endif + +#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT + EXTI_ClearITPendingBit(EXTI_Line20); + + EXTI_InitStructure.EXTI_Line = EXTI_Line20; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); + + EXTI_ClearITPendingBit(EXTI_Line20); + + NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_WKUP_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + EXTI_ClearITPendingBit(EXTI_Line20); +#endif + + EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE); +} +#endif + +/** +* @brief USB_OTG_BSP_EnableInterrupt +* Enabele USB Global interrupt +* @param None +* @retval None +*/ +void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev) +{ +#if 1 + NVIC_InitTypeDef NVIC_InitStructure; + + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); +#ifdef USE_USB_OTG_HS + NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_IRQn; +#else + NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn; +#endif + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); + NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_OUT_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); + NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_IN_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +#endif +#endif +} + +void USB_OTG_BSP_DisableInterrupt(USB_OTG_CORE_HANDLE *pdev) +{ +#if 1 + NVIC_InitTypeDef NVIC_InitStructure; + + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); +#ifdef USE_USB_OTG_HS + NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_IRQn; +#else + NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn; +#endif + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; + NVIC_Init(&NVIC_InitStructure); +#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); + NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_OUT_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); + NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_IN_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; + NVIC_Init(&NVIC_InitStructure); +#endif +#endif +} + +/** +* @brief USB_OTG_BSP_uDelay +* This function provides delay time in micro sec +* @param usec : Value of delay required in micro sec +* @retval None +*/ +void USB_OTG_BSP_uDelay (const uint32_t usec) +{ + uint32_t count = 0; + const uint32_t utime = (120 * usec / 7); + do + { + if ( ++count > utime ) + { + return ; + } + } + while (1); +} + + +/** +* @brief USB_OTG_BSP_mDelay +* This function provides delay time in milli sec +* @param msec : Value of delay required in milli sec +* @retval None +*/ +void USB_OTG_BSP_mDelay (const uint32_t msec) +{ + USB_OTG_BSP_uDelay(msec * 1000); +} +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/usb_conf.h b/Libmaple/libmaple/libmaple/usbF4/VCP/usb_conf.h index 2c75b19a..61b0ac50 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/usb_conf.h +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/usb_conf.h @@ -1,262 +1,262 @@ -/** - ****************************************************************************** - * @file usb_conf.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief General low level driver configuration - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CONF__H__ -#define __USB_CONF__H__ - - -#define USE_USB_OTG_FS -#define __IO volatile -typedef unsigned long uint32_t; -typedef unsigned int u32; -typedef unsigned short uint16_t; -typedef unsigned short u16; -typedef unsigned char uint8_t; -typedef unsigned char u8; - -/* Includes ------------------------------------------------------------------*/ -//#include "stm32f4xx.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_CONF - * @brief USB low level driver configuration file - * @{ - */ - -/** @defgroup USB_CONF_Exported_Defines - * @{ - */ - -/* USB Core and PHY interface configuration. - Tip: To avoid modifying these defines each time you need to change the USB - configuration, you can declare the needed define in your toolchain - compiler preprocessor. - */ -#ifndef USE_USB_OTG_FS - //#define USE_USB_OTG_FS -#endif /* USE_USB_OTG_FS */ - -#ifdef USE_USB_OTG_FS - #define USB_OTG_FS_CORE -#endif - -/******************************************************************************* -* FIFO Size Configuration in Device mode -* -* (i) Receive data FIFO size = RAM for setup packets + -* OUT endpoint control information + -* data OUT packets + miscellaneous -* Space = ONE 32-bits words -* --> RAM for setup packets = 10 spaces -* (n is the nbr of CTRL EPs the device core supports) -* --> OUT EP CTRL info = 1 space -* (one space for status information written to the FIFO along with each -* received packet) -* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces -* (MINIMUM to receive packets) -* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces -* (if high-bandwidth EP is enabled or multiple isochronous EPs) -* --> miscellaneous = 1 space per OUT EP -* (one space for transfer complete status information also pushed to the -* FIFO with each endpoint's last packet) -* -* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for -* that particular IN EP. More space allocated in the IN EP Tx FIFO results -* in a better performance on the USB and can hide latencies on the AHB. -* -* (iii) TXn min size = 16 words. (n : Transmit FIFO index) -* (iv) When a TxFIFO is not used, the Configuration should be as follows: -* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) -* --> Txm can use the space allocated for Txn. -* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) -* --> Txn should be configured with the minimum space of 16 words -* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top -* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. -*******************************************************************************/ - - - -/****************** USB OTG FS CONFIGURATION **********************************/ -#ifdef USB_OTG_FS_CORE - #define RX_FIFO_FS_SIZE 128 - #define TX0_FIFO_FS_SIZE 64 - #define TX1_FIFO_FS_SIZE 128 - #define TX2_FIFO_FS_SIZE 0 - #define TX3_FIFO_FS_SIZE 0 - - //#define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - //#define USB_OTG_FS_SOF_OUTPUT_ENABLED -#endif - -/****************** USB OTG MODE CONFIGURATION ********************************/ - -//#define USE_HOST_MODE -#define USE_DEVICE_MODE -//#define USE_OTG_MODE - - -#ifndef USB_OTG_FS_CORE - #ifndef USB_OTG_HS_CORE - #error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined" - #endif -#endif - - -#ifndef USE_DEVICE_MODE - #ifndef USE_HOST_MODE - #error "USE_DEVICE_MODE or USE_HOST_MODE should be defined" - #endif -#endif - -#ifndef USE_USB_OTG_HS - #ifndef USE_USB_OTG_FS - #error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined" - #endif -#else //USE_USB_OTG_HS - #ifndef USE_ULPI_PHY - #ifndef USE_EMBEDDED_PHY - #ifndef USE_I2C_PHY - #error "USE_ULPI_PHY or USE_EMBEDDED_PHY or USE_I2C_PHY should be defined" - #endif - #endif - #endif -#endif - -/****************** C Compilers dependant keywords ****************************/ -/* In HS mode and when the DMA is used, all variables and data structures dealing - with the DMA during the transaction process should be 4-bytes aligned */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined (__GNUC__) /* GNU Compiler */ - #define __ALIGN_END __attribute__ ((aligned (4))) - #define __ALIGN_BEGIN - #else - #define __ALIGN_END - #if defined (__CC_ARM) /* ARM Compiler */ - #define __ALIGN_BEGIN __align(4) - #elif defined (__ICCARM__) /* IAR Compiler */ - #define __ALIGN_BEGIN - #elif defined (__TASKING__) /* TASKING Compiler */ - #define __ALIGN_BEGIN __align(4) - #endif /* __CC_ARM */ - #endif /* __GNUC__ */ -#else - #define __ALIGN_BEGIN - #define __ALIGN_END -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/* __packed keyword used to decrease the data type alignment to 1-byte */ -#if defined (__CC_ARM) /* ARM Compiler */ - #define __packed __packed -#elif defined (__ICCARM__) /* IAR Compiler */ - #define __packed __packed -#elif defined ( __GNUC__ ) /* GNU Compiler */ - #define __packed __attribute__ ((__packed__)) -#elif defined (__TASKING__) /* TASKING Compiler */ - #define __packed __unaligned -#endif /* __CC_ARM */ - -/****************** C Compilers dependant keywords ****************************/ -/* In HS mode and when the DMA is used, all variables and data structures dealing - with the DMA during the transaction process should be 4-bytes aligned */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined (__GNUC__) /* GNU Compiler */ - #define __ALIGN_END __attribute__ ((aligned (4))) - #define __ALIGN_BEGIN - #else - #define __ALIGN_END - #if defined (__CC_ARM) /* ARM Compiler */ - #define __ALIGN_BEGIN __align(4) - #elif defined (__ICCARM__) /* IAR Compiler */ - #define __ALIGN_BEGIN - #elif defined (__TASKING__) /* TASKING Compiler */ - #define __ALIGN_BEGIN __align(4) - #endif /* __CC_ARM */ - #endif /* __GNUC__ */ -#else - #define __ALIGN_BEGIN - #define __ALIGN_END -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/* __packed keyword used to decrease the data type alignment to 1-byte */ -#if defined (__CC_ARM) /* ARM Compiler */ - #define __packed __packed -#elif defined (__ICCARM__) /* IAR Compiler */ - #define __packed __packed -#elif defined ( __GNUC__ ) /* GNU Compiler */ - #define __packed __attribute__ ((__packed__)) -#elif defined (__TASKING__) /* TASKING Compiler */ - #define __packed __unaligned -#endif /* __CC_ARM */ - - -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USB_CONF__H__ - - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usb_conf.h + * @author MCD Application Team + * @version V1.0.0 + * @date 19-September-2011 + * @brief General low level driver configuration + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CONF__H__ +#define __USB_CONF__H__ + + +#define USE_USB_OTG_FS +#define __IO volatile +typedef unsigned long uint32_t; +typedef unsigned int u32; +typedef unsigned short uint16_t; +typedef unsigned short u16; +typedef unsigned char uint8_t; +typedef unsigned char u8; + +/* Includes ------------------------------------------------------------------*/ +//#include "stm32f4xx.h" + + +/** @addtogroup USB_OTG_DRIVER + * @{ + */ + +/** @defgroup USB_CONF + * @brief USB low level driver configuration file + * @{ + */ + +/** @defgroup USB_CONF_Exported_Defines + * @{ + */ + +/* USB Core and PHY interface configuration. + Tip: To avoid modifying these defines each time you need to change the USB + configuration, you can declare the needed define in your toolchain + compiler preprocessor. + */ +#ifndef USE_USB_OTG_FS + //#define USE_USB_OTG_FS +#endif /* USE_USB_OTG_FS */ + +#ifdef USE_USB_OTG_FS + #define USB_OTG_FS_CORE +#endif + +/******************************************************************************* +* FIFO Size Configuration in Device mode +* +* (i) Receive data FIFO size = RAM for setup packets + +* OUT endpoint control information + +* data OUT packets + miscellaneous +* Space = ONE 32-bits words +* --> RAM for setup packets = 10 spaces +* (n is the nbr of CTRL EPs the device core supports) +* --> OUT EP CTRL info = 1 space +* (one space for status information written to the FIFO along with each +* received packet) +* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces +* (MINIMUM to receive packets) +* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces +* (if high-bandwidth EP is enabled or multiple isochronous EPs) +* --> miscellaneous = 1 space per OUT EP +* (one space for transfer complete status information also pushed to the +* FIFO with each endpoint's last packet) +* +* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for +* that particular IN EP. More space allocated in the IN EP Tx FIFO results +* in a better performance on the USB and can hide latencies on the AHB. +* +* (iii) TXn min size = 16 words. (n : Transmit FIFO index) +* (iv) When a TxFIFO is not used, the Configuration should be as follows: +* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) +* --> Txm can use the space allocated for Txn. +* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) +* --> Txn should be configured with the minimum space of 16 words +* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top +* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. +*******************************************************************************/ + + + +/****************** USB OTG FS CONFIGURATION **********************************/ +#ifdef USB_OTG_FS_CORE + #define RX_FIFO_FS_SIZE 128 + #define TX0_FIFO_FS_SIZE 64 + #define TX1_FIFO_FS_SIZE 128 + #define TX2_FIFO_FS_SIZE 0 + #define TX3_FIFO_FS_SIZE 0 + + //#define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT + //#define USB_OTG_FS_SOF_OUTPUT_ENABLED +#endif + +/****************** USB OTG MODE CONFIGURATION ********************************/ + +//#define USE_HOST_MODE +#define USE_DEVICE_MODE +//#define USE_OTG_MODE + + +#ifndef USB_OTG_FS_CORE + #ifndef USB_OTG_HS_CORE + #error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined" + #endif +#endif + + +#ifndef USE_DEVICE_MODE + #ifndef USE_HOST_MODE + #error "USE_DEVICE_MODE or USE_HOST_MODE should be defined" + #endif +#endif + +#ifndef USE_USB_OTG_HS + #ifndef USE_USB_OTG_FS + #error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined" + #endif +#else //USE_USB_OTG_HS + #ifndef USE_ULPI_PHY + #ifndef USE_EMBEDDED_PHY + #ifndef USE_I2C_PHY + #error "USE_ULPI_PHY or USE_EMBEDDED_PHY or USE_I2C_PHY should be defined" + #endif + #endif + #endif +#endif + +/****************** C Compilers dependant keywords ****************************/ +/* In HS mode and when the DMA is used, all variables and data structures dealing + with the DMA during the transaction process should be 4-bytes aligned */ +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined (__GNUC__) /* GNU Compiler */ + #define __ALIGN_END __attribute__ ((aligned (4))) + #define __ALIGN_BEGIN + #else + #define __ALIGN_END + #if defined (__CC_ARM) /* ARM Compiler */ + #define __ALIGN_BEGIN __align(4) + #elif defined (__ICCARM__) /* IAR Compiler */ + #define __ALIGN_BEGIN + #elif defined (__TASKING__) /* TASKING Compiler */ + #define __ALIGN_BEGIN __align(4) + #endif /* __CC_ARM */ + #endif /* __GNUC__ */ +#else + #define __ALIGN_BEGIN + #define __ALIGN_END +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + +/* __packed keyword used to decrease the data type alignment to 1-byte */ +#if defined (__CC_ARM) /* ARM Compiler */ + #define __packed __packed +#elif defined (__ICCARM__) /* IAR Compiler */ + #define __packed __packed +#elif defined ( __GNUC__ ) /* GNU Compiler */ + #define __packed __attribute__ ((__packed__)) +#elif defined (__TASKING__) /* TASKING Compiler */ + #define __packed __unaligned +#endif /* __CC_ARM */ + +/****************** C Compilers dependant keywords ****************************/ +/* In HS mode and when the DMA is used, all variables and data structures dealing + with the DMA during the transaction process should be 4-bytes aligned */ +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined (__GNUC__) /* GNU Compiler */ + #define __ALIGN_END __attribute__ ((aligned (4))) + #define __ALIGN_BEGIN + #else + #define __ALIGN_END + #if defined (__CC_ARM) /* ARM Compiler */ + #define __ALIGN_BEGIN __align(4) + #elif defined (__ICCARM__) /* IAR Compiler */ + #define __ALIGN_BEGIN + #elif defined (__TASKING__) /* TASKING Compiler */ + #define __ALIGN_BEGIN __align(4) + #endif /* __CC_ARM */ + #endif /* __GNUC__ */ +#else + #define __ALIGN_BEGIN + #define __ALIGN_END +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + +/* __packed keyword used to decrease the data type alignment to 1-byte */ +#if defined (__CC_ARM) /* ARM Compiler */ + #define __packed __packed +#elif defined (__ICCARM__) /* IAR Compiler */ + #define __packed __packed +#elif defined ( __GNUC__ ) /* GNU Compiler */ + #define __packed __attribute__ ((__packed__)) +#elif defined (__TASKING__) /* TASKING Compiler */ + #define __packed __unaligned +#endif /* __CC_ARM */ + + +/** + * @} + */ + + +/** @defgroup USB_CONF_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_CONF_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_CONF_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_CONF_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + + +#endif //__USB_CONF__H__ + + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_cdc_vcp.c b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_cdc_vcp.c index f10e86a1..b13260ee 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_cdc_vcp.c +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_cdc_vcp.c @@ -1,422 +1,422 @@ -/** - ****************************************************************************** - * @file usbd_cdc_vcp.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Generic media access Layer. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED -#pragma data_alignment = 4 -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_cdc_vcp.h" -//#include "stm32f4_discovery.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -LINE_CODING linecoding = - { - 115200, /* baud rate*/ - 0x00, /* stop bits-1*/ - 0x00, /* parity - none*/ - 0x08 /* nb. of bits 8*/ - }; - - -//USART_InitTypeDef USART_InitStructure; - -/* These are external variables imported from CDC core to be used for IN - transfer management. */ -extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer. - These data will be sent over USB IN endpoint - in the CDC core functions. */ -extern volatile int APP_Rx_ptr_in; /* Increment this pointer or roll it back to - start address when writing received data - in the buffer APP_Rx_Buffer. */ -extern volatile int APP_Rx_ptr_out; - -#define UsbRecBufferSize 2048 -uint8_t UsbRecBuffer[UsbRecBufferSize]; -volatile int UsbRecRead = 0; -volatile int UsbRecWrite = 0; -volatile int VCP_DTRHIGH = 0; -uint8_t UsbTXBlock = 0; - -uint32_t VCPBytesAvailable(void) { - return (UsbRecWrite - UsbRecRead + UsbRecBufferSize) % UsbRecBufferSize; -} - -uint8_t VCPGetByte(void) { - if(UsbRecWrite == UsbRecRead) { - return 0; - } else { - uint8_t c = UsbRecBuffer[UsbRecRead++]; - if(UsbRecRead == UsbRecBufferSize) { - UsbRecRead = 0; - } - return c; - } -} - -/* Private function prototypes -----------------------------------------------*/ -static uint16_t VCP_Init (void); -static uint16_t VCP_DeInit (void); -static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len); -uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len); -static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len); - -static uint16_t VCP_COMConfig(uint8_t Conf); - -CDC_IF_Prop_TypeDef VCP_fops = -{ - VCP_Init, - VCP_DeInit, - VCP_Ctrl, - VCP_DataTx, - VCP_DataRx -}; - -/* Private functions ---------------------------------------------------------*/ -/** - * @brief VCP_Init - * Initializes the Media on the STM32 - * @param None - * @retval Result of the opeartion (USBD_OK in all cases) - */ -static uint16_t VCP_Init(void) -{ - return USBD_OK; -} - -/** - * @brief VCP_DeInit - * DeInitializes the Media on the STM32 - * @param None - * @retval Result of the opeartion (USBD_OK in all cases) - */ -static uint16_t VCP_DeInit(void) -{ - - return USBD_OK; -} - -/** - * @brief VCP_SetUSBTxBlocking - * Set USB blocking mode for output buffer overrun - * @param Mode: 0: non blocking, 1: blocking - * @retval None - */ -void VCP_SetUSBTxBlocking(uint8_t Mode) -{ - UsbTXBlock = Mode; -} - -/** - * @brief VCP_Ctrl - * Manage the CDC class requests - * @param Cmd: Command code - * @param Buf: Buffer containing command data (request parameters) - * @param Len: Number of data to be sent (in bytes) - * @retval Result of the opeartion (USBD_OK in all cases) - */ -static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) -{ - switch (Cmd) - { - case SEND_ENCAPSULATED_COMMAND: - /* Not needed for this driver */ - break; - - case GET_ENCAPSULATED_RESPONSE: - /* Not needed for this driver */ - break; - - case SET_COMM_FEATURE: - /* Not needed for this driver */ - break; - - case GET_COMM_FEATURE: - /* Not needed for this driver */ - break; - - case CLEAR_COMM_FEATURE: - /* Not needed for this driver */ - break; - - case SET_LINE_CODING: - linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24)); - linecoding.format = Buf[4]; - linecoding.paritytype = Buf[5]; - linecoding.datatype = Buf[6]; - /* Set the new configuration */ - VCP_COMConfig(OTHER_CONFIG); - break; - - case GET_LINE_CODING: - Buf[0] = (uint8_t)(linecoding.bitrate); - Buf[1] = (uint8_t)(linecoding.bitrate >> 8); - Buf[2] = (uint8_t)(linecoding.bitrate >> 16); - Buf[3] = (uint8_t)(linecoding.bitrate >> 24); - Buf[4] = linecoding.format; - Buf[5] = linecoding.paritytype; - Buf[6] = linecoding.datatype; - break; - - case SET_CONTROL_LINE_STATE: - linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8)); - if(Buf[0] & 1) { - VCP_DTRHIGH = 1; - } - /* Not needed for this driver */ - break; - - case SEND_BREAK: - /* Not needed for this driver */ - break; - - default: - break; - } - - return USBD_OK; -} - -/** - * @brief VCP_DataTx - * CDC received data to be send over USB IN endpoint are managed in - * this function. - * @param Buf: Buffer of data to be sent - * @param Len: Number of data to be sent (in bytes) - * @retval Result of the operation: USBD_OK if all operations are OK else VCP_FAIL - */ -uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len) -{ - while(Len-- > 0) { - if(UsbTXBlock) { - while ((APP_Rx_ptr_in - APP_Rx_ptr_out + APP_RX_DATA_SIZE) % APP_RX_DATA_SIZE + 1 >= APP_RX_DATA_SIZE) - ; - } else { - if ((APP_Rx_ptr_in - APP_Rx_ptr_out + APP_RX_DATA_SIZE) % APP_RX_DATA_SIZE + 1 >= APP_RX_DATA_SIZE) { - return USBD_BUSY; - } - } - - - APP_Rx_Buffer[APP_Rx_ptr_in++] = *Buf++; - /* To avoid buffer overflow */ - if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) - { - APP_Rx_ptr_in = 0; - } - } - return USBD_OK; -} - -typedef volatile unsigned long vu32; - -typedef struct { - vu32 CPUID; - vu32 ICSR; - vu32 VTOR; - vu32 AIRCR; - vu32 SCR; - vu32 CCR; - vu32 SHPR[3]; - vu32 SHCSR; - vu32 CFSR; - vu32 HFSR; - vu32 DFSR; - vu32 MMFAR; - vu32 BFAR; - vu32 AFSR; -} SCB_TypeDef; - -#define AIRCR_RESET 0x05FA0000 -#define AIRCR_RESET_REQ (AIRCR_RESET | (u32)0x04); -#define SCS_BASE ((u32)0xE000E000) -#define SCB_BASE (SCS_BASE + 0x0D00) - -void systemHardReset(void) { - SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE; - typedef void (*funcPtr)(void); - - /* Reset */ - rSCB->AIRCR = (u32)AIRCR_RESET_REQ; - - /* Should never get here */ - while (1) { - asm volatile("nop"); - } -} - -/** - * @brief VCP_DataRx - * Data received over USB OUT endpoint are sent over CDC interface - * through this function. - * - * @note - * This function will block any OUT packet reception on USB endpoint - * until exiting this function. If you exit this function before transfer - * is complete on CDC interface (ie. using DMA controller) it will result - * in receiving more data while previous ones are still not sent. - * - * @param Buf: Buffer of data to be received - * @param Len: Number of data received (in bytes) - * @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL - */ -static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) -{ - if(VCP_DTRHIGH) { - if(Len >= 4) { - if(Buf[0] == '1' && Buf[1] == 'E' && Buf[2] == 'A' && Buf[3] == 'F') { - Len = 0; - *(int*)0x20000BFC = 0x4AFC6BB2; - systemHardReset(); - } - } - } - VCP_DTRHIGH = 0; - while(Len-- > 0) { - UsbRecBuffer[UsbRecWrite] = *Buf++; - if(UsbRecWrite == UsbRecBufferSize) { - UsbRecWrite = 0; - } else { - UsbRecWrite ++; - } - } - - return USBD_OK; -} - -/** - * @brief VCP_COMConfig - * Configure the COM Port with default values or values received from host. - * @param Conf: can be DEFAULT_CONFIG to set the default configuration or OTHER_CONFIG - * to set a configuration received from the host. - * @retval None. - */ -static uint16_t VCP_COMConfig(uint8_t Conf) -{ -#if 0 - if (Conf == DEFAULT_CONFIG) - { - /* EVAL_COM1 default configuration */ - /* EVAL_COM1 configured as follow: - - BaudRate = 115200 baud - - Word Length = 8 Bits - - One Stop Bit - - Parity Odd - - Hardware flow control disabled - - Receive and transmit enabled - */ - USART_InitStructure.USART_BaudRate = 115200; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_Odd; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - - /* Configure and enable the USART */ - STM_EVAL_COMInit(COM1, &USART_InitStructure); - - /* Enable the USART Receive interrupt */ - USART_ITConfig(EVAL_COM1, USART_IT_RXNE, ENABLE); - } - else - { - /* set the Stop bit*/ - switch (linecoding.format) - { - case 0: - USART_InitStructure.USART_StopBits = USART_StopBits_1; - break; - case 1: - USART_InitStructure.USART_StopBits = USART_StopBits_1_5; - break; - case 2: - USART_InitStructure.USART_StopBits = USART_StopBits_2; - break; - default : - VCP_COMConfig(DEFAULT_CONFIG); - return (USBD_FAIL); - } - - /* set the parity bit*/ - switch (linecoding.paritytype) - { - case 0: - USART_InitStructure.USART_Parity = USART_Parity_No; - break; - case 1: - USART_InitStructure.USART_Parity = USART_Parity_Even; - break; - case 2: - USART_InitStructure.USART_Parity = USART_Parity_Odd; - break; - default : - VCP_COMConfig(DEFAULT_CONFIG); - return (USBD_FAIL); - } - - /*set the data type : only 8bits and 9bits is supported */ - switch (linecoding.datatype) - { - case 0x07: - /* With this configuration a parity (Even or Odd) should be set */ - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - break; - case 0x08: - if (USART_InitStructure.USART_Parity == USART_Parity_No) - { - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - } - else - { - USART_InitStructure.USART_WordLength = USART_WordLength_9b; - } - - break; - default : - VCP_COMConfig(DEFAULT_CONFIG); - return (USBD_FAIL); - } - - USART_InitStructure.USART_BaudRate = linecoding.bitrate; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - - /* Configure and enable the USART */ - STM_EVAL_COMInit(COM1, &USART_InitStructure); - } -#endif - return USBD_OK; -} - -/** - * @brief EVAL_COM_IRQHandler - * - * @param None. - * @retval None. - */ -void EVAL_COM_IRQHandler(void) -{ -} - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_cdc_vcp.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Generic media access Layer. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED +#pragma data_alignment = 4 +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc_vcp.h" +//#include "stm32f4_discovery.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +LINE_CODING linecoding = + { + 115200, /* baud rate*/ + 0x00, /* stop bits-1*/ + 0x00, /* parity - none*/ + 0x08 /* nb. of bits 8*/ + }; + + +//USART_InitTypeDef USART_InitStructure; + +/* These are external variables imported from CDC core to be used for IN + transfer management. */ +extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer. + These data will be sent over USB IN endpoint + in the CDC core functions. */ +extern volatile int APP_Rx_ptr_in; /* Increment this pointer or roll it back to + start address when writing received data + in the buffer APP_Rx_Buffer. */ +extern volatile int APP_Rx_ptr_out; + +#define UsbRecBufferSize 2048 +uint8_t UsbRecBuffer[UsbRecBufferSize]; +volatile int UsbRecRead = 0; +volatile int UsbRecWrite = 0; +volatile int VCP_DTRHIGH = 0; +uint8_t UsbTXBlock = 0; + +uint32_t VCPBytesAvailable(void) { + return (UsbRecWrite - UsbRecRead + UsbRecBufferSize) % UsbRecBufferSize; +} + +uint8_t VCPGetByte(void) { + if(UsbRecWrite == UsbRecRead) { + return 0; + } else { + uint8_t c = UsbRecBuffer[UsbRecRead++]; + if(UsbRecRead == UsbRecBufferSize) { + UsbRecRead = 0; + } + return c; + } +} + +/* Private function prototypes -----------------------------------------------*/ +static uint16_t VCP_Init (void); +static uint16_t VCP_DeInit (void); +static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len); +uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len); +static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len); + +static uint16_t VCP_COMConfig(uint8_t Conf); + +CDC_IF_Prop_TypeDef VCP_fops = +{ + VCP_Init, + VCP_DeInit, + VCP_Ctrl, + VCP_DataTx, + VCP_DataRx +}; + +/* Private functions ---------------------------------------------------------*/ +/** + * @brief VCP_Init + * Initializes the Media on the STM32 + * @param None + * @retval Result of the opeartion (USBD_OK in all cases) + */ +static uint16_t VCP_Init(void) +{ + return USBD_OK; +} + +/** + * @brief VCP_DeInit + * DeInitializes the Media on the STM32 + * @param None + * @retval Result of the opeartion (USBD_OK in all cases) + */ +static uint16_t VCP_DeInit(void) +{ + + return USBD_OK; +} + +/** + * @brief VCP_SetUSBTxBlocking + * Set USB blocking mode for output buffer overrun + * @param Mode: 0: non blocking, 1: blocking + * @retval None + */ +void VCP_SetUSBTxBlocking(uint8_t Mode) +{ + UsbTXBlock = Mode; +} + +/** + * @brief VCP_Ctrl + * Manage the CDC class requests + * @param Cmd: Command code + * @param Buf: Buffer containing command data (request parameters) + * @param Len: Number of data to be sent (in bytes) + * @retval Result of the opeartion (USBD_OK in all cases) + */ +static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) +{ + switch (Cmd) + { + case SEND_ENCAPSULATED_COMMAND: + /* Not needed for this driver */ + break; + + case GET_ENCAPSULATED_RESPONSE: + /* Not needed for this driver */ + break; + + case SET_COMM_FEATURE: + /* Not needed for this driver */ + break; + + case GET_COMM_FEATURE: + /* Not needed for this driver */ + break; + + case CLEAR_COMM_FEATURE: + /* Not needed for this driver */ + break; + + case SET_LINE_CODING: + linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24)); + linecoding.format = Buf[4]; + linecoding.paritytype = Buf[5]; + linecoding.datatype = Buf[6]; + /* Set the new configuration */ + VCP_COMConfig(OTHER_CONFIG); + break; + + case GET_LINE_CODING: + Buf[0] = (uint8_t)(linecoding.bitrate); + Buf[1] = (uint8_t)(linecoding.bitrate >> 8); + Buf[2] = (uint8_t)(linecoding.bitrate >> 16); + Buf[3] = (uint8_t)(linecoding.bitrate >> 24); + Buf[4] = linecoding.format; + Buf[5] = linecoding.paritytype; + Buf[6] = linecoding.datatype; + break; + + case SET_CONTROL_LINE_STATE: + linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8)); + if(Buf[0] & 1) { + VCP_DTRHIGH = 1; + } + /* Not needed for this driver */ + break; + + case SEND_BREAK: + /* Not needed for this driver */ + break; + + default: + break; + } + + return USBD_OK; +} + +/** + * @brief VCP_DataTx + * CDC received data to be send over USB IN endpoint are managed in + * this function. + * @param Buf: Buffer of data to be sent + * @param Len: Number of data to be sent (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else VCP_FAIL + */ +uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len) +{ + while(Len-- > 0) { + if(UsbTXBlock) { + while ((APP_Rx_ptr_in - APP_Rx_ptr_out + APP_RX_DATA_SIZE) % APP_RX_DATA_SIZE + 1 >= APP_RX_DATA_SIZE) + ; + } else { + if ((APP_Rx_ptr_in - APP_Rx_ptr_out + APP_RX_DATA_SIZE) % APP_RX_DATA_SIZE + 1 >= APP_RX_DATA_SIZE) { + return USBD_BUSY; + } + } + + + APP_Rx_Buffer[APP_Rx_ptr_in++] = *Buf++; + /* To avoid buffer overflow */ + if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) + { + APP_Rx_ptr_in = 0; + } + } + return USBD_OK; +} + +typedef volatile unsigned long vu32; + +typedef struct { + vu32 CPUID; + vu32 ICSR; + vu32 VTOR; + vu32 AIRCR; + vu32 SCR; + vu32 CCR; + vu32 SHPR[3]; + vu32 SHCSR; + vu32 CFSR; + vu32 HFSR; + vu32 DFSR; + vu32 MMFAR; + vu32 BFAR; + vu32 AFSR; +} SCB_TypeDef; + +#define AIRCR_RESET 0x05FA0000 +#define AIRCR_RESET_REQ (AIRCR_RESET | (u32)0x04); +#define SCS_BASE ((u32)0xE000E000) +#define SCB_BASE (SCS_BASE + 0x0D00) + +void systemHardReset(void) { + SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE; + typedef void (*funcPtr)(void); + + /* Reset */ + rSCB->AIRCR = (u32)AIRCR_RESET_REQ; + + /* Should never get here */ + while (1) { + asm volatile("nop"); + } +} + +/** + * @brief VCP_DataRx + * Data received over USB OUT endpoint are sent over CDC interface + * through this function. + * + * @note + * This function will block any OUT packet reception on USB endpoint + * until exiting this function. If you exit this function before transfer + * is complete on CDC interface (ie. using DMA controller) it will result + * in receiving more data while previous ones are still not sent. + * + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL + */ +static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) +{ + if(VCP_DTRHIGH) { + if(Len >= 4) { + if(Buf[0] == '1' && Buf[1] == 'E' && Buf[2] == 'A' && Buf[3] == 'F') { + Len = 0; + *(int*)0x20000BFC = 0x4AFC6BB2; + systemHardReset(); + } + } + } + VCP_DTRHIGH = 0; + while(Len-- > 0) { + UsbRecBuffer[UsbRecWrite] = *Buf++; + if(UsbRecWrite == UsbRecBufferSize) { + UsbRecWrite = 0; + } else { + UsbRecWrite ++; + } + } + + return USBD_OK; +} + +/** + * @brief VCP_COMConfig + * Configure the COM Port with default values or values received from host. + * @param Conf: can be DEFAULT_CONFIG to set the default configuration or OTHER_CONFIG + * to set a configuration received from the host. + * @retval None. + */ +static uint16_t VCP_COMConfig(uint8_t Conf) +{ +#if 0 + if (Conf == DEFAULT_CONFIG) + { + /* EVAL_COM1 default configuration */ + /* EVAL_COM1 configured as follow: + - BaudRate = 115200 baud + - Word Length = 8 Bits + - One Stop Bit + - Parity Odd + - Hardware flow control disabled + - Receive and transmit enabled + */ + USART_InitStructure.USART_BaudRate = 115200; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_Odd; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + + /* Configure and enable the USART */ + STM_EVAL_COMInit(COM1, &USART_InitStructure); + + /* Enable the USART Receive interrupt */ + USART_ITConfig(EVAL_COM1, USART_IT_RXNE, ENABLE); + } + else + { + /* set the Stop bit*/ + switch (linecoding.format) + { + case 0: + USART_InitStructure.USART_StopBits = USART_StopBits_1; + break; + case 1: + USART_InitStructure.USART_StopBits = USART_StopBits_1_5; + break; + case 2: + USART_InitStructure.USART_StopBits = USART_StopBits_2; + break; + default : + VCP_COMConfig(DEFAULT_CONFIG); + return (USBD_FAIL); + } + + /* set the parity bit*/ + switch (linecoding.paritytype) + { + case 0: + USART_InitStructure.USART_Parity = USART_Parity_No; + break; + case 1: + USART_InitStructure.USART_Parity = USART_Parity_Even; + break; + case 2: + USART_InitStructure.USART_Parity = USART_Parity_Odd; + break; + default : + VCP_COMConfig(DEFAULT_CONFIG); + return (USBD_FAIL); + } + + /*set the data type : only 8bits and 9bits is supported */ + switch (linecoding.datatype) + { + case 0x07: + /* With this configuration a parity (Even or Odd) should be set */ + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + break; + case 0x08: + if (USART_InitStructure.USART_Parity == USART_Parity_No) + { + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + } + else + { + USART_InitStructure.USART_WordLength = USART_WordLength_9b; + } + + break; + default : + VCP_COMConfig(DEFAULT_CONFIG); + return (USBD_FAIL); + } + + USART_InitStructure.USART_BaudRate = linecoding.bitrate; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + + /* Configure and enable the USART */ + STM_EVAL_COMInit(COM1, &USART_InitStructure); + } +#endif + return USBD_OK; +} + +/** + * @brief EVAL_COM_IRQHandler + * + * @param None. + * @retval None. + */ +void EVAL_COM_IRQHandler(void) +{ +} + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_cdc_vcp.h b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_cdc_vcp.h index 28ba613d..67475e7a 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_cdc_vcp.h +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_cdc_vcp.h @@ -1,63 +1,63 @@ -/** - ****************************************************************************** - * @file usbd_cdc_vcp.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header for usbd_cdc_vcp.c file. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CDC_VCP_H -#define __USBD_CDC_VCP_H - -/* Includes ------------------------------------------------------------------*/ -//#include "stm32f4xx.h" - -#include "usbd_cdc_core.h" -#include "usbd_conf.h" - - -/* Exported typef ------------------------------------------------------------*/ -/* The following structures groups all needed parameters to be configured for the - ComPort. These parameters can modified on the fly by the host through CDC class - command class requests. */ -typedef struct -{ - uint32_t bitrate; - uint8_t format; - uint8_t paritytype; - uint8_t datatype; -}LINE_CODING; - -/* Exported constants --------------------------------------------------------*/ -/* The following define is used to route the USART IRQ handler to be used. - The IRQ handler function is implemented in the usbd_cdc_vcp.c file. */ -#ifdef USE_STM322xG_EVAL - #define EVAL_COM_IRQHandler USART3_IRQHandler -#elif defined(USE_STM3210C_EVAL) - #define EVAL_COM_IRQHandler USART2_IRQHandler -#endif /* USE_STM322xG_EVAL */ -#define EVAL_COM_IRQHandler USART2_IRQHandler - -#define DEFAULT_CONFIG 0 -#define OTHER_CONFIG 1 - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#endif /* __USBD_CDC_VCP_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_cdc_vcp.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief Header for usbd_cdc_vcp.c file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CDC_VCP_H +#define __USBD_CDC_VCP_H + +/* Includes ------------------------------------------------------------------*/ +//#include "stm32f4xx.h" + +#include "usbd_cdc_core.h" +#include "usbd_conf.h" + + +/* Exported typef ------------------------------------------------------------*/ +/* The following structures groups all needed parameters to be configured for the + ComPort. These parameters can modified on the fly by the host through CDC class + command class requests. */ +typedef struct +{ + uint32_t bitrate; + uint8_t format; + uint8_t paritytype; + uint8_t datatype; +}LINE_CODING; + +/* Exported constants --------------------------------------------------------*/ +/* The following define is used to route the USART IRQ handler to be used. + The IRQ handler function is implemented in the usbd_cdc_vcp.c file. */ +#ifdef USE_STM322xG_EVAL + #define EVAL_COM_IRQHandler USART3_IRQHandler +#elif defined(USE_STM3210C_EVAL) + #define EVAL_COM_IRQHandler USART2_IRQHandler +#endif /* USE_STM322xG_EVAL */ +#define EVAL_COM_IRQHandler USART2_IRQHandler + +#define DEFAULT_CONFIG 0 +#define OTHER_CONFIG 1 + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* __USBD_CDC_VCP_H */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_conf.h b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_conf.h index 8d7b1501..516a2fbb 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_conf.h +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_conf.h @@ -1,98 +1,98 @@ -/** - ****************************************************************************** - * @file usbd_conf.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief USB Device configuration file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CONF__H__ -#define __USBD_CONF__H__ - -/* Includes ------------------------------------------------------------------*/ -//#include "stm32f4_discovery.h" - -/** @defgroup USB_CONF_Exported_Defines - * @{ - */ -#define USBD_CFG_MAX_NUM 1 -#define USBD_ITF_MAX_NUM 1 -#define USB_MAX_STR_DESC_SIZ 50 - -/** @defgroup USB_VCP_Class_Layer_Parameter - * @{ - */ -#define CDC_IN_EP 0x81 /* EP1 for data IN */ -#define CDC_OUT_EP 0x01 /* EP1 for data OUT */ -#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ - -/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ -#ifdef USE_USB_OTG_HS - #define CDC_DATA_MAX_PACKET_SIZE 512 /* Endpoint IN & OUT Packet size */ - #define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */ - - #define CDC_IN_FRAME_INTERVAL 40 /* Number of micro-frames between IN transfers */ - #define APP_RX_DATA_SIZE 2048 /* Total size of IN buffer: - APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL*8 */ -#else - #define CDC_DATA_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ - #define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */ - - #define CDC_IN_FRAME_INTERVAL 5 /* Number of frames between IN transfers */ - #define APP_RX_DATA_SIZE 2048 /* Total size of IN buffer: - APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */ -#endif /* USE_USB_OTG_HS */ - -#define APP_FOPS VCP_fops -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USBD_CONF__H__ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usbd_conf.h + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief USB Device configuration file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CONF__H__ +#define __USBD_CONF__H__ + +/* Includes ------------------------------------------------------------------*/ +//#include "stm32f4_discovery.h" + +/** @defgroup USB_CONF_Exported_Defines + * @{ + */ +#define USBD_CFG_MAX_NUM 1 +#define USBD_ITF_MAX_NUM 1 +#define USB_MAX_STR_DESC_SIZ 50 + +/** @defgroup USB_VCP_Class_Layer_Parameter + * @{ + */ +#define CDC_IN_EP 0x81 /* EP1 for data IN */ +#define CDC_OUT_EP 0x01 /* EP1 for data OUT */ +#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ + +/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ +#ifdef USE_USB_OTG_HS + #define CDC_DATA_MAX_PACKET_SIZE 512 /* Endpoint IN & OUT Packet size */ + #define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */ + + #define CDC_IN_FRAME_INTERVAL 40 /* Number of micro-frames between IN transfers */ + #define APP_RX_DATA_SIZE 2048 /* Total size of IN buffer: + APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL*8 */ +#else + #define CDC_DATA_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ + #define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */ + + #define CDC_IN_FRAME_INTERVAL 5 /* Number of frames between IN transfers */ + #define APP_RX_DATA_SIZE 2048 /* Total size of IN buffer: + APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */ +#endif /* USE_USB_OTG_HS */ + +#define APP_FOPS VCP_fops +/** + * @} + */ + +/** @defgroup USB_CONF_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USB_CONF_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_CONF_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USB_CONF_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + + +#endif //__USBD_CONF__H__ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_desc.c b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_desc.c index eab1a42c..537f2665 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_desc.c +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_desc.c @@ -1,316 +1,316 @@ -/** - ****************************************************************************** - * @file usbd_desc.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the USBD descriptors and string formating method. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_core.h" -#include "usbd_desc.h" -#include "usbd_req.h" -#include "usbd_conf.h" -#include "usb_regs.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_DESC - * @brief USBD descriptors module - * @{ - */ - -/** @defgroup USBD_DESC_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_DESC_Private_Defines - * @{ - */ -#define USBD_VID 0x0483 - -#define USBD_PID 0x5740 - -/** @defgroup USB_String_Descriptors - * @{ - */ -#define USBD_LANGID_STRING 0x409 -#define USBD_MANUFACTURER_STRING (uint8_t*)"STMicroelectronics" - -#define USBD_PRODUCT_HS_STRING (uint8_t*)"STM32 Virtual ComPort in HS mode" -#define USBD_SERIALNUMBER_HS_STRING (uint8_t*)"00000000050B" - -#define USBD_PRODUCT_FS_STRING (uint8_t*)"STM32 Virtual ComPort in FS Mode" -#define USBD_SERIALNUMBER_FS_STRING (uint8_t*)"00000000050C" - -#define USBD_CONFIGURATION_HS_STRING (uint8_t*)"VCP Config" -#define USBD_INTERFACE_HS_STRING (uint8_t*)"VCP Interface" - -#define USBD_CONFIGURATION_FS_STRING (uint8_t*)"VCP Config" -#define USBD_INTERFACE_FS_STRING (uint8_t*)"VCP Interface" -/** - * @} - */ - - -/** @defgroup USBD_DESC_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_DESC_Private_Variables - * @{ - */ - -USBD_DEVICE USR_desc = -{ - USBD_USR_DeviceDescriptor, - USBD_USR_LangIDStrDescriptor, - USBD_USR_ManufacturerStrDescriptor, - USBD_USR_ProductStrDescriptor, - USBD_USR_SerialStrDescriptor, - USBD_USR_ConfigStrDescriptor, - USBD_USR_InterfaceStrDescriptor, - -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB Standard Device Descriptor */ -__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] __ALIGN_END = - { - 0x12, /*bLength */ - USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/ - 0x00, /*bcdUSB */ - 0x02, - 0x00, /*bDeviceClass*/ - 0x00, /*bDeviceSubClass*/ - 0x00, /*bDeviceProtocol*/ - USB_OTG_MAX_EP0_SIZE, /*bMaxPacketSize*/ - LOBYTE(USBD_VID), /*idVendor*/ - HIBYTE(USBD_VID), /*idVendor*/ - LOBYTE(USBD_PID), /*idVendor*/ - HIBYTE(USBD_PID), /*idVendor*/ - 0x00, /*bcdDevice rel. 2.00*/ - 0x02, - USBD_IDX_MFC_STR, /*Index of manufacturer string*/ - USBD_IDX_PRODUCT_STR, /*Index of product string*/ - USBD_IDX_SERIAL_STR, /*Index of serial number string*/ - USBD_CFG_MAX_NUM /*bNumConfigurations*/ - } ; /* USB_DeviceDescriptor */ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB Standard Device Descriptor */ -__ALIGN_BEGIN uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = -{ - USB_LEN_DEV_QUALIFIER_DESC, - USB_DESC_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x01, - 0x00, -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB Standard Device Descriptor */ -__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID] __ALIGN_END = -{ - USB_SIZ_STRING_LANGID, - USB_DESC_TYPE_STRING, - LOBYTE(USBD_LANGID_STRING), - HIBYTE(USBD_LANGID_STRING), -}; -/** - * @} - */ - - -/** @defgroup USBD_DESC_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_DESC_Private_Functions - * @{ - */ - -/** -* @brief USBD_USR_DeviceDescriptor -* return the device descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length) -{ - *length = sizeof(USBD_DeviceDesc); - return USBD_DeviceDesc; -} - -/** -* @brief USBD_USR_LangIDStrDescriptor -* return the LangID string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length) -{ - *length = sizeof(USBD_LangIDDesc); - return USBD_LangIDDesc; -} - - -/** -* @brief USBD_USR_ProductStrDescriptor -* return the product string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_ProductStrDescriptor( uint8_t speed , uint16_t *length) -{ - - - if(speed == 0) - { - USBD_GetString (USBD_PRODUCT_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString (USBD_PRODUCT_FS_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - -/** -* @brief USBD_USR_ManufacturerStrDescriptor -* return the manufacturer string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_ManufacturerStrDescriptor( uint8_t speed , uint16_t *length) -{ - USBD_GetString (USBD_MANUFACTURER_STRING, USBD_StrDesc, length); - return USBD_StrDesc; -} - -/** -* @brief USBD_USR_SerialStrDescriptor -* return the serial number string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length) -{ - if(speed == USB_OTG_SPEED_HIGH) - { - USBD_GetString (USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString (USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - -/** -* @brief USBD_USR_ConfigStrDescriptor -* return the configuration string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length) -{ - if(speed == USB_OTG_SPEED_HIGH) - { - USBD_GetString (USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString (USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - - -/** -* @brief USBD_USR_InterfaceStrDescriptor -* return the interface string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length) -{ - if(speed == 0) - { - USBD_GetString (USBD_INTERFACE_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString (USBD_INTERFACE_FS_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - +/** + ****************************************************************************** + * @file usbd_desc.c + * @author MCD Application Team + * @version V1.0.0 + * @date 22-July-2011 + * @brief This file provides the USBD descriptors and string formating method. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_req.h" +#include "usbd_conf.h" +#include "usb_regs.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_DESC + * @brief USBD descriptors module + * @{ + */ + +/** @defgroup USBD_DESC_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_DESC_Private_Defines + * @{ + */ +#define USBD_VID 0x0483 + +#define USBD_PID 0x5740 + +/** @defgroup USB_String_Descriptors + * @{ + */ +#define USBD_LANGID_STRING 0x409 +#define USBD_MANUFACTURER_STRING (uint8_t*)"STMicroelectronics" + +#define USBD_PRODUCT_HS_STRING (uint8_t*)"STM32 Virtual ComPort in HS mode" +#define USBD_SERIALNUMBER_HS_STRING (uint8_t*)"00000000050B" + +#define USBD_PRODUCT_FS_STRING (uint8_t*)"STM32 Virtual ComPort in FS Mode" +#define USBD_SERIALNUMBER_FS_STRING (uint8_t*)"00000000050C" + +#define USBD_CONFIGURATION_HS_STRING (uint8_t*)"VCP Config" +#define USBD_INTERFACE_HS_STRING (uint8_t*)"VCP Interface" + +#define USBD_CONFIGURATION_FS_STRING (uint8_t*)"VCP Config" +#define USBD_INTERFACE_FS_STRING (uint8_t*)"VCP Interface" +/** + * @} + */ + + +/** @defgroup USBD_DESC_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_DESC_Private_Variables + * @{ + */ + +USBD_DEVICE USR_desc = +{ + USBD_USR_DeviceDescriptor, + USBD_USR_LangIDStrDescriptor, + USBD_USR_ManufacturerStrDescriptor, + USBD_USR_ProductStrDescriptor, + USBD_USR_SerialStrDescriptor, + USBD_USR_ConfigStrDescriptor, + USBD_USR_InterfaceStrDescriptor, + +}; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] __ALIGN_END = + { + 0x12, /*bLength */ + USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/ + 0x00, /*bcdUSB */ + 0x02, + 0x00, /*bDeviceClass*/ + 0x00, /*bDeviceSubClass*/ + 0x00, /*bDeviceProtocol*/ + USB_OTG_MAX_EP0_SIZE, /*bMaxPacketSize*/ + LOBYTE(USBD_VID), /*idVendor*/ + HIBYTE(USBD_VID), /*idVendor*/ + LOBYTE(USBD_PID), /*idVendor*/ + HIBYTE(USBD_PID), /*idVendor*/ + 0x00, /*bcdDevice rel. 2.00*/ + 0x02, + USBD_IDX_MFC_STR, /*Index of manufacturer string*/ + USBD_IDX_PRODUCT_STR, /*Index of product string*/ + USBD_IDX_SERIAL_STR, /*Index of serial number string*/ + USBD_CFG_MAX_NUM /*bNumConfigurations*/ + } ; /* USB_DeviceDescriptor */ + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 + #endif +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID] __ALIGN_END = +{ + USB_SIZ_STRING_LANGID, + USB_DESC_TYPE_STRING, + LOBYTE(USBD_LANGID_STRING), + HIBYTE(USBD_LANGID_STRING), +}; +/** + * @} + */ + + +/** @defgroup USBD_DESC_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_DESC_Private_Functions + * @{ + */ + +/** +* @brief USBD_USR_DeviceDescriptor +* return the device descriptor +* @param speed : current device speed +* @param length : pointer to data length variable +* @retval pointer to descriptor buffer +*/ +uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length) +{ + *length = sizeof(USBD_DeviceDesc); + return USBD_DeviceDesc; +} + +/** +* @brief USBD_USR_LangIDStrDescriptor +* return the LangID string descriptor +* @param speed : current device speed +* @param length : pointer to data length variable +* @retval pointer to descriptor buffer +*/ +uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length) +{ + *length = sizeof(USBD_LangIDDesc); + return USBD_LangIDDesc; +} + + +/** +* @brief USBD_USR_ProductStrDescriptor +* return the product string descriptor +* @param speed : current device speed +* @param length : pointer to data length variable +* @retval pointer to descriptor buffer +*/ +uint8_t * USBD_USR_ProductStrDescriptor( uint8_t speed , uint16_t *length) +{ + + + if(speed == 0) + { + USBD_GetString (USBD_PRODUCT_HS_STRING, USBD_StrDesc, length); + } + else + { + USBD_GetString (USBD_PRODUCT_FS_STRING, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** +* @brief USBD_USR_ManufacturerStrDescriptor +* return the manufacturer string descriptor +* @param speed : current device speed +* @param length : pointer to data length variable +* @retval pointer to descriptor buffer +*/ +uint8_t * USBD_USR_ManufacturerStrDescriptor( uint8_t speed , uint16_t *length) +{ + USBD_GetString (USBD_MANUFACTURER_STRING, USBD_StrDesc, length); + return USBD_StrDesc; +} + +/** +* @brief USBD_USR_SerialStrDescriptor +* return the serial number string descriptor +* @param speed : current device speed +* @param length : pointer to data length variable +* @retval pointer to descriptor buffer +*/ +uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length) +{ + if(speed == USB_OTG_SPEED_HIGH) + { + USBD_GetString (USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length); + } + else + { + USBD_GetString (USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** +* @brief USBD_USR_ConfigStrDescriptor +* return the configuration string descriptor +* @param speed : current device speed +* @param length : pointer to data length variable +* @retval pointer to descriptor buffer +*/ +uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length) +{ + if(speed == USB_OTG_SPEED_HIGH) + { + USBD_GetString (USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length); + } + else + { + USBD_GetString (USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + + +/** +* @brief USBD_USR_InterfaceStrDescriptor +* return the interface string descriptor +* @param speed : current device speed +* @param length : pointer to data length variable +* @retval pointer to descriptor buffer +*/ +uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length) +{ + if(speed == 0) + { + USBD_GetString (USBD_INTERFACE_HS_STRING, USBD_StrDesc, length); + } + else + { + USBD_GetString (USBD_INTERFACE_FS_STRING, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_desc.h b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_desc.h index 4f818155..ed999dc6 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_desc.h +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_desc.h @@ -1,114 +1,114 @@ -/** - ****************************************************************************** - * @file usbd_desc.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief header file for the usbd_desc.c file - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USB_DESC_H -#define __USB_DESC_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USB_DESC - * @brief general defines for the usb device library file - * @{ - */ - -/** @defgroup USB_DESC_Exported_Defines - * @{ - */ -#define USB_DEVICE_DESCRIPTOR_TYPE 0x01 -#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02 -#define USB_STRING_DESCRIPTOR_TYPE 0x03 -#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04 -#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05 -#define USB_SIZ_DEVICE_DESC 18 -#define USB_SIZ_STRING_LANGID 4 - -/** - * @} - */ - - -/** @defgroup USBD_DESC_Exported_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_DESC_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_DESC_Exported_Variables - * @{ - */ -extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC]; -extern uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ]; -extern uint8_t USBD_OtherSpeedCfgDesc[USB_LEN_CFG_DESC]; -extern uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]; -extern uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID]; -extern USBD_DEVICE USR_desc; -/** - * @} - */ - -/** @defgroup USBD_DESC_Exported_FunctionsPrototype - * @{ - */ - - -uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_ManufacturerStrDescriptor ( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_ProductStrDescriptor ( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length); - -#ifdef USB_SUPPORT_USER_STRING_DESC -uint8_t * USBD_USR_USRStringDesc (uint8_t speed, uint8_t idx , uint16_t *length); -#endif /* USB_SUPPORT_USER_STRING_DESC */ - -/** - * @} - */ - -#endif /* __USBD_DESC_H */ - -/** - * @} - */ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file usbd_desc.h + * @author MCD Application Team + * @version V1.0.0 + * @date 19-September-2011 + * @brief header file for the usbd_desc.c file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __USB_DESC_H +#define __USB_DESC_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USB_DESC + * @brief general defines for the usb device library file + * @{ + */ + +/** @defgroup USB_DESC_Exported_Defines + * @{ + */ +#define USB_DEVICE_DESCRIPTOR_TYPE 0x01 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02 +#define USB_STRING_DESCRIPTOR_TYPE 0x03 +#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05 +#define USB_SIZ_DEVICE_DESC 18 +#define USB_SIZ_STRING_LANGID 4 + +/** + * @} + */ + + +/** @defgroup USBD_DESC_Exported_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_DESC_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_DESC_Exported_Variables + * @{ + */ +extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC]; +extern uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ]; +extern uint8_t USBD_OtherSpeedCfgDesc[USB_LEN_CFG_DESC]; +extern uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]; +extern uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID]; +extern USBD_DEVICE USR_desc; +/** + * @} + */ + +/** @defgroup USBD_DESC_Exported_FunctionsPrototype + * @{ + */ + + +uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length); +uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length); +uint8_t * USBD_USR_ManufacturerStrDescriptor ( uint8_t speed , uint16_t *length); +uint8_t * USBD_USR_ProductStrDescriptor ( uint8_t speed , uint16_t *length); +uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length); +uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length); +uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length); + +#ifdef USB_SUPPORT_USER_STRING_DESC +uint8_t * USBD_USR_USRStringDesc (uint8_t speed, uint8_t idx , uint16_t *length); +#endif /* USB_SUPPORT_USER_STRING_DESC */ + +/** + * @} + */ + +#endif /* __USBD_DESC_H */ + +/** + * @} + */ + +/** +* @} +*/ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_usr.c b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_usr.c index c2b09081..84e8d6a5 100644 --- a/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_usr.c +++ b/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_usr.c @@ -1,240 +1,240 @@ -/** - ****************************************************************************** - * @file usbd_usr.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file includes the user application layer - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_usr.h" -#include "usbd_ioreq.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY -* @{ -*/ - -/** @defgroup USBD_USR -* @brief This file includes the user application layer -* @{ -*/ - -/** @defgroup USBD_USR_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBD_USR_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBD_USR_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBD_USR_Private_Variables -* @{ -*/ - -USBD_Usr_cb_TypeDef USR_cb = -{ - USBD_USR_Init, - USBD_USR_DeviceReset, - USBD_USR_DeviceConfigured, - USBD_USR_DeviceSuspended, - USBD_USR_DeviceResumed, - - USBD_USR_DeviceConnected, - USBD_USR_DeviceDisconnected, - - -}; - - - -/** -* @} -*/ - -/** @defgroup USBD_USR_Private_Constants -* @{ -*/ - -/** -* @} -*/ - - - -/** @defgroup USBD_USR_Private_FunctionPrototypes -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBD_USR_Private_Functions -* @{ -*/ - -/** -* @brief USBD_USR_Init -* Displays the message on LCD for host lib initialization -* @param None -* @retval None -*/ -void USBD_USR_Init(void) -{ - /* Setup SysTick Timer for 40 msec interrupts - This interrupt is used to probe the joystick */ -#if 0 - if (SysTick_Config(SystemCoreClock / 24)) - { - /* Capture error */ - while (1); - } -#endif -} - -/** -* @brief USBD_USR_DeviceReset -* Displays the message on LCD on device Reset Event -* @param speed : device speed -* @retval None -*/ -void USBD_USR_DeviceReset(uint8_t speed ) -{ - switch (speed) - { - case USB_OTG_SPEED_HIGH: - break; - - case USB_OTG_SPEED_FULL: - break; - default: - break; - - } -} - - -/** -* @brief USBD_USR_DeviceConfigured -* Displays the message on LCD on device configuration Event -* @param None -* @retval Staus -*/ -void USBD_USR_DeviceConfigured (void) -{ -} - - -/** -* @brief USBD_USR_DeviceConnected -* Displays the message on LCD on device connection Event -* @param None -* @retval Staus -*/ -void USBD_USR_DeviceConnected (void) -{ -} - - -/** -* @brief USBD_USR_DeviceDisonnected -* Displays the message on LCD on device disconnection Event -* @param None -* @retval Staus -*/ -void USBD_USR_DeviceDisconnected (void) -{ -} - -/** -* @brief USBD_USR_DeviceSuspended -* Displays the message on LCD on device suspend Event -* @param None -* @retval None -*/ -void USBD_USR_DeviceSuspended(void) -{ - /* Users can do their application actions here for the USB-Reset */ -} - - -/** -* @brief USBD_USR_DeviceResumed -* Displays the message on LCD on device resume Event -* @param None -* @retval None -*/ -void USBD_USR_DeviceResumed(void) -{ - /* Users can do their application actions here for the USB-Reset */ -} - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/** + ****************************************************************************** + * @file usbd_usr.c + * @author MCD Application Team + * @version V1.0.0 + * @date 19-September-2011 + * @brief This file includes the user application layer + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_usr.h" +#include "usbd_ioreq.h" + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY +* @{ +*/ + +/** @defgroup USBD_USR +* @brief This file includes the user application layer +* @{ +*/ + +/** @defgroup USBD_USR_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBD_USR_Private_Defines +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBD_USR_Private_Macros +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBD_USR_Private_Variables +* @{ +*/ + +USBD_Usr_cb_TypeDef USR_cb = +{ + USBD_USR_Init, + USBD_USR_DeviceReset, + USBD_USR_DeviceConfigured, + USBD_USR_DeviceSuspended, + USBD_USR_DeviceResumed, + + USBD_USR_DeviceConnected, + USBD_USR_DeviceDisconnected, + + +}; + + + +/** +* @} +*/ + +/** @defgroup USBD_USR_Private_Constants +* @{ +*/ + +/** +* @} +*/ + + + +/** @defgroup USBD_USR_Private_FunctionPrototypes +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBD_USR_Private_Functions +* @{ +*/ + +/** +* @brief USBD_USR_Init +* Displays the message on LCD for host lib initialization +* @param None +* @retval None +*/ +void USBD_USR_Init(void) +{ + /* Setup SysTick Timer for 40 msec interrupts + This interrupt is used to probe the joystick */ +#if 0 + if (SysTick_Config(SystemCoreClock / 24)) + { + /* Capture error */ + while (1); + } +#endif +} + +/** +* @brief USBD_USR_DeviceReset +* Displays the message on LCD on device Reset Event +* @param speed : device speed +* @retval None +*/ +void USBD_USR_DeviceReset(uint8_t speed ) +{ + switch (speed) + { + case USB_OTG_SPEED_HIGH: + break; + + case USB_OTG_SPEED_FULL: + break; + default: + break; + + } +} + + +/** +* @brief USBD_USR_DeviceConfigured +* Displays the message on LCD on device configuration Event +* @param None +* @retval Staus +*/ +void USBD_USR_DeviceConfigured (void) +{ +} + + +/** +* @brief USBD_USR_DeviceConnected +* Displays the message on LCD on device connection Event +* @param None +* @retval Staus +*/ +void USBD_USR_DeviceConnected (void) +{ +} + + +/** +* @brief USBD_USR_DeviceDisonnected +* Displays the message on LCD on device disconnection Event +* @param None +* @retval Staus +*/ +void USBD_USR_DeviceDisconnected (void) +{ +} + +/** +* @brief USBD_USR_DeviceSuspended +* Displays the message on LCD on device suspend Event +* @param None +* @retval None +*/ +void USBD_USR_DeviceSuspended(void) +{ + /* Users can do their application actions here for the USB-Reset */ +} + + +/** +* @brief USBD_USR_DeviceResumed +* Displays the message on LCD on device resume Event +* @param None +* @retval None +*/ +void USBD_USR_DeviceResumed(void) +{ + /* Users can do their application actions here for the USB-Reset */ +} + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Libmaple/libmaple/libmaple/usbF4/usb.c b/Libmaple/libmaple/libmaple/usbF4/usb.c index 28922bd6..2c0672f6 100644 --- a/Libmaple/libmaple/libmaple/usbF4/usb.c +++ b/Libmaple/libmaple/libmaple/usbF4/usb.c @@ -1,104 +1,104 @@ -#include "usbd_cdc_core.h" -#include "usbd_usr.h" -#include "usbd_desc.h" -#include "usb.h" -#include -#include -#include - -USB_OTG_CORE_HANDLE USB_OTG_dev; - - - -void setupUSB (void) { - #define USB_DISC_DEV GPIOD - #define USB_DISC_PIN 11 - - gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42 -#ifdef USB_DISC_OD - //gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42 -#else - //gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_PP); // ala42 for active pull-up on disconnect pin -#endif - - gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN,0); // ala42 - delay_us(200000); - - /* setup the apb1 clock for USB */ - //rcc_reg_map *pRCC = RCC_BASE; - //pRCC->APB1ENR |= RCC_APB1ENR_USBEN; - - /* initialize the usb application */ - gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 1); // ala42 // presents us to the host - USBD_Init(&USB_OTG_dev, - USB_OTG_FS_CORE_ID, - &USR_desc, - &USBD_CDC_cb, - &USR_cb); -} - -extern uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len); -extern void VCP_SetUSBTxBlocking(uint8_t mode); -extern uint32_t VCPBytesAvailable(void); -extern uint8_t VCPGetByte(void); - -uint32_t usbSendBytes(const uint8_t* sendBuf, uint32_t len) { - VCP_DataTx((uint8_t*)sendBuf, len); - return len; -} - -void usbEnableBlockingTx(void) { - VCP_SetUSBTxBlocking(1); -} - -void usbDisableBlockingTx(void) { - VCP_SetUSBTxBlocking(0); -} - - -uint32_t usbBytesAvailable(void) { - return VCPBytesAvailable(); - -} -uint32_t usbReceiveBytes(uint8_t* recvBuf, uint32_t len) { - int newBytes = usbBytesAvailable(); - if (len > newBytes) { - len = newBytes; - } - - int i; - for (i=0;i +#include +#include + +USB_OTG_CORE_HANDLE USB_OTG_dev; + + + +void setupUSB (void) { + #define USB_DISC_DEV GPIOD + #define USB_DISC_PIN 11 + + gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42 +#ifdef USB_DISC_OD + //gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42 +#else + //gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_PP); // ala42 for active pull-up on disconnect pin +#endif + + gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN,0); // ala42 + delay_us(200000); + + /* setup the apb1 clock for USB */ + //rcc_reg_map *pRCC = RCC_BASE; + //pRCC->APB1ENR |= RCC_APB1ENR_USBEN; + + /* initialize the usb application */ + gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 1); // ala42 // presents us to the host + USBD_Init(&USB_OTG_dev, + USB_OTG_FS_CORE_ID, + &USR_desc, + &USBD_CDC_cb, + &USR_cb); +} + +extern uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len); +extern void VCP_SetUSBTxBlocking(uint8_t mode); +extern uint32_t VCPBytesAvailable(void); +extern uint8_t VCPGetByte(void); + +uint32_t usbSendBytes(const uint8_t* sendBuf, uint32_t len) { + VCP_DataTx((uint8_t*)sendBuf, len); + return len; +} + +void usbEnableBlockingTx(void) { + VCP_SetUSBTxBlocking(1); +} + +void usbDisableBlockingTx(void) { + VCP_SetUSBTxBlocking(0); +} + + +uint32_t usbBytesAvailable(void) { + return VCPBytesAvailable(); + +} +uint32_t usbReceiveBytes(uint8_t* recvBuf, uint32_t len) { + int newBytes = usbBytesAvailable(); + if (len > newBytes) { + len = newBytes; + } + + int i; + for (i=0;i> ((31 - (n)) + (m))) -/** True if v is a power of two (1, 2, 4, 8, ...) */ -#define IS_POWER_OF_TWO(v) ((v) && !((v) & ((v) - 1))) - -/* - * Failure routines - */ - -void __error(int num); -void _fail(const char*, int, const char*); -void throb(void); - -/* - * Asserts and debug levels - */ - -#define DEBUG_NONE 0 -#define DEBUG_FAULT 1 -#define DEBUG_ALL 2 - -/** - * \def DEBUG_LEVEL - * - * Controls the level of assertion checking. - * - * The higher the debug level, the more assertions will be compiled - * in. This increases the amount of debugging information, but slows - * down (and increases the size of) the binary. - * - * The debug levels, from lowest to highest, are DEBUG_NONE, - * DEBUG_FAULT, and DEBUG_ALL. The default level is DEBUG_ALL. - */ - -#ifndef DEBUG_LEVEL -#define DEBUG_LEVEL DEBUG_ALL -#endif - -#if DEBUG_LEVEL >= DEBUG_ALL -#define ASSERT(exp) \ - if (exp) { \ - } else { \ - _fail(__FILE__, __LINE__, #exp); \ - } -#else -#define ASSERT(exp) (void)((0)) -#endif - -#if DEBUG_LEVEL >= DEBUG_FAULT -#define ASSERT_FAULT(exp) \ - if (exp) { \ - } else { \ - _fail(__FILE__, __LINE__, #exp); \ - } -#else -#define ASSERT_FAULT(exp) (void)((0)) -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file util.h + * @brief Miscellaneous utility macros and procedures. + */ + +#include "libmaple_types.h" + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * Bit manipulation + */ + +/** 1 << the bit number */ +#define BIT(shift) (1UL << (shift)) +/** Mask shifted left by 'shift' */ +#define BIT_MASK_SHIFT(mask, shift) ((mask) << (shift)) +/** Bits m to n of x */ +#define GET_BITS(x, m, n) ((((uint32)x) << (31 - (n))) >> ((31 - (n)) + (m))) +/** True if v is a power of two (1, 2, 4, 8, ...) */ +#define IS_POWER_OF_TWO(v) ((v) && !((v) & ((v) - 1))) + +/* + * Failure routines + */ + +void __error(int num); +void _fail(const char*, int, const char*); +void throb(void); + +/* + * Asserts and debug levels + */ + +#define DEBUG_NONE 0 +#define DEBUG_FAULT 1 +#define DEBUG_ALL 2 + +/** + * \def DEBUG_LEVEL + * + * Controls the level of assertion checking. + * + * The higher the debug level, the more assertions will be compiled + * in. This increases the amount of debugging information, but slows + * down (and increases the size of) the binary. + * + * The debug levels, from lowest to highest, are DEBUG_NONE, + * DEBUG_FAULT, and DEBUG_ALL. The default level is DEBUG_ALL. + */ + +#ifndef DEBUG_LEVEL +#define DEBUG_LEVEL DEBUG_ALL +#endif + +#if DEBUG_LEVEL >= DEBUG_ALL +#define ASSERT(exp) \ + if (exp) { \ + } else { \ + _fail(__FILE__, __LINE__, #exp); \ + } +#else +#define ASSERT(exp) (void)((0)) +#endif + +#if DEBUG_LEVEL >= DEBUG_FAULT +#define ASSERT_FAULT(exp) \ + if (exp) { \ + } else { \ + _fail(__FILE__, __LINE__, #exp); \ + } +#else +#define ASSERT_FAULT(exp) (void)((0)) +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/Libmaple/libmaple/libraries/FreeRTOS/MapleFreeRTOS.cpp b/Libmaple/libmaple/libraries/FreeRTOS/MapleFreeRTOS.cpp index 2d8bcb55..d235ceb5 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/MapleFreeRTOS.cpp +++ b/Libmaple/libmaple/libraries/FreeRTOS/MapleFreeRTOS.cpp @@ -1,44 +1,44 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include "MapleFreeRTOS.h" - -extern "C" { - -void vApplicationStackOverflowHook(xTaskHandle *pxTask, - signed char *pcTaskName) { - /* This function will get called if a task overflows its stack. - * If the parameters are corrupt then inspect pxCurrentTCB to find - * which was the offending task. */ - - (void) pxTask; - (void) pcTaskName; - - while (1) - ; -} - -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +#include "MapleFreeRTOS.h" + +extern "C" { + +void vApplicationStackOverflowHook(xTaskHandle *pxTask, + signed char *pcTaskName) { + /* This function will get called if a task overflows its stack. + * If the parameters are corrupt then inspect pxCurrentTCB to find + * which was the offending task. */ + + (void) pxTask; + (void) pcTaskName; + + while (1) + ; +} + +} diff --git a/Libmaple/libmaple/libraries/FreeRTOS/MapleFreeRTOS.h b/Libmaple/libmaple/libraries/FreeRTOS/MapleFreeRTOS.h index 4874ea36..839e3e28 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/MapleFreeRTOS.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/MapleFreeRTOS.h @@ -1,40 +1,40 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#ifndef __MAPLE_FREERTOS_H__ -#define __MAPLE_FREERTOS_H__ - -#include "wirish.h" - -extern "C" { -#define GCC_ARMCM3 -#include "utility/FreeRTOS.h" -#include "utility/task.h" -#include "utility/queue.h" -#include "utility/semphr.h" -} - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +#ifndef __MAPLE_FREERTOS_H__ +#define __MAPLE_FREERTOS_H__ + +#include "wirish.h" + +extern "C" { +#define GCC_ARMCM3 +#include "utility/FreeRTOS.h" +#include "utility/task.h" +#include "utility/queue.h" +#include "utility/semphr.h" +} + +#endif diff --git a/Libmaple/libmaple/libraries/FreeRTOS/keywords.txt b/Libmaple/libmaple/libraries/FreeRTOS/keywords.txt index dff12f33..4a20baee 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/keywords.txt +++ b/Libmaple/libmaple/libraries/FreeRTOS/keywords.txt @@ -1,27 +1,27 @@ -####################################### -# Syntax Coloring Map For CoOS -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -####################################### -# Methods and Functions (KEYWORD2) -####################################### -vTaskDelay KEYWORD2 -vTaskDelayUntil KEYWORD2 -xTaskCreate KEYWORD2 -vTaskSuspend KEYWORD2 -vTaskDelete KEYWORD2 -vTaskPrioritySet KEYWORD2 -uxTaskPriorityGet KEYWORD2 -vTaskStartScheduler KEYWORD2 -vApplicationIdleHook KEYWORD2 - -####################################### -# Constants (LITERAL1) -####################################### -configUSE_IDLE_HOOK LITERAL1 -configMINIMAL_STACK_SIZE LITERAL1 +####################################### +# Syntax Coloring Map For CoOS +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +vTaskDelay KEYWORD2 +vTaskDelayUntil KEYWORD2 +xTaskCreate KEYWORD2 +vTaskSuspend KEYWORD2 +vTaskDelete KEYWORD2 +vTaskPrioritySet KEYWORD2 +uxTaskPriorityGet KEYWORD2 +vTaskStartScheduler KEYWORD2 +vApplicationIdleHook KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +configUSE_IDLE_HOOK LITERAL1 +configMINIMAL_STACK_SIZE LITERAL1 tskIDLE_PRIORITY LITERAL1 \ No newline at end of file diff --git a/Libmaple/libmaple/libraries/FreeRTOS/rules.mk b/Libmaple/libmaple/libraries/FreeRTOS/rules.mk index fbfece74..2b415ba9 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/rules.mk +++ b/Libmaple/libmaple/libraries/FreeRTOS/rules.mk @@ -1,38 +1,38 @@ -# Standard things -sp := $(sp).x -dirstack_$(sp) := $(d) -d := $(dir) -BUILDDIRS += $(BUILD_PATH)/$(d) -BUILDDIRS += $(BUILD_PATH)/$(d)/utility - -# Local flags -CXXFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) -CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) - -# Local rules and targets -cSRCS_$(d) := utility/croutine.c \ - utility/heap_2.c \ - utility/list.c \ - utility/port.c \ - utility/queue.c \ - utility/timers.c \ - utility/tasks.c \ - -cppSRCS_$(d) := MapleFreeRTOS.cpp - -cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) -cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) - -OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ - $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) -DEPS_$(d) := $(OBJS_$(d):%.o=%.d) - -$(OBJS_$(d)): TGT_CXXFLAGS := $(CXXFLAGS_$(d)) -$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) - -TGT_BIN += $(OBJS_$(d)) - -# Standard things --include $(DEPS_$(d)) -d := $(dirstack_$(sp)) +# Standard things +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) +BUILDDIRS += $(BUILD_PATH)/$(d) +BUILDDIRS += $(BUILD_PATH)/$(d)/utility + +# Local flags +CXXFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) +CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) + +# Local rules and targets +cSRCS_$(d) := utility/croutine.c \ + utility/heap_2.c \ + utility/list.c \ + utility/port.c \ + utility/queue.c \ + utility/timers.c \ + utility/tasks.c \ + +cppSRCS_$(d) := MapleFreeRTOS.cpp + +cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) + +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ + $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) +DEPS_$(d) := $(OBJS_$(d):%.o=%.d) + +$(OBJS_$(d)): TGT_CXXFLAGS := $(CXXFLAGS_$(d)) +$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) + +TGT_BIN += $(OBJS_$(d)) + +# Standard things +-include $(DEPS_$(d)) +d := $(dirstack_$(sp)) sp := $(basename $(sp)) \ No newline at end of file diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/FreeRTOS.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/FreeRTOS.h index e5eb39ab..a609bb32 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/FreeRTOS.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/FreeRTOS.h @@ -1,468 +1,468 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 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_TIMERS - #define configUSE_TIMERS 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 - #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h -#endif - -#ifndef INCLUDE_xTaskResumeFromISR - #define INCLUDE_xTaskResumeFromISR 1 -#endif - -#ifndef configASSERT - #define configASSERT( x ) -#endif - -/* The timers module relies on xTaskGetSchedulerState(). */ -#if configUSE_TIMERS == 1 - - #ifndef configTIMER_TASK_PRIORITY - #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. - #endif /* configTIMER_TASK_PRIORITY */ - - #ifndef configTIMER_QUEUE_LENGTH - #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. - #endif /* configTIMER_QUEUE_LENGTH */ - - #ifndef configTIMER_TASK_STACK_DEPTH - #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. - #endif /* configTIMER_TASK_STACK_DEPTH */ - -#endif /* configUSE_TIMERS */ - -#ifndef INCLUDE_xTaskGetSchedulerState - #define INCLUDE_xTaskGetSchedulerState 0 -#endif - -#ifndef INCLUDE_xTaskGetCurrentTaskHandle - #define INCLUDE_xTaskGetCurrentTaskHandle 0 -#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 0U -#endif - -#if ( configQUEUE_REGISTRY_SIZE < 1U ) - #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 traceTAKE_MUTEX_RECURSIVE_FAILED - #define traceTAKE_MUTEX_RECURSIVE_FAILED( 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() -#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 traceTIMER_CREATE - #define traceTIMER_CREATE( pxNewTimer ) -#endif - -#ifndef traceTIMER_CREATE_FAILED - #define traceTIMER_CREATE_FAILED() -#endif - -#ifndef traceTIMER_COMMAND_SEND - #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) -#endif - -#ifndef traceTIMER_EXPIRED - #define traceTIMER_EXPIRED( pxTimer ) -#endif - -#ifndef traceTIMER_COMMAND_RECEIVED - #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) -#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 - #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE - #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. - #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ - #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 /* INC_FREERTOS_H */ - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 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_TIMERS + #define configUSE_TIMERS 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 + #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef configASSERT + #define configASSERT( x ) +#endif + +/* The timers module relies on xTaskGetSchedulerState(). */ +#if configUSE_TIMERS == 1 + + #ifndef configTIMER_TASK_PRIORITY + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. + #endif /* configTIMER_TASK_PRIORITY */ + + #ifndef configTIMER_QUEUE_LENGTH + #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. + #endif /* configTIMER_QUEUE_LENGTH */ + + #ifndef configTIMER_TASK_STACK_DEPTH + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. + #endif /* configTIMER_TASK_STACK_DEPTH */ + +#endif /* configUSE_TIMERS */ + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 0 +#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 0U +#endif + +#if ( configQUEUE_REGISTRY_SIZE < 1U ) + #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 traceTAKE_MUTEX_RECURSIVE_FAILED + #define traceTAKE_MUTEX_RECURSIVE_FAILED( 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() +#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 traceTIMER_CREATE + #define traceTIMER_CREATE( pxNewTimer ) +#endif + +#ifndef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() +#endif + +#ifndef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) +#endif + +#ifndef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( pxTimer ) +#endif + +#ifndef traceTIMER_COMMAND_RECEIVED + #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) +#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 + #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. + #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ + #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 /* INC_FREERTOS_H */ + diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/FreeRTOSConfig.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/FreeRTOSConfig.h index ca8e1d91..3f451a1d 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/FreeRTOSConfig.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/FreeRTOSConfig.h @@ -1,126 +1,126 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_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. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ - -#define configUSE_PREEMPTION 1 -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 0 -#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 ) -#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) -#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) -#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) -#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 8 * 1024 ) ) -#define configMAX_TASK_NAME_LEN ( 16 ) -#define configUSE_TRACE_FACILITY 1 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 - -/* Co-routine definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) - -#define configUSE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configUSE_ALTERNATIVE_API 0 -#define configCHECK_FOR_STACK_OVERFLOW 2 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configQUEUE_REGISTRY_SIZE 0 -#define configGENERATE_RUN_TIME_STATS 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 - -/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 -(lowest) to 0 (1?) (highest). */ -#define configKERNEL_INTERRUPT_PRIORITY 255 -#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */ - - -/* This is the value being used as per the ST library which permits 16 -priority values, 0 to 15. This must correspond to the -configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest -NVIC value of 255. */ -#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 - -/*----------------------------------------------------------- - * UART configuration. - *-----------------------------------------------------------*/ -#define configCOM0_RX_BUFFER_LENGTH 128 -#define configCOM0_TX_BUFFER_LENGTH 128 -#define configCOM1_RX_BUFFER_LENGTH 128 -#define configCOM1_TX_BUFFER_LENGTH 128 - -#endif /* FREERTOS_CONFIG_H */ - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_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. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 8 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +#define configUSE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 0 +#define configGENERATE_RUN_TIME_STATS 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 + +/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 +(lowest) to 0 (1?) (highest). */ +#define configKERNEL_INTERRUPT_PRIORITY 255 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */ + + +/* This is the value being used as per the ST library which permits 16 +priority values, 0 to 15. This must correspond to the +configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest +NVIC value of 255. */ +#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 + +/*----------------------------------------------------------- + * UART configuration. + *-----------------------------------------------------------*/ +#define configCOM0_RX_BUFFER_LENGTH 128 +#define configCOM0_TX_BUFFER_LENGTH 128 +#define configCOM1_RX_BUFFER_LENGTH 128 +#define configCOM1_TX_BUFFER_LENGTH 128 + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/StackMacros.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/StackMacros.h index 1114b6d2..547a58cf 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/StackMacros.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/StackMacros.h @@ -1,174 +1,174 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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() \ - { \ - /* 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() \ - { \ - \ - /* 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() \ - { \ - 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() \ - { \ - 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 */ - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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() \ + { \ + /* 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() \ + { \ + \ + /* 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() \ + { \ + 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() \ + { \ + 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/Libmaple/libmaple/libraries/FreeRTOS/utility/croutine.c b/Libmaple/libmaple/libraries/FreeRTOS/utility/croutine.c index 58fb1bf4..fe567306 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/croutine.c +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/croutine.c @@ -1,380 +1,380 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" -#include "task.h" -#include "croutine.h" - -/* - * Some kernel aware debuggers require data to be viewed to be global, rather - * than file scope. - */ -#ifdef portREMOVE_STATIC_QUALIFIER - #define static -#endif - - -/* Lists for ready and blocked co-routines. --------------------*/ -static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ -static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */ -static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ -static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ -static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ -static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ - -/* Other file private variables. --------------------------------*/ -corCRCB * pxCurrentCoRoutine = NULL; -static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0; -static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; - -/* The initial state of the co-routine when it is created. */ -#define corINITIAL_STATE ( 0 ) - -/* - * Place the co-routine represented by pxCRCB into the appropriate ready queue - * for the priority. It is inserted at the end of the list. - * - * This macro accesses the co-routine ready lists and therefore must not be - * used from within an ISR. - */ -#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ -{ \ - if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ - { \ - uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ - } \ - vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ -} - -/* - * Utility to ready all the lists used by the scheduler. This is called - * automatically upon the creation of the first co-routine. - */ -static void prvInitialiseCoRoutineLists( void ); - -/* - * Co-routines that are readied by an interrupt cannot be placed directly into - * the ready lists (there is no mutual exclusion). Instead they are placed in - * in the pending ready list in order that they can later be moved to the ready - * list by the co-routine scheduler. - */ -static void prvCheckPendingReadyList( void ); - -/* - * Macro that looks at the list of co-routines that are currently delayed to - * see if any require waking. - * - * Co-routines are stored in the queue in the order of their wake time - - * meaning once one co-routine has been found whose timer has not expired - * we need not look any further down the list. - */ -static void prvCheckDelayedList( void ); - -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ) -{ -signed portBASE_TYPE xReturn; -corCRCB *pxCoRoutine; - - /* Allocate the memory that will store the co-routine control block. */ - pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) ); - if( pxCoRoutine ) - { - /* If pxCurrentCoRoutine is NULL then this is the first co-routine to - be created and the co-routine data structures need initialising. */ - if( pxCurrentCoRoutine == NULL ) - { - pxCurrentCoRoutine = pxCoRoutine; - prvInitialiseCoRoutineLists(); - } - - /* Check the priority is within limits. */ - if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) - { - uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; - } - - /* Fill out the co-routine control block from the function parameters. */ - pxCoRoutine->uxState = corINITIAL_STATE; - pxCoRoutine->uxPriority = uxPriority; - pxCoRoutine->uxIndex = uxIndex; - pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; - - /* Initialise all the other co-routine control block parameters. */ - vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); - vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); - - /* Set the co-routine control block as a link back from the xListItem. - This is so we can get back to the containing CRCB from a generic item - in a list. */ - listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); - listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); - - /* Event lists are always in priority order. */ - listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); - - /* Now the co-routine has been initialised it can be added to the ready - list at the correct priority. */ - prvAddCoRoutineToReadyQueue( pxCoRoutine ); - - xReturn = pdPASS; - } - else - { - xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ) -{ -portTickType xTimeToWake; - - /* Calculate the time to wake - this may overflow but this is - not a problem. */ - xTimeToWake = xCoRoutineTickCount + 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 * ) &( pxCurrentCoRoutine->xGenericListItem ) ); - - /* The list item will be inserted in wake time order. */ - listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); - - if( xTimeToWake < xCoRoutineTickCount ) - { - /* Wake time has overflowed. Place this item in the - overflow list. */ - vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); - } - else - { - /* The wake time has not overflowed, so we can use the - current block list. */ - vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); - } - - if( pxEventList ) - { - /* Also add the co-routine to an event list. If this is done then the - function must be called with interrupts disabled. */ - vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); - } -} -/*-----------------------------------------------------------*/ - -static void prvCheckPendingReadyList( void ) -{ - /* Are there any co-routines waiting to get moved to the ready list? These - are co-routines that have been readied by an ISR. The ISR cannot access - the ready lists itself. */ - while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) - { - corCRCB *pxUnblockedCRCB; - - /* The pending ready list can be accessed by an ISR. */ - portDISABLE_INTERRUPTS(); - { - pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); - vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); - } - portENABLE_INTERRUPTS(); - - vListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); - prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); - } -} -/*-----------------------------------------------------------*/ - -static void prvCheckDelayedList( void ) -{ -corCRCB *pxCRCB; - - xPassedTicks = xTaskGetTickCount() - xLastTickCount; - while( xPassedTicks ) - { - xCoRoutineTickCount++; - xPassedTicks--; - - /* If the tick count has overflowed we need to swap the ready lists. */ - if( xCoRoutineTickCount == 0 ) - { - xList * pxTemp; - - /* Tick count has overflowed so we need to swap the delay lists. If there are - any items in pxDelayedCoRoutineList here then there is an error! */ - pxTemp = pxDelayedCoRoutineList; - pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; - pxOverflowDelayedCoRoutineList = pxTemp; - } - - /* See if this tick has made a timeout expire. */ - while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) - { - pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); - - if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) - { - /* Timeout not yet expired. */ - break; - } - - portDISABLE_INTERRUPTS(); - { - /* The event could have occurred just before this critical - section. If this is the case then the generic list item will - have been moved to the pending ready list and the following - line is still valid. Also the pvContainer parameter will have - been set to NULL so the following lines are also valid. */ - vListRemove( &( pxCRCB->xGenericListItem ) ); - - /* Is the co-routine waiting on an event also? */ - if( pxCRCB->xEventListItem.pvContainer ) - { - vListRemove( &( pxCRCB->xEventListItem ) ); - } - } - portENABLE_INTERRUPTS(); - - prvAddCoRoutineToReadyQueue( pxCRCB ); - } - } - - xLastTickCount = xCoRoutineTickCount; -} -/*-----------------------------------------------------------*/ - -void vCoRoutineSchedule( void ) -{ - /* See if any co-routines readied by events need moving to the ready lists. */ - prvCheckPendingReadyList(); - - /* See if any delayed co-routines have timed out. */ - prvCheckDelayedList(); - - /* Find the highest priority queue that contains ready co-routines. */ - while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) - { - if( uxTopCoRoutineReadyPriority == 0 ) - { - /* No more co-routines to check. */ - return; - } - --uxTopCoRoutineReadyPriority; - } - - /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines - of the same priority get an equal share of the processor time. */ - listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); - - /* Call the co-routine. */ - ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); - - return; -} -/*-----------------------------------------------------------*/ - -static void prvInitialiseCoRoutineLists( void ) -{ -unsigned portBASE_TYPE uxPriority; - - for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) - { - vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); - } - - vListInitialise( ( xList * ) &xDelayedCoRoutineList1 ); - vListInitialise( ( xList * ) &xDelayedCoRoutineList2 ); - vListInitialise( ( xList * ) &xPendingReadyCoRoutineList ); - - /* Start with pxDelayedCoRoutineList using list1 and the - pxOverflowDelayedCoRoutineList using list2. */ - pxDelayedCoRoutineList = &xDelayedCoRoutineList1; - pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; -} -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ) -{ -corCRCB *pxUnblockedCRCB; -signed portBASE_TYPE xReturn; - - /* This function is called from within an interrupt. It can only access - event lists and the pending ready list. This function assumes that a - check has already been made to ensure pxEventList is not empty. */ - pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); - vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); - vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); - - if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) - { - xReturn = pdTRUE; - } - else - { - xReturn = pdFALSE; - } - - return xReturn; -} - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + + +/* Lists for ready and blocked co-routines. --------------------*/ +static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ +static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */ +static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ +static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ +static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ +static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ + +/* Other file private variables. --------------------------------*/ +corCRCB * pxCurrentCoRoutine = NULL; +static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0; +static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + +/* The initial state of the co-routine when it is created. */ +#define corINITIAL_STATE ( 0 ) + +/* + * Place the co-routine represented by pxCRCB into the appropriate ready queue + * for the priority. It is inserted at the end of the list. + * + * This macro accesses the co-routine ready lists and therefore must not be + * used from within an ISR. + */ +#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ +{ \ + if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ + { \ + uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ + } \ + vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ +} + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first co-routine. + */ +static void prvInitialiseCoRoutineLists( void ); + +/* + * Co-routines that are readied by an interrupt cannot be placed directly into + * the ready lists (there is no mutual exclusion). Instead they are placed in + * in the pending ready list in order that they can later be moved to the ready + * list by the co-routine scheduler. + */ +static void prvCheckPendingReadyList( void ); + +/* + * Macro that looks at the list of co-routines that are currently delayed to + * see if any require waking. + * + * Co-routines are stored in the queue in the order of their wake time - + * meaning once one co-routine has been found whose timer has not expired + * we need not look any further down the list. + */ +static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ) +{ +signed portBASE_TYPE xReturn; +corCRCB *pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) ); + if( pxCoRoutine ) + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + { + pxCurrentCoRoutine = pxCoRoutine; + prvInitialiseCoRoutineLists(); + } + + /* Check the priority is within limits. */ + if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + pxCoRoutine->uxPriority = uxPriority; + pxCoRoutine->uxIndex = uxIndex; + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + + /* Set the co-routine control block as a link back from the xListItem. + This is so we can get back to the containing CRCB from a generic item + in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); + + /* Now the co-routine has been initialised it can be added to the ready + list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ) +{ +portTickType xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xCoRoutineTickCount + 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 * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xCoRoutineTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckPendingReadyList( void ) +{ + /* Are there any co-routines waiting to get moved to the ready list? These + are co-routines that have been readied by an ISR. The ISR cannot access + the ready lists itself. */ + while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) + { + corCRCB *pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + { + pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); + vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + vListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckDelayedList( void ) +{ +corCRCB *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + while( xPassedTicks ) + { + xCoRoutineTickCount++; + xPassedTicks--; + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + { + xList * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) + { + pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); + + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + { + /* The event could have occurred just before this critical + section. If this is the case then the generic list item will + have been moved to the pending ready list and the following + line is still valid. Also the pvContainer parameter will have + been set to NULL so the following lines are also valid. */ + vListRemove( &( pxCRCB->xGenericListItem ) ); + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pvContainer ) + { + vListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineSchedule( void ) +{ + /* See if any co-routines readied by events need moving to the ready lists. */ + prvCheckPendingReadyList(); + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + { + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + --uxTopCoRoutineReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + + return; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseCoRoutineLists( void ) +{ +unsigned portBASE_TYPE uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + } + + vListInitialise( ( xList * ) &xDelayedCoRoutineList1 ); + vListInitialise( ( xList * ) &xDelayedCoRoutineList2 ); + vListInitialise( ( xList * ) &xPendingReadyCoRoutineList ); + + /* Start with pxDelayedCoRoutineList using list1 and the + pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ) +{ +corCRCB *pxUnblockedCRCB; +signed portBASE_TYPE xReturn; + + /* This function is called from within an interrupt. It can only access + event lists and the pending ready list. This function assumes that a + check has already been made to ensure pxEventList is not empty. */ + pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} + diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/croutine.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/croutine.h index 65fdc48e..6801c410 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/croutine.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/croutine.h @@ -1,752 +1,752 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 CO_ROUTINE_H -#define CO_ROUTINE_H - -#ifndef INC_FREERTOS_H - #error "include FreeRTOS.h must appear in source files before include croutine.h" -#endif - -#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 */ +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#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/Libmaple/libmaple/libraries/FreeRTOS/utility/heap_2.c b/Libmaple/libmaple/libraries/FreeRTOS/utility/heap_2.c index 1d1c76a6..d135d8f7 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/heap_2.c +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/heap_2.c @@ -1,278 +1,278 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" -#include "task.h" - -#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. */ -} +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" +#include "task.h" + +#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. */ +} diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/list.c b/Libmaple/libmaple/libraries/FreeRTOS/utility/list.c index c3ef2a89..872b7dd0 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/list.c +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/list.c @@ -1,197 +1,197 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" -#include "list.h" - -/*----------------------------------------------------------- - * 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 = ( unsigned portBASE_TYPE ) 0U; -} -/*-----------------------------------------------------------*/ - -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 )--; -} -/*-----------------------------------------------------------*/ - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" +#include "list.h" + +/*----------------------------------------------------------- + * 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 = ( unsigned portBASE_TYPE ) 0U; +} +/*-----------------------------------------------------------*/ + +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 )--; +} +/*-----------------------------------------------------------*/ + diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/list.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/list.h index e8b47c43..01e69cbd 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/list.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/list.h @@ -1,314 +1,314 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 - */ - - -#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 the retrieve the value of the list item at the head of a given - * list. - * - * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE - * \ingroup LinkedList - */ -#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->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 )->xListEnd ))->pxNext->pvOwner ) - -/* - * 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 - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 + */ + + +#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 the retrieve the value of the list item at the head of a given + * list. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->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 )->xListEnd ))->pxNext->pvOwner ) + +/* + * 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/Libmaple/libmaple/libraries/FreeRTOS/utility/mpu_wrappers.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/mpu_wrappers.h index b7371b9b..a0c27234 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/mpu_wrappers.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/mpu_wrappers.h @@ -1,141 +1,141 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 */ - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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/Libmaple/libmaple/libraries/FreeRTOS/utility/port.c b/Libmaple/libmaple/libraries/FreeRTOS/utility/port.c index 34ab6ed3..dc01720f 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/port.c +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/port.c @@ -1,292 +1,292 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" -#include "task.h" - -/* 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 )); - -/* - * 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; -} -/*-----------------------------------------------------------*/ - -// !!! Maple -// void vPortSVCHandler( void ) -void __exc_svc( void ) -// !!! Maple -{ - __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. */ - " cpsie i \n" /* Globally enable interrupts. */ - " svc 0 \n" /* System call to start first task. */ - " nop \n" - ); -} -/*-----------------------------------------------------------*/ - -/* - * 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; - -// !!! Maple - systick_attach_callback(&xPortSysTickHandler); -// /* Start the timer that generates the tick ISR. Interrupts are disabled -// here already. */ -// prvSetupTimerInterrupt(); -// !!! Maple - - /* 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(); - } -} -/*-----------------------------------------------------------*/ - -// !!! Maple -// void xPortPendSVHandler( void ) -void __exc_pendsv( void ) -// !!! Maple -{ - /* 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; -} -/*-----------------------------------------------------------*/ - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" +#include "task.h" + +/* 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 )); + +/* + * 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; +} +/*-----------------------------------------------------------*/ + +// !!! Maple +// void vPortSVCHandler( void ) +void __exc_svc( void ) +// !!! Maple +{ + __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. */ + " cpsie i \n" /* Globally enable interrupts. */ + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * 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; + +// !!! Maple + systick_attach_callback(&xPortSysTickHandler); +// /* Start the timer that generates the tick ISR. Interrupts are disabled +// here already. */ +// prvSetupTimerInterrupt(); +// !!! Maple + + /* 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(); + } +} +/*-----------------------------------------------------------*/ + +// !!! Maple +// void xPortPendSVHandler( void ) +void __exc_pendsv( void ) +// !!! Maple +{ + /* 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; +} +/*-----------------------------------------------------------*/ + diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/portable.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/portable.h index 6f5248b8..b48a6755 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/portable.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/portable.h @@ -1,396 +1,396 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 "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 */ - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 "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/Libmaple/libmaple/libraries/FreeRTOS/utility/portmacro.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/portmacro.h index 461bf905..7f2d1af6 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/portmacro.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/portmacro.h @@ -1,156 +1,156 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 */ - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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/Libmaple/libmaple/libraries/FreeRTOS/utility/projdefs.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/projdefs.h index bf118a8a..18366fae 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/projdefs.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/projdefs.h @@ -1,83 +1,83 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 */ - - - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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/Libmaple/libmaple/libraries/FreeRTOS/utility/queue.c b/Libmaple/libmaple/libraries/FreeRTOS/utility/queue.c index 2ae7c703..c7ed600e 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/queue.c +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/queue.c @@ -1,1539 +1,1539 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" -#include "task.h" -#include "croutine.h" - -#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; -void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ) 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; -xQueueHandle xReturn = NULL; - - /* 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 = ( unsigned portBASE_TYPE ) 0U; - pxNewQueue->pcWriteTo = pxNewQueue->pcHead; - pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - ( unsigned portBASE_TYPE ) 1U ) * 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 ); - xReturn = pxNewQueue; - } - else - { - traceQUEUE_CREATE_FAILED(); - vPortFree( pxNewQueue ); - } - } - } - - configASSERT( xReturn ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -#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 = ( unsigned portBASE_TYPE ) 0U; - pxNewQueue->uxLength = ( unsigned portBASE_TYPE ) 1U; - pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U; - 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, ( portTickType ) 0U, queueSEND_TO_BACK ); - - traceCREATE_MUTEX( pxNewQueue ); - } - else - { - traceCREATE_MUTEX_FAILED(); - } - - configASSERT( pxNewQueue ); - return pxNewQueue; - } - -#endif /* configUSE_MUTEXES */ -/*-----------------------------------------------------------*/ - -#if configUSE_RECURSIVE_MUTEXES == 1 - - portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ) - { - portBASE_TYPE xReturn; - - configASSERT( pxMutex ); - - /* 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; - - configASSERT( pxMutex ); - - /* 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 )++; - } - else - { - traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); - } - } - - 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(); - } - - configASSERT( pxHandle ); - 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; - - configASSERT( pxQueue ); - configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - /* 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; - - configASSERT( pxQueue ); - configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - 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; - - configASSERT( pxQueue ); - configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - 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 ) ) == pdFALSE ) - { - /* 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; - - configASSERT( pxQueue ); - configASSERT( pxHigherPriorityTaskWoken ); - configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - /* 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 ) ) == pdFALSE ) - { - 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; - - configASSERT( pxQueue ); - configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - /* 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 ) ) == pdFALSE ) - { - /* 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; - - configASSERT( pxQueue ); - configASSERT( pxTaskWoken ); - configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - 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 ) ) == pdFALSE ) - { - 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; - - configASSERT( pxQueue ); - - taskENTER_CRITICAL(); - uxReturn = pxQueue->uxMessagesWaiting; - taskEXIT_CRITICAL(); - - return uxReturn; -} -/*-----------------------------------------------------------*/ - -unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) -{ -unsigned portBASE_TYPE uxReturn; - - configASSERT( pxQueue ); - - uxReturn = pxQueue->uxMessagesWaiting; - - return uxReturn; -} -/*-----------------------------------------------------------*/ - -void vQueueDelete( xQueueHandle pxQueue ) -{ - configASSERT( 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 ) ) == pdFALSE ) - { - /* 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 ) ) == pdFALSE ) - { - 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; - - configASSERT( pxQueue ); - 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; - - configASSERT( pxQueue ); - 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 ) ) == pdFALSE ) - { - /* 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 ) ) == pdFALSE ) - { - /* 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 ) ) == pdFALSE ) - { - 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 ) ) == pdFALSE ) - { - 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 = ( unsigned portBASE_TYPE ) 0U; 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 = ( unsigned portBASE_TYPE ) 0U; 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 -/*-----------------------------------------------------------*/ - -#if configUSE_TIMERS == 1 - - void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ) - { - /* This function should not be called by application code hence the - 'Restricted' in its name. It is not part of the public API. It is - designed for use by kernel code, and has special calling requirements. - It can result in vListInsert() being called on a list that can only - possibly ever have one item in it, so the list will be fast, but even - so it should be called with the scheduler locked and not from a critical - section. */ - - /* Only do anything if there are no messages in the queue. This function - will not actually cause the task to block, just place it on a blocked - list. It will not block until the scheduler is unlocked - at which - time a yield will be performed. If an item is added to the queue while - the queue is locked, and the calling task blocks on the queue, then the - calling task will be immediately unblocked when the queue is unlocked. */ - prvLockQueue( pxQueue ); - if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0U ) - { - /* There is nothing in the queue, block for the specified period. */ - vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); - } - prvUnlockQueue( pxQueue ); - } - -#endif - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +#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; +void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ) 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; +xQueueHandle xReturn = NULL; + + /* 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 = ( unsigned portBASE_TYPE ) 0U; + pxNewQueue->pcWriteTo = pxNewQueue->pcHead; + pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - ( unsigned portBASE_TYPE ) 1U ) * 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 ); + xReturn = pxNewQueue; + } + else + { + traceQUEUE_CREATE_FAILED(); + vPortFree( pxNewQueue ); + } + } + } + + configASSERT( xReturn ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#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 = ( unsigned portBASE_TYPE ) 0U; + pxNewQueue->uxLength = ( unsigned portBASE_TYPE ) 1U; + pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U; + 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, ( portTickType ) 0U, queueSEND_TO_BACK ); + + traceCREATE_MUTEX( pxNewQueue ); + } + else + { + traceCREATE_MUTEX_FAILED(); + } + + configASSERT( pxNewQueue ); + return pxNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if configUSE_RECURSIVE_MUTEXES == 1 + + portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ) + { + portBASE_TYPE xReturn; + + configASSERT( pxMutex ); + + /* 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; + + configASSERT( pxMutex ); + + /* 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 )++; + } + else + { + traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + } + + 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(); + } + + configASSERT( pxHandle ); + 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; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + /* 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; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + 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; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + 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 ) ) == pdFALSE ) + { + /* 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; + + configASSERT( pxQueue ); + configASSERT( pxHigherPriorityTaskWoken ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + /* 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 ) ) == pdFALSE ) + { + 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; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + /* 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 ) ) == pdFALSE ) + { + /* 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; + + configASSERT( pxQueue ); + configASSERT( pxTaskWoken ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + 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 ) ) == pdFALSE ) + { + 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; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + uxReturn = pxQueue->uxMessagesWaiting; + taskEXIT_CRITICAL(); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) +{ +unsigned portBASE_TYPE uxReturn; + + configASSERT( pxQueue ); + + uxReturn = pxQueue->uxMessagesWaiting; + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +void vQueueDelete( xQueueHandle pxQueue ) +{ + configASSERT( 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 ) ) == pdFALSE ) + { + /* 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 ) ) == pdFALSE ) + { + 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; + + configASSERT( pxQueue ); + 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; + + configASSERT( pxQueue ); + 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 ) ) == pdFALSE ) + { + /* 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 ) ) == pdFALSE ) + { + /* 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 ) ) == pdFALSE ) + { + 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 ) ) == pdFALSE ) + { + 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 = ( unsigned portBASE_TYPE ) 0U; 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 = ( unsigned portBASE_TYPE ) 0U; 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 +/*-----------------------------------------------------------*/ + +#if configUSE_TIMERS == 1 + + void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ) + { + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements. + It can result in vListInsert() being called on a list that can only + possibly ever have one item in it, so the list will be fast, but even + so it should be called with the scheduler locked and not from a critical + section. */ + + /* Only do anything if there are no messages in the queue. This function + will not actually cause the task to block, just place it on a blocked + list. It will not block until the scheduler is unlocked - at which + time a yield will be performed. If an item is added to the queue while + the queue is locked, and the calling task blocks on the queue, then the + calling task will be immediately unblocked when the queue is unlocked. */ + prvLockQueue( pxQueue ); + if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0U ) + { + /* There is nothing in the queue, block for the specified period. */ + vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + } + prvUnlockQueue( pxQueue ); + } + +#endif + diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/queue.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/queue.h index 47add266..9a6c86a0 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/queue.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/queue.h @@ -1,1270 +1,1270 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 QUEUE_H -#define QUEUE_H - -#ifndef INC_FREERTOS_H - #error "#include FreeRTOS.h" must appear in source files before "#include queue.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -#include "mpu_wrappers.h" - -/** - * Type by which queues are referenced. For example, a call to xQueueCreate - * returns (via a pointer parameter) an xQueueHandle variable that can then - * be used as a parameter to xQueueSend(), xQueueReceive(), etc. - */ -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 pxQueue, 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 pxQueue ); - -/** - * 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 pxMutex, portTickType xBlockTime ); -portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ); - -/* - * 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 > 0U - void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ); -#endif - -/* Not a public API function, hence the 'Restricted' in the name. */ -void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ); - - -#ifdef __cplusplus -} -#endif - -#endif /* QUEUE_H */ - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 QUEUE_H +#define QUEUE_H + +#ifndef INC_FREERTOS_H + #error "#include FreeRTOS.h" must appear in source files before "#include queue.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "mpu_wrappers.h" + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate + * returns (via a pointer parameter) an xQueueHandle variable that can then + * be used as a parameter to xQueueSend(), xQueueReceive(), etc. + */ +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 pxQueue, 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 pxQueue ); + +/** + * 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 pxMutex, portTickType xBlockTime ); +portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ); + +/* + * 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 > 0U + void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ); +#endif + +/* Not a public API function, hence the 'Restricted' in the name. */ +void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ); + + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/semphr.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/semphr.h index 0130f1d7..7a9e83fa 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/semphr.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/semphr.h @@ -1,717 +1,717 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 SEMAPHORE_H -#define SEMAPHORE_H - -#ifndef INC_FREERTOS_H - #error "#include FreeRTOS.h" must appear in source files before "#include semphr.h" -#endif - -#include "queue.h" - -typedef xQueueHandle xSemaphoreHandle; - -#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1U ) -#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0U ) -#define semGIVE_BLOCK_TIME ( ( portTickType ) 0U ) - - -/** - * 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 */ - - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 SEMAPHORE_H +#define SEMAPHORE_H + +#ifndef INC_FREERTOS_H + #error "#include FreeRTOS.h" must appear in source files before "#include semphr.h" +#endif + +#include "queue.h" + +typedef xQueueHandle xSemaphoreHandle; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0U ) +#define semGIVE_BLOCK_TIME ( ( portTickType ) 0U ) + + +/** + * 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/Libmaple/libmaple/libraries/FreeRTOS/utility/task.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/task.h index 3c44904d..96ba68e4 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/task.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/task.h @@ -1,1307 +1,1307 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 TASK_H -#define TASK_H - -#ifndef INC_FREERTOS_H - #error "include FreeRTOS.h must appear in source files before include task.h" -#endif - -#include "portable.h" -#include "list.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*----------------------------------------------------------- - * MACROS AND DEFINITIONS - *----------------------------------------------------------*/ - -#define tskKERNEL_VERSION_NUMBER "V7.0.1" - -/** - * 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 ) 0U ) - -/** - * 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 pxTaskToDelete ) 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 words, so on a 32 bit machine - * a value of 1 means 4 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; - -/* When using trace macros it is sometimes necessary to include tasks.h before -FreeRTOS.h. When this is done pdTASK_HOOK_CODE will not yet have been defined, -so the following two prototypes will cause a compilation error. This can be -fixed by simply guarding against the inclusion of these two prototypes unless -they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration -constant. */ -#ifdef configUSE_APPLICATION_TASK_TAG - #if configUSE_APPLICATION_TASK_TAG == 1 - /** - * 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; - #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ -#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ - -/** - * 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. - * - * This function performs nearly the same function as vTaskPlaceOnEventList(). - * The difference being that this function does not permit tasks to block - * indefinitely, whereas vTaskPlaceOnEventList() does. - * - * @return pdTRUE if the task being removed has a higher priority than the task - * making the call, otherwise pdFALSE. - */ -void vTaskPlaceOnEventListRestricted( 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 pxTaskCode, 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 */ - - - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 TASK_H +#define TASK_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include task.h" +#endif + +#include "portable.h" +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V7.0.1" + +/** + * 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 ) 0U ) + +/** + * 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 pxTaskToDelete ) 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 words, so on a 32 bit machine + * a value of 1 means 4 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; + +/* When using trace macros it is sometimes necessary to include tasks.h before +FreeRTOS.h. When this is done pdTASK_HOOK_CODE will not yet have been defined, +so the following two prototypes will cause a compilation error. This can be +fixed by simply guarding against the inclusion of these two prototypes unless +they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration +constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG + #if configUSE_APPLICATION_TASK_TAG == 1 + /** + * 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; + #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +/** + * 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. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +void vTaskPlaceOnEventListRestricted( 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 pxTaskCode, 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/Libmaple/libmaple/libraries/FreeRTOS/utility/tasks.c b/Libmaple/libmaple/libraries/FreeRTOS/utility/tasks.c index 020443d3..d48dd4dd 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/tasks.c +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/tasks.c @@ -1,2522 +1,2522 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" -#include "task.h" -#include "timers.h" -#include "StackMacros.h" - -#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; -PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY; - -#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 ( 0xa5U ) - -/* - * 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 = 255U; - 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() \ -{ \ -portTickType xItemValue; \ - \ - /* Is the tick count greater than or equal to the wake time of the first \ - task referenced from the delayed tasks list? */ \ - if( xTickCount >= xNextTaskUnblockTime ) \ - { \ - for( ;; ) \ - { \ - if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \ - { \ - /* The delayed list is empty. Set xNextTaskUnblockTime to the \ - maximum possible value so it is extremely unlikely that the \ - if( xTickCount >= xNextTaskUnblockTime ) test will pass next \ - time through. */ \ - xNextTaskUnblockTime = portMAX_DELAY; \ - break; \ - } \ - else \ - { \ - /* The delayed list is not empty, get the value of the item at \ - the head of the delayed list. This is the time at which the \ - task at the head of the delayed list should be removed from \ - the Blocked state. */ \ - pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \ - xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); \ - \ - if( xTickCount < xItemValue ) \ - { \ - /* It is not time to unblock this item yet, but the item \ - value is the time at which the task at the head of the \ - blocked list should be removed from the Blocked state - \ - so record the item value in xNextTaskUnblockTime. */ \ - xNextTaskUnblockTime = xItemValue; \ - break; \ - } \ - \ - /* It is time to remove the item from the Blocked state. */ \ - 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 ) ) - -/* Callback function prototypes. --------------------------*/ -extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); -extern void vApplicationTickHook( void ); - -/* 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; - -/* - * The currently executing task is entering the Blocked state. Add the task to - * either the current or the overflow delayed task list. - */ -static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) 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; - - configASSERT( pxTaskCode ); - configASSERT( ( uxPriority < configMAX_PRIORITIES ) ); - - /* 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 - ( unsigned short ) 1 ); - pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( unsigned long ) pxTopOfStack ) & ( ( unsigned long ) ~portBYTE_ALIGNMENT_MASK ) ); - - /* Check the alignment of the calculated top of stack is correct. */ - configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); - } - #else - { - pxTopOfStack = pxNewTCB->pxStack; - - /* Check the alignment of the stack buffer is correct. */ - configASSERT( ( ( ( unsigned long ) pxNewTCB->pxStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); - - /* 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 - - /* Check the alignment of the initialised stack. */ - configASSERT( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); - - 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. */ - taskENTER_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 ); - } - taskEXIT_CRITICAL(); - } - else - { - xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; - traceTASK_CREATE_FAILED(); - } - - 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; - - taskENTER_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 ); - } - taskEXIT_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; - - configASSERT( pxPreviousWakeTime ); - configASSERT( ( xTimeIncrement > 0 ) ); - - 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 != pdFALSE ) - { - 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 ) ); - prvAddCurrentTaskToDelayedList( xTimeToWake ); - } - } - 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 ) ); - prvAddCurrentTaskToDelayedList( xTimeToWake ); - } - 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; - - taskENTER_CRITICAL(); - { - /* If null is passed in here then we are changing the - priority of the calling function. */ - pxTCB = prvGetTCBFromHandle( pxTask ); - uxReturn = pxTCB->uxPriority; - } - taskEXIT_CRITICAL(); - - return uxReturn; - } - -#endif -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_vTaskPrioritySet == 1 ) - - void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) - { - tskTCB *pxTCB; - unsigned portBASE_TYPE uxCurrentPriority; - portBASE_TYPE xYieldRequired = pdFALSE; - - configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) ); - - /* Ensure the new priority is valid. */ - if( uxNewPriority >= configMAX_PRIORITIES ) - { - uxNewPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U; - } - - taskENTER_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(); - } - } - } - taskEXIT_CRITICAL(); - } - -#endif -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_vTaskSuspend == 1 ) - - void vTaskSuspend( xTaskHandle pxTaskToSuspend ) - { - tskTCB *pxTCB; - - taskENTER_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 ) ); - } - taskEXIT_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( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) - { - /* No other tasks are ready, 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; - - /* It does not make sense to check if the calling task is suspended. */ - configASSERT( 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; - - /* It does not make sense to resume the calling task. */ - configASSERT( pxTaskToResume ); - - /* 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 ) ) - { - taskENTER_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(); - } - } - } - taskEXIT_CRITICAL(); - } - } - -#endif - -/*-----------------------------------------------------------*/ - -#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) - - portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) - { - portBASE_TYPE xYieldRequired = pdFALSE; - tskTCB *pxTCB; - - configASSERT( pxTaskToResume ); - - 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 ( configUSE_TIMERS == 1 ) - { - if( xReturn == pdPASS ) - { - xReturn = xTimerCreateTimerTask(); - } - } - #endif - - 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(). */ - } - } - - /* This line will only be reached if the kernel could not be started. */ - configASSERT( xReturn ); -} -/*-----------------------------------------------------------*/ - -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; - - /* If uxSchedulerSuspended is zero then this function does not match a - previous call to vTaskSuspendAll(). */ - configASSERT( uxSchedulerSuspended ); - - /* 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. */ - taskENTER_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( listLIST_IS_EMPTY( ( xList * ) &xPendingReadyList ) == pdFALSE ) - { - pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ); - 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(); - } - } - } - } - taskEXIT_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. */ - taskENTER_CRITICAL(); - { - xTicks = xTickCount; - } - taskEXIT_CRITICAL(); - - return xTicks; -} -/*-----------------------------------------------------------*/ - -portTickType xTaskGetTickCountFromISR( void ) -{ -portTickType xReturn; -unsigned portBASE_TYPE uxSavedInterruptStatus; - - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - xReturn = xTickCount; - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -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 = ( signed char ) 0x00; - strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" ); - - uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U; - - do - { - uxQueue--; - - if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE ) - { - prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR ); - } - }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY ); - - if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE ) - { - prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR ); - } - - if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE ) - { - prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR ); - } - - #if( INCLUDE_vTaskDelete == 1 ) - { - if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE ) - { - prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, tskDELETED_CHAR ); - } - } - #endif - - #if ( INCLUDE_vTaskSuspend == 1 ) - { - if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE ) - { - 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; - - /* This is a VERY costly function that should be used for debug only. - It leaves interrupts disabled for a LONG time. */ - - vTaskSuspendAll(); - { - #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE - portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); - #else - ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); - #endif - - /* Divide ulTotalRunTime by 100 to make the percentage caluclations - simpler in the prvGenerateRunTimeStatsForTasksInList() function. */ - ulTotalRunTime /= 100UL; - - /* Run through all the lists that could potentially contain a TCB, - generating a table of run timer percentages in the provided - buffer. */ - - *pcWriteBuffer = ( signed char ) 0x00; - strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" ); - - uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U; - - do - { - uxQueue--; - - if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE ) - { - prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), ulTotalRunTime ); - } - }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY ); - - if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE ) - { - prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, ulTotalRunTime ); - } - - if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE ) - { - prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, ulTotalRunTime ); - } - - #if ( INCLUDE_vTaskDelete == 1 ) - { - if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE ) - { - prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, ulTotalRunTime ); - } - } - #endif - - #if ( INCLUDE_vTaskSuspend == 1 ) - { - if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE ) - { - prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, ulTotalRunTime ); - } - } - #endif - } - xTaskResumeAll(); - } - -#endif -/*----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) - { - configASSERT( pcBuffer ); - configASSERT( ulBufferSize ); - - taskENTER_CRITICAL(); - { - pcTraceBuffer = ( signed char * )pcBuffer; - pcTraceBufferStart = pcBuffer; - pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE ); - xTracing = pdTRUE; - } - taskEXIT_CRITICAL(); - } - -#endif -/*----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - unsigned long ulTaskEndTrace( void ) - { - unsigned long ulBufferLength; - - taskENTER_CRITICAL(); - xTracing = pdFALSE; - taskEXIT_CRITICAL(); - - ulBufferLength = ( unsigned long ) ( pcTraceBuffer - pcTraceBufferStart ); - - return ulBufferLength; - } - -#endif - - - -/*----------------------------------------------------------- - * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES - * documented in task.h - *----------------------------------------------------------*/ - - -void vTaskIncrementTick( void ) -{ -tskTCB * pxTCB; - - /* 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! */ - configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); - - pxTemp = pxDelayedTaskList; - pxDelayedTaskList = pxOverflowDelayedTaskList; - pxOverflowDelayedTaskList = pxTemp; - xNumOfOverflows++; - - if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) - { - /* The new current delayed list is empty. Set - xNextTaskUnblockTime to the maximum possible value so it is - extremely unlikely that the - if( xTickCount >= xNextTaskUnblockTime ) test will pass until - there is an item in the delayed list. */ - xNextTaskUnblockTime = portMAX_DELAY; - } - else - { - /* The new current delayed list is not empty, get the value of - the item at the head of the delayed list. This is the time at - which the task at the head of the delayed list should be removed - from the Blocked state. */ - pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); - xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); - } - } - - /* 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 ) - { - vApplicationTickHook(); - } - #endif - } - - #if ( configUSE_TICK_HOOK == 1 ) - { - /* Guard against the tick hook being called when the missed tick - count is being unwound (when the scheduler is being unlocked. */ - if( uxMissedTicks == ( unsigned portBASE_TYPE ) 0U ) - { - 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 ] ) ) == pdFALSE ) - { - 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 ) == pdFALSE ) - { - 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 ) == pdFALSE ) - { - listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList2 ); - vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ); - - prvDeleteTCB( ( tskTCB * ) pxTCB ); - } - - while( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE ) - { - 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 pxHookFunction ) - { - 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. */ - taskENTER_CRITICAL(); - xTCB->pxTaskTag = pxHookFunction; - taskEXIT_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. */ - taskENTER_CRITICAL(); - xReturn = xTCB->pxTaskTag; - taskEXIT_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; - } - else - { - traceTASK_SWITCHED_OUT(); - - #if ( configGENERATE_RUN_TIME_STATS == 1 ) - { - unsigned long ulTempCounter; - - #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE - portALT_GET_RUN_TIME_COUNTER_VALUE( ulTempCounter ); - #else - ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE(); - #endif - - /* 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 ] ) ) ) - { - configASSERT( 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; - - configASSERT( pxEventList ); - - /* 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; - prvAddCurrentTaskToDelayedList( xTimeToWake ); - } - } - #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; - prvAddCurrentTaskToDelayedList( xTimeToWake ); - } - #endif -} -/*-----------------------------------------------------------*/ - -#if configUSE_TIMERS == 1 - - void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait ) - { - portTickType xTimeToWake; - - configASSERT( pxEventList ); - - /* This function should not be called by application code hence the - 'Restricted' in its name. It is not part of the public API. It is - designed for use by kernel code, and has special calling requirements - - it should be called from a critical section. */ - - - /* Place the event list item of the TCB in the appropriate event list. - In this case it is assume that this is the only task that is going to - be waiting on this event list, so the faster vListInsertEnd() function - can be used in place of vListInsert. */ - vListInsertEnd( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) ); - - /* We must remove this task from the ready list before adding it to the - blocked list as the same list item is used for both lists. This - function is called form a critical section. */ - vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); - - /* 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; - prvAddCurrentTaskToDelayedList( xTimeToWake ); - } - -#endif /* configUSE_TIMERS */ -/*-----------------------------------------------------------*/ - -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. - - This function assumes that a check has already been made to ensure that - pxEventList is not empty. */ - pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); - configASSERT( pxUnblockedTCB ); - 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 ) -{ - configASSERT( pxTimeOut ); - pxTimeOut->xOverflowCount = xNumOfOverflows; - pxTimeOut->xTimeOnEntering = xTickCount; -} -/*-----------------------------------------------------------*/ - -portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) -{ -portBASE_TYPE xReturn; - - configASSERT( pxTimeOut ); - configASSERT( pxTicksToWait ); - - taskENTER_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; - } - } - taskEXIT_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 ] = ( signed char ) '\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 - ( unsigned portBASE_TYPE ) 1U; - } - - 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 = ( unsigned portBASE_TYPE ) 0U; 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 == pdFALSE ) - { - tskTCB *pxTCB; - - taskENTER_CRITICAL(); - { - pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) ); - vListRemove( &( pxTCB->xGenericListItem ) ); - --uxCurrentNumberOfTasks; - --uxTasksDeleted; - } - taskEXIT_CRITICAL(); - - prvDeleteTCB( pxTCB ); - } - } - } - #endif -} -/*-----------------------------------------------------------*/ - -static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) -{ - /* 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 ) ); - - /* If the task entering the blocked state was placed at the head of the - list of blocked tasks then xNextTaskUnblockTime needs to be updated - too. */ - if( xTimeToWake < xNextTaskUnblockTime ) - { - xNextTaskUnblockTime = xTimeToWake; - } - } -} -/*-----------------------------------------------------------*/ - -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 has the task used? - This will always be rounded down to the nearest integer. - ulTotalRunTime has already been divided by 100. */ - ulStatsAsPercentage = pxNextTCB->ulRunTimeCounter / ulTotalRunTime; - - if( ulStatsAsPercentage > 0UL ) - { - #ifdef portLU_PRINTF_SPECIFIER_REQUIRED - { - sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter, ulStatsAsPercentage ); - } - #else - { - /* sizeof( int ) == sizeof( long ) so a smaller - printf() library can be used. */ - sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); - } - #endif - } - else - { - /* If the percentage is zero here then the task has - consumed less than 1% of the total run time. */ - #ifdef portLU_PRINTF_SPECIFIER_REQUIRED - { - sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter ); - } - #else - { - /* sizeof( int ) == sizeof( long ) so a smaller - printf() library can be used. */ - sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter ); - } - #endif - } - } - - 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 ) || ( configUSE_MUTEXES == 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 ) || ( configUSE_TIMERS == 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; - - configASSERT( 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 -/*-----------------------------------------------------------*/ - - - - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "StackMacros.h" + +#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; +PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY; + +#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 ( 0xa5U ) + +/* + * 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 = 255U; + 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() \ +{ \ +portTickType xItemValue; \ + \ + /* Is the tick count greater than or equal to the wake time of the first \ + task referenced from the delayed tasks list? */ \ + if( xTickCount >= xNextTaskUnblockTime ) \ + { \ + for( ;; ) \ + { \ + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \ + { \ + /* The delayed list is empty. Set xNextTaskUnblockTime to the \ + maximum possible value so it is extremely unlikely that the \ + if( xTickCount >= xNextTaskUnblockTime ) test will pass next \ + time through. */ \ + xNextTaskUnblockTime = portMAX_DELAY; \ + break; \ + } \ + else \ + { \ + /* The delayed list is not empty, get the value of the item at \ + the head of the delayed list. This is the time at which the \ + task at the head of the delayed list should be removed from \ + the Blocked state. */ \ + pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \ + xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); \ + \ + if( xTickCount < xItemValue ) \ + { \ + /* It is not time to unblock this item yet, but the item \ + value is the time at which the task at the head of the \ + blocked list should be removed from the Blocked state - \ + so record the item value in xNextTaskUnblockTime. */ \ + xNextTaskUnblockTime = xItemValue; \ + break; \ + } \ + \ + /* It is time to remove the item from the Blocked state. */ \ + 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 ) ) + +/* Callback function prototypes. --------------------------*/ +extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); +extern void vApplicationTickHook( void ); + +/* 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; + +/* + * The currently executing task is entering the Blocked state. Add the task to + * either the current or the overflow delayed task list. + */ +static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) 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; + + configASSERT( pxTaskCode ); + configASSERT( ( uxPriority < configMAX_PRIORITIES ) ); + + /* 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 - ( unsigned short ) 1 ); + pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( unsigned long ) pxTopOfStack ) & ( ( unsigned long ) ~portBYTE_ALIGNMENT_MASK ) ); + + /* Check the alignment of the calculated top of stack is correct. */ + configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + } + #else + { + pxTopOfStack = pxNewTCB->pxStack; + + /* Check the alignment of the stack buffer is correct. */ + configASSERT( ( ( ( unsigned long ) pxNewTCB->pxStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + /* 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 + + /* Check the alignment of the initialised stack. */ + configASSERT( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + 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. */ + taskENTER_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 ); + } + taskEXIT_CRITICAL(); + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + traceTASK_CREATE_FAILED(); + } + + 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; + + taskENTER_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 ); + } + taskEXIT_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; + + configASSERT( pxPreviousWakeTime ); + configASSERT( ( xTimeIncrement > 0 ) ); + + 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 != pdFALSE ) + { + 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 ) ); + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + } + 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 ) ); + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + 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; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then we are changing the + priority of the calling function. */ + pxTCB = prvGetTCBFromHandle( pxTask ); + uxReturn = pxTCB->uxPriority; + } + taskEXIT_CRITICAL(); + + return uxReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) + { + tskTCB *pxTCB; + unsigned portBASE_TYPE uxCurrentPriority; + portBASE_TYPE xYieldRequired = pdFALSE; + + configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) ); + + /* Ensure the new priority is valid. */ + if( uxNewPriority >= configMAX_PRIORITIES ) + { + uxNewPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U; + } + + taskENTER_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(); + } + } + } + taskEXIT_CRITICAL(); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( xTaskHandle pxTaskToSuspend ) + { + tskTCB *pxTCB; + + taskENTER_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 ) ); + } + taskEXIT_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( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) + { + /* No other tasks are ready, 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; + + /* It does not make sense to check if the calling task is suspended. */ + configASSERT( 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; + + /* It does not make sense to resume the calling task. */ + configASSERT( pxTaskToResume ); + + /* 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 ) ) + { + taskENTER_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(); + } + } + } + taskEXIT_CRITICAL(); + } + } + +#endif + +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) + { + portBASE_TYPE xYieldRequired = pdFALSE; + tskTCB *pxTCB; + + configASSERT( pxTaskToResume ); + + 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 ( configUSE_TIMERS == 1 ) + { + if( xReturn == pdPASS ) + { + xReturn = xTimerCreateTimerTask(); + } + } + #endif + + 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(). */ + } + } + + /* This line will only be reached if the kernel could not be started. */ + configASSERT( xReturn ); +} +/*-----------------------------------------------------------*/ + +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; + + /* If uxSchedulerSuspended is zero then this function does not match a + previous call to vTaskSuspendAll(). */ + configASSERT( uxSchedulerSuspended ); + + /* 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. */ + taskENTER_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( listLIST_IS_EMPTY( ( xList * ) &xPendingReadyList ) == pdFALSE ) + { + pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ); + 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(); + } + } + } + } + taskEXIT_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. */ + taskENTER_CRITICAL(); + { + xTicks = xTickCount; + } + taskEXIT_CRITICAL(); + + return xTicks; +} +/*-----------------------------------------------------------*/ + +portTickType xTaskGetTickCountFromISR( void ) +{ +portTickType xReturn; +unsigned portBASE_TYPE uxSavedInterruptStatus; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + xReturn = xTickCount; + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +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 = ( signed char ) 0x00; + strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" ); + + uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U; + + do + { + uxQueue--; + + if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR ); + } + }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY ); + + if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR ); + } + + if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR ); + } + + #if( INCLUDE_vTaskDelete == 1 ) + { + if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE ) + { + prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, tskDELETED_CHAR ); + } + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE ) + { + 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; + + /* This is a VERY costly function that should be used for debug only. + It leaves interrupts disabled for a LONG time. */ + + vTaskSuspendAll(); + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + #else + ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + /* Divide ulTotalRunTime by 100 to make the percentage caluclations + simpler in the prvGenerateRunTimeStatsForTasksInList() function. */ + ulTotalRunTime /= 100UL; + + /* Run through all the lists that could potentially contain a TCB, + generating a table of run timer percentages in the provided + buffer. */ + + *pcWriteBuffer = ( signed char ) 0x00; + strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" ); + + uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U; + + do + { + uxQueue--; + + if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), ulTotalRunTime ); + } + }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY ); + + if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, ulTotalRunTime ); + } + + if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, ulTotalRunTime ); + } + + #if ( INCLUDE_vTaskDelete == 1 ) + { + if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, ulTotalRunTime ); + } + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE ) + { + prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, ulTotalRunTime ); + } + } + #endif + } + xTaskResumeAll(); + } + +#endif +/*----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) + { + configASSERT( pcBuffer ); + configASSERT( ulBufferSize ); + + taskENTER_CRITICAL(); + { + pcTraceBuffer = ( signed char * )pcBuffer; + pcTraceBufferStart = pcBuffer; + pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE ); + xTracing = pdTRUE; + } + taskEXIT_CRITICAL(); + } + +#endif +/*----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + unsigned long ulTaskEndTrace( void ) + { + unsigned long ulBufferLength; + + taskENTER_CRITICAL(); + xTracing = pdFALSE; + taskEXIT_CRITICAL(); + + ulBufferLength = ( unsigned long ) ( pcTraceBuffer - pcTraceBufferStart ); + + return ulBufferLength; + } + +#endif + + + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + * documented in task.h + *----------------------------------------------------------*/ + + +void vTaskIncrementTick( void ) +{ +tskTCB * pxTCB; + + /* 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! */ + configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); + + pxTemp = pxDelayedTaskList; + pxDelayedTaskList = pxOverflowDelayedTaskList; + pxOverflowDelayedTaskList = pxTemp; + xNumOfOverflows++; + + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The new current delayed list is empty. Set + xNextTaskUnblockTime to the maximum possible value so it is + extremely unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass until + there is an item in the delayed list. */ + xNextTaskUnblockTime = portMAX_DELAY; + } + else + { + /* The new current delayed list is not empty, get the value of + the item at the head of the delayed list. This is the time at + which the task at the head of the delayed list should be removed + from the Blocked state. */ + pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); + xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); + } + } + + /* 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 ) + { + vApplicationTickHook(); + } + #endif + } + + #if ( configUSE_TICK_HOOK == 1 ) + { + /* Guard against the tick hook being called when the missed tick + count is being unwound (when the scheduler is being unlocked. */ + if( uxMissedTicks == ( unsigned portBASE_TYPE ) 0U ) + { + 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 ] ) ) == pdFALSE ) + { + 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 ) == pdFALSE ) + { + 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 ) == pdFALSE ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList2 ); + vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ); + + prvDeleteTCB( ( tskTCB * ) pxTCB ); + } + + while( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE ) + { + 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 pxHookFunction ) + { + 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. */ + taskENTER_CRITICAL(); + xTCB->pxTaskTag = pxHookFunction; + taskEXIT_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. */ + taskENTER_CRITICAL(); + xReturn = xTCB->pxTaskTag; + taskEXIT_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; + } + else + { + traceTASK_SWITCHED_OUT(); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + unsigned long ulTempCounter; + + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTempCounter ); + #else + ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + /* 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 ] ) ) ) + { + configASSERT( 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; + + configASSERT( pxEventList ); + + /* 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; + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + } + #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; + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + #endif +} +/*-----------------------------------------------------------*/ + +#if configUSE_TIMERS == 1 + + void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait ) + { + portTickType xTimeToWake; + + configASSERT( pxEventList ); + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements - + it should be called from a critical section. */ + + + /* Place the event list item of the TCB in the appropriate event list. + In this case it is assume that this is the only task that is going to + be waiting on this event list, so the faster vListInsertEnd() function + can be used in place of vListInsert. */ + vListInsertEnd( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) ); + + /* We must remove this task from the ready list before adding it to the + blocked list as the same list item is used for both lists. This + function is called form a critical section. */ + vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); + + /* 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; + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +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. + + This function assumes that a check has already been made to ensure that + pxEventList is not empty. */ + pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + configASSERT( pxUnblockedTCB ); + 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 ) +{ + configASSERT( pxTimeOut ); + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) +{ +portBASE_TYPE xReturn; + + configASSERT( pxTimeOut ); + configASSERT( pxTicksToWait ); + + taskENTER_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; + } + } + taskEXIT_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 ] = ( signed char ) '\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 - ( unsigned portBASE_TYPE ) 1U; + } + + 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 = ( unsigned portBASE_TYPE ) 0U; 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 == pdFALSE ) + { + tskTCB *pxTCB; + + taskENTER_CRITICAL(); + { + pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) ); + vListRemove( &( pxTCB->xGenericListItem ) ); + --uxCurrentNumberOfTasks; + --uxTasksDeleted; + } + taskEXIT_CRITICAL(); + + prvDeleteTCB( pxTCB ); + } + } + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) +{ + /* 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 ) ); + + /* If the task entering the blocked state was placed at the head of the + list of blocked tasks then xNextTaskUnblockTime needs to be updated + too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + } +} +/*-----------------------------------------------------------*/ + +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 has the task used? + This will always be rounded down to the nearest integer. + ulTotalRunTime has already been divided by 100. */ + ulStatsAsPercentage = pxNextTCB->ulRunTimeCounter / ulTotalRunTime; + + if( ulStatsAsPercentage > 0UL ) + { + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter, ulStatsAsPercentage ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ + sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); + } + #endif + } + else + { + /* If the percentage is zero here then the task has + consumed less than 1% of the total run time. */ + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ + sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter ); + } + #endif + } + } + + 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 ) || ( configUSE_MUTEXES == 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 ) || ( configUSE_TIMERS == 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; + + configASSERT( 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 +/*-----------------------------------------------------------*/ + + + + diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/timers.c b/Libmaple/libmaple/libraries/FreeRTOS/utility/timers.c index 7e5ef22a..1dd7555a 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/timers.c +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/timers.c @@ -1,649 +1,649 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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. -*/ - -/* 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 "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "timers.h" - -#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -/* This entire source file will be skipped if the application is not configured -to include software timer functionality. This #if is closed at the very bottom -of this file. If you want to include software timer functionality then ensure -configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ -#if ( configUSE_TIMERS == 1 ) - -/* Misc definitions. */ -#define tmrNO_DELAY ( portTickType ) 0U - -/* The definition of the timers themselves. */ -typedef struct tmrTimerControl -{ - const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ - xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ - portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ - unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */ - void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ - tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */ -} xTIMER; - -/* The definition of messages that can be sent and received on the timer -queue. */ -typedef struct tmrTimerQueueMessage -{ - portBASE_TYPE xMessageID; /*<< The command being sent to the timer service task. */ - portTickType xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ - xTIMER * pxTimer; /*<< The timer to which the command will be applied. */ -} xTIMER_MESSAGE; - - -/* The list in which active timers are stored. Timers are referenced in expire -time order, with the nearest expiry time at the front of the list. Only the -timer service task is allowed to access xActiveTimerList. */ -PRIVILEGED_DATA static xList xActiveTimerList1; -PRIVILEGED_DATA static xList xActiveTimerList2; -PRIVILEGED_DATA static xList *pxCurrentTimerList; -PRIVILEGED_DATA static xList *pxOverflowTimerList; - -/* A queue that is used to send commands to the timer service task. */ -PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL; - -/*-----------------------------------------------------------*/ - -/* - * Initialise the infrastructure used by the timer service task if it has not - * been initialised already. - */ -static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; - -/* - * The timer service task (daemon). Timer functionality is controlled by this - * task. Other tasks communicate with the timer service task using the - * xTimerQueue queue. - */ -static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION; - -/* - * Called by the timer service task to interpret and process a command it - * received on the timer queue. - */ -static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; - -/* - * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, - * depending on if the expire time causes a timer counter overflow. - */ -static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION; - -/* - * An active timer has reached its expire time. Reload the timer if it is an - * auto reload timer, then call its callback. - */ -static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION; - -/* - * The tick count has overflowed. Switch the timer lists after ensuring the - * current timer list does not still reference some timers. - */ -static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION; - -/* - * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE - * if a tick count overflow occurred since prvSampleTimeNow() was last called. - */ -static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; - -/* - * If the timer list contains any active timers then return the expire time of - * the timer that will expire first and set *pxListWasEmpty to false. If the - * timer list does not contain any timers then return 0 and set *pxListWasEmpty - * to pdTRUE. - */ -static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) PRIVILEGED_FUNCTION; - -/* - * If a timer has expired, process it. Otherwise, block the timer service task - * until either a timer does expire or a command is received. - */ -static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION; - -/*-----------------------------------------------------------*/ - -portBASE_TYPE xTimerCreateTimerTask( void ) -{ -portBASE_TYPE xReturn = pdFAIL; - - /* This function is called when the scheduler is started if - configUSE_TIMERS is set to 1. Check that the infrastructure used by the - timer service task has been created/initialised. If timers have already - been created then the initialisation will already have been performed. */ - prvCheckForValidListAndQueue(); - - if( xTimerQueue != NULL ) - { - xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY, NULL); - } - - configASSERT( xReturn ); - return xReturn; -} -/*-----------------------------------------------------------*/ - -xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) -{ -xTIMER *pxNewTimer; - - /* Allocate the timer structure. */ - if( xTimerPeriodInTicks == ( portTickType ) 0U ) - { - pxNewTimer = NULL; - configASSERT( ( xTimerPeriodInTicks > 0 ) ); - } - else - { - pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) ); - if( pxNewTimer != NULL ) - { - /* Ensure the infrastructure used by the timer service task has been - created/initialised. */ - prvCheckForValidListAndQueue(); - - /* Initialise the timer structure members using the function parameters. */ - pxNewTimer->pcTimerName = pcTimerName; - pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; - pxNewTimer->uxAutoReload = uxAutoReload; - pxNewTimer->pvTimerID = pvTimerID; - pxNewTimer->pxCallbackFunction = pxCallbackFunction; - vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); - - traceTIMER_CREATE( pxNewTimer ); - } - else - { - traceTIMER_CREATE_FAILED(); - } - } - - return ( xTimerHandle ) pxNewTimer; -} -/*-----------------------------------------------------------*/ - -portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) -{ -portBASE_TYPE xReturn = pdFAIL; -xTIMER_MESSAGE xMessage; - - /* Send a message to the timer service task to perform a particular action - on a particular timer definition. */ - if( xTimerQueue != NULL ) - { - /* Send a command to the timer service task to start the xTimer timer. */ - xMessage.xMessageID = xCommandID; - xMessage.xMessageValue = xOptionalValue; - xMessage.pxTimer = ( xTIMER * ) xTimer; - - if( pxHigherPriorityTaskWoken == NULL ) - { - if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) - { - xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime ); - } - else - { - xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); - } - } - else - { - xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); - } - - traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) -{ -xTIMER *pxTimer; -portBASE_TYPE xResult; - - /* Remove the timer from the list of active timers. A check has already - been performed to ensure the list is not empty. */ - pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); - vListRemove( &( pxTimer->xTimerListItem ) ); - traceTIMER_EXPIRED( pxTimer ); - - /* If the timer is an auto reload timer then calculate the next - expiry time and re-insert the timer in the list of active timers. */ - if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) - { - /* This is the only time a timer is inserted into a list using - a time relative to anything other than the current time. It - will therefore be inserted into the correct list relative to - the time this task thinks it is now, even if a command to - switch lists due to a tick count overflow is already waiting in - the timer queue. */ - if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE ) - { - /* The timer expired before it was added to the active timer - list. Reload it now. */ - xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY ); - configASSERT( xResult ); - ( void ) xResult; - } - } - - /* Call the timer callback. */ - pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); -} -/*-----------------------------------------------------------*/ - -static void prvTimerTask( void *pvParameters ) -{ -portTickType xNextExpireTime; -portBASE_TYPE xListWasEmpty; - - /* Just to avoid compiler warnings. */ - ( void ) pvParameters; - - for( ;; ) - { - /* Query the timers list to see if it contains any timers, and if so, - obtain the time at which the next timer will expire. */ - xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); - - /* If a timer has expired, process it. Otherwise, block this task - until either a timer does expire, or a command is received. */ - prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); - - /* Empty the command queue. */ - prvProcessReceivedCommands(); - } -} -/*-----------------------------------------------------------*/ - -static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) -{ -portTickType xTimeNow; -portBASE_TYPE xTimerListsWereSwitched; - - vTaskSuspendAll(); - { - /* Obtain the time now to make an assessment as to whether the timer - has expired or not. If obtaining the time causes the lists to switch - then don't process this timer as any timers that remained in the list - when the lists were switched will have been processed within the - prvSampelTimeNow() function. */ - xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); - if( xTimerListsWereSwitched == pdFALSE ) - { - /* The tick count has not overflowed, has the timer expired? */ - if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) - { - xTaskResumeAll(); - prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); - } - else - { - /* The tick count has not overflowed, and the next expire - time has not been reached yet. This task should therefore - block to wait for the next expire time or a command to be - received - whichever comes first. The following line cannot - be reached unless xNextExpireTime > xTimeNow, except in the - case when the current timer list is empty. */ - vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) ); - - if( xTaskResumeAll() == pdFALSE ) - { - /* Yield to wait for either a command to arrive, or the block time - to expire. If a command arrived between the critical section being - exited and this yield then the yield will not cause the task - to block. */ - portYIELD_WITHIN_API(); - } - } - } - else - { - xTaskResumeAll(); - } - } -} -/*-----------------------------------------------------------*/ - -static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) -{ -portTickType xNextExpireTime; - - /* Timers are listed in expiry time order, with the head of the list - referencing the task that will expire first. Obtain the time at which - the timer with the nearest expiry time will expire. If there are no - active timers then just set the next expire time to 0. That will cause - this task to unblock when the tick count overflows, at which point the - timer lists will be switched and the next expiry time can be - re-assessed. */ - *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); - if( *pxListWasEmpty == pdFALSE ) - { - xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); - } - else - { - /* Ensure the task unblocks when the tick count rolls over. */ - xNextExpireTime = ( portTickType ) 0U; - } - - return xNextExpireTime; -} -/*-----------------------------------------------------------*/ - -static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) -{ -portTickType xTimeNow; -static portTickType xLastTime = ( portTickType ) 0U; - - xTimeNow = xTaskGetTickCount(); - - if( xTimeNow < xLastTime ) - { - prvSwitchTimerLists( xLastTime ); - *pxTimerListsWereSwitched = pdTRUE; - } - else - { - *pxTimerListsWereSwitched = pdFALSE; - } - - xLastTime = xTimeNow; - - return xTimeNow; -} -/*-----------------------------------------------------------*/ - -static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) -{ -portBASE_TYPE xProcessTimerNow = pdFALSE; - - listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); - listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); - - if( xNextExpiryTime <= xTimeNow ) - { - /* Has the expiry time elapsed between the command to start/reset a - timer was issued, and the time the command was processed? */ - if( ( ( portTickType ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) - { - /* The time between a command being issued and the command being - processed actually exceeds the timers period. */ - xProcessTimerNow = pdTRUE; - } - else - { - vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); - } - } - else - { - if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) - { - /* If, since the command was issued, the tick count has overflowed - but the expiry time has not, then the timer must have already passed - its expiry time and should be processed immediately. */ - xProcessTimerNow = pdTRUE; - } - else - { - vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); - } - } - - return xProcessTimerNow; -} -/*-----------------------------------------------------------*/ - -static void prvProcessReceivedCommands( void ) -{ -xTIMER_MESSAGE xMessage; -xTIMER *pxTimer; -portBASE_TYPE xTimerListsWereSwitched, xResult; -portTickType xTimeNow; - - /* In this case the xTimerListsWereSwitched parameter is not used, but it - must be present in the function call. */ - xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); - - while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) - { - pxTimer = xMessage.pxTimer; - - /* Is the timer already in a list of active timers? When the command - is trmCOMMAND_PROCESS_TIMER_OVERFLOW, the timer will be NULL as the - command is to the task rather than to an individual timer. */ - if( pxTimer != NULL ) - { - if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) - { - /* The timer is in a list, remove it. */ - vListRemove( &( pxTimer->xTimerListItem ) ); - } - } - - traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue ); - - switch( xMessage.xMessageID ) - { - case tmrCOMMAND_START : - /* Start or restart a timer. */ - if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE ) - { - /* The timer expired before it was added to the active timer - list. Process it now. */ - pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); - - if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) - { - xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); - configASSERT( xResult ); - ( void ) xResult; - } - } - break; - - case tmrCOMMAND_STOP : - /* The timer has already been removed from the active list. - There is nothing to do here. */ - break; - - case tmrCOMMAND_CHANGE_PERIOD : - pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue; - configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); - prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); - break; - - case tmrCOMMAND_DELETE : - /* The timer has already been removed from the active list, - just free up the memory. */ - vPortFree( pxTimer ); - break; - - default : - /* Don't expect to get here. */ - break; - } - } -} -/*-----------------------------------------------------------*/ - -static void prvSwitchTimerLists( portTickType xLastTime ) -{ -portTickType xNextExpireTime, xReloadTime; -xList *pxTemp; -xTIMER *pxTimer; -portBASE_TYPE xResult; - - /* Remove compiler warnings if configASSERT() is not defined. */ - ( void ) xLastTime; - - /* The tick count has overflowed. The timer lists must be switched. - If there are any timers still referenced from the current timer list - then they must have expired and should be processed before the lists - are switched. */ - while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) - { - xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); - - /* Remove the timer from the list. */ - pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); - vListRemove( &( pxTimer->xTimerListItem ) ); - - /* Execute its callback, then send a command to restart the timer if - it is an auto-reload timer. It cannot be restarted here as the lists - have not yet been switched. */ - pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); - - if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) - { - /* Calculate the reload value, and if the reload value results in - the timer going into the same timer list then it has already expired - and the timer should be re-inserted into the current list so it is - processed again within this loop. Otherwise a command should be sent - to restart the timer to ensure it is only inserted into a list after - the lists have been swapped. */ - xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); - if( xReloadTime > xNextExpireTime ) - { - listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); - listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); - vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); - } - else - { - xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY ); - configASSERT( xResult ); - ( void ) xResult; - } - } - } - - pxTemp = pxCurrentTimerList; - pxCurrentTimerList = pxOverflowTimerList; - pxOverflowTimerList = pxTemp; -} -/*-----------------------------------------------------------*/ - -static void prvCheckForValidListAndQueue( void ) -{ - /* Check that the list from which active timers are referenced, and the - queue used to communicate with the timer service, have been - initialised. */ - taskENTER_CRITICAL(); - { - if( xTimerQueue == NULL ) - { - vListInitialise( &xActiveTimerList1 ); - vListInitialise( &xActiveTimerList2 ); - pxCurrentTimerList = &xActiveTimerList1; - pxOverflowTimerList = &xActiveTimerList2; - xTimerQueue = xQueueCreate( ( unsigned portBASE_TYPE ) configTIMER_QUEUE_LENGTH, sizeof( xTIMER_MESSAGE ) ); - } - } - taskEXIT_CRITICAL(); -} -/*-----------------------------------------------------------*/ - -portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) -{ -portBASE_TYPE xTimerIsInActiveList; -xTIMER *pxTimer = ( xTIMER * ) xTimer; - - /* Is the timer in the list of active timers? */ - taskENTER_CRITICAL(); - { - /* Checking to see if it is in the NULL list in effect checks to see if - it is referenced from either the current or the overflow timer lists in - one go, but the logic has to be reversed, hence the '!'. */ - xTimerIsInActiveList = !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); - } - taskEXIT_CRITICAL(); - - return xTimerIsInActiveList; -} -/*-----------------------------------------------------------*/ - -void *pvTimerGetTimerID( xTimerHandle xTimer ) -{ -xTIMER *pxTimer = ( xTIMER * ) xTimer; - - return pxTimer->pvTimerID; -} -/*-----------------------------------------------------------*/ - -/* This entire source file will be skipped if the application is not configured -to include software timer functionality. If you want to include software timer -functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ -#endif /* configUSE_TIMERS == 1 */ +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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. +*/ + +/* 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 "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. This #if is closed at the very bottom +of this file. If you want to include software timer functionality then ensure +configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#if ( configUSE_TIMERS == 1 ) + +/* Misc definitions. */ +#define tmrNO_DELAY ( portTickType ) 0U + +/* The definition of the timers themselves. */ +typedef struct tmrTimerControl +{ + const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ + xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ + portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ + unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */ + void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ + tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */ +} xTIMER; + +/* The definition of messages that can be sent and received on the timer +queue. */ +typedef struct tmrTimerQueueMessage +{ + portBASE_TYPE xMessageID; /*<< The command being sent to the timer service task. */ + portTickType xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ + xTIMER * pxTimer; /*<< The timer to which the command will be applied. */ +} xTIMER_MESSAGE; + + +/* The list in which active timers are stored. Timers are referenced in expire +time order, with the nearest expiry time at the front of the list. Only the +timer service task is allowed to access xActiveTimerList. */ +PRIVILEGED_DATA static xList xActiveTimerList1; +PRIVILEGED_DATA static xList xActiveTimerList2; +PRIVILEGED_DATA static xList *pxCurrentTimerList; +PRIVILEGED_DATA static xList *pxOverflowTimerList; + +/* A queue that is used to send commands to the timer service task. */ +PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL; + +/*-----------------------------------------------------------*/ + +/* + * Initialise the infrastructure used by the timer service task if it has not + * been initialised already. + */ +static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; + +/* + * The timer service task (daemon). Timer functionality is controlled by this + * task. Other tasks communicate with the timer service task using the + * xTimerQueue queue. + */ +static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION; + +/* + * Called by the timer service task to interpret and process a command it + * received on the timer queue. + */ +static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; + +/* + * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, + * depending on if the expire time causes a timer counter overflow. + */ +static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION; + +/* + * An active timer has reached its expire time. Reload the timer if it is an + * auto reload timer, then call its callback. + */ +static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION; + +/* + * The tick count has overflowed. Switch the timer lists after ensuring the + * current timer list does not still reference some timers. + */ +static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION; + +/* + * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE + * if a tick count overflow occurred since prvSampleTimeNow() was last called. + */ +static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; + +/* + * If the timer list contains any active timers then return the expire time of + * the timer that will expire first and set *pxListWasEmpty to false. If the + * timer list does not contain any timers then return 0 and set *pxListWasEmpty + * to pdTRUE. + */ +static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * If a timer has expired, process it. Otherwise, block the timer service task + * until either a timer does expire or a command is received. + */ +static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +portBASE_TYPE xTimerCreateTimerTask( void ) +{ +portBASE_TYPE xReturn = pdFAIL; + + /* This function is called when the scheduler is started if + configUSE_TIMERS is set to 1. Check that the infrastructure used by the + timer service task has been created/initialised. If timers have already + been created then the initialisation will already have been performed. */ + prvCheckForValidListAndQueue(); + + if( xTimerQueue != NULL ) + { + xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY, NULL); + } + + configASSERT( xReturn ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) +{ +xTIMER *pxNewTimer; + + /* Allocate the timer structure. */ + if( xTimerPeriodInTicks == ( portTickType ) 0U ) + { + pxNewTimer = NULL; + configASSERT( ( xTimerPeriodInTicks > 0 ) ); + } + else + { + pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) ); + if( pxNewTimer != NULL ) + { + /* Ensure the infrastructure used by the timer service task has been + created/initialised. */ + prvCheckForValidListAndQueue(); + + /* Initialise the timer structure members using the function parameters. */ + pxNewTimer->pcTimerName = pcTimerName; + pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; + pxNewTimer->uxAutoReload = uxAutoReload; + pxNewTimer->pvTimerID = pvTimerID; + pxNewTimer->pxCallbackFunction = pxCallbackFunction; + vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + + traceTIMER_CREATE( pxNewTimer ); + } + else + { + traceTIMER_CREATE_FAILED(); + } + } + + return ( xTimerHandle ) pxNewTimer; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) +{ +portBASE_TYPE xReturn = pdFAIL; +xTIMER_MESSAGE xMessage; + + /* Send a message to the timer service task to perform a particular action + on a particular timer definition. */ + if( xTimerQueue != NULL ) + { + /* Send a command to the timer service task to start the xTimer timer. */ + xMessage.xMessageID = xCommandID; + xMessage.xMessageValue = xOptionalValue; + xMessage.pxTimer = ( xTIMER * ) xTimer; + + if( pxHigherPriorityTaskWoken == NULL ) + { + if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime ); + } + else + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); + } + } + else + { + xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + } + + traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) +{ +xTIMER *pxTimer; +portBASE_TYPE xResult; + + /* Remove the timer from the list of active timers. A check has already + been performed to ensure the list is not empty. */ + pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); + vListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* If the timer is an auto reload timer then calculate the next + expiry time and re-insert the timer in the list of active timers. */ + if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) + { + /* This is the only time a timer is inserted into a list using + a time relative to anything other than the current time. It + will therefore be inserted into the correct list relative to + the time this task thinks it is now, even if a command to + switch lists due to a tick count overflow is already waiting in + the timer queue. */ + if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE ) + { + /* The timer expired before it was added to the active timer + list. Reload it now. */ + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + + /* Call the timer callback. */ + pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); +} +/*-----------------------------------------------------------*/ + +static void prvTimerTask( void *pvParameters ) +{ +portTickType xNextExpireTime; +portBASE_TYPE xListWasEmpty; + + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Query the timers list to see if it contains any timers, and if so, + obtain the time at which the next timer will expire. */ + xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); + + /* If a timer has expired, process it. Otherwise, block this task + until either a timer does expire, or a command is received. */ + prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); + + /* Empty the command queue. */ + prvProcessReceivedCommands(); + } +} +/*-----------------------------------------------------------*/ + +static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) +{ +portTickType xTimeNow; +portBASE_TYPE xTimerListsWereSwitched; + + vTaskSuspendAll(); + { + /* Obtain the time now to make an assessment as to whether the timer + has expired or not. If obtaining the time causes the lists to switch + then don't process this timer as any timers that remained in the list + when the lists were switched will have been processed within the + prvSampelTimeNow() function. */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + if( xTimerListsWereSwitched == pdFALSE ) + { + /* The tick count has not overflowed, has the timer expired? */ + if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) + { + xTaskResumeAll(); + prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); + } + else + { + /* The tick count has not overflowed, and the next expire + time has not been reached yet. This task should therefore + block to wait for the next expire time or a command to be + received - whichever comes first. The following line cannot + be reached unless xNextExpireTime > xTimeNow, except in the + case when the current timer list is empty. */ + vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) ); + + if( xTaskResumeAll() == pdFALSE ) + { + /* Yield to wait for either a command to arrive, or the block time + to expire. If a command arrived between the critical section being + exited and this yield then the yield will not cause the task + to block. */ + portYIELD_WITHIN_API(); + } + } + } + else + { + xTaskResumeAll(); + } + } +} +/*-----------------------------------------------------------*/ + +static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) +{ +portTickType xNextExpireTime; + + /* Timers are listed in expiry time order, with the head of the list + referencing the task that will expire first. Obtain the time at which + the timer with the nearest expiry time will expire. If there are no + active timers then just set the next expire time to 0. That will cause + this task to unblock when the tick count overflows, at which point the + timer lists will be switched and the next expiry time can be + re-assessed. */ + *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); + if( *pxListWasEmpty == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + } + else + { + /* Ensure the task unblocks when the tick count rolls over. */ + xNextExpireTime = ( portTickType ) 0U; + } + + return xNextExpireTime; +} +/*-----------------------------------------------------------*/ + +static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) +{ +portTickType xTimeNow; +static portTickType xLastTime = ( portTickType ) 0U; + + xTimeNow = xTaskGetTickCount(); + + if( xTimeNow < xLastTime ) + { + prvSwitchTimerLists( xLastTime ); + *pxTimerListsWereSwitched = pdTRUE; + } + else + { + *pxTimerListsWereSwitched = pdFALSE; + } + + xLastTime = xTimeNow; + + return xTimeNow; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) +{ +portBASE_TYPE xProcessTimerNow = pdFALSE; + + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + + if( xNextExpiryTime <= xTimeNow ) + { + /* Has the expiry time elapsed between the command to start/reset a + timer was issued, and the time the command was processed? */ + if( ( ( portTickType ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) + { + /* The time between a command being issued and the command being + processed actually exceeds the timers period. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); + } + } + else + { + if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) + { + /* If, since the command was issued, the tick count has overflowed + but the expiry time has not, then the timer must have already passed + its expiry time and should be processed immediately. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + } + + return xProcessTimerNow; +} +/*-----------------------------------------------------------*/ + +static void prvProcessReceivedCommands( void ) +{ +xTIMER_MESSAGE xMessage; +xTIMER *pxTimer; +portBASE_TYPE xTimerListsWereSwitched, xResult; +portTickType xTimeNow; + + /* In this case the xTimerListsWereSwitched parameter is not used, but it + must be present in the function call. */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + + while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) + { + pxTimer = xMessage.pxTimer; + + /* Is the timer already in a list of active timers? When the command + is trmCOMMAND_PROCESS_TIMER_OVERFLOW, the timer will be NULL as the + command is to the task rather than to an individual timer. */ + if( pxTimer != NULL ) + { + if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) + { + /* The timer is in a list, remove it. */ + vListRemove( &( pxTimer->xTimerListItem ) ); + } + } + + traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue ); + + switch( xMessage.xMessageID ) + { + case tmrCOMMAND_START : + /* Start or restart a timer. */ + if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE ) + { + /* The timer expired before it was added to the active timer + list. Process it now. */ + pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); + + if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + break; + + case tmrCOMMAND_STOP : + /* The timer has already been removed from the active list. + There is nothing to do here. */ + break; + + case tmrCOMMAND_CHANGE_PERIOD : + pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue; + configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); + prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); + break; + + case tmrCOMMAND_DELETE : + /* The timer has already been removed from the active list, + just free up the memory. */ + vPortFree( pxTimer ); + break; + + default : + /* Don't expect to get here. */ + break; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSwitchTimerLists( portTickType xLastTime ) +{ +portTickType xNextExpireTime, xReloadTime; +xList *pxTemp; +xTIMER *pxTimer; +portBASE_TYPE xResult; + + /* Remove compiler warnings if configASSERT() is not defined. */ + ( void ) xLastTime; + + /* The tick count has overflowed. The timer lists must be switched. + If there are any timers still referenced from the current timer list + then they must have expired and should be processed before the lists + are switched. */ + while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + + /* Remove the timer from the list. */ + pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); + vListRemove( &( pxTimer->xTimerListItem ) ); + + /* Execute its callback, then send a command to restart the timer if + it is an auto-reload timer. It cannot be restarted here as the lists + have not yet been switched. */ + pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); + + if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) + { + /* Calculate the reload value, and if the reload value results in + the timer going into the same timer list then it has already expired + and the timer should be re-inserted into the current list so it is + processed again within this loop. Otherwise a command should be sent + to restart the timer to ensure it is only inserted into a list after + the lists have been swapped. */ + xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); + if( xReloadTime > xNextExpireTime ) + { + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + else + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + } + + pxTemp = pxCurrentTimerList; + pxCurrentTimerList = pxOverflowTimerList; + pxOverflowTimerList = pxTemp; +} +/*-----------------------------------------------------------*/ + +static void prvCheckForValidListAndQueue( void ) +{ + /* Check that the list from which active timers are referenced, and the + queue used to communicate with the timer service, have been + initialised. */ + taskENTER_CRITICAL(); + { + if( xTimerQueue == NULL ) + { + vListInitialise( &xActiveTimerList1 ); + vListInitialise( &xActiveTimerList2 ); + pxCurrentTimerList = &xActiveTimerList1; + pxOverflowTimerList = &xActiveTimerList2; + xTimerQueue = xQueueCreate( ( unsigned portBASE_TYPE ) configTIMER_QUEUE_LENGTH, sizeof( xTIMER_MESSAGE ) ); + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) +{ +portBASE_TYPE xTimerIsInActiveList; +xTIMER *pxTimer = ( xTIMER * ) xTimer; + + /* Is the timer in the list of active timers? */ + taskENTER_CRITICAL(); + { + /* Checking to see if it is in the NULL list in effect checks to see if + it is referenced from either the current or the overflow timer lists in + one go, but the logic has to be reversed, hence the '!'. */ + xTimerIsInActiveList = !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); + } + taskEXIT_CRITICAL(); + + return xTimerIsInActiveList; +} +/*-----------------------------------------------------------*/ + +void *pvTimerGetTimerID( xTimerHandle xTimer ) +{ +xTIMER *pxTimer = ( xTIMER * ) xTimer; + + return pxTimer->pvTimerID; +} +/*-----------------------------------------------------------*/ + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. If you want to include software timer +functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#endif /* configUSE_TIMERS == 1 */ diff --git a/Libmaple/libmaple/libraries/FreeRTOS/utility/timers.h b/Libmaple/libmaple/libraries/FreeRTOS/utility/timers.h index 3d78c0ae..f1bcb0d8 100644 --- a/Libmaple/libmaple/libraries/FreeRTOS/utility/timers.h +++ b/Libmaple/libmaple/libraries/FreeRTOS/utility/timers.h @@ -1,936 +1,936 @@ -/* - FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. - - - FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: - Atollic AB - Atollic provides professional embedded systems development - tools for C/C++ development, code analysis and test automation. - See http://www.atollic.com - - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and 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 modification 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 TIMERS_H -#define TIMERS_H - -#ifndef INC_FREERTOS_H - #error "include FreeRTOS.h must appear in source files before include timers.h" -#endif - -#include "portable.h" -#include "list.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* IDs for commands that can be sent/received on the timer queue. These are to -be used solely through the macros that make up the public software timer API, -as defined below. */ -#define tmrCOMMAND_START 0 -#define tmrCOMMAND_STOP 1 -#define tmrCOMMAND_CHANGE_PERIOD 2 -#define tmrCOMMAND_DELETE 3 - -/*----------------------------------------------------------- - * MACROS AND DEFINITIONS - *----------------------------------------------------------*/ - - /** - * Type by which software timers are referenced. For example, a call to - * xTimerCreate() returns an xTimerHandle variable that can then be used to - * reference the subject timer in calls to other software timer API functions - * (for example, xTimerStart(), xTimerReset(), etc.). - */ -typedef void * xTimerHandle; - -/* Define the prototype to which timer callback functions must conform. */ -typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer ); - -/** - * xTimerHandle xTimerCreate( const signed char *pcTimerName, - * portTickType xTimerPeriod, - * unsigned portBASE_TYPE uxAutoReload, - * void * pvTimerID, - * tmrTIMER_CALLBACK pxCallbackFunction ); - * - * Creates a new software timer instance. This allocates the storage required - * by the new timer, initialises the new timers internal state, and returns a - * handle by which the new timer can be referenced. - * - * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), - * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and - * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the - * active state. - * - * @param pcTimerName A text name that is assigned to the timer. This is done - * purely to assist debugging. The kernel itself only ever references a timer by - * its handle, and never by its name. - * - * @param xTimerPeriod The timer period. The time is defined in tick periods so - * the constant portTICK_RATE_MS can be used to convert a time that has been - * specified in milliseconds. For example, if the timer must expire after 100 - * ticks, then xTimerPeriod should be set to 100. Alternatively, if the timer - * must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_RATE_MS ) - * provided configTICK_RATE_HZ is less than or equal to 1000. - * - * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will - * expire repeatedly with a frequency set by the xTimerPeriod parameter. If - * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and - * enter the dormant state after it expires. - * - * @param pvTimerID An identifier that is assigned to the timer being created. - * Typically this would be used in the timer callback function to identify which - * timer expired when the same callback function is assigned to more than one - * timer. - * - * @param pxCallbackFunction The function to call when the timer expires. - * Callback functions must have the prototype defined by tmrTIMER_CALLBACK, - * which is "void vCallbackFunction( xTIMER *xTimer );". - * - * @return If the timer is successfully create then a handle to the newly - * created timer is returned. If the timer cannot be created (because either - * there is insufficient FreeRTOS heap remaining to allocate the timer - * structures, or the timer period was set to 0) then 0 is returned. - * - * Example usage: - * - * - * #define NUM_TIMERS 5 - * - * // An array to hold handles to the created timers. - * xTimerHandle xTimers[ NUM_TIMERS ]; - * - * // An array to hold a count of the number of times each timer expires. - * long lExpireCounters[ NUM_TIMERS ] = { 0 }; - * - * // Define a callback function that will be used by multiple timer instances. - * // The callback function does nothing but count the number of times the - * // associated timer expires, and stop the timer once the timer has expired - * // 10 times. - * void vTimerCallback( xTIMER *pxTimer ) - * { - * long lArrayIndex; - * const long xMaxExpiryCountBeforeStopping = 10; - * - * // Optionally do something if the pxTimer parameter is NULL. - * configASSERT( pxTimer ); - * - * // Which timer expired? - * lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer ); - * - * // Increment the number of times that pxTimer has expired. - * lExpireCounters[ lArrayIndex ] += 1; - * - * // If the timer has expired 10 times then stop it from running. - * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) - * { - * // Do not use a block time if calling a timer API function from a - * // timer callback function, as doing so could cause a deadlock! - * xTimerStop( pxTimer, 0 ); - * } - * } - * - * void main( void ) - * { - * long x; - * - * // Create then start some timers. Starting the timers before the scheduler - * // has been started means the timers will start running immediately that - * // the scheduler starts. - * for( x = 0; x < NUM_TIMERS; x++ ) - * { - * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. - * ( 100 * x ), // The timer period in ticks. - * pdTRUE, // The timers will auto-reload themselves when they expire. - * ( void * ) x, // Assign each timer a unique id equal to its array index. - * vTimerCallback // Each timer calls the same callback when it expires. - * ); - * - * if( xTimers[ x ] == NULL ) - * { - * // The timer was not created. - * } - * else - * { - * // Start the timer. No block time is specified, and even if one was - * // it would be ignored because the scheduler has not yet been - * // started. - * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) - * { - * // The timer could not be set into the Active state. - * } - * } - * } - * - * // ... - * // Create tasks here. - * // ... - * - * // Starting the scheduler will start the timers running as they have already - * // been set into the active state. - * xTaskStartScheduler(); - * - * // Should not reach here. - * for( ;; ); - * } - */ -xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION; - -/** - * void *pvTimerGetTimerID( xTimerHandle xTimer ); - * - * Returns the ID assigned to the timer. - * - * IDs are assigned to timers using the pvTimerID parameter of the call to - * xTimerCreated() that was used to create the timer. - * - * If the same callback function is assigned to multiple timers then the timer - * ID can be used within the callback function to identify which timer actually - * expired. - * - * @param xTimer The timer being queried. - * - * @return The ID assigned to the timer being queried. - * - * Example usage: - * - * See the xTimerCreate() API function example usage scenario. - */ -void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION; - -/** - * portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ); - * - * Queries a timer to see if it is active or dormant. - * - * A timer will be dormant if: - * 1) It has been created but not started, or - * 2) It is an expired on-shot timer that has not been restarted. - * - * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), - * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and - * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the - * active state. - * - * @param xTimer The timer being queried. - * - * @return pdFALSE will be returned if the timer is dormant. A value other than - * pdFALSE will be returned if the timer is active. - * - * Example usage: - * - * // This function assumes xTimer has already been created. - * void vAFunction( xTimerHandle xTimer ) - * { - * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" - * { - * // xTimer is active, do something. - * } - * else - * { - * // xTimer is not active, do something else. - * } - * } - */ -portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION; - -/** - * portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime ); - * - * Timer functionality is provided by a timer service/daemon task. Many of the - * public FreeRTOS timer API functions send commands to the timer service task - * though a queue called the timer command queue. The timer command queue is - * private to the kernel itself and is not directly accessible to application - * code. The length of the timer command queue is set by the - * configTIMER_QUEUE_LENGTH configuration constant. - * - * xTimerStart() starts a timer that was previously created using the - * xTimerCreate() API function. If the timer had already been started and was - * already in the active state, then xTimerStart() has equivalent functionality - * to the xTimerReset() API function. - * - * Starting a timer ensures the timer is in the active state. If the timer - * is not stopped, deleted, or reset in the mean time, the callback function - * associated with the timer will get called 'n' ticks after xTimerStart() was - * called, where 'n' is the timers defined period. - * - * It is valid to call xTimerStart() before the scheduler has been started, but - * when this is done the timer will not actually start until the scheduler is - * started, and the timers expiry time will be relative to when the scheduler is - * started, not relative to when xTimerStart() was called. - * - * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() - * to be available. - * - * @param xTimer The handle of the timer being started/restarted. - * - * @param xBlockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the start command to be successfully - * sent to the timer command queue, should the queue already be full when - * xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called - * before the scheduler is started. - * - * @return pdFAIL will be returned if the start command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will - * be returned if the command was successfully sent to the timer command queue. - * When the command is actually processed will depend on the priority of the - * timer service/daemon task relative to other tasks in the system, although the - * timers expiry time is relative to when xTimerStart() is actually called. The - * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * - * Example usage: - * - * See the xTimerCreate() API function example usage scenario. - * - */ -#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) - -/** - * portBASE_TYPE xTimerStop( xTimerHandle xTimer, portTickType xBlockTime ); - * - * Timer functionality is provided by a timer service/daemon task. Many of the - * public FreeRTOS timer API functions send commands to the timer service task - * though a queue called the timer command queue. The timer command queue is - * private to the kernel itself and is not directly accessible to application - * code. The length of the timer command queue is set by the - * configTIMER_QUEUE_LENGTH configuration constant. - * - * xTimerStop() stops a timer that was previously started using either of the - * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), - * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. - * - * Stopping a timer ensures the timer is not in the active state. - * - * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() - * to be available. - * - * @param xTimer The handle of the timer being stopped. - * - * @param xBlockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the stop command to be successfully - * sent to the timer command queue, should the queue already be full when - * xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called - * before the scheduler is started. - * - * @return pdFAIL will be returned if the stop command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will - * be returned if the command was successfully sent to the timer command queue. - * When the command is actually processed will depend on the priority of the - * timer service/daemon task relative to other tasks in the system. The timer - * service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * - * Example usage: - * - * See the xTimerCreate() API function example usage scenario. - * - */ -#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) ) - -/** - * portBASE_TYPE xTimerChangePeriod( xTimerHandle xTimer, - * portTickType xNewPeriod, - * portTickType xBlockTime ); - * - * Timer functionality is provided by a timer service/daemon task. Many of the - * public FreeRTOS timer API functions send commands to the timer service task - * though a queue called the timer command queue. The timer command queue is - * private to the kernel itself and is not directly accessible to application - * code. The length of the timer command queue is set by the - * configTIMER_QUEUE_LENGTH configuration constant. - * - * xTimerChangePeriod() changes the period of a timer that was previously - * created using the xTimerCreate() API function. - * - * xTimerChangePeriod() can be called to change the period of an active or - * dormant state timer. - * - * The configUSE_TIMERS configuration constant must be set to 1 for - * xTimerChangePeriod() to be available. - * - * @param xTimer The handle of the timer that is having its period changed. - * - * @param xNewPeriod The new period for xTimer. Timer periods are specified in - * tick periods, so the constant portTICK_RATE_MS can be used to convert a time - * that has been specified in milliseconds. For example, if the timer must - * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, - * if the timer must expire after 500ms, then xNewPeriod can be set to - * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than - * or equal to 1000. - * - * @param xBlockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the change period command to be - * successfully sent to the timer command queue, should the queue already be - * full when xTimerChangePeriod() was called. xBlockTime is ignored if - * xTimerChangePeriod() is called before the scheduler is started. - * - * @return pdFAIL will be returned if the change period command could not be - * sent to the timer command queue even after xBlockTime ticks had passed. - * pdPASS will be returned if the command was successfully sent to the timer - * command queue. When the command is actually processed will depend on the - * priority of the timer service/daemon task relative to other tasks in the - * system. The timer service/daemon task priority is set by the - * configTIMER_TASK_PRIORITY configuration constant. - * - * Example usage: - * - * // This function assumes xTimer has already been created. If the timer - * // referenced by xTimer is already active when it is called, then the timer - * // is deleted. If the timer referenced by xTimer is not active when it is - * // called, then the period of the timer is set to 500ms and the timer is - * // started. - * void vAFunction( xTimerHandle xTimer ) - * { - * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" - * { - * // xTimer is already active - delete it. - * xTimerDelete( xTimer ); - * } - * else - * { - * // xTimer is not active, change its period to 500ms. This will also - * // cause the timer to start. Block for a maximum of 100 ticks if the - * // change period command cannot immediately be sent to the timer - * // command queue. - * if( xTimerChangePeriod( xTimer, 500 / portTICK_RATE_MS, 100 ) == pdPASS ) - * { - * // The command was successfully sent. - * } - * else - * { - * // The command could not be sent, even after waiting for 100 ticks - * // to pass. Take appropriate action here. - * } - * } - * } - */ - #define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) ) - -/** - * portBASE_TYPE xTimerDelete( xTimerHandle xTimer, portTickType xBlockTime ); - * - * Timer functionality is provided by a timer service/daemon task. Many of the - * public FreeRTOS timer API functions send commands to the timer service task - * though a queue called the timer command queue. The timer command queue is - * private to the kernel itself and is not directly accessible to application - * code. The length of the timer command queue is set by the - * configTIMER_QUEUE_LENGTH configuration constant. - * - * xTimerDelete() deletes a timer that was previously created using the - * xTimerCreate() API function. - * - * The configUSE_TIMERS configuration constant must be set to 1 for - * xTimerDelete() to be available. - * - * @param xTimer The handle of the timer being deleted. - * - * @param xBlockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the delete command to be - * successfully sent to the timer command queue, should the queue already be - * full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete() - * is called before the scheduler is started. - * - * @return pdFAIL will be returned if the delete command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will - * be returned if the command was successfully sent to the timer command queue. - * When the command is actually processed will depend on the priority of the - * timer service/daemon task relative to other tasks in the system. The timer - * service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * - * Example usage: - * - * See the xTimerChangePeriod() API function example usage scenario. - */ -#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) ) - -/** - * portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType xBlockTime ); - * - * Timer functionality is provided by a timer service/daemon task. Many of the - * public FreeRTOS timer API functions send commands to the timer service task - * though a queue called the timer command queue. The timer command queue is - * private to the kernel itself and is not directly accessible to application - * code. The length of the timer command queue is set by the - * configTIMER_QUEUE_LENGTH configuration constant. - * - * xTimerReset() re-starts a timer that was previously created using the - * xTimerCreate() API function. If the timer had already been started and was - * already in the active state, then xTimerReset() will cause the timer to - * re-evaluate its expiry time so that it is relative to when xTimerReset() was - * called. If the timer was in the dormant state then xTimerReset() has - * equivalent functionality to the xTimerStart() API function. - * - * Resetting a timer ensures the timer is in the active state. If the timer - * is not stopped, deleted, or reset in the mean time, the callback function - * associated with the timer will get called 'n' ticks after xTimerReset() was - * called, where 'n' is the timers defined period. - * - * It is valid to call xTimerReset() before the scheduler has been started, but - * when this is done the timer will not actually start until the scheduler is - * started, and the timers expiry time will be relative to when the scheduler is - * started, not relative to when xTimerReset() was called. - * - * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() - * to be available. - * - * @param xTimer The handle of the timer being reset/started/restarted. - * - * @param xBlockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the reset command to be successfully - * sent to the timer command queue, should the queue already be full when - * xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called - * before the scheduler is started. - * - * @return pdFAIL will be returned if the reset command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will - * be returned if the command was successfully sent to the timer command queue. - * When the command is actually processed will depend on the priority of the - * timer service/daemon task relative to other tasks in the system, although the - * timers expiry time is relative to when xTimerStart() is actually called. The - * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * - * Example usage: - * - * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass - * // without a key being pressed, then the LCD back-light is switched off. In - * // this case, the timer is a one-shot timer. - * - * xTimerHandle xBacklightTimer = NULL; - * - * // The callback function assigned to the one-shot timer. In this case the - * // parameter is not used. - * void vBacklightTimerCallback( xTIMER *pxTimer ) - * { - * // The timer expired, therefore 5 seconds must have passed since a key - * // was pressed. Switch off the LCD back-light. - * vSetBacklightState( BACKLIGHT_OFF ); - * } - * - * // The key press event handler. - * void vKeyPressEventHandler( char cKey ) - * { - * // Ensure the LCD back-light is on, then reset the timer that is - * // responsible for turning the back-light off after 5 seconds of - * // key inactivity. Wait 10 ticks for the command to be successfully sent - * // if it cannot be sent immediately. - * vSetBacklightState( BACKLIGHT_ON ); - * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) - * { - * // The reset command was not executed successfully. Take appropriate - * // action here. - * } - * - * // Perform the rest of the key processing here. - * } - * - * void main( void ) - * { - * long x; - * - * // Create then start the one-shot timer that is responsible for turning - * // the back-light off if no keys are pressed within a 5 second period. - * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. - * ( 5000 / portTICK_RATE_MS), // The timer period in ticks. - * pdFALSE, // The timer is a one-shot timer. - * 0, // The id is not used by the callback so can take any value. - * vBacklightTimerCallback // The callback function that switches the LCD back-light off. - * ); - * - * if( xBacklightTimer == NULL ) - * { - * // The timer was not created. - * } - * else - * { - * // Start the timer. No block time is specified, and even if one was - * // it would be ignored because the scheduler has not yet been - * // started. - * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) - * { - * // The timer could not be set into the Active state. - * } - * } - * - * // ... - * // Create tasks here. - * // ... - * - * // Starting the scheduler will start the timer running as it has already - * // been set into the active state. - * xTaskStartScheduler(); - * - * // Should not reach here. - * for( ;; ); - * } - */ -#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) - -/** - * portBASE_TYPE xTimerStartFromISR( xTimerHandle xTimer, - * portBASE_TYPE *pxHigherPriorityTaskWoken ); - * - * A version of xTimerStart() that can be called from an interrupt service - * routine. - * - * @param xTimer The handle of the timer being started/restarted. - * - * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most - * of its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling xTimerStartFromISR() writes a message to the timer - * command queue, so has the potential to transition the timer service/daemon - * task out of the Blocked state. If calling xTimerStartFromISR() causes the - * timer service/daemon task to leave the Blocked state, and the timer service/ - * daemon task has a priority equal to or greater than the currently executing - * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will - * get set to pdTRUE internally within the xTimerStartFromISR() function. If - * xTimerStartFromISR() sets this value to pdTRUE then a context switch should - * be performed before the interrupt exits. - * - * @return pdFAIL will be returned if the start command could not be sent to - * the timer command queue. pdPASS will be returned if the command was - * successfully sent to the timer command queue. When the command is actually - * processed will depend on the priority of the timer service/daemon task - * relative to other tasks in the system, although the timers expiry time is - * relative to when xTimerStartFromISR() is actually called. The timer service/daemon - * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. - * - * Example usage: - * - * // This scenario assumes xBacklightTimer has already been created. When a - * // key is pressed, an LCD back-light is switched on. If 5 seconds pass - * // without a key being pressed, then the LCD back-light is switched off. In - * // this case, the timer is a one-shot timer, and unlike the example given for - * // the xTimerReset() function, the key press event handler is an interrupt - * // service routine. - * - * // The callback function assigned to the one-shot timer. In this case the - * // parameter is not used. - * void vBacklightTimerCallback( xTIMER *pxTimer ) - * { - * // The timer expired, therefore 5 seconds must have passed since a key - * // was pressed. Switch off the LCD back-light. - * vSetBacklightState( BACKLIGHT_OFF ); - * } - * - * // The key press interrupt service routine. - * void vKeyPressEventInterruptHandler( void ) - * { - * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - * - * // Ensure the LCD back-light is on, then restart the timer that is - * // responsible for turning the back-light off after 5 seconds of - * // key inactivity. This is an interrupt service routine so can only - * // call FreeRTOS API functions that end in "FromISR". - * vSetBacklightState( BACKLIGHT_ON ); - * - * // xTimerStartFromISR() or xTimerResetFromISR() could be called here - * // as both cause the timer to re-calculate its expiry time. - * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was - * // declared (in this function). - * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) - * { - * // The start command was not executed successfully. Take appropriate - * // action here. - * } - * - * // Perform the rest of the key processing here. - * - * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch - * // should be performed. The syntax required to perform a context switch - * // from inside an ISR varies from port to port, and from compiler to - * // compiler. Inspect the demos for the port you are using to find the - * // actual syntax required. - * if( xHigherPriorityTaskWoken != pdFALSE ) - * { - * // Call the interrupt safe yield function here (actual function - * // depends on the FreeRTOS port being used. - * } - * } - */ -#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) - -/** - * portBASE_TYPE xTimerStopFromISR( xTimerHandle xTimer, - * portBASE_TYPE *pxHigherPriorityTaskWoken ); - * - * A version of xTimerStop() that can be called from an interrupt service - * routine. - * - * @param xTimer The handle of the timer being stopped. - * - * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most - * of its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling xTimerStopFromISR() writes a message to the timer - * command queue, so has the potential to transition the timer service/daemon - * task out of the Blocked state. If calling xTimerStopFromISR() causes the - * timer service/daemon task to leave the Blocked state, and the timer service/ - * daemon task has a priority equal to or greater than the currently executing - * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will - * get set to pdTRUE internally within the xTimerStopFromISR() function. If - * xTimerStopFromISR() sets this value to pdTRUE then a context switch should - * be performed before the interrupt exits. - * - * @return pdFAIL will be returned if the stop command could not be sent to - * the timer command queue. pdPASS will be returned if the command was - * successfully sent to the timer command queue. When the command is actually - * processed will depend on the priority of the timer service/daemon task - * relative to other tasks in the system. The timer service/daemon task - * priority is set by the configTIMER_TASK_PRIORITY configuration constant. - * - * Example usage: - * - * // This scenario assumes xTimer has already been created and started. When - * // an interrupt occurs, the timer should be simply stopped. - * - * // The interrupt service routine that stops the timer. - * void vAnExampleInterruptServiceRoutine( void ) - * { - * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - * - * // The interrupt has occurred - simply stop the timer. - * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined - * // (within this function). As this is an interrupt service routine, only - * // FreeRTOS API functions that end in "FromISR" can be used. - * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) - * { - * // The stop command was not executed successfully. Take appropriate - * // action here. - * } - * - * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch - * // should be performed. The syntax required to perform a context switch - * // from inside an ISR varies from port to port, and from compiler to - * // compiler. Inspect the demos for the port you are using to find the - * // actual syntax required. - * if( xHigherPriorityTaskWoken != pdFALSE ) - * { - * // Call the interrupt safe yield function here (actual function - * // depends on the FreeRTOS port being used. - * } - * } - */ -#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U ) - -/** - * portBASE_TYPE xTimerChangePeriodFromISR( xTimerHandle xTimer, - * portTickType xNewPeriod, - * portBASE_TYPE *pxHigherPriorityTaskWoken ); - * - * A version of xTimerChangePeriod() that can be called from an interrupt - * service routine. - * - * @param xTimer The handle of the timer that is having its period changed. - * - * @param xNewPeriod The new period for xTimer. Timer periods are specified in - * tick periods, so the constant portTICK_RATE_MS can be used to convert a time - * that has been specified in milliseconds. For example, if the timer must - * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, - * if the timer must expire after 500ms, then xNewPeriod can be set to - * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than - * or equal to 1000. - * - * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most - * of its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling xTimerChangePeriodFromISR() writes a message to the - * timer command queue, so has the potential to transition the timer service/ - * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() - * causes the timer service/daemon task to leave the Blocked state, and the - * timer service/daemon task has a priority equal to or greater than the - * currently executing task (the task that was interrupted), then - * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the - * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets - * this value to pdTRUE then a context switch should be performed before the - * interrupt exits. - * - * @return pdFAIL will be returned if the command to change the timers period - * could not be sent to the timer command queue. pdPASS will be returned if the - * command was successfully sent to the timer command queue. When the command - * is actually processed will depend on the priority of the timer service/daemon - * task relative to other tasks in the system. The timer service/daemon task - * priority is set by the configTIMER_TASK_PRIORITY configuration constant. - * - * Example usage: - * - * // This scenario assumes xTimer has already been created and started. When - * // an interrupt occurs, the period of xTimer should be changed to 500ms. - * - * // The interrupt service routine that changes the period of xTimer. - * void vAnExampleInterruptServiceRoutine( void ) - * { - * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - * - * // The interrupt has occurred - change the period of xTimer to 500ms. - * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined - * // (within this function). As this is an interrupt service routine, only - * // FreeRTOS API functions that end in "FromISR" can be used. - * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) - * { - * // The command to change the timers period was not executed - * // successfully. Take appropriate action here. - * } - * - * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch - * // should be performed. The syntax required to perform a context switch - * // from inside an ISR varies from port to port, and from compiler to - * // compiler. Inspect the demos for the port you are using to find the - * // actual syntax required. - * if( xHigherPriorityTaskWoken != pdFALSE ) - * { - * // Call the interrupt safe yield function here (actual function - * // depends on the FreeRTOS port being used. - * } - * } - */ -#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) - -/** - * portBASE_TYPE xTimerResetFromISR( xTimerHandle xTimer, - * portBASE_TYPE *pxHigherPriorityTaskWoken ); - * - * A version of xTimerReset() that can be called from an interrupt service - * routine. - * - * @param xTimer The handle of the timer that is to be started, reset, or - * restarted. - * - * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most - * of its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling xTimerResetFromISR() writes a message to the timer - * command queue, so has the potential to transition the timer service/daemon - * task out of the Blocked state. If calling xTimerResetFromISR() causes the - * timer service/daemon task to leave the Blocked state, and the timer service/ - * daemon task has a priority equal to or greater than the currently executing - * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will - * get set to pdTRUE internally within the xTimerResetFromISR() function. If - * xTimerResetFromISR() sets this value to pdTRUE then a context switch should - * be performed before the interrupt exits. - * - * @return pdFAIL will be returned if the reset command could not be sent to - * the timer command queue. pdPASS will be returned if the command was - * successfully sent to the timer command queue. When the command is actually - * processed will depend on the priority of the timer service/daemon task - * relative to other tasks in the system, although the timers expiry time is - * relative to when xTimerResetFromISR() is actually called. The timer service/daemon - * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. - * - * Example usage: - * - * // This scenario assumes xBacklightTimer has already been created. When a - * // key is pressed, an LCD back-light is switched on. If 5 seconds pass - * // without a key being pressed, then the LCD back-light is switched off. In - * // this case, the timer is a one-shot timer, and unlike the example given for - * // the xTimerReset() function, the key press event handler is an interrupt - * // service routine. - * - * // The callback function assigned to the one-shot timer. In this case the - * // parameter is not used. - * void vBacklightTimerCallback( xTIMER *pxTimer ) - * { - * // The timer expired, therefore 5 seconds must have passed since a key - * // was pressed. Switch off the LCD back-light. - * vSetBacklightState( BACKLIGHT_OFF ); - * } - * - * // The key press interrupt service routine. - * void vKeyPressEventInterruptHandler( void ) - * { - * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - * - * // Ensure the LCD back-light is on, then reset the timer that is - * // responsible for turning the back-light off after 5 seconds of - * // key inactivity. This is an interrupt service routine so can only - * // call FreeRTOS API functions that end in "FromISR". - * vSetBacklightState( BACKLIGHT_ON ); - * - * // xTimerStartFromISR() or xTimerResetFromISR() could be called here - * // as both cause the timer to re-calculate its expiry time. - * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was - * // declared (in this function). - * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) - * { - * // The reset command was not executed successfully. Take appropriate - * // action here. - * } - * - * // Perform the rest of the key processing here. - * - * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch - * // should be performed. The syntax required to perform a context switch - * // from inside an ISR varies from port to port, and from compiler to - * // compiler. Inspect the demos for the port you are using to find the - * // actual syntax required. - * if( xHigherPriorityTaskWoken != pdFALSE ) - * { - * // Call the interrupt safe yield function here (actual function - * // depends on the FreeRTOS port being used. - * } - * } - */ -#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) - -/* - * Functions beyond this part are not part of the public API and are intended - * for use by the kernel only. - */ -portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; -portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION; - -#ifdef __cplusplus -} -#endif -#endif /* TIMERS_H */ - - - +/* + FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 TIMERS_H +#define TIMERS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include timers.h" +#endif + +#include "portable.h" +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* IDs for commands that can be sent/received on the timer queue. These are to +be used solely through the macros that make up the public software timer API, +as defined below. */ +#define tmrCOMMAND_START 0 +#define tmrCOMMAND_STOP 1 +#define tmrCOMMAND_CHANGE_PERIOD 2 +#define tmrCOMMAND_DELETE 3 + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + + /** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an xTimerHandle variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ +typedef void * xTimerHandle; + +/* Define the prototype to which timer callback functions must conform. */ +typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer ); + +/** + * xTimerHandle xTimerCreate( const signed char *pcTimerName, + * portTickType xTimerPeriod, + * unsigned portBASE_TYPE uxAutoReload, + * void * pvTimerID, + * tmrTIMER_CALLBACK pxCallbackFunction ); + * + * Creates a new software timer instance. This allocates the storage required + * by the new timer, initialises the new timers internal state, and returns a + * handle by which the new timer can be referenced. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer by + * its handle, and never by its name. + * + * @param xTimerPeriod The timer period. The time is defined in tick periods so + * the constant portTICK_RATE_MS can be used to convert a time that has been + * specified in milliseconds. For example, if the timer must expire after 100 + * ticks, then xTimerPeriod should be set to 100. Alternatively, if the timer + * must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_RATE_MS ) + * provided configTICK_RATE_HZ is less than or equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriod parameter. If + * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by tmrTIMER_CALLBACK, + * which is "void vCallbackFunction( xTIMER *xTimer );". + * + * @return If the timer is successfully create then a handle to the newly + * created timer is returned. If the timer cannot be created (because either + * there is insufficient FreeRTOS heap remaining to allocate the timer + * structures, or the timer period was set to 0) then 0 is returned. + * + * Example usage: + * + * + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * xTimerHandle xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * long lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( xTIMER *pxTimer ) + * { + * long lArrayIndex; + * const long xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * long x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * x ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * xTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + */ +xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION; + +/** + * void *pvTimerGetTimerID( xTimerHandle xTimer ); + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used within the callback function to identify which timer actually + * expired. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION; + +/** + * portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ); + * + * Queries a timer to see if it is active or dormant. + * + * A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired on-shot timer that has not been restarted. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * + * // This function assumes xTimer has already been created. + * void vAFunction( xTimerHandle xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + */ +portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION; + +/** + * portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * though a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStart() starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerStart() has equivalent functionality + * to the xTimerReset() API function. + * + * Starting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerStart() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerStart() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerStart() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() + * to be available. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param xBlockTime Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the start command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) + +/** + * portBASE_TYPE xTimerStop( xTimerHandle xTimer, portTickType xBlockTime ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * though a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStop() stops a timer that was previously started using either of the + * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), + * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. + * + * Stopping a timer ensures the timer is not in the active state. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() + * to be available. + * + * @param xTimer The handle of the timer being stopped. + * + * @param xBlockTime Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) ) + +/** + * portBASE_TYPE xTimerChangePeriod( xTimerHandle xTimer, + * portTickType xNewPeriod, + * portTickType xBlockTime ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * though a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerChangePeriod() changes the period of a timer that was previously + * created using the xTimerCreate() API function. + * + * xTimerChangePeriod() can be called to change the period of an active or + * dormant state timer. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerChangePeriod() to be available. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_RATE_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param xBlockTime Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerChangePeriod() was called. xBlockTime is ignored if + * xTimerChangePeriod() is called before the scheduler is started. + * + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xBlockTime ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. The timer service/daemon task priority is set by the + * configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * + * // This function assumes xTimer has already been created. If the timer + * // referenced by xTimer is already active when it is called, then the timer + * // is deleted. If the timer referenced by xTimer is not active when it is + * // called, then the period of the timer is set to 500ms and the timer is + * // started. + * void vAFunction( xTimerHandle xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is already active - delete it. + * xTimerDelete( xTimer ); + * } + * else + * { + * // xTimer is not active, change its period to 500ms. This will also + * // cause the timer to start. Block for a maximum of 100 ticks if the + * // change period command cannot immediately be sent to the timer + * // command queue. + * if( xTimerChangePeriod( xTimer, 500 / portTICK_RATE_MS, 100 ) == pdPASS ) + * { + * // The command was successfully sent. + * } + * else + * { + * // The command could not be sent, even after waiting for 100 ticks + * // to pass. Take appropriate action here. + * } + * } + * } + */ + #define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) ) + +/** + * portBASE_TYPE xTimerDelete( xTimerHandle xTimer, portTickType xBlockTime ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * though a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerDelete() deletes a timer that was previously created using the + * xTimerCreate() API function. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerDelete() to be available. + * + * @param xTimer The handle of the timer being deleted. + * + * @param xBlockTime Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the delete command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete() + * is called before the scheduler is started. + * + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerChangePeriod() API function example usage scenario. + */ +#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) ) + +/** + * portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType xBlockTime ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * though a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerReset() re-starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerReset() will cause the timer to + * re-evaluate its expiry time so that it is relative to when xTimerReset() was + * called. If the timer was in the dormant state then xTimerReset() has + * equivalent functionality to the xTimerStart() API function. + * + * Resetting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerReset() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerReset() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerReset() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() + * to be available. + * + * @param xTimer The handle of the timer being reset/started/restarted. + * + * @param xBlockTime Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the reset command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer. + * + * xTimerHandle xBacklightTimer = NULL; + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( xTIMER *pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press event handler. + * void vKeyPressEventHandler( char cKey ) + * { + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. Wait 10 ticks for the command to be successfully sent + * // if it cannot be sent immediately. + * vSetBacklightState( BACKLIGHT_ON ); + * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * } + * + * void main( void ) + * { + * long x; + * + * // Create then start the one-shot timer that is responsible for turning + * // the back-light off if no keys are pressed within a 5 second period. + * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. + * ( 5000 / portTICK_RATE_MS), // The timer period in ticks. + * pdFALSE, // The timer is a one-shot timer. + * 0, // The id is not used by the callback so can take any value. + * vBacklightTimerCallback // The callback function that switches the LCD back-light off. + * ); + * + * if( xBacklightTimer == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timer running as it has already + * // been set into the active state. + * xTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + */ +#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) + +/** + * portBASE_TYPE xTimerStartFromISR( xTimerHandle xTimer, + * portBASE_TYPE *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStart() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStartFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStartFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStartFromISR() function. If + * xTimerStartFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerStartFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( xTIMER *pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then restart the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The start command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used. + * } + * } + */ +#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * portBASE_TYPE xTimerStopFromISR( xTimerHandle xTimer, + * portBASE_TYPE *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStop() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being stopped. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStopFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStopFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStopFromISR() function. If + * xTimerStopFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the timer should be simply stopped. + * + * // The interrupt service routine that stops the timer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - simply stop the timer. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The stop command was not executed successfully. Take appropriate + * // action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used. + * } + * } + */ +#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * portBASE_TYPE xTimerChangePeriodFromISR( xTimerHandle xTimer, + * portTickType xNewPeriod, + * portBASE_TYPE *pxHigherPriorityTaskWoken ); + * + * A version of xTimerChangePeriod() that can be called from an interrupt + * service routine. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_RATE_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerChangePeriodFromISR() writes a message to the + * timer command queue, so has the potential to transition the timer service/ + * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() + * causes the timer service/daemon task to leave the Blocked state, and the + * timer service/daemon task has a priority equal to or greater than the + * currently executing task (the task that was interrupted), then + * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the + * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets + * this value to pdTRUE then a context switch should be performed before the + * interrupt exits. + * + * @return pdFAIL will be returned if the command to change the timers period + * could not be sent to the timer command queue. pdPASS will be returned if the + * command was successfully sent to the timer command queue. When the command + * is actually processed will depend on the priority of the timer service/daemon + * task relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the period of xTimer should be changed to 500ms. + * + * // The interrupt service routine that changes the period of xTimer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - change the period of xTimer to 500ms. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The command to change the timers period was not executed + * // successfully. Take appropriate action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used. + * } + * } + */ +#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * portBASE_TYPE xTimerResetFromISR( xTimerHandle xTimer, + * portBASE_TYPE *pxHigherPriorityTaskWoken ); + * + * A version of xTimerReset() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer that is to be started, reset, or + * restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerResetFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerResetFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerResetFromISR() function. If + * xTimerResetFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerResetFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( xTIMER *pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used. + * } + * } + */ +#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; +portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif +#endif /* TIMERS_H */ + + + diff --git a/Libmaple/libmaple/libraries/LiquidCrystal/LiquidCrystal.cpp b/Libmaple/libmaple/libraries/LiquidCrystal/LiquidCrystal.cpp index fbfc54bc..85e19ef8 100644 --- a/Libmaple/libmaple/libraries/LiquidCrystal/LiquidCrystal.cpp +++ b/Libmaple/libmaple/libraries/LiquidCrystal/LiquidCrystal.cpp @@ -1,333 +1,333 @@ -#include "LiquidCrystal.h" - -#include -#include -#include "WProgram.h" - -// When the display powers up, it is configured as follows: -// -// 1. Display clear -// 2. Function set: -// DL = 1; 8-bit interface data -// N = 0; 1-line display -// F = 0; 5x8 dot character font -// 3. Display on/off control: -// D = 0; Display off -// C = 0; Cursor off -// B = 0; Blinking off -// 4. Entry mode set: -// I/D = 1; Increment by 1 -// S = 0; No shift -// -// Note, however, that resetting the Arduino doesn't reset the LCD, so we -// can't assume that its in that state when a sketch starts (and the -// LiquidCrystal constructor is called). - -// This library has been modified to be compatible with the LeafLabs Maple; -// very conservative timing is used due to problems with delayMicroseconds() -// that should be fixed in the 0.0.7 release of the libmaple. [bnewbold] - -LiquidCrystal::LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, - uint8 d0, uint8 d1, uint8 d2, uint8 d3, - uint8 d4, uint8 d5, uint8 d6, uint8 d7) -{ - init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); -} - -LiquidCrystal::LiquidCrystal(uint8 rs, uint8 enable, - uint8 d0, uint8 d1, uint8 d2, uint8 d3, - uint8 d4, uint8 d5, uint8 d6, uint8 d7) -{ - init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7); -} - -LiquidCrystal::LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, - uint8 d0, uint8 d1, uint8 d2, uint8 d3) -{ - init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); -} - -LiquidCrystal::LiquidCrystal(uint8 rs, uint8 enable, - uint8 d0, uint8 d1, uint8 d2, uint8 d3) -{ - init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); -} - -void LiquidCrystal::init(uint8 fourbitmode, uint8 rs, uint8 rw, uint8 enable, - uint8 d0, uint8 d1, uint8 d2, uint8 d3, - uint8 d4, uint8 d5, uint8 d6, uint8 d7) -{ - _rs_pin = rs; - _rw_pin = rw; - _enable_pin = enable; - - _data_pins[0] = d0; - _data_pins[1] = d1; - _data_pins[2] = d2; - _data_pins[3] = d3; - _data_pins[4] = d4; - _data_pins[5] = d5; - _data_pins[6] = d6; - _data_pins[7] = d7; - - for (int i = 0; i < 8 - fourbitmode * 4; i++) { - pinMode(_data_pins[i], OUTPUT); - } - - pinMode(_rs_pin, OUTPUT); - // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# - if (_rw_pin != 255) { - pinMode(_rw_pin, OUTPUT); - } - pinMode(_enable_pin, OUTPUT); - - if (fourbitmode) - _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; - else - _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; - - // TODO: bnewbold, re-enable this? - begin(16, 1); -} - -void LiquidCrystal::begin(uint8 cols, uint8 lines, uint8 dotsize) { - if (lines > 1) { - _displayfunction |= LCD_2LINE; - } - _numlines = lines; - _currline = 0; - - // for some 1 line displays you can select a 10 pixel high font - if ((dotsize != 0) && (lines == 1)) { - _displayfunction |= LCD_5x10DOTS; - } - - // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! according to - // datasheet, we need at least 40ms after power rises above 2.7V - // before sending commands. Arduino can turn on way befer 4.5V so - // we'll wait 50 - delay(50); // Maple mod - //delayMicroseconds(50000); - // Now we pull both RS and R/W low to begin commands - digitalWrite(_rs_pin, LOW); - digitalWrite(_enable_pin, LOW); - if (_rw_pin != 255) { - digitalWrite(_rw_pin, LOW); - } - - //put the LCD into 4 bit or 8 bit mode - if (! (_displayfunction & LCD_8BITMODE)) { - // this is according to the hitachi HD44780 datasheet - // figure 24, pg 46 - - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03); - delay(5); // Maple mod - //delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03); - delay(5); // Maple mod - //delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03); - delay(1); // Maple mod - //delayMicroseconds(150); - - // finally, set to 8-bit interface - write4bits(0x02); - } else { - // this is according to the hitachi HD44780 datasheet - // page 45 figure 23 - - // Send function set command sequence - command(LCD_FUNCTIONSET | _displayfunction); - delay(5); // Maple mod - //delayMicroseconds(4500); // wait more than 4.1ms - - // second try - command(LCD_FUNCTIONSET | _displayfunction); - delay(1); // Maple mod - //delayMicroseconds(150); - - // third go - command(LCD_FUNCTIONSET | _displayfunction); - } - - // finally, set # lines, font size, etc. - command(LCD_FUNCTIONSET | _displayfunction); - - // turn the display on with no cursor or blinking default - _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; - display(); - - // clear it off - clear(); - - // Initialize to default text direction (for romance languages) - _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; - // set the entry mode - command(LCD_ENTRYMODESET | _displaymode); - -} - -/********** high level commands, for the user! */ -void LiquidCrystal::clear() -{ - command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - delay(2); // Maple mod - //delayMicroseconds(2000); // this command takes a long time! -} - -void LiquidCrystal::home() -{ - command(LCD_RETURNHOME); // set cursor position to zero - delay(2); // Maple mod - //delayMicroseconds(2000); // this command takes a long time! -} - -void LiquidCrystal::setCursor(uint8 col, uint8 row) -{ - int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; - if ( row > _numlines ) { - row = _numlines-1; // we count rows starting w/0 - } - - command(LCD_SETDDRAMADDR | (col + row_offsets[row])); -} - -// Turn the display on/off (quickly) -void LiquidCrystal::noDisplay() { - _displaycontrol &= ~LCD_DISPLAYON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} -void LiquidCrystal::display() { - _displaycontrol |= LCD_DISPLAYON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} - -// Turns the underline cursor on/off -void LiquidCrystal::noCursor() { - _displaycontrol &= ~LCD_CURSORON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} -void LiquidCrystal::cursor() { - _displaycontrol |= LCD_CURSORON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} - -// Turn on and off the blinking cursor -void LiquidCrystal::noBlink() { - _displaycontrol &= ~LCD_BLINKON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} -void LiquidCrystal::blink() { - _displaycontrol |= LCD_BLINKON; - command(LCD_DISPLAYCONTROL | _displaycontrol); -} - -// These commands scroll the display without changing the RAM -void LiquidCrystal::scrollDisplayLeft(void) { - command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); -} -void LiquidCrystal::scrollDisplayRight(void) { - command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); -} - -// This is for text that flows Left to Right -void LiquidCrystal::leftToRight(void) { - _displaymode |= LCD_ENTRYLEFT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// This is for text that flows Right to Left -void LiquidCrystal::rightToLeft(void) { - _displaymode &= ~LCD_ENTRYLEFT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// This will 'right justify' text from the cursor -void LiquidCrystal::autoscroll(void) { - _displaymode |= LCD_ENTRYSHIFTINCREMENT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// This will 'left justify' text from the cursor -void LiquidCrystal::noAutoscroll(void) { - _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; - command(LCD_ENTRYMODESET | _displaymode); -} - -// Allows us to fill the first 8 CGRAM locations -// with custom characters -void LiquidCrystal::createChar(uint8 location, uint8 charmap[]) { - location &= 0x7; // we only have 8 locations 0-7 - command(LCD_SETCGRAMADDR | (location << 3)); - for (int i=0; i<8; i++) { - write(charmap[i]); - } -} - -/*********** mid level commands, for sending data/cmds */ - -inline void LiquidCrystal::command(uint8 value) { - send(value, LOW); -} - -inline void LiquidCrystal::write(uint8 value) { - send(value, HIGH); -} - -/************ low level data pushing commands **********/ - -// write either command or data, with automatic 4/8-bit selection -void LiquidCrystal::send(uint8 value, uint8 mode) { - digitalWrite(_rs_pin, mode); - - // if there is a RW pin indicated, set it low to Write - if (_rw_pin != 255) { - digitalWrite(_rw_pin, LOW); - } - - if (_displayfunction & LCD_8BITMODE) { - write8bits(value); - } else { - write4bits(value>>4); - write4bits(value); - } -} - -void LiquidCrystal::pulseEnable(void) { - // _enable_pin should already be LOW (unless someone else messed - // with it), so don't sit around waiting for long. - digitalWrite(_enable_pin, LOW); - delayMicroseconds(1); - - // Enable pulse must be > 450 ns. Value chosen here according to - // the following threads: - // http://forums.leaflabs.com/topic.php?id=640 - // http://forums.leaflabs.com/topic.php?id=512 - togglePin(_enable_pin); - delayMicroseconds(1); - togglePin(_enable_pin); - - // Commands needs > 37us to settle. - delayMicroseconds(42); -} - -void LiquidCrystal::write4bits(uint8 value) { - for (int i = 0; i < 4; i++) { - digitalWrite(_data_pins[i], (value >> i) & 0x01); - } - - pulseEnable(); -} - -void LiquidCrystal::write8bits(uint8 value) { - for (int i = 0; i < 8; i++) { - digitalWrite(_data_pins[i], (value >> i) & 0x01); - } - - pulseEnable(); -} +#include "LiquidCrystal.h" + +#include +#include +#include "WProgram.h" + +// When the display powers up, it is configured as follows: +// +// 1. Display clear +// 2. Function set: +// DL = 1; 8-bit interface data +// N = 0; 1-line display +// F = 0; 5x8 dot character font +// 3. Display on/off control: +// D = 0; Display off +// C = 0; Cursor off +// B = 0; Blinking off +// 4. Entry mode set: +// I/D = 1; Increment by 1 +// S = 0; No shift +// +// Note, however, that resetting the Arduino doesn't reset the LCD, so we +// can't assume that its in that state when a sketch starts (and the +// LiquidCrystal constructor is called). + +// This library has been modified to be compatible with the LeafLabs Maple; +// very conservative timing is used due to problems with delayMicroseconds() +// that should be fixed in the 0.0.7 release of the libmaple. [bnewbold] + +LiquidCrystal::LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7) +{ + init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); +} + +LiquidCrystal::LiquidCrystal(uint8 rs, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7) +{ + init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7); +} + +LiquidCrystal::LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3) +{ + init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); +} + +LiquidCrystal::LiquidCrystal(uint8 rs, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3) +{ + init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); +} + +void LiquidCrystal::init(uint8 fourbitmode, uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7) +{ + _rs_pin = rs; + _rw_pin = rw; + _enable_pin = enable; + + _data_pins[0] = d0; + _data_pins[1] = d1; + _data_pins[2] = d2; + _data_pins[3] = d3; + _data_pins[4] = d4; + _data_pins[5] = d5; + _data_pins[6] = d6; + _data_pins[7] = d7; + + for (int i = 0; i < 8 - fourbitmode * 4; i++) { + pinMode(_data_pins[i], OUTPUT); + } + + pinMode(_rs_pin, OUTPUT); + // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# + if (_rw_pin != 255) { + pinMode(_rw_pin, OUTPUT); + } + pinMode(_enable_pin, OUTPUT); + + if (fourbitmode) + _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; + else + _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; + + // TODO: bnewbold, re-enable this? + begin(16, 1); +} + +void LiquidCrystal::begin(uint8 cols, uint8 lines, uint8 dotsize) { + if (lines > 1) { + _displayfunction |= LCD_2LINE; + } + _numlines = lines; + _currline = 0; + + // for some 1 line displays you can select a 10 pixel high font + if ((dotsize != 0) && (lines == 1)) { + _displayfunction |= LCD_5x10DOTS; + } + + // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! according to + // datasheet, we need at least 40ms after power rises above 2.7V + // before sending commands. Arduino can turn on way befer 4.5V so + // we'll wait 50 + delay(50); // Maple mod + //delayMicroseconds(50000); + // Now we pull both RS and R/W low to begin commands + digitalWrite(_rs_pin, LOW); + digitalWrite(_enable_pin, LOW); + if (_rw_pin != 255) { + digitalWrite(_rw_pin, LOW); + } + + //put the LCD into 4 bit or 8 bit mode + if (! (_displayfunction & LCD_8BITMODE)) { + // this is according to the hitachi HD44780 datasheet + // figure 24, pg 46 + + // we start in 8bit mode, try to set 4 bit mode + write4bits(0x03); + delay(5); // Maple mod + //delayMicroseconds(4500); // wait min 4.1ms + + // second try + write4bits(0x03); + delay(5); // Maple mod + //delayMicroseconds(4500); // wait min 4.1ms + + // third go! + write4bits(0x03); + delay(1); // Maple mod + //delayMicroseconds(150); + + // finally, set to 8-bit interface + write4bits(0x02); + } else { + // this is according to the hitachi HD44780 datasheet + // page 45 figure 23 + + // Send function set command sequence + command(LCD_FUNCTIONSET | _displayfunction); + delay(5); // Maple mod + //delayMicroseconds(4500); // wait more than 4.1ms + + // second try + command(LCD_FUNCTIONSET | _displayfunction); + delay(1); // Maple mod + //delayMicroseconds(150); + + // third go + command(LCD_FUNCTIONSET | _displayfunction); + } + + // finally, set # lines, font size, etc. + command(LCD_FUNCTIONSET | _displayfunction); + + // turn the display on with no cursor or blinking default + _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; + display(); + + // clear it off + clear(); + + // Initialize to default text direction (for romance languages) + _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; + // set the entry mode + command(LCD_ENTRYMODESET | _displaymode); + +} + +/********** high level commands, for the user! */ +void LiquidCrystal::clear() +{ + command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero + delay(2); // Maple mod + //delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal::home() +{ + command(LCD_RETURNHOME); // set cursor position to zero + delay(2); // Maple mod + //delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal::setCursor(uint8 col, uint8 row) +{ + int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; + if ( row > _numlines ) { + row = _numlines-1; // we count rows starting w/0 + } + + command(LCD_SETDDRAMADDR | (col + row_offsets[row])); +} + +// Turn the display on/off (quickly) +void LiquidCrystal::noDisplay() { + _displaycontrol &= ~LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::display() { + _displaycontrol |= LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turns the underline cursor on/off +void LiquidCrystal::noCursor() { + _displaycontrol &= ~LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::cursor() { + _displaycontrol |= LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turn on and off the blinking cursor +void LiquidCrystal::noBlink() { + _displaycontrol &= ~LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::blink() { + _displaycontrol |= LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// These commands scroll the display without changing the RAM +void LiquidCrystal::scrollDisplayLeft(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); +} +void LiquidCrystal::scrollDisplayRight(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); +} + +// This is for text that flows Left to Right +void LiquidCrystal::leftToRight(void) { + _displaymode |= LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This is for text that flows Right to Left +void LiquidCrystal::rightToLeft(void) { + _displaymode &= ~LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'right justify' text from the cursor +void LiquidCrystal::autoscroll(void) { + _displaymode |= LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'left justify' text from the cursor +void LiquidCrystal::noAutoscroll(void) { + _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// Allows us to fill the first 8 CGRAM locations +// with custom characters +void LiquidCrystal::createChar(uint8 location, uint8 charmap[]) { + location &= 0x7; // we only have 8 locations 0-7 + command(LCD_SETCGRAMADDR | (location << 3)); + for (int i=0; i<8; i++) { + write(charmap[i]); + } +} + +/*********** mid level commands, for sending data/cmds */ + +inline void LiquidCrystal::command(uint8 value) { + send(value, LOW); +} + +inline void LiquidCrystal::write(uint8 value) { + send(value, HIGH); +} + +/************ low level data pushing commands **********/ + +// write either command or data, with automatic 4/8-bit selection +void LiquidCrystal::send(uint8 value, uint8 mode) { + digitalWrite(_rs_pin, mode); + + // if there is a RW pin indicated, set it low to Write + if (_rw_pin != 255) { + digitalWrite(_rw_pin, LOW); + } + + if (_displayfunction & LCD_8BITMODE) { + write8bits(value); + } else { + write4bits(value>>4); + write4bits(value); + } +} + +void LiquidCrystal::pulseEnable(void) { + // _enable_pin should already be LOW (unless someone else messed + // with it), so don't sit around waiting for long. + digitalWrite(_enable_pin, LOW); + delayMicroseconds(1); + + // Enable pulse must be > 450 ns. Value chosen here according to + // the following threads: + // http://forums.leaflabs.com/topic.php?id=640 + // http://forums.leaflabs.com/topic.php?id=512 + togglePin(_enable_pin); + delayMicroseconds(1); + togglePin(_enable_pin); + + // Commands needs > 37us to settle. + delayMicroseconds(42); +} + +void LiquidCrystal::write4bits(uint8 value) { + for (int i = 0; i < 4; i++) { + digitalWrite(_data_pins[i], (value >> i) & 0x01); + } + + pulseEnable(); +} + +void LiquidCrystal::write8bits(uint8 value) { + for (int i = 0; i < 8; i++) { + digitalWrite(_data_pins[i], (value >> i) & 0x01); + } + + pulseEnable(); +} diff --git a/Libmaple/libmaple/libraries/LiquidCrystal/LiquidCrystal.h b/Libmaple/libmaple/libraries/LiquidCrystal/LiquidCrystal.h index 1115fa92..0baf5433 100644 --- a/Libmaple/libmaple/libraries/LiquidCrystal/LiquidCrystal.h +++ b/Libmaple/libmaple/libraries/LiquidCrystal/LiquidCrystal.h @@ -1,105 +1,105 @@ -#ifndef LiquidCrystal_h -#define LiquidCrystal_h - -//#include -#include "wirish.h" -#include "Print.h" - -// commands -#define LCD_CLEARDISPLAY 0x01 -#define LCD_RETURNHOME 0x02 -#define LCD_ENTRYMODESET 0x04 -#define LCD_DISPLAYCONTROL 0x08 -#define LCD_CURSORSHIFT 0x10 -#define LCD_FUNCTIONSET 0x20 -#define LCD_SETCGRAMADDR 0x40 -#define LCD_SETDDRAMADDR 0x80 - -// flags for display entry mode -#define LCD_ENTRYRIGHT 0x00 -#define LCD_ENTRYLEFT 0x02 -#define LCD_ENTRYSHIFTINCREMENT 0x01 -#define LCD_ENTRYSHIFTDECREMENT 0x00 - -// flags for display on/off control -#define LCD_DISPLAYON 0x04 -#define LCD_DISPLAYOFF 0x00 -#define LCD_CURSORON 0x02 -#define LCD_CURSOROFF 0x00 -#define LCD_BLINKON 0x01 -#define LCD_BLINKOFF 0x00 - -// flags for display/cursor shift -#define LCD_DISPLAYMOVE 0x08 -#define LCD_CURSORMOVE 0x00 -#define LCD_MOVERIGHT 0x04 -#define LCD_MOVELEFT 0x00 - -// flags for function set -#define LCD_8BITMODE 0x10 -#define LCD_4BITMODE 0x00 -#define LCD_2LINE 0x08 -#define LCD_1LINE 0x00 -#define LCD_5x10DOTS 0x04 -#define LCD_5x8DOTS 0x00 - -class LiquidCrystal : public Print { -public: - LiquidCrystal(uint8 rs, uint8 enable, - uint8 d0, uint8 d1, uint8 d2, uint8 d3, - uint8 d4, uint8 d5, uint8 d6, uint8 d7); - LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, - uint8 d0, uint8 d1, uint8 d2, uint8 d3, - uint8 d4, uint8 d5, uint8 d6, uint8 d7); - LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, - uint8 d0, uint8 d1, uint8 d2, uint8 d3); - LiquidCrystal(uint8 rs, uint8 enable, - uint8 d0, uint8 d1, uint8 d2, uint8 d3); - - void init(uint8 fourbitmode, uint8 rs, uint8 rw, uint8 enable, - uint8 d0, uint8 d1, uint8 d2, uint8 d3, - uint8 d4, uint8 d5, uint8 d6, uint8 d7); - - void begin(uint8 cols, uint8 rows, uint8 charsize = LCD_5x8DOTS); - - void clear(); - void home(); - - void noDisplay(); - void display(); - void noBlink(); - void blink(); - void noCursor(); - void cursor(); - void scrollDisplayLeft(); - void scrollDisplayRight(); - void leftToRight(); - void rightToLeft(); - void autoscroll(); - void noAutoscroll(); - - void createChar(uint8, uint8[]); - void setCursor(uint8, uint8); - virtual void write(uint8); - void command(uint8); -private: - void send(uint8, uint8); - void write4bits(uint8); - void write8bits(uint8); - void pulseEnable(); - - uint8 _rs_pin; // LOW: command. HIGH: character. - uint8 _rw_pin; // LOW: write to LCD. HIGH: read from LCD. - uint8 _enable_pin; // activated by a HIGH pulse. - uint8 _data_pins[8]; - - uint8 _displayfunction; - uint8 _displaycontrol; - uint8 _displaymode; - - uint8 _initialized; - - uint8 _numlines,_currline; -}; - -#endif +#ifndef LiquidCrystal_h +#define LiquidCrystal_h + +//#include +#include "wirish.h" +#include "Print.h" + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +class LiquidCrystal : public Print { +public: + LiquidCrystal(uint8 rs, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7); + LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7); + LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3); + LiquidCrystal(uint8 rs, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3); + + void init(uint8 fourbitmode, uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7); + + void begin(uint8 cols, uint8 rows, uint8 charsize = LCD_5x8DOTS); + + void clear(); + void home(); + + void noDisplay(); + void display(); + void noBlink(); + void blink(); + void noCursor(); + void cursor(); + void scrollDisplayLeft(); + void scrollDisplayRight(); + void leftToRight(); + void rightToLeft(); + void autoscroll(); + void noAutoscroll(); + + void createChar(uint8, uint8[]); + void setCursor(uint8, uint8); + virtual void write(uint8); + void command(uint8); +private: + void send(uint8, uint8); + void write4bits(uint8); + void write8bits(uint8); + void pulseEnable(); + + uint8 _rs_pin; // LOW: command. HIGH: character. + uint8 _rw_pin; // LOW: write to LCD. HIGH: read from LCD. + uint8 _enable_pin; // activated by a HIGH pulse. + uint8 _data_pins[8]; + + uint8 _displayfunction; + uint8 _displaycontrol; + uint8 _displaymode; + + uint8 _initialized; + + uint8 _numlines,_currline; +}; + +#endif diff --git a/Libmaple/libmaple/libraries/LiquidCrystal/rules.mk b/Libmaple/libmaple/libraries/LiquidCrystal/rules.mk index ddb77a3c..7b18203b 100644 --- a/Libmaple/libmaple/libraries/LiquidCrystal/rules.mk +++ b/Libmaple/libmaple/libraries/LiquidCrystal/rules.mk @@ -1,29 +1,29 @@ -# Standard things -sp := $(sp).x -dirstack_$(sp) := $(d) -d := $(dir) -BUILDDIRS += $(BUILD_PATH)/$(d) - -# Local flags -CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) - -# Local rules and targets -cSRCS_$(d) := - -cppSRCS_$(d) := LiquidCrystal.cpp - -cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) -cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) - -OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ - $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) -DEPS_$(d) := $(OBJS_$(d):%.o=%.d) - -$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) - -TGT_BIN += $(OBJS_$(d)) - -# Standard things --include $(DEPS_$(d)) -d := $(dirstack_$(sp)) +# Standard things +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) +BUILDDIRS += $(BUILD_PATH)/$(d) + +# Local flags +CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) + +# Local rules and targets +cSRCS_$(d) := + +cppSRCS_$(d) := LiquidCrystal.cpp + +cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) + +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ + $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) +DEPS_$(d) := $(OBJS_$(d):%.o=%.d) + +$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) + +TGT_BIN += $(OBJS_$(d)) + +# Standard things +-include $(DEPS_$(d)) +d := $(dirstack_$(sp)) sp := $(basename $(sp)) \ No newline at end of file diff --git a/Libmaple/libmaple/libraries/Servo/Servo.cpp b/Libmaple/libmaple/libraries/Servo/Servo.cpp index 9aafac1a..8fbd3660 100644 --- a/Libmaple/libmaple/libraries/Servo/Servo.cpp +++ b/Libmaple/libmaple/libraries/Servo/Servo.cpp @@ -1,150 +1,150 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010, LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include "Servo.h" - -#include "boards.h" -#include "io.h" -#include "pwm.h" -#include "wirish_math.h" - -// 20 millisecond period config. For a 1-based prescaler, -// -// (prescaler * overflow / CYC_MSEC) msec = 1 timer cycle = 20 msec -// => prescaler * overflow = 20 * CYC_MSEC -// -// This picks the smallest prescaler that allows an overflow < 2^16. -#define MAX_OVERFLOW ((1 << 16) - 1) -#define CYC_MSEC (1000 * CYCLES_PER_MICROSECOND) -#define TAU_MSEC 20 -#define TAU_USEC (TAU_MSEC * 1000) -#define TAU_CYC (TAU_MSEC * CYC_MSEC) -#define SERVO_PRESCALER (TAU_CYC / MAX_OVERFLOW + 1) -#define SERVO_OVERFLOW ((uint16)round((double)TAU_CYC / SERVO_PRESCALER)) - -// Unit conversions -#define US_TO_COMPARE(us) ((uint16)map((us), 0, TAU_USEC, 0, SERVO_OVERFLOW)) -#define COMPARE_TO_US(c) ((uint32)map((c), 0, SERVO_OVERFLOW, 0, TAU_USEC)) -#define ANGLE_TO_US(a) ((uint16)(map((a), this->minAngle, this->maxAngle, \ - this->minPW, this->maxPW))) -#define US_TO_ANGLE(us) ((int16)(map((us), this->minPW, this->maxPW, \ - this->minAngle, this->maxAngle))) - -Servo::Servo() { - this->resetFields(); -} - -bool Servo::attach(uint8 pin, - uint16 minPW, - uint16 maxPW, - int16 minAngle, - int16 maxAngle) { - timer_dev *tdev = PIN_MAP[pin].timer_device; - - if (tdev == NULL) { - // don't reset any fields or ASSERT(0), to keep driving any - // previously attach()ed servo. - return false; - } - - if (this->attached()) { - this->detach(); - } - - this->pin = pin; - this->minPW = minPW; - this->maxPW = maxPW; - this->minAngle = minAngle; - this->maxAngle = maxAngle; - - pinMode(pin, PWM); - - timer_pause(tdev); - timer_set_prescaler(tdev, SERVO_PRESCALER - 1); // prescaler is 1-based - timer_set_reload(tdev, SERVO_OVERFLOW); - timer_generate_update(tdev); - timer_resume(tdev); - - return true; -} - -bool Servo::detach() { - if (!this->attached()) { - return false; - } - - timer_dev *tdev = PIN_MAP[this->pin].timer_device; - uint8 tchan = PIN_MAP[this->pin].timer_channel; - timer_set_mode(tdev, tchan, TIMER_DISABLED); - - this->resetFields(); - - return true; -} - -void Servo::write(int degrees) { - degrees = constrain(degrees, this->minAngle, this->maxAngle); - this->writeMicroseconds(ANGLE_TO_US(degrees)); -} - -int Servo::read() const { - int a = US_TO_ANGLE(this->readMicroseconds()); - // map() round-trips in a weird way we mostly correct for here; - // the round-trip is still sometimes off-by-one for write(1) and - // write(179). - return a == this->minAngle || a == this->maxAngle ? a : a + 1; -} - -void Servo::writeMicroseconds(uint16 pulseWidth) { - if (!this->attached()) { - ASSERT(0); - return; - } - - pulseWidth = constrain(pulseWidth, this->minPW, this->maxPW); - pwmWrite(this->pin, US_TO_COMPARE(pulseWidth)); -} - -uint16 Servo::readMicroseconds() const { - if (!this->attached()) { - ASSERT(0); - return 0; - } - - stm32_pin_info pin_info = PIN_MAP[this->pin]; - uint16 compare = timer_get_compare(pin_info.timer_device, - pin_info.timer_channel); - - return COMPARE_TO_US(compare); -} - -void Servo::resetFields(void) { - this->pin = NOT_ATTACHED; - this->minAngle = SERVO_DEFAULT_MIN_ANGLE; - this->maxAngle = SERVO_DEFAULT_MAX_ANGLE; - this->minPW = SERVO_DEFAULT_MIN_PW; - this->maxPW = SERVO_DEFAULT_MAX_PW; -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010, LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +#include "Servo.h" + +#include "boards.h" +#include "io.h" +#include "pwm.h" +#include "wirish_math.h" + +// 20 millisecond period config. For a 1-based prescaler, +// +// (prescaler * overflow / CYC_MSEC) msec = 1 timer cycle = 20 msec +// => prescaler * overflow = 20 * CYC_MSEC +// +// This picks the smallest prescaler that allows an overflow < 2^16. +#define MAX_OVERFLOW ((1 << 16) - 1) +#define CYC_MSEC (1000 * CYCLES_PER_MICROSECOND) +#define TAU_MSEC 20 +#define TAU_USEC (TAU_MSEC * 1000) +#define TAU_CYC (TAU_MSEC * CYC_MSEC) +#define SERVO_PRESCALER (TAU_CYC / MAX_OVERFLOW + 1) +#define SERVO_OVERFLOW ((uint16)round((double)TAU_CYC / SERVO_PRESCALER)) + +// Unit conversions +#define US_TO_COMPARE(us) ((uint16)map((us), 0, TAU_USEC, 0, SERVO_OVERFLOW)) +#define COMPARE_TO_US(c) ((uint32)map((c), 0, SERVO_OVERFLOW, 0, TAU_USEC)) +#define ANGLE_TO_US(a) ((uint16)(map((a), this->minAngle, this->maxAngle, \ + this->minPW, this->maxPW))) +#define US_TO_ANGLE(us) ((int16)(map((us), this->minPW, this->maxPW, \ + this->minAngle, this->maxAngle))) + +Servo::Servo() { + this->resetFields(); +} + +bool Servo::attach(uint8 pin, + uint16 minPW, + uint16 maxPW, + int16 minAngle, + int16 maxAngle) { + timer_dev *tdev = PIN_MAP[pin].timer_device; + + if (tdev == NULL) { + // don't reset any fields or ASSERT(0), to keep driving any + // previously attach()ed servo. + return false; + } + + if (this->attached()) { + this->detach(); + } + + this->pin = pin; + this->minPW = minPW; + this->maxPW = maxPW; + this->minAngle = minAngle; + this->maxAngle = maxAngle; + + pinMode(pin, PWM); + + timer_pause(tdev); + timer_set_prescaler(tdev, SERVO_PRESCALER - 1); // prescaler is 1-based + timer_set_reload(tdev, SERVO_OVERFLOW); + timer_generate_update(tdev); + timer_resume(tdev); + + return true; +} + +bool Servo::detach() { + if (!this->attached()) { + return false; + } + + timer_dev *tdev = PIN_MAP[this->pin].timer_device; + uint8 tchan = PIN_MAP[this->pin].timer_channel; + timer_set_mode(tdev, tchan, TIMER_DISABLED); + + this->resetFields(); + + return true; +} + +void Servo::write(int degrees) { + degrees = constrain(degrees, this->minAngle, this->maxAngle); + this->writeMicroseconds(ANGLE_TO_US(degrees)); +} + +int Servo::read() const { + int a = US_TO_ANGLE(this->readMicroseconds()); + // map() round-trips in a weird way we mostly correct for here; + // the round-trip is still sometimes off-by-one for write(1) and + // write(179). + return a == this->minAngle || a == this->maxAngle ? a : a + 1; +} + +void Servo::writeMicroseconds(uint16 pulseWidth) { + if (!this->attached()) { + ASSERT(0); + return; + } + + pulseWidth = constrain(pulseWidth, this->minPW, this->maxPW); + pwmWrite(this->pin, US_TO_COMPARE(pulseWidth)); +} + +uint16 Servo::readMicroseconds() const { + if (!this->attached()) { + ASSERT(0); + return 0; + } + + stm32_pin_info pin_info = PIN_MAP[this->pin]; + uint16 compare = timer_get_compare(pin_info.timer_device, + pin_info.timer_channel); + + return COMPARE_TO_US(compare); +} + +void Servo::resetFields(void) { + this->pin = NOT_ATTACHED; + this->minAngle = SERVO_DEFAULT_MIN_ANGLE; + this->maxAngle = SERVO_DEFAULT_MAX_ANGLE; + this->minPW = SERVO_DEFAULT_MIN_PW; + this->maxPW = SERVO_DEFAULT_MAX_PW; +} diff --git a/Libmaple/libmaple/libraries/Servo/Servo.h b/Libmaple/libmaple/libraries/Servo/Servo.h index ec2e4aaa..7753b4be 100644 --- a/Libmaple/libmaple/libraries/Servo/Servo.h +++ b/Libmaple/libmaple/libraries/Servo/Servo.h @@ -1,200 +1,200 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010, LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#ifndef _SERVO_H_ -#define _SERVO_H_ - -#include "libmaple_types.h" -#include "timer.h" - -#include "wirish_types.h" - -#ifdef MAPLE_IDE -#include "wirish.h" /* hack for IDE compile */ -#endif - -/* - * Note on Arduino compatibility: - * - * In the Arduino implementation, PWM is done "by hand" in the sense - * that timer channels are hijacked in groups and an ISR is set which - * toggles Servo::attach()ed pins using digitalWrite(). - * - * While this scheme allows any pin to drive a servo, it chews up - * cycles and complicates the programmer's notion of when a particular - * timer channel will be in use. - * - * This implementation only allows Servo instances to attach() to pins - * that already have a timer channel associated with them, and just - * uses pwmWrite() to drive the wave. - * - * This introduces an incompatibility: while the Arduino - * implementation of attach() returns the affected channel on success - * and 0 on failure, this one returns true on success and false on - * failure. - * - * RC Servos expect a pulse every 20ms. Since periods are set for - * entire timers, rather than individual channels, attach()ing a Servo - * to a pin can interfere with other pins associated with the same - * timer. As always, your board's pin map is your friend. - */ - -// Pin number of unattached pins -#define NOT_ATTACHED (-1) - -// Default min/max pulse widths (in microseconds) and angles (in -// degrees). Values chosen for Arduino compatibility. These values -// are part of the public API; DO NOT CHANGE THEM. -#define SERVO_DEFAULT_MIN_PW 544 -#define SERVO_DEFAULT_MAX_PW 2400 -#define SERVO_DEFAULT_MIN_ANGLE 0 -#define SERVO_DEFAULT_MAX_ANGLE 180 - -/** Class for interfacing with RC servomotors. */ -class Servo { -public: - /** - * @brief Construct a new Servo instance. - * - * The new instance will not be attached to any pin. - */ - Servo(); - - /** - * @brief Associate this instance with a servomotor whose input is - * connected to pin. - * - * If this instance is already attached to a pin, it will be - * detached before being attached to the new pin. This function - * doesn't detach any interrupt attached with the pin's timer - * channel. - * - * @param pin Pin connected to the servo pulse wave input. This - * pin must be capable of PWM output. - * - * @param minPulseWidth Minimum pulse width to write to pin, in - * microseconds. This will be associated - * with a minAngle degree angle. Defaults to - * SERVO_DEFAULT_MIN_PW = 544. - * - * @param maxPulseWidth Maximum pulse width to write to pin, in - * microseconds. This will be associated - * with a maxAngle degree angle. Defaults to - * SERVO_DEFAULT_MAX_PW = 2400. - * - * @param minAngle Target angle (in degrees) associated with - * minPulseWidth. Defaults to - * SERVO_DEFAULT_MIN_ANGLE = 0. - * - * @param maxAngle Target angle (in degrees) associated with - * maxPulseWidth. Defaults to - * SERVO_DEFAULT_MAX_ANGLE = 180. - * - * @sideeffect May set pinMode(pin, PWM). - * - * @return true if successful, false when pin doesn't support PWM. - */ - bool attach(uint8 pin, - uint16 minPulseWidth=SERVO_DEFAULT_MIN_PW, - uint16 maxPulseWidth=SERVO_DEFAULT_MAX_PW, - int16 minAngle=SERVO_DEFAULT_MIN_ANGLE, - int16 maxAngle=SERVO_DEFAULT_MAX_ANGLE); - - /** - * @brief Check if this instance is attached to a servo. - * @return true if this instance is attached to a servo, false otherwise. - * @see Servo::attachedPin() - */ - bool attached() const { return this->pin != NOT_ATTACHED; } - - /** - * @brief Get the pin this instance is attached to. - * @return Pin number if currently attached to a pin, NOT_ATTACHED - * otherwise. - * @see Servo::attach() - */ - int attachedPin() const { return this->pin; } - - /** - * @brief Stop driving the servo pulse train. - * - * If not currently attached to a motor, this function has no effect. - * - * @return true if this call did anything, false otherwise. - */ - bool detach(); - - /** - * @brief Set the servomotor target angle. - * - * @param angle Target angle, in degrees. If the target angle is - * outside the range specified at attach() time, it - * will be clamped to lie in that range. - * - * @see Servo::attach() - */ - void write(int angle); - - - /** - * Get the servomotor's target angle, in degrees. This will - * lie inside the range specified at attach() time. - * - * @see Servo::attach() - */ - int read() const; - - /** - * @brief Set the pulse width, in microseconds. - * - * @param pulseWidth Pulse width to send to the servomotor, in - * microseconds. If outside of the range - * specified at attach() time, it is clamped to - * lie in that range. - * - * @see Servo::attach() - */ - void writeMicroseconds(uint16 pulseWidth); - - /** - * Get the current pulse width, in microseconds. This will - * lie within the range specified at attach() time. - * - * @see Servo::attach() - */ - uint16 readMicroseconds() const; - -private: - int16 pin; - uint16 minPW; - uint16 maxPW; - int16 minAngle; - int16 maxAngle; - - void resetFields(void); -}; - -#endif /* _SERVO_H_ */ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010, LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +#ifndef _SERVO_H_ +#define _SERVO_H_ + +#include "libmaple_types.h" +#include "timer.h" + +#include "wirish_types.h" + +#ifdef MAPLE_IDE +#include "wirish.h" /* hack for IDE compile */ +#endif + +/* + * Note on Arduino compatibility: + * + * In the Arduino implementation, PWM is done "by hand" in the sense + * that timer channels are hijacked in groups and an ISR is set which + * toggles Servo::attach()ed pins using digitalWrite(). + * + * While this scheme allows any pin to drive a servo, it chews up + * cycles and complicates the programmer's notion of when a particular + * timer channel will be in use. + * + * This implementation only allows Servo instances to attach() to pins + * that already have a timer channel associated with them, and just + * uses pwmWrite() to drive the wave. + * + * This introduces an incompatibility: while the Arduino + * implementation of attach() returns the affected channel on success + * and 0 on failure, this one returns true on success and false on + * failure. + * + * RC Servos expect a pulse every 20ms. Since periods are set for + * entire timers, rather than individual channels, attach()ing a Servo + * to a pin can interfere with other pins associated with the same + * timer. As always, your board's pin map is your friend. + */ + +// Pin number of unattached pins +#define NOT_ATTACHED (-1) + +// Default min/max pulse widths (in microseconds) and angles (in +// degrees). Values chosen for Arduino compatibility. These values +// are part of the public API; DO NOT CHANGE THEM. +#define SERVO_DEFAULT_MIN_PW 544 +#define SERVO_DEFAULT_MAX_PW 2400 +#define SERVO_DEFAULT_MIN_ANGLE 0 +#define SERVO_DEFAULT_MAX_ANGLE 180 + +/** Class for interfacing with RC servomotors. */ +class Servo { +public: + /** + * @brief Construct a new Servo instance. + * + * The new instance will not be attached to any pin. + */ + Servo(); + + /** + * @brief Associate this instance with a servomotor whose input is + * connected to pin. + * + * If this instance is already attached to a pin, it will be + * detached before being attached to the new pin. This function + * doesn't detach any interrupt attached with the pin's timer + * channel. + * + * @param pin Pin connected to the servo pulse wave input. This + * pin must be capable of PWM output. + * + * @param minPulseWidth Minimum pulse width to write to pin, in + * microseconds. This will be associated + * with a minAngle degree angle. Defaults to + * SERVO_DEFAULT_MIN_PW = 544. + * + * @param maxPulseWidth Maximum pulse width to write to pin, in + * microseconds. This will be associated + * with a maxAngle degree angle. Defaults to + * SERVO_DEFAULT_MAX_PW = 2400. + * + * @param minAngle Target angle (in degrees) associated with + * minPulseWidth. Defaults to + * SERVO_DEFAULT_MIN_ANGLE = 0. + * + * @param maxAngle Target angle (in degrees) associated with + * maxPulseWidth. Defaults to + * SERVO_DEFAULT_MAX_ANGLE = 180. + * + * @sideeffect May set pinMode(pin, PWM). + * + * @return true if successful, false when pin doesn't support PWM. + */ + bool attach(uint8 pin, + uint16 minPulseWidth=SERVO_DEFAULT_MIN_PW, + uint16 maxPulseWidth=SERVO_DEFAULT_MAX_PW, + int16 minAngle=SERVO_DEFAULT_MIN_ANGLE, + int16 maxAngle=SERVO_DEFAULT_MAX_ANGLE); + + /** + * @brief Check if this instance is attached to a servo. + * @return true if this instance is attached to a servo, false otherwise. + * @see Servo::attachedPin() + */ + bool attached() const { return this->pin != NOT_ATTACHED; } + + /** + * @brief Get the pin this instance is attached to. + * @return Pin number if currently attached to a pin, NOT_ATTACHED + * otherwise. + * @see Servo::attach() + */ + int attachedPin() const { return this->pin; } + + /** + * @brief Stop driving the servo pulse train. + * + * If not currently attached to a motor, this function has no effect. + * + * @return true if this call did anything, false otherwise. + */ + bool detach(); + + /** + * @brief Set the servomotor target angle. + * + * @param angle Target angle, in degrees. If the target angle is + * outside the range specified at attach() time, it + * will be clamped to lie in that range. + * + * @see Servo::attach() + */ + void write(int angle); + + + /** + * Get the servomotor's target angle, in degrees. This will + * lie inside the range specified at attach() time. + * + * @see Servo::attach() + */ + int read() const; + + /** + * @brief Set the pulse width, in microseconds. + * + * @param pulseWidth Pulse width to send to the servomotor, in + * microseconds. If outside of the range + * specified at attach() time, it is clamped to + * lie in that range. + * + * @see Servo::attach() + */ + void writeMicroseconds(uint16 pulseWidth); + + /** + * Get the current pulse width, in microseconds. This will + * lie within the range specified at attach() time. + * + * @see Servo::attach() + */ + uint16 readMicroseconds() const; + +private: + int16 pin; + uint16 minPW; + uint16 maxPW; + int16 minAngle; + int16 maxAngle; + + void resetFields(void); +}; + +#endif /* _SERVO_H_ */ diff --git a/Libmaple/libmaple/libraries/Servo/rules.mk b/Libmaple/libmaple/libraries/Servo/rules.mk index cd6ba218..e013754a 100644 --- a/Libmaple/libmaple/libraries/Servo/rules.mk +++ b/Libmaple/libmaple/libraries/Servo/rules.mk @@ -1,29 +1,29 @@ -# Standard things -sp := $(sp).x -dirstack_$(sp) := $(d) -d := $(dir) -BUILDDIRS += $(BUILD_PATH)/$(d) - -# Local flags -CXXFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) - -# Local rules and targets -cSRCS_$(d) := - -cppSRCS_$(d) := Servo.cpp - -cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) -cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) - -OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ - $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) -DEPS_$(d) := $(OBJS_$(d):%.o=%.d) - -$(OBJS_$(d)): TGT_CXXFLAGS := $(CXXFLAGS_$(d)) - -TGT_BIN += $(OBJS_$(d)) - -# Standard things --include $(DEPS_$(d)) -d := $(dirstack_$(sp)) +# Standard things +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) +BUILDDIRS += $(BUILD_PATH)/$(d) + +# Local flags +CXXFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) + +# Local rules and targets +cSRCS_$(d) := + +cppSRCS_$(d) := Servo.cpp + +cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) + +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ + $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) +DEPS_$(d) := $(OBJS_$(d):%.o=%.d) + +$(OBJS_$(d)): TGT_CXXFLAGS := $(CXXFLAGS_$(d)) + +TGT_BIN += $(OBJS_$(d)) + +# Standard things +-include $(DEPS_$(d)) +d := $(dirstack_$(sp)) sp := $(basename $(sp)) \ No newline at end of file diff --git a/Libmaple/libmaple/libraries/Wire/README b/Libmaple/libmaple/libraries/Wire/README index 2b86fe04..353d51a3 100644 --- a/Libmaple/libmaple/libraries/Wire/README +++ b/Libmaple/libmaple/libraries/Wire/README @@ -1,5 +1,5 @@ -Wirish soft (bit-banged) implementation of the Wire I2C library. - -This implementation is synchronous, and thus supports only a subset of -the full Wire interface. An asynchronous hardware version implemented -with DMA is expected for Maple IDE release 0.1.0. +Wirish soft (bit-banged) implementation of the Wire I2C library. + +This implementation is synchronous, and thus supports only a subset of +the full Wire interface. An asynchronous hardware version implemented +with DMA is expected for Maple IDE release 0.1.0. diff --git a/Libmaple/libmaple/libraries/Wire/Wire.cpp b/Libmaple/libmaple/libraries/Wire/Wire.cpp index a6b15f67..7344d5ee 100644 --- a/Libmaple/libmaple/libraries/Wire/Wire.cpp +++ b/Libmaple/libmaple/libraries/Wire/Wire.cpp @@ -1,323 +1,323 @@ -/****************************************************************************** -* The MIT License -* -* Copyright (c) 2010 LeafLabs LLC. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*****************************************************************************/ - -/** -* @brief Wire library, ported from Arduino. Provides a simplistic -* interface to i2c. -*/ - -#include "Wire.h" -#include "wirish.h" - -/* low level conventions: -* - SDA/SCL idle high (expected high) -* - always start with i2c_delay rather than end -*/ -uint32 i2c_delay = 1; - -void i2c_scl_low(Port port) { - digitalWrite(port.scl,LOW); - I2C_DELAY_SCL; -} - -void i2c_scl_high(Port port) { - digitalWrite(port.scl,HIGH); - while(digitalRead(port.scl) == 0) - ; - I2C_DELAY_SCL; -} - -void i2c_sda_high(Port port) { - digitalWrite(port.sda,HIGH); - I2C_DELAY_SDA; -} - -void i2c_sda_low(Port port) { - digitalWrite(port.sda,LOW); - I2C_DELAY_SDA; -} - -void i2c_start(Port port) { - i2c_sda_high(port); - i2c_scl_high(port); - i2c_sda_low(port); - i2c_scl_low(port); -} - -void i2c_stop(Port port) { - i2c_sda_low(port); - i2c_scl_high(port); - i2c_sda_high(port); -} - -boolean i2c_get_ack(Port port) { - i2c_sda_high(port); - i2c_scl_high(port); - - bool ret =!digitalRead(port.sda); - i2c_scl_low(port); - return ret; -} - -void i2c_send_ack(Port port) { - i2c_sda_low(port); - i2c_scl_high(port); - i2c_scl_low(port); -} - -void i2c_send_nack(Port port) { - i2c_sda_high(port); - i2c_scl_high(port); - i2c_scl_low(port); -} - -uint8 i2c_shift_in(Port port) { - uint8 data = 0; - i2c_sda_high(port); - - int i; - for (i=0; i<8; i++) { - data <<= 1; - i2c_scl_high(port); - if(digitalRead(port.sda)) { - data |= 1; - } - i2c_scl_low(port); - } - - return data; -} - -void i2c_shift_out(Port port, uint8 val) { - int i; - for (i=0;i<8;i++) { - if((val & 0x80) != 0) { - i2c_sda_high(port); - } else { - i2c_sda_low(port); - } - val <<= 1; - i2c_scl_high(port); - i2c_scl_low(port); - } - /* - i2c_sda_high(port); - i2c_scl_high(port); - bool nack = digitalRead(port.sda); - i2c_scl_low(port); - */ - -} - -TwoWire::TwoWire() { - i2c_delay = 0; - rx_buf_idx = 0; - rx_buf_len = 0; - tx_addr = 0; - tx_buf_idx = 0; - tx_buf_overflow = false; -} - -/* -* Sets pins SDA and SCL to OUPTUT_OPEN_DRAIN, joining I2C bus as -* master. If you want them to be some other pins, use begin(uint8, -* uint8); -*/ -void TwoWire::begin() { - begin(SDA, SCL); -} - -/* -* Joins I2C bus as master on given SDA and SCL pins. -*/ -void TwoWire::begin(uint8 sda, uint8 scl) { - port.sda = sda; - port.scl = scl; - pinMode(scl, OUTPUT_OPEN_DRAIN); - pinMode(sda, OUTPUT_OPEN_DRAIN); - digitalWrite(scl, HIGH); - digitalWrite(sda, HIGH); -/* - long t0 = systick_get_count(); - i2c_scl_high(port); - long t1 = systick_get_count(); - Serial2.print("i2c_scl_high: "); - Serial2.print(t1-t0); - Serial2.println(); -*/ -} - -void TwoWire::beginTransmission(uint8 slave_address) { - tx_addr = slave_address; - tx_buf_idx = 0; - tx_buf_overflow = false; - rx_buf_idx = 0; - rx_buf_len = 0; -} - -void TwoWire::beginTransmission(int slave_address) { - beginTransmission((uint8)slave_address); -} - -uint8 TwoWire::endTransmission(void) { - if (tx_buf_overflow) return EDATA; - - i2c_start(port); - - i2c_shift_out(port, (tx_addr << 1) | I2C_WRITE); - if (!i2c_get_ack(port)) return ENACKADDR; - - // shift out the address we're transmitting to - for (uint8 i = 0; i < tx_buf_idx; i++) { - uint8 ret = writeOneByte(tx_buf[i]); - if (ret) { - //Serial1.println("endTransmission failed"); - return ret; // SUCCESS is 0 - } - } - - i2c_stop(port); - - tx_buf_idx = 0; - tx_buf_overflow = false; - return SUCCESS; -} - -#if 0 -uint8 TwoWire::requestFromOld(uint8 address, int num_bytes) { - if (num_bytes > WIRE_BUFSIZ) num_bytes = WIRE_BUFSIZ; - - rx_buf_idx = 0; - rx_buf_len = 0; - while (rx_buf_len < num_bytes) { - if(!readOneByte(address, rx_buf + rx_buf_len)) - rx_buf_len++; - else { - Serial1.print("requestFrom failed at byte "); - Serial1.print(rx_buf_len,10); - Serial1.println(); - break; - } - } - return rx_buf_len; -} -#endif - -uint8 TwoWire::requestFrom(uint8 address, int num_bytes) { - if (num_bytes > WIRE_BUFSIZ) num_bytes = WIRE_BUFSIZ; - - rx_buf_idx = 0; - rx_buf_len = 0; - - i2c_start(port); - - i2c_shift_out(port, (address << 1) | I2C_READ); - if (!i2c_get_ack(port)) { - //Serial1.print("requestFrom failed at byte "); - //Serial1.print(rx_buf_len,10); - //Serial1.println(); - return 0; - } - - while (rx_buf_len < num_bytes) { - rx_buf[rx_buf_len++] = i2c_shift_in(port); - if(rx_buf_len < num_bytes) { - i2c_send_ack(port); - } - } - - i2c_send_nack(port); - i2c_stop(port); - - return rx_buf_len; -} - -uint8 TwoWire::requestFrom(int address, int numBytes) { - return TwoWire::requestFrom((uint8)address, (uint8) numBytes); -} - -void TwoWire::send(uint8 value) { - if (tx_buf_idx == WIRE_BUFSIZ) { - tx_buf_overflow = true; - return; - } - - tx_buf[tx_buf_idx++] = value; -} - -void TwoWire::send(uint8* buf, int len) { - for (uint8 i = 0; i < len; i++) send(buf[i]); -} - -void TwoWire::send(int value) { - send((uint8)value); -} - -void TwoWire::send(int* buf, int len) { - send((uint8*)buf, (uint8)len); -} - -void TwoWire::send(char* buf) { - uint8 *ptr = (uint8*)buf; - while(*ptr) { - send(*ptr); - ptr++; - } -} - -uint8 TwoWire::available() { - return rx_buf_len - rx_buf_idx; -} - -uint8 TwoWire::receive() { - if (rx_buf_idx == rx_buf_len) return 0; - return rx_buf[rx_buf_idx++]; -} - -// private methods - -uint8 TwoWire::writeOneByte(uint8 byte) { - i2c_shift_out(port, byte); - if (!i2c_get_ack(port)) return ENACKTRNS; - - return SUCCESS; -} - -uint8 TwoWire::readOneByte(uint8 address, uint8 *byte) { - i2c_start(port); - - i2c_shift_out(port, (address << 1) | I2C_READ); - if (!i2c_get_ack(port)) return ENACKADDR; - - *byte = i2c_shift_in(port); - - i2c_send_nack(port); - i2c_stop(port); - - return SUCCESS; // no real way of knowing, but be optimistic! -} - -// Declare the instance that the users of the library can use -TwoWire Wire; - +/****************************************************************************** +* The MIT License +* +* Copyright (c) 2010 LeafLabs LLC. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*****************************************************************************/ + +/** +* @brief Wire library, ported from Arduino. Provides a simplistic +* interface to i2c. +*/ + +#include "Wire.h" +#include "wirish.h" + +/* low level conventions: +* - SDA/SCL idle high (expected high) +* - always start with i2c_delay rather than end +*/ +uint32 i2c_delay = 1; + +void i2c_scl_low(Port port) { + digitalWrite(port.scl,LOW); + I2C_DELAY_SCL; +} + +void i2c_scl_high(Port port) { + digitalWrite(port.scl,HIGH); + while(digitalRead(port.scl) == 0) + ; + I2C_DELAY_SCL; +} + +void i2c_sda_high(Port port) { + digitalWrite(port.sda,HIGH); + I2C_DELAY_SDA; +} + +void i2c_sda_low(Port port) { + digitalWrite(port.sda,LOW); + I2C_DELAY_SDA; +} + +void i2c_start(Port port) { + i2c_sda_high(port); + i2c_scl_high(port); + i2c_sda_low(port); + i2c_scl_low(port); +} + +void i2c_stop(Port port) { + i2c_sda_low(port); + i2c_scl_high(port); + i2c_sda_high(port); +} + +boolean i2c_get_ack(Port port) { + i2c_sda_high(port); + i2c_scl_high(port); + + bool ret =!digitalRead(port.sda); + i2c_scl_low(port); + return ret; +} + +void i2c_send_ack(Port port) { + i2c_sda_low(port); + i2c_scl_high(port); + i2c_scl_low(port); +} + +void i2c_send_nack(Port port) { + i2c_sda_high(port); + i2c_scl_high(port); + i2c_scl_low(port); +} + +uint8 i2c_shift_in(Port port) { + uint8 data = 0; + i2c_sda_high(port); + + int i; + for (i=0; i<8; i++) { + data <<= 1; + i2c_scl_high(port); + if(digitalRead(port.sda)) { + data |= 1; + } + i2c_scl_low(port); + } + + return data; +} + +void i2c_shift_out(Port port, uint8 val) { + int i; + for (i=0;i<8;i++) { + if((val & 0x80) != 0) { + i2c_sda_high(port); + } else { + i2c_sda_low(port); + } + val <<= 1; + i2c_scl_high(port); + i2c_scl_low(port); + } + /* + i2c_sda_high(port); + i2c_scl_high(port); + bool nack = digitalRead(port.sda); + i2c_scl_low(port); + */ + +} + +TwoWire::TwoWire() { + i2c_delay = 0; + rx_buf_idx = 0; + rx_buf_len = 0; + tx_addr = 0; + tx_buf_idx = 0; + tx_buf_overflow = false; +} + +/* +* Sets pins SDA and SCL to OUPTUT_OPEN_DRAIN, joining I2C bus as +* master. If you want them to be some other pins, use begin(uint8, +* uint8); +*/ +void TwoWire::begin() { + begin(SDA, SCL); +} + +/* +* Joins I2C bus as master on given SDA and SCL pins. +*/ +void TwoWire::begin(uint8 sda, uint8 scl) { + port.sda = sda; + port.scl = scl; + pinMode(scl, OUTPUT_OPEN_DRAIN); + pinMode(sda, OUTPUT_OPEN_DRAIN); + digitalWrite(scl, HIGH); + digitalWrite(sda, HIGH); +/* + long t0 = systick_get_count(); + i2c_scl_high(port); + long t1 = systick_get_count(); + Serial2.print("i2c_scl_high: "); + Serial2.print(t1-t0); + Serial2.println(); +*/ +} + +void TwoWire::beginTransmission(uint8 slave_address) { + tx_addr = slave_address; + tx_buf_idx = 0; + tx_buf_overflow = false; + rx_buf_idx = 0; + rx_buf_len = 0; +} + +void TwoWire::beginTransmission(int slave_address) { + beginTransmission((uint8)slave_address); +} + +uint8 TwoWire::endTransmission(void) { + if (tx_buf_overflow) return EDATA; + + i2c_start(port); + + i2c_shift_out(port, (tx_addr << 1) | I2C_WRITE); + if (!i2c_get_ack(port)) return ENACKADDR; + + // shift out the address we're transmitting to + for (uint8 i = 0; i < tx_buf_idx; i++) { + uint8 ret = writeOneByte(tx_buf[i]); + if (ret) { + //Serial1.println("endTransmission failed"); + return ret; // SUCCESS is 0 + } + } + + i2c_stop(port); + + tx_buf_idx = 0; + tx_buf_overflow = false; + return SUCCESS; +} + +#if 0 +uint8 TwoWire::requestFromOld(uint8 address, int num_bytes) { + if (num_bytes > WIRE_BUFSIZ) num_bytes = WIRE_BUFSIZ; + + rx_buf_idx = 0; + rx_buf_len = 0; + while (rx_buf_len < num_bytes) { + if(!readOneByte(address, rx_buf + rx_buf_len)) + rx_buf_len++; + else { + Serial1.print("requestFrom failed at byte "); + Serial1.print(rx_buf_len,10); + Serial1.println(); + break; + } + } + return rx_buf_len; +} +#endif + +uint8 TwoWire::requestFrom(uint8 address, int num_bytes) { + if (num_bytes > WIRE_BUFSIZ) num_bytes = WIRE_BUFSIZ; + + rx_buf_idx = 0; + rx_buf_len = 0; + + i2c_start(port); + + i2c_shift_out(port, (address << 1) | I2C_READ); + if (!i2c_get_ack(port)) { + //Serial1.print("requestFrom failed at byte "); + //Serial1.print(rx_buf_len,10); + //Serial1.println(); + return 0; + } + + while (rx_buf_len < num_bytes) { + rx_buf[rx_buf_len++] = i2c_shift_in(port); + if(rx_buf_len < num_bytes) { + i2c_send_ack(port); + } + } + + i2c_send_nack(port); + i2c_stop(port); + + return rx_buf_len; +} + +uint8 TwoWire::requestFrom(int address, int numBytes) { + return TwoWire::requestFrom((uint8)address, (uint8) numBytes); +} + +void TwoWire::send(uint8 value) { + if (tx_buf_idx == WIRE_BUFSIZ) { + tx_buf_overflow = true; + return; + } + + tx_buf[tx_buf_idx++] = value; +} + +void TwoWire::send(uint8* buf, int len) { + for (uint8 i = 0; i < len; i++) send(buf[i]); +} + +void TwoWire::send(int value) { + send((uint8)value); +} + +void TwoWire::send(int* buf, int len) { + send((uint8*)buf, (uint8)len); +} + +void TwoWire::send(char* buf) { + uint8 *ptr = (uint8*)buf; + while(*ptr) { + send(*ptr); + ptr++; + } +} + +uint8 TwoWire::available() { + return rx_buf_len - rx_buf_idx; +} + +uint8 TwoWire::receive() { + if (rx_buf_idx == rx_buf_len) return 0; + return rx_buf[rx_buf_idx++]; +} + +// private methods + +uint8 TwoWire::writeOneByte(uint8 byte) { + i2c_shift_out(port, byte); + if (!i2c_get_ack(port)) return ENACKTRNS; + + return SUCCESS; +} + +uint8 TwoWire::readOneByte(uint8 address, uint8 *byte) { + i2c_start(port); + + i2c_shift_out(port, (address << 1) | I2C_READ); + if (!i2c_get_ack(port)) return ENACKADDR; + + *byte = i2c_shift_in(port); + + i2c_send_nack(port); + i2c_stop(port); + + return SUCCESS; // no real way of knowing, but be optimistic! +} + +// Declare the instance that the users of the library can use +TwoWire Wire; + diff --git a/Libmaple/libmaple/libraries/Wire/Wire.h b/Libmaple/libmaple/libraries/Wire/Wire.h index e399e988..ce3dd3e7 100644 --- a/Libmaple/libmaple/libraries/Wire/Wire.h +++ b/Libmaple/libmaple/libraries/Wire/Wire.h @@ -1,112 +1,112 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -/** - * @brief Wire library, ported from Arduino. Provides a lean - * interface to I2C (two-wire) communication. - */ - -#include "wirish.h" - -#ifndef _WIRE_H_ -#define _WIRE_H_ - -typedef struct { - uint8 scl; - uint8 sda; -} Port; - -/* You must update the online docs if you change this value. */ -#define WIRE_BUFSIZ 32 - -/* return codes from endTransmission() */ -#define SUCCESS 0 /* transmission was successful */ -#define EDATA 1 /* too much data */ -#define ENACKADDR 2 /* received nack on transmit of address */ -#define ENACKTRNS 3 /* received nack on transmit of data */ -#define EOTHER 4 /* other error */ - -#define SDA 20 -#define SCL 21 - -#define I2C_WRITE 0 -#define I2C_READ 1 - -#if (F_CPU == 168000000) - #define I2C_DELAY_SCL delay_ns100(6) - #define I2C_DELAY_SDA delay_ns100(2) -#else - #define I2C_DELAY_SCL - #define I2C_DELAY_SDA -#endif - -class TwoWire { - private: - uint8 rx_buf[WIRE_BUFSIZ]; /* receive buffer */ - uint8 rx_buf_idx; /* first unread idx in rx_buf */ - uint8 rx_buf_len; /* number of bytes read */ - - uint8 tx_addr; /* address transmitting to */ - uint8 tx_buf[WIRE_BUFSIZ]; /* transmit buffer */ - uint8 tx_buf_idx; /* next idx available in tx_buf, -1 overflow */ - boolean tx_buf_overflow; - Port port; - uint8 writeOneByte(uint8); - uint8 readOneByte(uint8, uint8*); - public: - TwoWire(); - void begin(); - void begin(uint8, uint8); - void beginTransmission(uint8); - void beginTransmission(int); - uint8 endTransmission(void); - uint8 requestFrom(uint8, int); - uint8 requestFrom(int, int); - void send(uint8); - void send(uint8*, int); - void send(int); - void send(int*, int); - void send(char*); - uint8 available(); - uint8 receive(); - - uint8 read() { return receive(); }; - void write(uint8 data) { send(data); }; - void write(uint8* buf, int len) { send(buf, len); }; - void write(int data) { send(data); }; - void write(int* buf, int len) { send(buf, len); }; - void write(char* buf) { send(buf); }; -}; - -void i2c_start(Port port); -void i2c_stop(Port port); -boolean i2c_get_ack(Port port); -void i2c_send_ack(Port port); -void i2c_send_nack(Port port); -uint8 i2c_shift_in(Port port); -void i2c_shift_out(Port port, uint8 val); - -extern TwoWire Wire; - -#endif // _WIRE_H_ +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +/** + * @brief Wire library, ported from Arduino. Provides a lean + * interface to I2C (two-wire) communication. + */ + +#include "wirish.h" + +#ifndef _WIRE_H_ +#define _WIRE_H_ + +typedef struct { + uint8 scl; + uint8 sda; +} Port; + +/* You must update the online docs if you change this value. */ +#define WIRE_BUFSIZ 32 + +/* return codes from endTransmission() */ +#define SUCCESS 0 /* transmission was successful */ +#define EDATA 1 /* too much data */ +#define ENACKADDR 2 /* received nack on transmit of address */ +#define ENACKTRNS 3 /* received nack on transmit of data */ +#define EOTHER 4 /* other error */ + +#define SDA 20 +#define SCL 21 + +#define I2C_WRITE 0 +#define I2C_READ 1 + +#if (F_CPU == 168000000) + #define I2C_DELAY_SCL delay_ns100(6) + #define I2C_DELAY_SDA delay_ns100(2) +#else + #define I2C_DELAY_SCL + #define I2C_DELAY_SDA +#endif + +class TwoWire { + private: + uint8 rx_buf[WIRE_BUFSIZ]; /* receive buffer */ + uint8 rx_buf_idx; /* first unread idx in rx_buf */ + uint8 rx_buf_len; /* number of bytes read */ + + uint8 tx_addr; /* address transmitting to */ + uint8 tx_buf[WIRE_BUFSIZ]; /* transmit buffer */ + uint8 tx_buf_idx; /* next idx available in tx_buf, -1 overflow */ + boolean tx_buf_overflow; + Port port; + uint8 writeOneByte(uint8); + uint8 readOneByte(uint8, uint8*); + public: + TwoWire(); + void begin(); + void begin(uint8, uint8); + void beginTransmission(uint8); + void beginTransmission(int); + uint8 endTransmission(void); + uint8 requestFrom(uint8, int); + uint8 requestFrom(int, int); + void send(uint8); + void send(uint8*, int); + void send(int); + void send(int*, int); + void send(char*); + uint8 available(); + uint8 receive(); + + uint8 read() { return receive(); }; + void write(uint8 data) { send(data); }; + void write(uint8* buf, int len) { send(buf, len); }; + void write(int data) { send(data); }; + void write(int* buf, int len) { send(buf, len); }; + void write(char* buf) { send(buf); }; +}; + +void i2c_start(Port port); +void i2c_stop(Port port); +boolean i2c_get_ack(Port port); +void i2c_send_ack(Port port); +void i2c_send_nack(Port port); +uint8 i2c_shift_in(Port port); +void i2c_shift_out(Port port, uint8 val); + +extern TwoWire Wire; + +#endif // _WIRE_H_ diff --git a/Libmaple/libmaple/libraries/Wire/rules.mk b/Libmaple/libmaple/libraries/Wire/rules.mk index f442564b..71f5e75b 100644 --- a/Libmaple/libmaple/libraries/Wire/rules.mk +++ b/Libmaple/libmaple/libraries/Wire/rules.mk @@ -1,29 +1,29 @@ -# Standard things -sp := $(sp).x -dirstack_$(sp) := $(d) -d := $(dir) -BUILDDIRS += $(BUILD_PATH)/$(d) - -# Local flags -CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) - -# Local rules and targets -cSRCS_$(d) := - -cppSRCS_$(d) := Wire.cpp - -cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) -cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) - -OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ - $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) -DEPS_$(d) := $(OBJS_$(d):%.o=%.d) - -$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) - -TGT_BIN += $(OBJS_$(d)) - -# Standard things --include $(DEPS_$(d)) -d := $(dirstack_$(sp)) +# Standard things +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) +BUILDDIRS += $(BUILD_PATH)/$(d) + +# Local flags +CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) + +# Local rules and targets +cSRCS_$(d) := + +cppSRCS_$(d) := Wire.cpp + +cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) + +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ + $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) +DEPS_$(d) := $(OBJS_$(d):%.o=%.d) + +$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) + +TGT_BIN += $(OBJS_$(d)) + +# Standard things +-include $(DEPS_$(d)) +d := $(dirstack_$(sp)) sp := $(basename $(sp)) \ No newline at end of file diff --git a/Libmaple/libmaple/libraries/mapleSDfat/Document1.txt b/Libmaple/libmaple/libraries/mapleSDfat/Document1.txt index 9c61eb34..9a5d8851 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/Document1.txt +++ b/Libmaple/libmaple/libraries/mapleSDfat/Document1.txt @@ -1,38 +1,38 @@ -EB 3C 90 -4D 53 44 4F 53 35 2E 30 -0 2 -40 -8 0 -2 fat count -0 2 -0 0 F8 F0 0 3F 0 FF 0 3F 0 0 0 -C1 FF 3B 0 80 0 29 4D C5 39 80 4E 4F 20 4E 41 -4D 45 20 20 20 20 46 41 54 31 36 20 20 20 33 C9 -8E D1 BC F0 7B 8E D9 B8 0 20 8E C0 FC BD 0 7C -38 4E 24 7D 24 8B C1 99 E8 3C 1 72 1C 83 EB 3A -66 A1 1C 7C 26 66 3B 7 26 8A 57 FC 75 6 80 CA -2 88 56 2 80 C3 10 73 EB 33 C9 8A 46 10 98 F7 -66 16 3 46 1C 13 56 1E 3 46 E 13 D1 8B 76 11 -60 89 46 FC 89 56 FE B8 20 0 F7 E6 8B 5E B 3 -C3 48 F7 F3 1 46 FC 11 4E FE 61 BF 0 0 E8 E6 -0 72 39 26 38 2D 74 17 60 B1 B BE A1 7D F3 A6 -61 74 32 4E 74 9 83 C7 20 3B FB 72 E6 EB DC A0 -FB 7D B4 7D 8B F0 AC 98 40 74 C 48 74 13 B4 E -BB 7 0 CD 10 EB EF A0 FD 7D EB E6 A0 FC 7D EB -E1 CD 16 CD 19 26 8B 55 1A 52 B0 1 BB 0 0 E8 -3B 0 72 E8 5B 8A 56 24 BE B 7C 8B FC C7 46 F0 -3D 7D C7 46 F4 29 7D 8C D9 89 4E F2 89 4E F6 C6 -6 96 7D CB EA 3 0 0 20 F B6 C8 66 8B 46 F8 -66 3 46 1C 66 8B D0 66 C1 EA 10 EB 5E F B6 C8 -4A 4A 8A 46 D 32 E4 F7 E2 3 46 FC 13 56 FE EB -4A 52 50 6 53 6A 1 6A 10 91 8B 46 18 96 92 33 -D2 F7 F6 91 F7 F6 42 87 CA F7 76 1A 8A F2 8A E8 -C0 CC 2 A CC B8 1 2 80 7E 2 E 75 4 B4 42 -8B F4 8A 56 24 CD 13 61 61 72 B 40 75 1 42 3 -5E B 49 75 6 F8 C3 41 BB 0 0 60 66 6A 0 EB -B0 4E 54 4C 44 52 20 20 20 20 20 20 D A 52 65 -6D 6F 76 65 20 64 69 73 6B 73 20 6F 72 20 6F 74 -68 65 72 20 6D 65 64 69 61 2E FF D A 44 69 73 -6B 20 65 72 72 6F 72 FF D A 50 72 65 73 73 20 -61 6E 79 20 6B 65 79 20 74 6F 20 72 65 73 74 61 +EB 3C 90 +4D 53 44 4F 53 35 2E 30 +0 2 +40 +8 0 +2 fat count +0 2 +0 0 F8 F0 0 3F 0 FF 0 3F 0 0 0 +C1 FF 3B 0 80 0 29 4D C5 39 80 4E 4F 20 4E 41 +4D 45 20 20 20 20 46 41 54 31 36 20 20 20 33 C9 +8E D1 BC F0 7B 8E D9 B8 0 20 8E C0 FC BD 0 7C +38 4E 24 7D 24 8B C1 99 E8 3C 1 72 1C 83 EB 3A +66 A1 1C 7C 26 66 3B 7 26 8A 57 FC 75 6 80 CA +2 88 56 2 80 C3 10 73 EB 33 C9 8A 46 10 98 F7 +66 16 3 46 1C 13 56 1E 3 46 E 13 D1 8B 76 11 +60 89 46 FC 89 56 FE B8 20 0 F7 E6 8B 5E B 3 +C3 48 F7 F3 1 46 FC 11 4E FE 61 BF 0 0 E8 E6 +0 72 39 26 38 2D 74 17 60 B1 B BE A1 7D F3 A6 +61 74 32 4E 74 9 83 C7 20 3B FB 72 E6 EB DC A0 +FB 7D B4 7D 8B F0 AC 98 40 74 C 48 74 13 B4 E +BB 7 0 CD 10 EB EF A0 FD 7D EB E6 A0 FC 7D EB +E1 CD 16 CD 19 26 8B 55 1A 52 B0 1 BB 0 0 E8 +3B 0 72 E8 5B 8A 56 24 BE B 7C 8B FC C7 46 F0 +3D 7D C7 46 F4 29 7D 8C D9 89 4E F2 89 4E F6 C6 +6 96 7D CB EA 3 0 0 20 F B6 C8 66 8B 46 F8 +66 3 46 1C 66 8B D0 66 C1 EA 10 EB 5E F B6 C8 +4A 4A 8A 46 D 32 E4 F7 E2 3 46 FC 13 56 FE EB +4A 52 50 6 53 6A 1 6A 10 91 8B 46 18 96 92 33 +D2 F7 F6 91 F7 F6 42 87 CA F7 76 1A 8A F2 8A E8 +C0 CC 2 A CC B8 1 2 80 7E 2 E 75 4 B4 42 +8B F4 8A 56 24 CD 13 61 61 72 B 40 75 1 42 3 +5E B 49 75 6 F8 C3 41 BB 0 0 60 66 6A 0 EB +B0 4E 54 4C 44 52 20 20 20 20 20 20 D A 52 65 +6D 6F 76 65 20 64 69 73 6B 73 20 6F 72 20 6F 74 +68 65 72 20 6D 65 64 69 61 2E FF D A 44 69 73 +6B 20 65 72 72 6F 72 FF D A 50 72 65 73 73 20 +61 6E 79 20 6B 65 79 20 74 6F 20 72 65 73 74 61 72 74 D A 0 0 0 0 0 0 0 AC CB D8 55 AA \ No newline at end of file diff --git a/Libmaple/libmaple/libraries/mapleSDfat/FatStructs.h b/Libmaple/libmaple/libraries/mapleSDfat/FatStructs.h index e6ef84c2..b775c7e5 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/FatStructs.h +++ b/Libmaple/libmaple/libraries/mapleSDfat/FatStructs.h @@ -1,420 +1,420 @@ -/* Arduino SdFat Library - * Copyright (C) 2009 by William Greiman - * - * This file is part of the Arduino SdFat Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino SdFat Library. If not, see - * . - */ -#ifndef FatStructs_h -#define FatStructs_h - -/** - * \file - * FAT file structures - */ -/* - * mostly from Microsoft document fatgen103.doc - * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - */ -//------------------------------------------------------------------------------ -/** Value for byte 510 of boot block or MBR */ -uint8_t const BOOTSIG0 = 0X55; -/** Value for byte 511 of boot block or MBR */ -uint8_t const BOOTSIG1 = 0XAA; -//------------------------------------------------------------------------------ -/** - * \struct partitionTable - * \brief MBR partition table entry - * - * A partition table entry for a MBR formatted storage device. - * The MBR partition table has four entries. - */ -struct partitionTable { - /** - * Boot Indicator . Indicates whether the volume is the active - * partition. Legal values include: 0X00. Do not use for booting. - * 0X80 Active partition. - */ - uint8_t boot; - /** - * Head part of Cylinder-head-sector address of the first block in - * the partition. Legal values are 0-255. Only used in old PC BIOS. - */ - uint8_t beginHead; - /** - * Sector part of Cylinder-head-sector address of the first block in - * the partition. Legal values are 1-63. Only used in old PC BIOS. - */ - - uint8_t beginSector : 6; - /** High bits cylinder for first block in partition. */ - uint8_t beginCylinderHigh : 2; - /** - * Combine beginCylinderLow with beginCylinderHigh. Legal values - * are 0-1023. Only used in old PC BIOS. - */ - uint8_t beginCylinderLow; - /** - * Partition type. See defines that begin with PART_TYPE_ for - * some Microsoft partition types. - */ - uint8_t type; - /** - * head part of cylinder-head-sector address of the last sector in the - * partition. Legal values are 0-255. Only used in old PC BIOS. - */ - uint8_t endHead; - /** - * Sector part of cylinder-head-sector address of the last sector in - * the partition. Legal values are 1-63. Only used in old PC BIOS. - */ - uint8_t endSector : 6; - /** High bits of end cylinder */ - uint8_t endCylinderHigh : 2; - /** - * Combine endCylinderLow with endCylinderHigh. Legal values - * are 0-1023. Only used in old PC BIOS. - */ - uint8_t endCylinderLow; - /** Logical block address of the first block in the partition. */ - uint32_t firstSector; - /** Length of the partition, in blocks. */ - uint32_t totalSectors; -}__attribute__ ((packed)); -/** Type name for partitionTable */ -typedef struct partitionTable part_t; -//------------------------------------------------------------------------------ -/** - * \struct masterBootRecord - * - * \brief Master Boot Record - * - * The first block of a storage device that is formatted with a MBR. - */ -struct masterBootRecord { - /** Code Area for master boot program. */ - uint8_t codeArea[440]; - /** Optional WindowsNT disk signature. May contain more boot code. */ - uint32_t diskSignature; - /** Usually zero but may be more boot code. */ - uint16_t usuallyZero; - /** Partition tables. */ - part_t part[4]; - /** First MBR signature byte. Must be 0X55 */ - uint8_t mbrSig0; - /** Second MBR signature byte. Must be 0XAA */ - uint8_t mbrSig1; -}__attribute__ ((packed)); -/** Type name for masterBootRecord */ -typedef struct masterBootRecord mbr_t; -//------------------------------------------------------------------------------ -/** - * \struct biosParmBlock - * - * \brief BIOS parameter block - * - * The BIOS parameter block describes the physical layout of a FAT volume. - */ -struct biosParmBlock { - /** - * Count of bytes per sector. This value may take on only the - * following values: 512, 1024, 2048 or 4096 - */ - uint16_t bytesPerSector; - /** - * Number of sectors per allocation unit. This value must be a - * power of 2 that is greater than 0. The legal values are - * 1, 2, 4, 8, 16, 32, 64, and 128. - */ - uint8_t sectorsPerCluster; - /** - * Number of sectors before the first FAT. - * This value must not be zero. - */ - uint16_t reservedSectorCount; - /** The count of FAT data structures on the volume. This field should - * always contain the value 2 for any FAT volume of any type. - */ - uint8_t fatCount; - /** - * For FAT12 and FAT16 volumes, this field contains the count of - * 32-byte directory entries in the root directory. For FAT32 volumes, - * this field must be set to 0. For FAT12 and FAT16 volumes, this - * value should always specify a count that when multiplied by 32 - * results in a multiple of bytesPerSector. FAT16 volumes should - * use the value 512. - */ - uint16_t rootDirEntryCount; - /** - * This field is the old 16-bit total count of sectors on the volume. - * This count includes the count of all sectors in all four regions - * of the volume. This field can be 0; if it is 0, then totalSectors32 - * must be non-zero. For FAT32 volumes, this field must be 0. For - * FAT12 and FAT16 volumes, this field contains the sector count, and - * totalSectors32 is 0 if the total sector count fits - * (is less than 0x10000). - */ - uint16_t totalSectors16; - /** - * This dates back to the old MS-DOS 1.x media determination and is - * no longer usually used for anything. 0xF8 is the standard value - * for fixed (non-removable) media. For removable media, 0xF0 is - * frequently used. Legal values are 0xF0 or 0xF8-0xFF. - */ - uint8_t mediaType; - /** - * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. - * On FAT32 volumes this field must be 0, and sectorsPerFat32 - * contains the FAT size count. - */ - uint16_t sectorsPerFat16; - /** Sectors per track for interrupt 0x13. Not used otherwise. */ - uint16_t sectorsPerTrtack; - /** Number of heads for interrupt 0x13. Not used otherwise. */ - uint16_t headCount; - /** - * Count of hidden sectors preceding the partition that contains this - * FAT volume. This field is generally only relevant for media - * visible on interrupt 0x13. - */ - uint32_t hidddenSectors; - /** - * This field is the new 32-bit total count of sectors on the volume. - * This count includes the count of all sectors in all four regions - * of the volume. This field can be 0; if it is 0, then - * totalSectors16 must be non-zero. - */ - uint32_t totalSectors32; - /** - * Count of sectors occupied by one FAT on FAT32 volumes. - */ - uint32_t sectorsPerFat32; - /** - * This field is only defined for FAT32 media and does not exist on - * FAT12 and FAT16 media. - * Bits 0-3 -- Zero-based number of active FAT. - * Only valid if mirroring is disabled. - * Bits 4-6 -- Reserved. - * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. - * -- 1 means only one FAT is active; it is the one referenced in bits 0-3. - * Bits 8-15 -- Reserved. - */ - uint16_t fat32Flags; - /** - * FAT32 version. High byte is major revision number. - * Low byte is minor revision number. Only 0.0 define. - */ - uint16_t fat32Version; - /** - * Cluster number of the first cluster of the root directory for FAT32. - * This usually 2 but not required to be 2. - */ - uint32_t fat32RootCluster; - /** - * Sector number of FSINFO structure in the reserved area of the - * FAT32 volume. Usually 1. - */ - uint16_t fat32FSInfo; - /** - * If non-zero, indicates the sector number in the reserved area - * of the volume of a copy of the boot record. Usually 6. - * No value other than 6 is recommended. - */ - uint16_t fat32BackBootBlock; - /** - * Reserved for future expansion. Code that formats FAT32 volumes - * should always set all of the bytes of this field to 0. - */ - uint8_t fat32Reserved[12]; -}__attribute__ ((packed)); -/** Type name for biosParmBlock */ -typedef struct biosParmBlock bpb_t; -//------------------------------------------------------------------------------ -/** - * \struct fat32BootSector - * - * \brief Boot sector for a FAT16 or FAT32 volume. - * - */ -struct fat32BootSector { - /** X86 jmp to boot program */ - uint8_t jmpToBootCode[3]; - /** informational only - don't depend on it */ - uint8_t oemName[8]; - /** BIOS Parameter Block */ - bpb_t bpb; - /** for int0x13 use value 0X80 for hard drive */ - uint8_t driveNumber; - /** used by Windows NT - should be zero for FAT */ - uint8_t reserved1; - /** 0X29 if next three fields are valid */ - uint8_t bootSignature; - /** usually generated by combining date and time */ - uint32_t volumeSerialNumber; - /** should match volume label in root dir */ - uint8_t volumeLabel[11]; - /** informational only - don't depend on it */ - uint8_t fileSystemType[8]; - /** X86 boot code */ - uint8_t bootCode[420]; - /** must be 0X55 */ - uint8_t bootSectorSig0; - /** must be 0XAA */ - uint8_t bootSectorSig1; -}__attribute__ ((packed)); -//------------------------------------------------------------------------------ -// End Of Chain values for FAT entries -/** FAT16 end of chain value used by Microsoft. */ -uint16_t const FAT16EOC = 0XFFFF; -/** Minimum value for FAT16 EOC. Use to test for EOC. */ -uint16_t const FAT16EOC_MIN = 0XFFF8; -/** FAT32 end of chain value used by Microsoft. */ -uint32_t const FAT32EOC = 0X0FFFFFFF; -/** Minimum value for FAT32 EOC. Use to test for EOC. */ -uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; -/** Mask a for FAT32 entry. Entries are 28 bits. */ -uint32_t const FAT32MASK = 0X0FFFFFFF; - -/** Type name for fat32BootSector */ -typedef struct fat32BootSector fbs_t; -//------------------------------------------------------------------------------ -/** - * \struct directoryEntry - * \brief FAT short directory entry - * - * Short means short 8.3 name, not the entry size. - * - * Date Format. A FAT directory entry date stamp is a 16-bit field that is - * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the - * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the - * 16-bit word): - * - * Bits 9-15: Count of years from 1980, valid value range 0-127 - * inclusive (1980-2107). - * - * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. - * - * Bits 0-4: Day of month, valid value range 1-31 inclusive. - * - * Time Format. A FAT directory entry time stamp is a 16-bit field that has - * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the - * 16-bit word, bit 15 is the MSB of the 16-bit word). - * - * Bits 11-15: Hours, valid value range 0-23 inclusive. - * - * Bits 5-10: Minutes, valid value range 0-59 inclusive. - * - * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). - * - * The valid time range is from Midnight 00:00:00 to 23:59:58. - */ -struct directoryEntry { - /** - * Short 8.3 name. - * The first eight bytes contain the file name with blank fill. - * The last three bytes contain the file extension with blank fill. - */ - uint8_t name[11]; - /** Entry attributes. - * - * The upper two bits of the attribute byte are reserved and should - * always be set to 0 when a file is created and never modified or - * looked at after that. See defines that begin with DIR_ATT_. - */ - uint8_t attributes; - /** - * Reserved for use by Windows NT. Set value to 0 when a file is - * created and never modify or look at it after that. - */ - uint8_t reservedNT; - /** - * The granularity of the seconds part of creationTime is 2 seconds - * so this field is a count of tenths of a second and its valid - * value range is 0-199 inclusive. (WHG note - seems to be hundredths) - */ - uint8_t creationTimeTenths; - /** Time file was created. */ - uint16_t creationTime; - /** Date file was created. */ - uint16_t creationDate; - /** - * Last access date. Note that there is no last access time, only - * a date. This is the date of last read or write. In the case of - * a write, this should be set to the same date as lastWriteDate. - */ - uint16_t lastAccessDate; - /** - * High word of this entry's first cluster number (always 0 for a - * FAT12 or FAT16 volume). - */ - uint16_t firstClusterHigh; - /** Time of last write. File creation is considered a write. */ - uint16_t lastWriteTime; - /** Date of last write. File creation is considered a write. */ - uint16_t lastWriteDate; - /** Low word of this entry's first cluster number. */ - uint16_t firstClusterLow; - /** 32-bit unsigned holding this file's size in bytes. */ - uint32_t fileSize; -}__attribute__ ((packed)); -//------------------------------------------------------------------------------ -// Definitions for directory entries -// -/** Type name for directoryEntry */ -typedef struct directoryEntry dir_t; -/** escape for name[0] = 0XE5 */ -uint8_t const DIR_NAME_0XE5 = 0X05; -/** name[0] value for entry that is free after being "deleted" */ -uint8_t const DIR_NAME_DELETED = 0XE5; -/** name[0] value for entry that is free and no allocated entries follow */ -uint8_t const DIR_NAME_FREE = 0X00; -/** file is read-only */ -uint8_t const DIR_ATT_READ_ONLY = 0X01; -/** File should hidden in directory listings */ -uint8_t const DIR_ATT_HIDDEN = 0X02; -/** Entry is for a system file */ -uint8_t const DIR_ATT_SYSTEM = 0X04; -/** Directory entry contains the volume label */ -uint8_t const DIR_ATT_VOLUME_ID = 0X08; -/** Entry is for a directory */ -uint8_t const DIR_ATT_DIRECTORY = 0X10; -/** Old DOS archive bit for backup support */ -uint8_t const DIR_ATT_ARCHIVE = 0X20; -/** Test value for long name entry. Test is - (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ -uint8_t const DIR_ATT_LONG_NAME = 0X0F; -/** Test mask for long name entry */ -uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; -/** defined attribute bits */ -uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; -/** Directory entry is part of a long name */ -static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { - return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; -} -/** Mask for file/subdirectory tests */ -uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); -/** Directory entry is for a file */ -static inline uint8_t DIR_IS_FILE(const dir_t* dir) { - return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; -} -/** Directory entry is for a subdirectory */ -static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { - return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; -} -/** Directory entry is for a file or subdirectory */ -static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { - return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; -} -#endif // FatStructs_h +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#ifndef FatStructs_h +#define FatStructs_h + +/** + * \file + * FAT file structures + */ +/* + * mostly from Microsoft document fatgen103.doc + * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + */ +//------------------------------------------------------------------------------ +/** Value for byte 510 of boot block or MBR */ +uint8_t const BOOTSIG0 = 0X55; +/** Value for byte 511 of boot block or MBR */ +uint8_t const BOOTSIG1 = 0XAA; +//------------------------------------------------------------------------------ +/** + * \struct partitionTable + * \brief MBR partition table entry + * + * A partition table entry for a MBR formatted storage device. + * The MBR partition table has four entries. + */ +struct partitionTable { + /** + * Boot Indicator . Indicates whether the volume is the active + * partition. Legal values include: 0X00. Do not use for booting. + * 0X80 Active partition. + */ + uint8_t boot; + /** + * Head part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t beginHead; + /** + * Sector part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + + uint8_t beginSector : 6; + /** High bits cylinder for first block in partition. */ + uint8_t beginCylinderHigh : 2; + /** + * Combine beginCylinderLow with beginCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t beginCylinderLow; + /** + * Partition type. See defines that begin with PART_TYPE_ for + * some Microsoft partition types. + */ + uint8_t type; + /** + * head part of cylinder-head-sector address of the last sector in the + * partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t endHead; + /** + * Sector part of cylinder-head-sector address of the last sector in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + uint8_t endSector : 6; + /** High bits of end cylinder */ + uint8_t endCylinderHigh : 2; + /** + * Combine endCylinderLow with endCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t endCylinderLow; + /** Logical block address of the first block in the partition. */ + uint32_t firstSector; + /** Length of the partition, in blocks. */ + uint32_t totalSectors; +}__attribute__ ((packed)); +/** Type name for partitionTable */ +typedef struct partitionTable part_t; +//------------------------------------------------------------------------------ +/** + * \struct masterBootRecord + * + * \brief Master Boot Record + * + * The first block of a storage device that is formatted with a MBR. + */ +struct masterBootRecord { + /** Code Area for master boot program. */ + uint8_t codeArea[440]; + /** Optional WindowsNT disk signature. May contain more boot code. */ + uint32_t diskSignature; + /** Usually zero but may be more boot code. */ + uint16_t usuallyZero; + /** Partition tables. */ + part_t part[4]; + /** First MBR signature byte. Must be 0X55 */ + uint8_t mbrSig0; + /** Second MBR signature byte. Must be 0XAA */ + uint8_t mbrSig1; +}__attribute__ ((packed)); +/** Type name for masterBootRecord */ +typedef struct masterBootRecord mbr_t; +//------------------------------------------------------------------------------ +/** + * \struct biosParmBlock + * + * \brief BIOS parameter block + * + * The BIOS parameter block describes the physical layout of a FAT volume. + */ +struct biosParmBlock { + /** + * Count of bytes per sector. This value may take on only the + * following values: 512, 1024, 2048 or 4096 + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. + */ + uint8_t sectorsPerCluster; + /** + * Number of sectors before the first FAT. + * This value must not be zero. + */ + uint16_t reservedSectorCount; + /** The count of FAT data structures on the volume. This field should + * always contain the value 2 for any FAT volume of any type. + */ + uint8_t fatCount; + /** + * For FAT12 and FAT16 volumes, this field contains the count of + * 32-byte directory entries in the root directory. For FAT32 volumes, + * this field must be set to 0. For FAT12 and FAT16 volumes, this + * value should always specify a count that when multiplied by 32 + * results in a multiple of bytesPerSector. FAT16 volumes should + * use the value 512. + */ + uint16_t rootDirEntryCount; + /** + * This field is the old 16-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then totalSectors32 + * must be non-zero. For FAT32 volumes, this field must be 0. For + * FAT12 and FAT16 volumes, this field contains the sector count, and + * totalSectors32 is 0 if the total sector count fits + * (is less than 0x10000). + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (non-removable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrtack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * This field is the new 32-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then + * totalSectors16 must be non-zero. + */ + uint32_t totalSectors32; + /** + * Count of sectors occupied by one FAT on FAT32 volumes. + */ + uint32_t sectorsPerFat32; + /** + * This field is only defined for FAT32 media and does not exist on + * FAT12 and FAT16 media. + * Bits 0-3 -- Zero-based number of active FAT. + * Only valid if mirroring is disabled. + * Bits 4-6 -- Reserved. + * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. + * -- 1 means only one FAT is active; it is the one referenced in bits 0-3. + * Bits 8-15 -- Reserved. + */ + uint16_t fat32Flags; + /** + * FAT32 version. High byte is major revision number. + * Low byte is minor revision number. Only 0.0 define. + */ + uint16_t fat32Version; + /** + * Cluster number of the first cluster of the root directory for FAT32. + * This usually 2 but not required to be 2. + */ + uint32_t fat32RootCluster; + /** + * Sector number of FSINFO structure in the reserved area of the + * FAT32 volume. Usually 1. + */ + uint16_t fat32FSInfo; + /** + * If non-zero, indicates the sector number in the reserved area + * of the volume of a copy of the boot record. Usually 6. + * No value other than 6 is recommended. + */ + uint16_t fat32BackBootBlock; + /** + * Reserved for future expansion. Code that formats FAT32 volumes + * should always set all of the bytes of this field to 0. + */ + uint8_t fat32Reserved[12]; +}__attribute__ ((packed)); +/** Type name for biosParmBlock */ +typedef struct biosParmBlock bpb_t; +//------------------------------------------------------------------------------ +/** + * \struct fat32BootSector + * + * \brief Boot sector for a FAT16 or FAT32 volume. + * + */ +struct fat32BootSector { + /** X86 jmp to boot program */ + uint8_t jmpToBootCode[3]; + /** informational only - don't depend on it */ + uint8_t oemName[8]; + /** BIOS Parameter Block */ + bpb_t bpb; + /** for int0x13 use value 0X80 for hard drive */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0X29 if next three fields are valid */ + uint8_t bootSignature; + /** usually generated by combining date and time */ + uint32_t volumeSerialNumber; + /** should match volume label in root dir */ + uint8_t volumeLabel[11]; + /** informational only - don't depend on it */ + uint8_t fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[420]; + /** must be 0X55 */ + uint8_t bootSectorSig0; + /** must be 0XAA */ + uint8_t bootSectorSig1; +}__attribute__ ((packed)); +//------------------------------------------------------------------------------ +// End Of Chain values for FAT entries +/** FAT16 end of chain value used by Microsoft. */ +uint16_t const FAT16EOC = 0XFFFF; +/** Minimum value for FAT16 EOC. Use to test for EOC. */ +uint16_t const FAT16EOC_MIN = 0XFFF8; +/** FAT32 end of chain value used by Microsoft. */ +uint32_t const FAT32EOC = 0X0FFFFFFF; +/** Minimum value for FAT32 EOC. Use to test for EOC. */ +uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; +/** Mask a for FAT32 entry. Entries are 28 bits. */ +uint32_t const FAT32MASK = 0X0FFFFFFF; + +/** Type name for fat32BootSector */ +typedef struct fat32BootSector fbs_t; +//------------------------------------------------------------------------------ +/** + * \struct directoryEntry + * \brief FAT short directory entry + * + * Short means short 8.3 name, not the entry size. + * + * Date Format. A FAT directory entry date stamp is a 16-bit field that is + * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the + * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the + * 16-bit word): + * + * Bits 9-15: Count of years from 1980, valid value range 0-127 + * inclusive (1980-2107). + * + * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. + * + * Bits 0-4: Day of month, valid value range 1-31 inclusive. + * + * Time Format. A FAT directory entry time stamp is a 16-bit field that has + * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the + * 16-bit word, bit 15 is the MSB of the 16-bit word). + * + * Bits 11-15: Hours, valid value range 0-23 inclusive. + * + * Bits 5-10: Minutes, valid value range 0-59 inclusive. + * + * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). + * + * The valid time range is from Midnight 00:00:00 to 23:59:58. + */ +struct directoryEntry { + /** + * Short 8.3 name. + * The first eight bytes contain the file name with blank fill. + * The last three bytes contain the file extension with blank fill. + */ + uint8_t name[11]; + /** Entry attributes. + * + * The upper two bits of the attribute byte are reserved and should + * always be set to 0 when a file is created and never modified or + * looked at after that. See defines that begin with DIR_ATT_. + */ + uint8_t attributes; + /** + * Reserved for use by Windows NT. Set value to 0 when a file is + * created and never modify or look at it after that. + */ + uint8_t reservedNT; + /** + * The granularity of the seconds part of creationTime is 2 seconds + * so this field is a count of tenths of a second and its valid + * value range is 0-199 inclusive. (WHG note - seems to be hundredths) + */ + uint8_t creationTimeTenths; + /** Time file was created. */ + uint16_t creationTime; + /** Date file was created. */ + uint16_t creationDate; + /** + * Last access date. Note that there is no last access time, only + * a date. This is the date of last read or write. In the case of + * a write, this should be set to the same date as lastWriteDate. + */ + uint16_t lastAccessDate; + /** + * High word of this entry's first cluster number (always 0 for a + * FAT12 or FAT16 volume). + */ + uint16_t firstClusterHigh; + /** Time of last write. File creation is considered a write. */ + uint16_t lastWriteTime; + /** Date of last write. File creation is considered a write. */ + uint16_t lastWriteDate; + /** Low word of this entry's first cluster number. */ + uint16_t firstClusterLow; + /** 32-bit unsigned holding this file's size in bytes. */ + uint32_t fileSize; +}__attribute__ ((packed)); +//------------------------------------------------------------------------------ +// Definitions for directory entries +// +/** Type name for directoryEntry */ +typedef struct directoryEntry dir_t; +/** escape for name[0] = 0XE5 */ +uint8_t const DIR_NAME_0XE5 = 0X05; +/** name[0] value for entry that is free after being "deleted" */ +uint8_t const DIR_NAME_DELETED = 0XE5; +/** name[0] value for entry that is free and no allocated entries follow */ +uint8_t const DIR_NAME_FREE = 0X00; +/** file is read-only */ +uint8_t const DIR_ATT_READ_ONLY = 0X01; +/** File should hidden in directory listings */ +uint8_t const DIR_ATT_HIDDEN = 0X02; +/** Entry is for a system file */ +uint8_t const DIR_ATT_SYSTEM = 0X04; +/** Directory entry contains the volume label */ +uint8_t const DIR_ATT_VOLUME_ID = 0X08; +/** Entry is for a directory */ +uint8_t const DIR_ATT_DIRECTORY = 0X10; +/** Old DOS archive bit for backup support */ +uint8_t const DIR_ATT_ARCHIVE = 0X20; +/** Test value for long name entry. Test is + (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ +uint8_t const DIR_ATT_LONG_NAME = 0X0F; +/** Test mask for long name entry */ +uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; +/** defined attribute bits */ +uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; +/** Directory entry is part of a long name */ +static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { + return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; +} +/** Mask for file/subdirectory tests */ +uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); +/** Directory entry is for a file */ +static inline uint8_t DIR_IS_FILE(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; +} +/** Directory entry is for a subdirectory */ +static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; +} +/** Directory entry is for a file or subdirectory */ +static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; +} +#endif // FatStructs_h diff --git a/Libmaple/libmaple/libraries/mapleSDfat/Sd2Card.cpp b/Libmaple/libmaple/libraries/mapleSDfat/Sd2Card.cpp index bf59af77..f7729aeb 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/Sd2Card.cpp +++ b/Libmaple/libmaple/libraries/mapleSDfat/Sd2Card.cpp @@ -1,715 +1,715 @@ -/* Arduino Sd2Card Library - * Copyright (C) 2009 by William Greiman - * - * This file is part of the Arduino Sd2Card Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino Sd2Card Library. If not, see - * . - */ -#include -#include -#include "Sd2Card.h" -#include "HardwareSPI.h" -#include "spi.h" - -//pointer to spi object -HardwareSPI *SPIn; - -//------------------------------------------------------------------------------ -// functions for hardware SPI -/** Send a byte to the card */ -static void spiSend(uint8_t b) -{ - SPIn->send(b); - //while(SPIn->busy()) - //{ - //} -} - -#if 0 -static void spiSend(const uint8_t *data, int len) -{ - SPIn->send(data, len); -} -#endif - -/** Receive a byte from the card */ -static uint8_t spiRec(void) -{ - return SPIn->send(0XFF); -// return SPIn->read(); -} - -static void spiRec(uint8_t *data, int len) -{ - SPIn->readMaster(data, len); -} - -//------------------------------------------------------------------------------ -// send command and return error code. Return zero for OK -uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { - // end read if in partialBlockRead mode - readEnd(); - - // select card - chipSelectLow(); - - // wait up to 300 ms if busy - waitNotBusy(300); - - // send command - spiSend(cmd | 0x40); - - // send argument - for (int8_t s = 24; s >= 0; s -= 8) - spiSend(arg >> s); - - // send CRC - uint8_t crc = 0XFF; - if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0 - if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA - spiSend(crc); - - // wait for response - for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++); - return status_; -} -//------------------------------------------------------------------------------ -/** - * Determine the size of an SD flash memory card. - * - * \return The number of 512 byte data blocks in the card - * or zero if an error occurs. - */ -uint32_t Sd2Card::cardSize(void) { - csd_t csd; - if (!readCSD(&csd)) return 0; - if (csd.v1.csd_ver == 0) { - uint8_t read_bl_len = csd.v1.read_bl_len; - uint16_t c_size = (csd.v1.c_size_high << 10) - | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low; - uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1) - | csd.v1.c_size_mult_low; - return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7); - } else if (csd.v2.csd_ver == 1) { - uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16) - | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low; - return (c_size + 1) << 10; - } else { - error(SD_CARD_ERROR_BAD_CSD); - return 0; - } -} -//------------------------------------------------------------------------------ -void Sd2Card::chipSelectHigh(void) -{ - digitalWrite(74, HIGH); -} - -//------------------------------------------------------------------------------ -void Sd2Card::chipSelectLow(void) -{ - digitalWrite(74, LOW); -} - -//------------------------------------------------------------------------------ -/** Erase a range of blocks. - * - * \param[in] firstBlock The address of the first block in the range. - * \param[in] lastBlock The address of the last block in the range. - * - * \note This function requests the SD card to do a flash erase for a - * range of blocks. The data on the card after an erase operation is - * either 0 or 1, depends on the card vendor. The card must support - * single block erase. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - */ -uint8_t Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) -{ - if (!eraseSingleBlockEnable()) - { - error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); - SerialDebug.println("Error: Erase Single Block"); - goto fail; - } - if (type_ != SD_CARD_TYPE_SDHC) - { - firstBlock <<= 9; - lastBlock <<= 9; - } - if (cardCommand(CMD32, firstBlock) - || cardCommand(CMD33, lastBlock) - || cardCommand(CMD38, 0)) - { - error(SD_CARD_ERROR_ERASE); - SerialDebug.println("Error: Erase"); - goto fail; - } - if (!waitNotBusy(SD_ERASE_TIMEOUT)) - { - error(SD_CARD_ERROR_ERASE_TIMEOUT); - SerialDebug.println("Error: Erase timeout"); - goto fail; - } - chipSelectHigh(); - return true; - - fail: - chipSelectHigh(); - SerialDebug.println("Error: Sd2Card::Erase()"); - return false; -} -//------------------------------------------------------------------------------ -/** Determine if card supports single block erase. - * - * \return The value one, true, is returned if single block erase is supported. - * The value zero, false, is returned if single block erase is not supported. - */ -uint8_t Sd2Card::eraseSingleBlockEnable(void) -{ - csd_t csd; - return readCSD(&csd) ? csd.v1.erase_blk_en : 0; -} -//------------------------------------------------------------------------------ -/** - * Initialize an SD flash memory card. - * - * \param[in] sckRateID SPI clock rate selector. See setSckRate(). - * \param[in] chipSelectPin SD chip select pin number. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. The reason for failure - * can be determined by calling errorCode() and errorData(). - */ -uint8_t Sd2Card::init(HardwareSPI *s) -{ - errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0; - // 16-bit init start time allows over a minute - - uint16_t t0 = (uint16_t)millis(); - uint32_t arg; - - pinMode(74,OUTPUT); - - SPIn = s; - // set pin modes -/* pinMode(chipSelectPin_, OUTPUT); - chipSelectHigh(); - pinMode(SPI_MISO_PIN, INPUT); - pinMode(SPI_MOSI_PIN, OUTPUT); - pinMode(SPI_SCK_PIN, OUTPUT); -*/ - - // SS must be in output mode even it is not chip select -// pinMode(SS_PIN, OUTPUT); - // Enable SPI, Master, clock rate f_osc/128 -// SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); - // clear double speed -// SPSR &= ~(1 << SPI2X); - - // must supply min of 74 clock cycles with CS high. - - chipSelectHigh(); - for (uint8_t i = 0; i < 10; i++) spiSend(0XFF); - chipSelectLow(); - - // command to go idle in SPI mode - while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) - { - if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) - { - SerialDebug.println("Error: CMD0"); - error(SD_CARD_ERROR_CMD0); - goto fail; - } - } - // check SD version - if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) - { - type(SD_CARD_TYPE_SD1); - } - else - { - // only need last byte of r7 response - for (uint8_t i = 0; i < 4; i++) - status_ = spiRec(); - if (status_ != 0XAA) - { - error(SD_CARD_ERROR_CMD8); - SerialDebug.println("Error: CMD8"); - goto fail; - } - type(SD_CARD_TYPE_SD2); - } - // initialize card and send host supports SDHC if SD2 - arg = (type() == SD_CARD_TYPE_SD2) ? 0X40000000 : 0; - - while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) - { - // check for timeout - if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) - { - SerialDebug.println("Error: ACMD41"); - error(SD_CARD_ERROR_ACMD41); - goto fail; - } - } - // if SD2 read OCR register to check for SDHC card - if (type() == SD_CARD_TYPE_SD2) - { - if (cardCommand(CMD58, 0)) - { - SerialDebug.println("Error: CMD58"); - error(SD_CARD_ERROR_CMD58); - goto fail; - } - if ((spiRec() & 0XC0) == 0XC0) - type(SD_CARD_TYPE_SDHC); - // discard rest of ocr - contains allowed voltage range - for (uint8_t i = 0; i < 3; i++) - spiRec(); - } - chipSelectHigh(); - -// return setSckRate(sckRateID); - return true; - - fail: - chipSelectHigh(); - SerialDebug.println("Error: Sd2Card::init()"); - return false; -} -//------------------------------------------------------------------------------ -/** - * Enable or disable partial block reads. - * - * Enabling partial block reads improves performance by allowing a block - * to be read over the SPI bus as several sub-blocks. Errors may occur - * if the time between reads is too long since the SD card may timeout. - * The SPI SS line will be held low until the entire block is read or - * readEnd() is called. - * - * Use this for applications like the Adafruit Wave Shield. - * - * \param[in] value The value TRUE (non-zero) or FALSE (zero).) - */ -void Sd2Card::partialBlockRead(uint8_t value) -{ - readEnd(); - partialBlockRead_ = value; -} -//------------------------------------------------------------------------------ -/** - * Read a 512 byte block from an SD card device. - * - * \param[in] block Logical block to be read. - * \param[out] dst Pointer to the location that will receive the data. - - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - */ -uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) -{ - return readData(block, 0, 512, dst); -} -//------------------------------------------------------------------------------ -/** - * Read part of a 512 byte block from an SD card. - * - * \param[in] block Logical block to be read. - * \param[in] offset Number of bytes to skip at start of block - * \param[out] dst Pointer to the location that will receive the data. - * \param[in] count Number of bytes to read - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - */ -uint8_t Sd2Card::readData(uint32_t block, - uint16_t offset, uint16_t count, uint8_t* dst) -{ - if (count == 0) return true; - if ((count + offset) > 512) - { - goto fail; - } - if (!inBlock_ || block != block_ || offset < offset_) - { - block_ = block; - // use address if not SDHC card - if (type()!= SD_CARD_TYPE_SDHC) - block <<= 9; - if (cardCommand(CMD17, block)) - { - error(SD_CARD_ERROR_CMD17); - SerialDebug.println("Error: CMD17"); - goto fail; - } - if (!waitStartBlock()) - { - goto fail; - } - offset_ = 0; - inBlock_ = 1; - } - -#ifdef OPTIMIZE_HARDWARE_SPI -/* // start first spi transfer - SPDR = 0XFF; - - // skip data before offset - for (;offset_ < offset; offset_++) { - while (!(SPSR & (1 << SPIF))); - SPDR = 0XFF; - } - // transfer data - uint16_t n; - n = count - 1; - for (uint16_t i = 0; i < n; i++) { - while (!(SPSR & (1 << SPIF))); - dst[i] = SPDR; - SPDR = 0XFF; - } - // wait for last byte - while (!(SPSR & (1 << SPIF))); - dst[n] = SPDR; -*/ -#else // OPTIMIZE_HARDWARE_SPI - - // skip data before offset - for (;offset_ < offset; offset_++) - { - spiRec(); - } - // transfer data - //for (uint16_t i = 0; i < count; i++) - //{ - // dst[i] = spiRec(); - //} - spiRec(dst, count); - -#endif // OPTIMIZE_HARDWARE_SPI - - offset_ += count; - if (!partialBlockRead_ || offset_ >= 512) - { - // read rest of data, checksum and set chip select high - readEnd(); - } - return true; - - fail: - chipSelectHigh(); - SerialDebug.println("Error: Sd2Card::readData()"); - return false; -} -//------------------------------------------------------------------------------ -/** Skip remaining data in a block when in partial block read mode. */ -void Sd2Card::readEnd(void) -{ - if (inBlock_) - { - // skip data and crc -#ifdef OPTIMIZE_HARDWARE_SPI - // optimize skip for hardware -/* SPDR = 0XFF; - while (offset_++ < 513) { - while (!(SPSR & (1 << SPIF))); - SPDR = 0XFF; - } - // wait for last crc byte - while (!(SPSR & (1 << SPIF))); -*/ -#else // OPTIMIZE_HARDWARE_SPI - while (offset_++ < 514) - spiRec(); -#endif // OPTIMIZE_HARDWARE_SPI - chipSelectHigh(); - inBlock_ = 0; - } -} -//------------------------------------------------------------------------------ -/** read CID or CSR register */ -uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) -{ - uint8_t* dst = reinterpret_cast(buf); - if (cardCommand(cmd, 0)) - { - error(SD_CARD_ERROR_READ_REG); - SerialDebug.println("Error: Read reg"); - goto fail; - } - if (!waitStartBlock()) - goto fail; - // transfer data - for (uint16_t i = 0; i < 16; i++) - dst[i] = spiRec(); - spiRec(); // get first crc byte - spiRec(); // get second crc byte - chipSelectHigh(); - return true; - - fail: - SerialDebug.println("Error: Sd2Card::readRegister()"); - chipSelectHigh(); - return false; -} -//------------------------------------------------------------------------------ -/** - * Set the SPI clock rate. - * - * \param[in] sckRateID A value in the range [0, 6]. - * - * The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum - * SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128 - * for \a scsRateID = 6. - * - * \return The value one, true, is returned for success and the value zero, - * false, is returned for an invalid value of \a sckRateID. - */ -uint8_t Sd2Card::setSckRate(uint8_t sckRateID) { -/* if (sckRateID > 6) { - error(SD_CARD_ERROR_SCK_RATE); - return false; - } - // see avr processor datasheet for SPI register bit definitions - if ((sckRateID & 1) || sckRateID == 6) { - SPSR &= ~(1 << SPI2X); - } else { - SPSR |= (1 << SPI2X); - } - SPCR &= ~((1 < SD_READ_TIMEOUT) - { - error(SD_CARD_ERROR_READ_TIMEOUT); - SerialDebug.println("Error: Read timeout"); - goto fail; - } - } - if (status_ != DATA_START_BLOCK) - { - error(SD_CARD_ERROR_READ); - SerialDebug.println("Error: Read"); - goto fail; - } - return true; - - fail: - chipSelectHigh(); - SerialDebug.println("Error: Sd2Card::waitStartBlock()"); - return false; -} -//------------------------------------------------------------------------------ -/** - * Writes a 512 byte block to an SD card. - * - * \param[in] blockNumber Logical block to be written. - * \param[in] src Pointer to the location of the data to be written. - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - */ -uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) -{ -#if SD_PROTECT_BLOCK_ZERO - // don't allow write to first block - if (blockNumber == 0) - { - error(SD_CARD_ERROR_WRITE_BLOCK_ZERO); - SerialDebug.println("Error: Write block zero"); - goto fail; - } -#endif // SD_PROTECT_BLOCK_ZERO - - // use address if not SDHC card - if (type() != SD_CARD_TYPE_SDHC) - blockNumber <<= 9; - if (cardCommand(CMD24, blockNumber)) - { - SerialDebug.println("Error: CMD24"); - error(SD_CARD_ERROR_CMD24); - goto fail; - } - if (!writeData(DATA_START_BLOCK, src)) - goto fail; - - // wait for flash programming to complete - if (!waitNotBusy(SD_WRITE_TIMEOUT)) - { - error(SD_CARD_ERROR_WRITE_TIMEOUT); - SerialDebug.println("Error: Write timeout"); - goto fail; - } - // response is r2 so get and check two bytes for nonzero - if (cardCommand(CMD13, 0) || spiRec()) - { - error(SD_CARD_ERROR_WRITE_PROGRAMMING); - SerialDebug.println("Error: Write programming"); - goto fail; - } - chipSelectHigh(); - return true; - - fail: - chipSelectHigh(); - SerialDebug.println("Error: Sd2Card::writeBlock"); - return false; -} -//------------------------------------------------------------------------------ -/** Write one data block in a multiple block write sequence */ -uint8_t Sd2Card::writeData(const uint8_t* src) -{ - // wait for previous write to finish - if (!waitNotBusy(SD_WRITE_TIMEOUT)) - { - error(SD_CARD_ERROR_WRITE_MULTIPLE); - SerialDebug.println("Error: writeData"); - chipSelectHigh(); - return false; - } - return writeData(WRITE_MULTIPLE_TOKEN, src); -} -//------------------------------------------------------------------------------ -// send one block of data for write block or write multiple blocks -uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) { -#ifdef OPTIMIZE_HARDWARE_SPI -/* - // send data - optimized loop - SPDR = token; - - // send two byte per iteration - for (uint16_t i = 0; i < 512; i += 2) { - while (!(SPSR & (1 << SPIF))); - SPDR = src[i]; - while (!(SPSR & (1 << SPIF))); - SPDR = src[i+1]; - } - - // wait for last data byte - while (!(SPSR & (1 << SPIF))); -*/ -#else // OPTIMIZE_HARDWARE_SPI - spiSend(token); - for (uint16_t i = 0; i < 512; i++) - { - spiSend(src[i]); - } - //spiSend(src, 512); -#endif // OPTIMIZE_HARDWARE_SPI - spiSend(0xff); // dummy crc - spiSend(0xff); // dummy crc - - status_ = spiRec(); - if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) - { - error(SD_CARD_ERROR_WRITE); - chipSelectHigh(); - SerialDebug.println("Error: Write"); - SerialDebug.println("Error: Sd2Card::writeData()"); - return false; - } - return true; -} -//------------------------------------------------------------------------------ -/** Start a write multiple blocks sequence. - * - * \param[in] blockNumber Address of first block in sequence. - * \param[in] eraseCount The number of blocks to be pre-erased. - * - * \note This function is used with writeData() and writeStop() - * for optimized multiple block writes. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - */ -uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) -{ -#if SD_PROTECT_BLOCK_ZERO - // don't allow write to first block - if (blockNumber == 0) - { - error(SD_CARD_ERROR_WRITE_BLOCK_ZERO); - SerialDebug.println("Error: Write block zero"); - goto fail; - } -#endif // SD_PROTECT_BLOCK_ZERO - // send pre-erase count - if (cardAcmd(ACMD23, eraseCount)) - { - SerialDebug.println("Error: ACMD23"); - error(SD_CARD_ERROR_ACMD23); - goto fail; - } - // use address if not SDHC card - if (type() != SD_CARD_TYPE_SDHC) - blockNumber <<= 9; - if (cardCommand(CMD25, blockNumber)) - { - error(SD_CARD_ERROR_CMD25); - SerialDebug.println("Error: CMD25"); - goto fail; - } - return true; - - fail: - chipSelectHigh(); - SerialDebug.println("Error: Sd2Card::writeStart()"); - return false; -} -//------------------------------------------------------------------------------ -/** End a write multiple blocks sequence. - * -* \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - */ -uint8_t Sd2Card::writeStop(void) -{ - if (!waitNotBusy(SD_WRITE_TIMEOUT)) - goto fail; - spiSend(STOP_TRAN_TOKEN); - if (!waitNotBusy(SD_WRITE_TIMEOUT)) - goto fail; - chipSelectHigh(); - return true; - - fail: - error(SD_CARD_ERROR_STOP_TRAN); - chipSelectHigh(); - SerialDebug.println("Error: Sd2Card::writeStop()"); - return false; -} +/* Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino Sd2Card Library. If not, see + * . + */ +#include +#include +#include "Sd2Card.h" +#include "HardwareSPI.h" +#include "spi.h" + +//pointer to spi object +HardwareSPI *SPIn; + +//------------------------------------------------------------------------------ +// functions for hardware SPI +/** Send a byte to the card */ +static void spiSend(uint8_t b) +{ + SPIn->send(b); + //while(SPIn->busy()) + //{ + //} +} + +#if 0 +static void spiSend(const uint8_t *data, int len) +{ + SPIn->send(data, len); +} +#endif + +/** Receive a byte from the card */ +static uint8_t spiRec(void) +{ + return SPIn->send(0XFF); +// return SPIn->read(); +} + +static void spiRec(uint8_t *data, int len) +{ + SPIn->readMaster(data, len); +} + +//------------------------------------------------------------------------------ +// send command and return error code. Return zero for OK +uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { + // end read if in partialBlockRead mode + readEnd(); + + // select card + chipSelectLow(); + + // wait up to 300 ms if busy + waitNotBusy(300); + + // send command + spiSend(cmd | 0x40); + + // send argument + for (int8_t s = 24; s >= 0; s -= 8) + spiSend(arg >> s); + + // send CRC + uint8_t crc = 0XFF; + if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0 + if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA + spiSend(crc); + + // wait for response + for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++); + return status_; +} +//------------------------------------------------------------------------------ +/** + * Determine the size of an SD flash memory card. + * + * \return The number of 512 byte data blocks in the card + * or zero if an error occurs. + */ +uint32_t Sd2Card::cardSize(void) { + csd_t csd; + if (!readCSD(&csd)) return 0; + if (csd.v1.csd_ver == 0) { + uint8_t read_bl_len = csd.v1.read_bl_len; + uint16_t c_size = (csd.v1.c_size_high << 10) + | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low; + uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1) + | csd.v1.c_size_mult_low; + return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7); + } else if (csd.v2.csd_ver == 1) { + uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16) + | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low; + return (c_size + 1) << 10; + } else { + error(SD_CARD_ERROR_BAD_CSD); + return 0; + } +} +//------------------------------------------------------------------------------ +void Sd2Card::chipSelectHigh(void) +{ + digitalWrite(74, HIGH); +} + +//------------------------------------------------------------------------------ +void Sd2Card::chipSelectLow(void) +{ + digitalWrite(74, LOW); +} + +//------------------------------------------------------------------------------ +/** Erase a range of blocks. + * + * \param[in] firstBlock The address of the first block in the range. + * \param[in] lastBlock The address of the last block in the range. + * + * \note This function requests the SD card to do a flash erase for a + * range of blocks. The data on the card after an erase operation is + * either 0 or 1, depends on the card vendor. The card must support + * single block erase. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) +{ + if (!eraseSingleBlockEnable()) + { + error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); + SerialDebug.println("Error: Erase Single Block"); + goto fail; + } + if (type_ != SD_CARD_TYPE_SDHC) + { + firstBlock <<= 9; + lastBlock <<= 9; + } + if (cardCommand(CMD32, firstBlock) + || cardCommand(CMD33, lastBlock) + || cardCommand(CMD38, 0)) + { + error(SD_CARD_ERROR_ERASE); + SerialDebug.println("Error: Erase"); + goto fail; + } + if (!waitNotBusy(SD_ERASE_TIMEOUT)) + { + error(SD_CARD_ERROR_ERASE_TIMEOUT); + SerialDebug.println("Error: Erase timeout"); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + SerialDebug.println("Error: Sd2Card::Erase()"); + return false; +} +//------------------------------------------------------------------------------ +/** Determine if card supports single block erase. + * + * \return The value one, true, is returned if single block erase is supported. + * The value zero, false, is returned if single block erase is not supported. + */ +uint8_t Sd2Card::eraseSingleBlockEnable(void) +{ + csd_t csd; + return readCSD(&csd) ? csd.v1.erase_blk_en : 0; +} +//------------------------------------------------------------------------------ +/** + * Initialize an SD flash memory card. + * + * \param[in] sckRateID SPI clock rate selector. See setSckRate(). + * \param[in] chipSelectPin SD chip select pin number. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. The reason for failure + * can be determined by calling errorCode() and errorData(). + */ +uint8_t Sd2Card::init(HardwareSPI *s) +{ + errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0; + // 16-bit init start time allows over a minute + + uint16_t t0 = (uint16_t)millis(); + uint32_t arg; + + pinMode(74,OUTPUT); + + SPIn = s; + // set pin modes +/* pinMode(chipSelectPin_, OUTPUT); + chipSelectHigh(); + pinMode(SPI_MISO_PIN, INPUT); + pinMode(SPI_MOSI_PIN, OUTPUT); + pinMode(SPI_SCK_PIN, OUTPUT); +*/ + + // SS must be in output mode even it is not chip select +// pinMode(SS_PIN, OUTPUT); + // Enable SPI, Master, clock rate f_osc/128 +// SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); + // clear double speed +// SPSR &= ~(1 << SPI2X); + + // must supply min of 74 clock cycles with CS high. + + chipSelectHigh(); + for (uint8_t i = 0; i < 10; i++) spiSend(0XFF); + chipSelectLow(); + + // command to go idle in SPI mode + while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) + { + if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) + { + SerialDebug.println("Error: CMD0"); + error(SD_CARD_ERROR_CMD0); + goto fail; + } + } + // check SD version + if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) + { + type(SD_CARD_TYPE_SD1); + } + else + { + // only need last byte of r7 response + for (uint8_t i = 0; i < 4; i++) + status_ = spiRec(); + if (status_ != 0XAA) + { + error(SD_CARD_ERROR_CMD8); + SerialDebug.println("Error: CMD8"); + goto fail; + } + type(SD_CARD_TYPE_SD2); + } + // initialize card and send host supports SDHC if SD2 + arg = (type() == SD_CARD_TYPE_SD2) ? 0X40000000 : 0; + + while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) + { + // check for timeout + if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) + { + SerialDebug.println("Error: ACMD41"); + error(SD_CARD_ERROR_ACMD41); + goto fail; + } + } + // if SD2 read OCR register to check for SDHC card + if (type() == SD_CARD_TYPE_SD2) + { + if (cardCommand(CMD58, 0)) + { + SerialDebug.println("Error: CMD58"); + error(SD_CARD_ERROR_CMD58); + goto fail; + } + if ((spiRec() & 0XC0) == 0XC0) + type(SD_CARD_TYPE_SDHC); + // discard rest of ocr - contains allowed voltage range + for (uint8_t i = 0; i < 3; i++) + spiRec(); + } + chipSelectHigh(); + +// return setSckRate(sckRateID); + return true; + + fail: + chipSelectHigh(); + SerialDebug.println("Error: Sd2Card::init()"); + return false; +} +//------------------------------------------------------------------------------ +/** + * Enable or disable partial block reads. + * + * Enabling partial block reads improves performance by allowing a block + * to be read over the SPI bus as several sub-blocks. Errors may occur + * if the time between reads is too long since the SD card may timeout. + * The SPI SS line will be held low until the entire block is read or + * readEnd() is called. + * + * Use this for applications like the Adafruit Wave Shield. + * + * \param[in] value The value TRUE (non-zero) or FALSE (zero).) + */ +void Sd2Card::partialBlockRead(uint8_t value) +{ + readEnd(); + partialBlockRead_ = value; +} +//------------------------------------------------------------------------------ +/** + * Read a 512 byte block from an SD card device. + * + * \param[in] block Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) +{ + return readData(block, 0, 512, dst); +} +//------------------------------------------------------------------------------ +/** + * Read part of a 512 byte block from an SD card. + * + * \param[in] block Logical block to be read. + * \param[in] offset Number of bytes to skip at start of block + * \param[out] dst Pointer to the location that will receive the data. + * \param[in] count Number of bytes to read + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t Sd2Card::readData(uint32_t block, + uint16_t offset, uint16_t count, uint8_t* dst) +{ + if (count == 0) return true; + if ((count + offset) > 512) + { + goto fail; + } + if (!inBlock_ || block != block_ || offset < offset_) + { + block_ = block; + // use address if not SDHC card + if (type()!= SD_CARD_TYPE_SDHC) + block <<= 9; + if (cardCommand(CMD17, block)) + { + error(SD_CARD_ERROR_CMD17); + SerialDebug.println("Error: CMD17"); + goto fail; + } + if (!waitStartBlock()) + { + goto fail; + } + offset_ = 0; + inBlock_ = 1; + } + +#ifdef OPTIMIZE_HARDWARE_SPI +/* // start first spi transfer + SPDR = 0XFF; + + // skip data before offset + for (;offset_ < offset; offset_++) { + while (!(SPSR & (1 << SPIF))); + SPDR = 0XFF; + } + // transfer data + uint16_t n; + n = count - 1; + for (uint16_t i = 0; i < n; i++) { + while (!(SPSR & (1 << SPIF))); + dst[i] = SPDR; + SPDR = 0XFF; + } + // wait for last byte + while (!(SPSR & (1 << SPIF))); + dst[n] = SPDR; +*/ +#else // OPTIMIZE_HARDWARE_SPI + + // skip data before offset + for (;offset_ < offset; offset_++) + { + spiRec(); + } + // transfer data + //for (uint16_t i = 0; i < count; i++) + //{ + // dst[i] = spiRec(); + //} + spiRec(dst, count); + +#endif // OPTIMIZE_HARDWARE_SPI + + offset_ += count; + if (!partialBlockRead_ || offset_ >= 512) + { + // read rest of data, checksum and set chip select high + readEnd(); + } + return true; + + fail: + chipSelectHigh(); + SerialDebug.println("Error: Sd2Card::readData()"); + return false; +} +//------------------------------------------------------------------------------ +/** Skip remaining data in a block when in partial block read mode. */ +void Sd2Card::readEnd(void) +{ + if (inBlock_) + { + // skip data and crc +#ifdef OPTIMIZE_HARDWARE_SPI + // optimize skip for hardware +/* SPDR = 0XFF; + while (offset_++ < 513) { + while (!(SPSR & (1 << SPIF))); + SPDR = 0XFF; + } + // wait for last crc byte + while (!(SPSR & (1 << SPIF))); +*/ +#else // OPTIMIZE_HARDWARE_SPI + while (offset_++ < 514) + spiRec(); +#endif // OPTIMIZE_HARDWARE_SPI + chipSelectHigh(); + inBlock_ = 0; + } +} +//------------------------------------------------------------------------------ +/** read CID or CSR register */ +uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) +{ + uint8_t* dst = reinterpret_cast(buf); + if (cardCommand(cmd, 0)) + { + error(SD_CARD_ERROR_READ_REG); + SerialDebug.println("Error: Read reg"); + goto fail; + } + if (!waitStartBlock()) + goto fail; + // transfer data + for (uint16_t i = 0; i < 16; i++) + dst[i] = spiRec(); + spiRec(); // get first crc byte + spiRec(); // get second crc byte + chipSelectHigh(); + return true; + + fail: + SerialDebug.println("Error: Sd2Card::readRegister()"); + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** + * Set the SPI clock rate. + * + * \param[in] sckRateID A value in the range [0, 6]. + * + * The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum + * SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128 + * for \a scsRateID = 6. + * + * \return The value one, true, is returned for success and the value zero, + * false, is returned for an invalid value of \a sckRateID. + */ +uint8_t Sd2Card::setSckRate(uint8_t sckRateID) { +/* if (sckRateID > 6) { + error(SD_CARD_ERROR_SCK_RATE); + return false; + } + // see avr processor datasheet for SPI register bit definitions + if ((sckRateID & 1) || sckRateID == 6) { + SPSR &= ~(1 << SPI2X); + } else { + SPSR |= (1 << SPI2X); + } + SPCR &= ~((1 < SD_READ_TIMEOUT) + { + error(SD_CARD_ERROR_READ_TIMEOUT); + SerialDebug.println("Error: Read timeout"); + goto fail; + } + } + if (status_ != DATA_START_BLOCK) + { + error(SD_CARD_ERROR_READ); + SerialDebug.println("Error: Read"); + goto fail; + } + return true; + + fail: + chipSelectHigh(); + SerialDebug.println("Error: Sd2Card::waitStartBlock()"); + return false; +} +//------------------------------------------------------------------------------ +/** + * Writes a 512 byte block to an SD card. + * + * \param[in] blockNumber Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) +{ +#if SD_PROTECT_BLOCK_ZERO + // don't allow write to first block + if (blockNumber == 0) + { + error(SD_CARD_ERROR_WRITE_BLOCK_ZERO); + SerialDebug.println("Error: Write block zero"); + goto fail; + } +#endif // SD_PROTECT_BLOCK_ZERO + + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) + blockNumber <<= 9; + if (cardCommand(CMD24, blockNumber)) + { + SerialDebug.println("Error: CMD24"); + error(SD_CARD_ERROR_CMD24); + goto fail; + } + if (!writeData(DATA_START_BLOCK, src)) + goto fail; + + // wait for flash programming to complete + if (!waitNotBusy(SD_WRITE_TIMEOUT)) + { + error(SD_CARD_ERROR_WRITE_TIMEOUT); + SerialDebug.println("Error: Write timeout"); + goto fail; + } + // response is r2 so get and check two bytes for nonzero + if (cardCommand(CMD13, 0) || spiRec()) + { + error(SD_CARD_ERROR_WRITE_PROGRAMMING); + SerialDebug.println("Error: Write programming"); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + SerialDebug.println("Error: Sd2Card::writeBlock"); + return false; +} +//------------------------------------------------------------------------------ +/** Write one data block in a multiple block write sequence */ +uint8_t Sd2Card::writeData(const uint8_t* src) +{ + // wait for previous write to finish + if (!waitNotBusy(SD_WRITE_TIMEOUT)) + { + error(SD_CARD_ERROR_WRITE_MULTIPLE); + SerialDebug.println("Error: writeData"); + chipSelectHigh(); + return false; + } + return writeData(WRITE_MULTIPLE_TOKEN, src); +} +//------------------------------------------------------------------------------ +// send one block of data for write block or write multiple blocks +uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) { +#ifdef OPTIMIZE_HARDWARE_SPI +/* + // send data - optimized loop + SPDR = token; + + // send two byte per iteration + for (uint16_t i = 0; i < 512; i += 2) { + while (!(SPSR & (1 << SPIF))); + SPDR = src[i]; + while (!(SPSR & (1 << SPIF))); + SPDR = src[i+1]; + } + + // wait for last data byte + while (!(SPSR & (1 << SPIF))); +*/ +#else // OPTIMIZE_HARDWARE_SPI + spiSend(token); + for (uint16_t i = 0; i < 512; i++) + { + spiSend(src[i]); + } + //spiSend(src, 512); +#endif // OPTIMIZE_HARDWARE_SPI + spiSend(0xff); // dummy crc + spiSend(0xff); // dummy crc + + status_ = spiRec(); + if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) + { + error(SD_CARD_ERROR_WRITE); + chipSelectHigh(); + SerialDebug.println("Error: Write"); + SerialDebug.println("Error: Sd2Card::writeData()"); + return false; + } + return true; +} +//------------------------------------------------------------------------------ +/** Start a write multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * \param[in] eraseCount The number of blocks to be pre-erased. + * + * \note This function is used with writeData() and writeStop() + * for optimized multiple block writes. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) +{ +#if SD_PROTECT_BLOCK_ZERO + // don't allow write to first block + if (blockNumber == 0) + { + error(SD_CARD_ERROR_WRITE_BLOCK_ZERO); + SerialDebug.println("Error: Write block zero"); + goto fail; + } +#endif // SD_PROTECT_BLOCK_ZERO + // send pre-erase count + if (cardAcmd(ACMD23, eraseCount)) + { + SerialDebug.println("Error: ACMD23"); + error(SD_CARD_ERROR_ACMD23); + goto fail; + } + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) + blockNumber <<= 9; + if (cardCommand(CMD25, blockNumber)) + { + error(SD_CARD_ERROR_CMD25); + SerialDebug.println("Error: CMD25"); + goto fail; + } + return true; + + fail: + chipSelectHigh(); + SerialDebug.println("Error: Sd2Card::writeStart()"); + return false; +} +//------------------------------------------------------------------------------ +/** End a write multiple blocks sequence. + * +* \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t Sd2Card::writeStop(void) +{ + if (!waitNotBusy(SD_WRITE_TIMEOUT)) + goto fail; + spiSend(STOP_TRAN_TOKEN); + if (!waitNotBusy(SD_WRITE_TIMEOUT)) + goto fail; + chipSelectHigh(); + return true; + + fail: + error(SD_CARD_ERROR_STOP_TRAN); + chipSelectHigh(); + SerialDebug.println("Error: Sd2Card::writeStop()"); + return false; +} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/Sd2Card.h b/Libmaple/libmaple/libraries/mapleSDfat/Sd2Card.h index 40adb689..ba142959 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/Sd2Card.h +++ b/Libmaple/libmaple/libraries/mapleSDfat/Sd2Card.h @@ -1,191 +1,191 @@ -/* Arduino Sd2Card Library - * Copyright (C) 2009 by William Greiman - * - * This file is part of the Arduino Sd2Card Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino Sd2Card Library. If not, see - * . - */ -#ifndef Sd2Card_h -#define Sd2Card_h -/** - * \file - * Sd2Card class - */ -#include "Sd2PinMap.h" -#include "SdInfo.h" -#include "HardwareSPI.h" - -/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */ -uint8_t const SPI_FULL_SPEED = 0; -/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */ -uint8_t const SPI_HALF_SPEED = 1; -/** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */ -uint8_t const SPI_QUARTER_SPEED = 2; -//------------------------------------------------------------------------------ -/** Protect block zero from write if nonzero */ -#define SD_PROTECT_BLOCK_ZERO 1 -/** init timeout ms */ -uint16_t const SD_INIT_TIMEOUT = 2000; -/** erase timeout ms */ -uint16_t const SD_ERASE_TIMEOUT = 10000; -/** read timeout ms */ -uint16_t const SD_READ_TIMEOUT = 300; -/** write time out ms */ -uint16_t const SD_WRITE_TIMEOUT = 600; -//------------------------------------------------------------------------------ -// SD card errors -/** timeout error for command CMD0 */ -uint8_t const SD_CARD_ERROR_CMD0 = 0X1; -/** CMD8 was not accepted - not a valid SD card*/ -uint8_t const SD_CARD_ERROR_CMD8 = 0X2; -/** card returned an error response for CMD17 (read block) */ -uint8_t const SD_CARD_ERROR_CMD17 = 0X3; -/** card returned an error response for CMD24 (write block) */ -uint8_t const SD_CARD_ERROR_CMD24 = 0X4; -/** WRITE_MULTIPLE_BLOCKS command failed */ -uint8_t const SD_CARD_ERROR_CMD25 = 0X05; -/** card returned an error response for CMD58 (read OCR) */ -uint8_t const SD_CARD_ERROR_CMD58 = 0X06; -/** SET_WR_BLK_ERASE_COUNT failed */ -uint8_t const SD_CARD_ERROR_ACMD23 = 0X07; -/** card's ACMD41 initialization process timeout */ -uint8_t const SD_CARD_ERROR_ACMD41 = 0X08; -/** card returned a bad CSR version field */ -uint8_t const SD_CARD_ERROR_BAD_CSD = 0X09; -/** erase block group command failed */ -uint8_t const SD_CARD_ERROR_ERASE = 0X0A; -/** card not capable of single block erase */ -uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0X0B; -/** Erase sequence timed out */ -uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0X0C; -/** card returned an error token instead of read data */ -uint8_t const SD_CARD_ERROR_READ = 0X0D; -/** read CID or CSD failed */ -uint8_t const SD_CARD_ERROR_READ_REG = 0X0E; -/** timeout while waiting for start of read data */ -uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X0F; -/** card did not accept STOP_TRAN_TOKEN */ -uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X10; -/** card returned an error token as a response to a write operation */ -uint8_t const SD_CARD_ERROR_WRITE = 0X11; -/** attempt to write protected block zero */ -uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X12; -/** card did not go ready for a multiple block write */ -uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X13; -/** card returned an error to a CMD13 status check after a write */ -uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X14; -/** timeout occurred during write programming */ -uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X15; -/** incorrect rate selected */ -uint8_t const SD_CARD_ERROR_SCK_RATE = 0X16; -//------------------------------------------------------------------------------ -// card types -/** Standard capacity V1 SD card */ -uint8_t const SD_CARD_TYPE_SD1 = 1; -/** Standard capacity V2 SD card */ -uint8_t const SD_CARD_TYPE_SD2 = 2; -/** High Capacity SD card */ -uint8_t const SD_CARD_TYPE_SDHC = 3; -//------------------------------------------------------------------------------ -/** - * \class Sd2Card - * \brief Raw access to SD and SDHC flash memory cards. - */ -class Sd2Card { - public: - /** Construct an instance of Sd2Card. */ - Sd2Card(void) : errorCode_(0), inBlock_(0), partialBlockRead_(0), type_(0) {} - uint32_t cardSize(void); - uint8_t erase(uint32_t firstBlock, uint32_t lastBlock); - uint8_t eraseSingleBlockEnable(void); - /** - * \return error code for last error. See Sd2Card.h for a list of error codes. - */ - uint8_t errorCode(void) const {return errorCode_;} - /** \return error data for last error. */ - uint8_t errorData(void) const {return status_;} - /** - * Initialize an SD flash memory card with default clock rate and chip - * select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). - */ - uint8_t init(void) { -// return init(SPI_FULL_SPEED, SD_CHIP_SELECT_PIN); - return false; - } - - /** - * Initialize an SD flash memory card with the selected SPI clock rate - * and the default SD chip select pin. - * See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). - */ - uint8_t init(uint8_t sckRateID) { -// return init(sckRateID, SD_CHIP_SELECT_PIN); - return false; - } - - uint8_t init(HardwareSPI *); - void partialBlockRead(uint8_t value); - /** Returns the current value, true or false, for partial block read. */ - uint8_t partialBlockRead(void) const {return partialBlockRead_;} - uint8_t readBlock(uint32_t block, uint8_t* dst); - uint8_t readData(uint32_t block, - uint16_t offset, uint16_t count, uint8_t* dst); - /** - * Read a cards CID register. The CID contains card identification - * information such as Manufacturer ID, Product name, Product serial - * number and Manufacturing date. */ - uint8_t readCID(cid_t* cid) { - return readRegister(CMD10, cid); - } - /** - * Read a cards CSD register. The CSD contains Card-Specific Data that - * provides information regarding access to the card's contents. */ - uint8_t readCSD(csd_t* csd) { - return readRegister(CMD9, csd); - } - void readEnd(void); - uint8_t setSckRate(uint8_t sckRateID); - /** Return the card type: SD V1, SD V2 or SDHC */ - uint8_t type(void) const {return type_;} - uint8_t writeBlock(uint32_t blockNumber, const uint8_t* src); - uint8_t writeData(const uint8_t* src); - uint8_t writeStart(uint32_t blockNumber, uint32_t eraseCount); - uint8_t writeStop(void); - private: - uint32_t block_; - uint8_t chipSelectPin_; - uint8_t errorCode_; - uint8_t inBlock_; - uint16_t offset_; - uint8_t partialBlockRead_; - uint8_t status_; - uint8_t type_; - // private functions - uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { - cardCommand(CMD55, 0); - return cardCommand(cmd, arg); - } - uint8_t cardCommand(uint8_t cmd, uint32_t arg); - void error(uint8_t code) {errorCode_ = code;} - uint8_t readRegister(uint8_t cmd, void* buf); - uint8_t sendWriteCommand(uint32_t blockNumber, uint32_t eraseCount); - void chipSelectHigh(void); - void chipSelectLow(void); - void type(uint8_t value) {type_ = value;} - uint8_t waitNotBusy(uint16_t timeoutMillis); - uint8_t writeData(uint8_t token, const uint8_t* src); - uint8_t waitStartBlock(void); -}; -#endif // Sd2Card_h +/* Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino Sd2Card Library. If not, see + * . + */ +#ifndef Sd2Card_h +#define Sd2Card_h +/** + * \file + * Sd2Card class + */ +#include "Sd2PinMap.h" +#include "SdInfo.h" +#include "HardwareSPI.h" + +/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */ +uint8_t const SPI_FULL_SPEED = 0; +/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */ +uint8_t const SPI_HALF_SPEED = 1; +/** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */ +uint8_t const SPI_QUARTER_SPEED = 2; +//------------------------------------------------------------------------------ +/** Protect block zero from write if nonzero */ +#define SD_PROTECT_BLOCK_ZERO 1 +/** init timeout ms */ +uint16_t const SD_INIT_TIMEOUT = 2000; +/** erase timeout ms */ +uint16_t const SD_ERASE_TIMEOUT = 10000; +/** read timeout ms */ +uint16_t const SD_READ_TIMEOUT = 300; +/** write time out ms */ +uint16_t const SD_WRITE_TIMEOUT = 600; +//------------------------------------------------------------------------------ +// SD card errors +/** timeout error for command CMD0 */ +uint8_t const SD_CARD_ERROR_CMD0 = 0X1; +/** CMD8 was not accepted - not a valid SD card*/ +uint8_t const SD_CARD_ERROR_CMD8 = 0X2; +/** card returned an error response for CMD17 (read block) */ +uint8_t const SD_CARD_ERROR_CMD17 = 0X3; +/** card returned an error response for CMD24 (write block) */ +uint8_t const SD_CARD_ERROR_CMD24 = 0X4; +/** WRITE_MULTIPLE_BLOCKS command failed */ +uint8_t const SD_CARD_ERROR_CMD25 = 0X05; +/** card returned an error response for CMD58 (read OCR) */ +uint8_t const SD_CARD_ERROR_CMD58 = 0X06; +/** SET_WR_BLK_ERASE_COUNT failed */ +uint8_t const SD_CARD_ERROR_ACMD23 = 0X07; +/** card's ACMD41 initialization process timeout */ +uint8_t const SD_CARD_ERROR_ACMD41 = 0X08; +/** card returned a bad CSR version field */ +uint8_t const SD_CARD_ERROR_BAD_CSD = 0X09; +/** erase block group command failed */ +uint8_t const SD_CARD_ERROR_ERASE = 0X0A; +/** card not capable of single block erase */ +uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0X0B; +/** Erase sequence timed out */ +uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0X0C; +/** card returned an error token instead of read data */ +uint8_t const SD_CARD_ERROR_READ = 0X0D; +/** read CID or CSD failed */ +uint8_t const SD_CARD_ERROR_READ_REG = 0X0E; +/** timeout while waiting for start of read data */ +uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X0F; +/** card did not accept STOP_TRAN_TOKEN */ +uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X10; +/** card returned an error token as a response to a write operation */ +uint8_t const SD_CARD_ERROR_WRITE = 0X11; +/** attempt to write protected block zero */ +uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X12; +/** card did not go ready for a multiple block write */ +uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X13; +/** card returned an error to a CMD13 status check after a write */ +uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X14; +/** timeout occurred during write programming */ +uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X15; +/** incorrect rate selected */ +uint8_t const SD_CARD_ERROR_SCK_RATE = 0X16; +//------------------------------------------------------------------------------ +// card types +/** Standard capacity V1 SD card */ +uint8_t const SD_CARD_TYPE_SD1 = 1; +/** Standard capacity V2 SD card */ +uint8_t const SD_CARD_TYPE_SD2 = 2; +/** High Capacity SD card */ +uint8_t const SD_CARD_TYPE_SDHC = 3; +//------------------------------------------------------------------------------ +/** + * \class Sd2Card + * \brief Raw access to SD and SDHC flash memory cards. + */ +class Sd2Card { + public: + /** Construct an instance of Sd2Card. */ + Sd2Card(void) : errorCode_(0), inBlock_(0), partialBlockRead_(0), type_(0) {} + uint32_t cardSize(void); + uint8_t erase(uint32_t firstBlock, uint32_t lastBlock); + uint8_t eraseSingleBlockEnable(void); + /** + * \return error code for last error. See Sd2Card.h for a list of error codes. + */ + uint8_t errorCode(void) const {return errorCode_;} + /** \return error data for last error. */ + uint8_t errorData(void) const {return status_;} + /** + * Initialize an SD flash memory card with default clock rate and chip + * select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). + */ + uint8_t init(void) { +// return init(SPI_FULL_SPEED, SD_CHIP_SELECT_PIN); + return false; + } + + /** + * Initialize an SD flash memory card with the selected SPI clock rate + * and the default SD chip select pin. + * See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). + */ + uint8_t init(uint8_t sckRateID) { +// return init(sckRateID, SD_CHIP_SELECT_PIN); + return false; + } + + uint8_t init(HardwareSPI *); + void partialBlockRead(uint8_t value); + /** Returns the current value, true or false, for partial block read. */ + uint8_t partialBlockRead(void) const {return partialBlockRead_;} + uint8_t readBlock(uint32_t block, uint8_t* dst); + uint8_t readData(uint32_t block, + uint16_t offset, uint16_t count, uint8_t* dst); + /** + * Read a cards CID register. The CID contains card identification + * information such as Manufacturer ID, Product name, Product serial + * number and Manufacturing date. */ + uint8_t readCID(cid_t* cid) { + return readRegister(CMD10, cid); + } + /** + * Read a cards CSD register. The CSD contains Card-Specific Data that + * provides information regarding access to the card's contents. */ + uint8_t readCSD(csd_t* csd) { + return readRegister(CMD9, csd); + } + void readEnd(void); + uint8_t setSckRate(uint8_t sckRateID); + /** Return the card type: SD V1, SD V2 or SDHC */ + uint8_t type(void) const {return type_;} + uint8_t writeBlock(uint32_t blockNumber, const uint8_t* src); + uint8_t writeData(const uint8_t* src); + uint8_t writeStart(uint32_t blockNumber, uint32_t eraseCount); + uint8_t writeStop(void); + private: + uint32_t block_; + uint8_t chipSelectPin_; + uint8_t errorCode_; + uint8_t inBlock_; + uint16_t offset_; + uint8_t partialBlockRead_; + uint8_t status_; + uint8_t type_; + // private functions + uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { + cardCommand(CMD55, 0); + return cardCommand(cmd, arg); + } + uint8_t cardCommand(uint8_t cmd, uint32_t arg); + void error(uint8_t code) {errorCode_ = code;} + uint8_t readRegister(uint8_t cmd, void* buf); + uint8_t sendWriteCommand(uint32_t blockNumber, uint32_t eraseCount); + void chipSelectHigh(void); + void chipSelectLow(void); + void type(uint8_t value) {type_ = value;} + uint8_t waitNotBusy(uint16_t timeoutMillis); + uint8_t writeData(uint8_t token, const uint8_t* src); + uint8_t waitStartBlock(void); +}; +#endif // Sd2Card_h diff --git a/Libmaple/libmaple/libraries/mapleSDfat/Sd2PinMap.h b/Libmaple/libmaple/libraries/mapleSDfat/Sd2PinMap.h index f23e9691..09c5329a 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/Sd2PinMap.h +++ b/Libmaple/libmaple/libraries/mapleSDfat/Sd2PinMap.h @@ -1,357 +1,357 @@ -/* Arduino SdFat Library - * Copyright (C) 2010 by William Greiman - * - * This file is part of the Arduino SdFat Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino SdFat Library. If not, see - * . - */ -// Warning this file was generated by a program. -#ifndef Sd2PinMap_h -#define Sd2PinMap_h - -#include - -//------------------------------------------------------------------------------ -/** struct for mapping digital pins */ -struct pin_map_t -{ - volatile uint8_t* ddr; - volatile uint8_t* pin; - volatile uint8_t* port; - uint8_t bit; -}; -/* -//------------------------------------------------------------------------------ -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -// Mega - -// Two Wire (aka I2C) ports -uint8_t const SDA_PIN = 20; -uint8_t const SCL_PIN = 21; - -// SPI port -uint8_t const SS_PIN = 53; -uint8_t const MOSI_PIN = 51; -uint8_t const MISO_PIN = 50; -uint8_t const SCK_PIN = 52; - -static const pin_map_t digitalPinMap[] = { - {&DDRE, &PINE, &PORTE, 0}, // E0 0 - {&DDRE, &PINE, &PORTE, 1}, // E1 1 - {&DDRE, &PINE, &PORTE, 4}, // E4 2 - {&DDRE, &PINE, &PORTE, 5}, // E5 3 - {&DDRG, &PING, &PORTG, 5}, // G5 4 - {&DDRE, &PINE, &PORTE, 3}, // E3 5 - {&DDRH, &PINH, &PORTH, 3}, // H3 6 - {&DDRH, &PINH, &PORTH, 4}, // H4 7 - {&DDRH, &PINH, &PORTH, 5}, // H5 8 - {&DDRH, &PINH, &PORTH, 6}, // H6 9 - {&DDRB, &PINB, &PORTB, 4}, // B4 10 - {&DDRB, &PINB, &PORTB, 5}, // B5 11 - {&DDRB, &PINB, &PORTB, 6}, // B6 12 - {&DDRB, &PINB, &PORTB, 7}, // B7 13 - {&DDRJ, &PINJ, &PORTJ, 1}, // J1 14 - {&DDRJ, &PINJ, &PORTJ, 0}, // J0 15 - {&DDRH, &PINH, &PORTH, 1}, // H1 16 - {&DDRH, &PINH, &PORTH, 0}, // H0 17 - {&DDRD, &PIND, &PORTD, 3}, // D3 18 - {&DDRD, &PIND, &PORTD, 2}, // D2 19 - {&DDRD, &PIND, &PORTD, 1}, // D1 20 - {&DDRD, &PIND, &PORTD, 0}, // D0 21 - {&DDRA, &PINA, &PORTA, 0}, // A0 22 - {&DDRA, &PINA, &PORTA, 1}, // A1 23 - {&DDRA, &PINA, &PORTA, 2}, // A2 24 - {&DDRA, &PINA, &PORTA, 3}, // A3 25 - {&DDRA, &PINA, &PORTA, 4}, // A4 26 - {&DDRA, &PINA, &PORTA, 5}, // A5 27 - {&DDRA, &PINA, &PORTA, 6}, // A6 28 - {&DDRA, &PINA, &PORTA, 7}, // A7 29 - {&DDRC, &PINC, &PORTC, 7}, // C7 30 - {&DDRC, &PINC, &PORTC, 6}, // C6 31 - {&DDRC, &PINC, &PORTC, 5}, // C5 32 - {&DDRC, &PINC, &PORTC, 4}, // C4 33 - {&DDRC, &PINC, &PORTC, 3}, // C3 34 - {&DDRC, &PINC, &PORTC, 2}, // C2 35 - {&DDRC, &PINC, &PORTC, 1}, // C1 36 - {&DDRC, &PINC, &PORTC, 0}, // C0 37 - {&DDRD, &PIND, &PORTD, 7}, // D7 38 - {&DDRG, &PING, &PORTG, 2}, // G2 39 - {&DDRG, &PING, &PORTG, 1}, // G1 40 - {&DDRG, &PING, &PORTG, 0}, // G0 41 - {&DDRL, &PINL, &PORTL, 7}, // L7 42 - {&DDRL, &PINL, &PORTL, 6}, // L6 43 - {&DDRL, &PINL, &PORTL, 5}, // L5 44 - {&DDRL, &PINL, &PORTL, 4}, // L4 45 - {&DDRL, &PINL, &PORTL, 3}, // L3 46 - {&DDRL, &PINL, &PORTL, 2}, // L2 47 - {&DDRL, &PINL, &PORTL, 1}, // L1 48 - {&DDRL, &PINL, &PORTL, 0}, // L0 49 - {&DDRB, &PINB, &PORTB, 3}, // B3 50 - {&DDRB, &PINB, &PORTB, 2}, // B2 51 - {&DDRB, &PINB, &PORTB, 1}, // B1 52 - {&DDRB, &PINB, &PORTB, 0}, // B0 53 - {&DDRF, &PINF, &PORTF, 0}, // F0 54 - {&DDRF, &PINF, &PORTF, 1}, // F1 55 - {&DDRF, &PINF, &PORTF, 2}, // F2 56 - {&DDRF, &PINF, &PORTF, 3}, // F3 57 - {&DDRF, &PINF, &PORTF, 4}, // F4 58 - {&DDRF, &PINF, &PORTF, 5}, // F5 59 - {&DDRF, &PINF, &PORTF, 6}, // F6 60 - {&DDRF, &PINF, &PORTF, 7}, // F7 61 - {&DDRK, &PINK, &PORTK, 0}, // K0 62 - {&DDRK, &PINK, &PORTK, 1}, // K1 63 - {&DDRK, &PINK, &PORTK, 2}, // K2 64 - {&DDRK, &PINK, &PORTK, 3}, // K3 65 - {&DDRK, &PINK, &PORTK, 4}, // K4 66 - {&DDRK, &PINK, &PORTK, 5}, // K5 67 - {&DDRK, &PINK, &PORTK, 6}, // K6 68 - {&DDRK, &PINK, &PORTK, 7} // K7 69 -}; -//------------------------------------------------------------------------------ -#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) -// Sanguino - -// Two Wire (aka I2C) ports -uint8_t const SDA_PIN = 17; -uint8_t const SCL_PIN = 18; - -// SPI port -uint8_t const SS_PIN = 4; -uint8_t const MOSI_PIN = 5; -uint8_t const MISO_PIN = 6; -uint8_t const SCK_PIN = 7; - -static const pin_map_t digitalPinMap[] = { - {&DDRB, &PINB, &PORTB, 0}, // B0 0 - {&DDRB, &PINB, &PORTB, 1}, // B1 1 - {&DDRB, &PINB, &PORTB, 2}, // B2 2 - {&DDRB, &PINB, &PORTB, 3}, // B3 3 - {&DDRB, &PINB, &PORTB, 4}, // B4 4 - {&DDRB, &PINB, &PORTB, 5}, // B5 5 - {&DDRB, &PINB, &PORTB, 6}, // B6 6 - {&DDRB, &PINB, &PORTB, 7}, // B7 7 - {&DDRD, &PIND, &PORTD, 0}, // D0 8 - {&DDRD, &PIND, &PORTD, 1}, // D1 9 - {&DDRD, &PIND, &PORTD, 2}, // D2 10 - {&DDRD, &PIND, &PORTD, 3}, // D3 11 - {&DDRD, &PIND, &PORTD, 4}, // D4 12 - {&DDRD, &PIND, &PORTD, 5}, // D5 13 - {&DDRD, &PIND, &PORTD, 6}, // D6 14 - {&DDRD, &PIND, &PORTD, 7}, // D7 15 - {&DDRC, &PINC, &PORTC, 0}, // C0 16 - {&DDRC, &PINC, &PORTC, 1}, // C1 17 - {&DDRC, &PINC, &PORTC, 2}, // C2 18 - {&DDRC, &PINC, &PORTC, 3}, // C3 19 - {&DDRC, &PINC, &PORTC, 4}, // C4 20 - {&DDRC, &PINC, &PORTC, 5}, // C5 21 - {&DDRC, &PINC, &PORTC, 6}, // C6 22 - {&DDRC, &PINC, &PORTC, 7}, // C7 23 - {&DDRA, &PINA, &PORTA, 7}, // A7 24 - {&DDRA, &PINA, &PORTA, 6}, // A6 25 - {&DDRA, &PINA, &PORTA, 5}, // A5 26 - {&DDRA, &PINA, &PORTA, 4}, // A4 27 - {&DDRA, &PINA, &PORTA, 3}, // A3 28 - {&DDRA, &PINA, &PORTA, 2}, // A2 29 - {&DDRA, &PINA, &PORTA, 1}, // A1 30 - {&DDRA, &PINA, &PORTA, 0} // A0 31 -}; -//------------------------------------------------------------------------------ -#elif defined(__AVR_ATmega32U4__) -// Teensy 2.0 - -// Two Wire (aka I2C) ports -uint8_t const SDA_PIN = 6; -uint8_t const SCL_PIN = 5; - -// SPI port -uint8_t const SS_PIN = 0; -uint8_t const MOSI_PIN = 2; -uint8_t const MISO_PIN = 3; -uint8_t const SCK_PIN = 1; - -static const pin_map_t digitalPinMap[] = { - {&DDRB, &PINB, &PORTB, 0}, // B0 0 - {&DDRB, &PINB, &PORTB, 1}, // B1 1 - {&DDRB, &PINB, &PORTB, 2}, // B2 2 - {&DDRB, &PINB, &PORTB, 3}, // B3 3 - {&DDRB, &PINB, &PORTB, 7}, // B7 4 - {&DDRD, &PIND, &PORTD, 0}, // D0 5 - {&DDRD, &PIND, &PORTD, 1}, // D1 6 - {&DDRD, &PIND, &PORTD, 2}, // D2 7 - {&DDRD, &PIND, &PORTD, 3}, // D3 8 - {&DDRC, &PINC, &PORTC, 6}, // C6 9 - {&DDRC, &PINC, &PORTC, 7}, // C7 10 - {&DDRD, &PIND, &PORTD, 6}, // D6 11 - {&DDRD, &PIND, &PORTD, 7}, // D7 12 - {&DDRB, &PINB, &PORTB, 4}, // B4 13 - {&DDRB, &PINB, &PORTB, 5}, // B5 14 - {&DDRB, &PINB, &PORTB, 6}, // B6 15 - {&DDRF, &PINF, &PORTF, 7}, // F7 16 - {&DDRF, &PINF, &PORTF, 6}, // F6 17 - {&DDRF, &PINF, &PORTF, 5}, // F5 18 - {&DDRF, &PINF, &PORTF, 4}, // F4 19 - {&DDRF, &PINF, &PORTF, 1}, // F1 20 - {&DDRF, &PINF, &PORTF, 0}, // F0 21 - {&DDRD, &PIND, &PORTD, 4}, // D4 22 - {&DDRD, &PIND, &PORTD, 5}, // D5 23 - {&DDRE, &PINE, &PORTE, 6} // E6 24 -}; -//------------------------------------------------------------------------------ -#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) -// Teensy++ 1.0 & 2.0 - -// Two Wire (aka I2C) ports -uint8_t const SDA_PIN = 1; -uint8_t const SCL_PIN = 0; - -// SPI port -uint8_t const SS_PIN = 20; -uint8_t const MOSI_PIN = 22; -uint8_t const MISO_PIN = 23; -uint8_t const SCK_PIN = 21; - -static const pin_map_t digitalPinMap[] = { - {&DDRD, &PIND, &PORTD, 0}, // D0 0 - {&DDRD, &PIND, &PORTD, 1}, // D1 1 - {&DDRD, &PIND, &PORTD, 2}, // D2 2 - {&DDRD, &PIND, &PORTD, 3}, // D3 3 - {&DDRD, &PIND, &PORTD, 4}, // D4 4 - {&DDRD, &PIND, &PORTD, 5}, // D5 5 - {&DDRD, &PIND, &PORTD, 6}, // D6 6 - {&DDRD, &PIND, &PORTD, 7}, // D7 7 - {&DDRE, &PINE, &PORTE, 0}, // E0 8 - {&DDRE, &PINE, &PORTE, 1}, // E1 9 - {&DDRC, &PINC, &PORTC, 0}, // C0 10 - {&DDRC, &PINC, &PORTC, 1}, // C1 11 - {&DDRC, &PINC, &PORTC, 2}, // C2 12 - {&DDRC, &PINC, &PORTC, 3}, // C3 13 - {&DDRC, &PINC, &PORTC, 4}, // C4 14 - {&DDRC, &PINC, &PORTC, 5}, // C5 15 - {&DDRC, &PINC, &PORTC, 6}, // C6 16 - {&DDRC, &PINC, &PORTC, 7}, // C7 17 - {&DDRE, &PINE, &PORTE, 6}, // E6 18 - {&DDRE, &PINE, &PORTE, 7}, // E7 19 - {&DDRB, &PINB, &PORTB, 0}, // B0 20 - {&DDRB, &PINB, &PORTB, 1}, // B1 21 - {&DDRB, &PINB, &PORTB, 2}, // B2 22 - {&DDRB, &PINB, &PORTB, 3}, // B3 23 - {&DDRB, &PINB, &PORTB, 4}, // B4 24 - {&DDRB, &PINB, &PORTB, 5}, // B5 25 - {&DDRB, &PINB, &PORTB, 6}, // B6 26 - {&DDRB, &PINB, &PORTB, 7}, // B7 27 - {&DDRA, &PINA, &PORTA, 0}, // A0 28 - {&DDRA, &PINA, &PORTA, 1}, // A1 29 - {&DDRA, &PINA, &PORTA, 2}, // A2 30 - {&DDRA, &PINA, &PORTA, 3}, // A3 31 - {&DDRA, &PINA, &PORTA, 4}, // A4 32 - {&DDRA, &PINA, &PORTA, 5}, // A5 33 - {&DDRA, &PINA, &PORTA, 6}, // A6 34 - {&DDRA, &PINA, &PORTA, 7}, // A7 35 - {&DDRE, &PINE, &PORTE, 4}, // E4 36 - {&DDRE, &PINE, &PORTE, 5}, // E5 37 - {&DDRF, &PINF, &PORTF, 0}, // F0 38 - {&DDRF, &PINF, &PORTF, 1}, // F1 39 - {&DDRF, &PINF, &PORTF, 2}, // F2 40 - {&DDRF, &PINF, &PORTF, 3}, // F3 41 - {&DDRF, &PINF, &PORTF, 4}, // F4 42 - {&DDRF, &PINF, &PORTF, 5}, // F5 43 - {&DDRF, &PINF, &PORTF, 6}, // F6 44 - {&DDRF, &PINF, &PORTF, 7} // F7 45 -}; -//------------------------------------------------------------------------------ -#else // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -// 168 and 328 Arduinos - -// Two Wire (aka I2C) ports -uint8_t const SDA_PIN = 18; -uint8_t const SCL_PIN = 19; - -// SPI port -uint8_t const SS_PIN = 10; -uint8_t const MOSI_PIN = 11; -uint8_t const MISO_PIN = 12; -uint8_t const SCK_PIN = 13; - -static const pin_map_t digitalPinMap[] = { - {&DDRD, &PIND, &PORTD, 0}, // D0 0 - {&DDRD, &PIND, &PORTD, 1}, // D1 1 - {&DDRD, &PIND, &PORTD, 2}, // D2 2 - {&DDRD, &PIND, &PORTD, 3}, // D3 3 - {&DDRD, &PIND, &PORTD, 4}, // D4 4 - {&DDRD, &PIND, &PORTD, 5}, // D5 5 - {&DDRD, &PIND, &PORTD, 6}, // D6 6 - {&DDRD, &PIND, &PORTD, 7}, // D7 7 - {&DDRB, &PINB, &PORTB, 0}, // B0 8 - {&DDRB, &PINB, &PORTB, 1}, // B1 9 - {&DDRB, &PINB, &PORTB, 2}, // B2 10 - {&DDRB, &PINB, &PORTB, 3}, // B3 11 - {&DDRB, &PINB, &PORTB, 4}, // B4 12 - {&DDRB, &PINB, &PORTB, 5}, // B5 13 - {&DDRC, &PINC, &PORTC, 0}, // C0 14 - {&DDRC, &PINC, &PORTC, 1}, // C1 15 - {&DDRC, &PINC, &PORTC, 2}, // C2 16 - {&DDRC, &PINC, &PORTC, 3}, // C3 17 - {&DDRC, &PINC, &PORTC, 4}, // C4 18 - {&DDRC, &PINC, &PORTC, 5} // C5 19 -}; -#endif // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -//------------------------------------------------------------------------------ -static const uint8_t digitalPinCount = sizeof(digitalPinMap)/sizeof(pin_map_t); - -uint8_t badPinNumber(void) - __attribute__((error("Pin number is too large or not a constant"))); - -static inline __attribute__((always_inline)) - uint8_t getPinMode(uint8_t pin) { - if (__builtin_constant_p(pin) && pin < digitalPinCount) { - return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1; - } else { - return badPinNumber(); - } -} -static inline __attribute__((always_inline)) - void setPinMode(uint8_t pin, uint8_t mode) { - if (__builtin_constant_p(pin) && pin < digitalPinCount) { - if (mode) { - *digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit; - } else { - *digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit); - } - } else { - badPinNumber(); - } -} -static inline __attribute__((always_inline)) - uint8_t fastDigitalRead(uint8_t pin) { - if (__builtin_constant_p(pin) && pin < digitalPinCount) { - return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1; - } else { - return badPinNumber(); - } -} -static inline __attribute__((always_inline)) - void fastDigitalWrite(uint8_t pin, uint8_t value) { - if (__builtin_constant_p(pin) && pin < digitalPinCount) { - if (value) { - *digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit; - } else { - *digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit); - } - } else { - badPinNumber(); - } -} -*/ -#endif // Sd2PinMap_h +/* Arduino SdFat Library + * Copyright (C) 2010 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +// Warning this file was generated by a program. +#ifndef Sd2PinMap_h +#define Sd2PinMap_h + +#include + +//------------------------------------------------------------------------------ +/** struct for mapping digital pins */ +struct pin_map_t +{ + volatile uint8_t* ddr; + volatile uint8_t* pin; + volatile uint8_t* port; + uint8_t bit; +}; +/* +//------------------------------------------------------------------------------ +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +// Mega + +// Two Wire (aka I2C) ports +uint8_t const SDA_PIN = 20; +uint8_t const SCL_PIN = 21; + +// SPI port +uint8_t const SS_PIN = 53; +uint8_t const MOSI_PIN = 51; +uint8_t const MISO_PIN = 50; +uint8_t const SCK_PIN = 52; + +static const pin_map_t digitalPinMap[] = { + {&DDRE, &PINE, &PORTE, 0}, // E0 0 + {&DDRE, &PINE, &PORTE, 1}, // E1 1 + {&DDRE, &PINE, &PORTE, 4}, // E4 2 + {&DDRE, &PINE, &PORTE, 5}, // E5 3 + {&DDRG, &PING, &PORTG, 5}, // G5 4 + {&DDRE, &PINE, &PORTE, 3}, // E3 5 + {&DDRH, &PINH, &PORTH, 3}, // H3 6 + {&DDRH, &PINH, &PORTH, 4}, // H4 7 + {&DDRH, &PINH, &PORTH, 5}, // H5 8 + {&DDRH, &PINH, &PORTH, 6}, // H6 9 + {&DDRB, &PINB, &PORTB, 4}, // B4 10 + {&DDRB, &PINB, &PORTB, 5}, // B5 11 + {&DDRB, &PINB, &PORTB, 6}, // B6 12 + {&DDRB, &PINB, &PORTB, 7}, // B7 13 + {&DDRJ, &PINJ, &PORTJ, 1}, // J1 14 + {&DDRJ, &PINJ, &PORTJ, 0}, // J0 15 + {&DDRH, &PINH, &PORTH, 1}, // H1 16 + {&DDRH, &PINH, &PORTH, 0}, // H0 17 + {&DDRD, &PIND, &PORTD, 3}, // D3 18 + {&DDRD, &PIND, &PORTD, 2}, // D2 19 + {&DDRD, &PIND, &PORTD, 1}, // D1 20 + {&DDRD, &PIND, &PORTD, 0}, // D0 21 + {&DDRA, &PINA, &PORTA, 0}, // A0 22 + {&DDRA, &PINA, &PORTA, 1}, // A1 23 + {&DDRA, &PINA, &PORTA, 2}, // A2 24 + {&DDRA, &PINA, &PORTA, 3}, // A3 25 + {&DDRA, &PINA, &PORTA, 4}, // A4 26 + {&DDRA, &PINA, &PORTA, 5}, // A5 27 + {&DDRA, &PINA, &PORTA, 6}, // A6 28 + {&DDRA, &PINA, &PORTA, 7}, // A7 29 + {&DDRC, &PINC, &PORTC, 7}, // C7 30 + {&DDRC, &PINC, &PORTC, 6}, // C6 31 + {&DDRC, &PINC, &PORTC, 5}, // C5 32 + {&DDRC, &PINC, &PORTC, 4}, // C4 33 + {&DDRC, &PINC, &PORTC, 3}, // C3 34 + {&DDRC, &PINC, &PORTC, 2}, // C2 35 + {&DDRC, &PINC, &PORTC, 1}, // C1 36 + {&DDRC, &PINC, &PORTC, 0}, // C0 37 + {&DDRD, &PIND, &PORTD, 7}, // D7 38 + {&DDRG, &PING, &PORTG, 2}, // G2 39 + {&DDRG, &PING, &PORTG, 1}, // G1 40 + {&DDRG, &PING, &PORTG, 0}, // G0 41 + {&DDRL, &PINL, &PORTL, 7}, // L7 42 + {&DDRL, &PINL, &PORTL, 6}, // L6 43 + {&DDRL, &PINL, &PORTL, 5}, // L5 44 + {&DDRL, &PINL, &PORTL, 4}, // L4 45 + {&DDRL, &PINL, &PORTL, 3}, // L3 46 + {&DDRL, &PINL, &PORTL, 2}, // L2 47 + {&DDRL, &PINL, &PORTL, 1}, // L1 48 + {&DDRL, &PINL, &PORTL, 0}, // L0 49 + {&DDRB, &PINB, &PORTB, 3}, // B3 50 + {&DDRB, &PINB, &PORTB, 2}, // B2 51 + {&DDRB, &PINB, &PORTB, 1}, // B1 52 + {&DDRB, &PINB, &PORTB, 0}, // B0 53 + {&DDRF, &PINF, &PORTF, 0}, // F0 54 + {&DDRF, &PINF, &PORTF, 1}, // F1 55 + {&DDRF, &PINF, &PORTF, 2}, // F2 56 + {&DDRF, &PINF, &PORTF, 3}, // F3 57 + {&DDRF, &PINF, &PORTF, 4}, // F4 58 + {&DDRF, &PINF, &PORTF, 5}, // F5 59 + {&DDRF, &PINF, &PORTF, 6}, // F6 60 + {&DDRF, &PINF, &PORTF, 7}, // F7 61 + {&DDRK, &PINK, &PORTK, 0}, // K0 62 + {&DDRK, &PINK, &PORTK, 1}, // K1 63 + {&DDRK, &PINK, &PORTK, 2}, // K2 64 + {&DDRK, &PINK, &PORTK, 3}, // K3 65 + {&DDRK, &PINK, &PORTK, 4}, // K4 66 + {&DDRK, &PINK, &PORTK, 5}, // K5 67 + {&DDRK, &PINK, &PORTK, 6}, // K6 68 + {&DDRK, &PINK, &PORTK, 7} // K7 69 +}; +//------------------------------------------------------------------------------ +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) +// Sanguino + +// Two Wire (aka I2C) ports +uint8_t const SDA_PIN = 17; +uint8_t const SCL_PIN = 18; + +// SPI port +uint8_t const SS_PIN = 4; +uint8_t const MOSI_PIN = 5; +uint8_t const MISO_PIN = 6; +uint8_t const SCK_PIN = 7; + +static const pin_map_t digitalPinMap[] = { + {&DDRB, &PINB, &PORTB, 0}, // B0 0 + {&DDRB, &PINB, &PORTB, 1}, // B1 1 + {&DDRB, &PINB, &PORTB, 2}, // B2 2 + {&DDRB, &PINB, &PORTB, 3}, // B3 3 + {&DDRB, &PINB, &PORTB, 4}, // B4 4 + {&DDRB, &PINB, &PORTB, 5}, // B5 5 + {&DDRB, &PINB, &PORTB, 6}, // B6 6 + {&DDRB, &PINB, &PORTB, 7}, // B7 7 + {&DDRD, &PIND, &PORTD, 0}, // D0 8 + {&DDRD, &PIND, &PORTD, 1}, // D1 9 + {&DDRD, &PIND, &PORTD, 2}, // D2 10 + {&DDRD, &PIND, &PORTD, 3}, // D3 11 + {&DDRD, &PIND, &PORTD, 4}, // D4 12 + {&DDRD, &PIND, &PORTD, 5}, // D5 13 + {&DDRD, &PIND, &PORTD, 6}, // D6 14 + {&DDRD, &PIND, &PORTD, 7}, // D7 15 + {&DDRC, &PINC, &PORTC, 0}, // C0 16 + {&DDRC, &PINC, &PORTC, 1}, // C1 17 + {&DDRC, &PINC, &PORTC, 2}, // C2 18 + {&DDRC, &PINC, &PORTC, 3}, // C3 19 + {&DDRC, &PINC, &PORTC, 4}, // C4 20 + {&DDRC, &PINC, &PORTC, 5}, // C5 21 + {&DDRC, &PINC, &PORTC, 6}, // C6 22 + {&DDRC, &PINC, &PORTC, 7}, // C7 23 + {&DDRA, &PINA, &PORTA, 7}, // A7 24 + {&DDRA, &PINA, &PORTA, 6}, // A6 25 + {&DDRA, &PINA, &PORTA, 5}, // A5 26 + {&DDRA, &PINA, &PORTA, 4}, // A4 27 + {&DDRA, &PINA, &PORTA, 3}, // A3 28 + {&DDRA, &PINA, &PORTA, 2}, // A2 29 + {&DDRA, &PINA, &PORTA, 1}, // A1 30 + {&DDRA, &PINA, &PORTA, 0} // A0 31 +}; +//------------------------------------------------------------------------------ +#elif defined(__AVR_ATmega32U4__) +// Teensy 2.0 + +// Two Wire (aka I2C) ports +uint8_t const SDA_PIN = 6; +uint8_t const SCL_PIN = 5; + +// SPI port +uint8_t const SS_PIN = 0; +uint8_t const MOSI_PIN = 2; +uint8_t const MISO_PIN = 3; +uint8_t const SCK_PIN = 1; + +static const pin_map_t digitalPinMap[] = { + {&DDRB, &PINB, &PORTB, 0}, // B0 0 + {&DDRB, &PINB, &PORTB, 1}, // B1 1 + {&DDRB, &PINB, &PORTB, 2}, // B2 2 + {&DDRB, &PINB, &PORTB, 3}, // B3 3 + {&DDRB, &PINB, &PORTB, 7}, // B7 4 + {&DDRD, &PIND, &PORTD, 0}, // D0 5 + {&DDRD, &PIND, &PORTD, 1}, // D1 6 + {&DDRD, &PIND, &PORTD, 2}, // D2 7 + {&DDRD, &PIND, &PORTD, 3}, // D3 8 + {&DDRC, &PINC, &PORTC, 6}, // C6 9 + {&DDRC, &PINC, &PORTC, 7}, // C7 10 + {&DDRD, &PIND, &PORTD, 6}, // D6 11 + {&DDRD, &PIND, &PORTD, 7}, // D7 12 + {&DDRB, &PINB, &PORTB, 4}, // B4 13 + {&DDRB, &PINB, &PORTB, 5}, // B5 14 + {&DDRB, &PINB, &PORTB, 6}, // B6 15 + {&DDRF, &PINF, &PORTF, 7}, // F7 16 + {&DDRF, &PINF, &PORTF, 6}, // F6 17 + {&DDRF, &PINF, &PORTF, 5}, // F5 18 + {&DDRF, &PINF, &PORTF, 4}, // F4 19 + {&DDRF, &PINF, &PORTF, 1}, // F1 20 + {&DDRF, &PINF, &PORTF, 0}, // F0 21 + {&DDRD, &PIND, &PORTD, 4}, // D4 22 + {&DDRD, &PIND, &PORTD, 5}, // D5 23 + {&DDRE, &PINE, &PORTE, 6} // E6 24 +}; +//------------------------------------------------------------------------------ +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) +// Teensy++ 1.0 & 2.0 + +// Two Wire (aka I2C) ports +uint8_t const SDA_PIN = 1; +uint8_t const SCL_PIN = 0; + +// SPI port +uint8_t const SS_PIN = 20; +uint8_t const MOSI_PIN = 22; +uint8_t const MISO_PIN = 23; +uint8_t const SCK_PIN = 21; + +static const pin_map_t digitalPinMap[] = { + {&DDRD, &PIND, &PORTD, 0}, // D0 0 + {&DDRD, &PIND, &PORTD, 1}, // D1 1 + {&DDRD, &PIND, &PORTD, 2}, // D2 2 + {&DDRD, &PIND, &PORTD, 3}, // D3 3 + {&DDRD, &PIND, &PORTD, 4}, // D4 4 + {&DDRD, &PIND, &PORTD, 5}, // D5 5 + {&DDRD, &PIND, &PORTD, 6}, // D6 6 + {&DDRD, &PIND, &PORTD, 7}, // D7 7 + {&DDRE, &PINE, &PORTE, 0}, // E0 8 + {&DDRE, &PINE, &PORTE, 1}, // E1 9 + {&DDRC, &PINC, &PORTC, 0}, // C0 10 + {&DDRC, &PINC, &PORTC, 1}, // C1 11 + {&DDRC, &PINC, &PORTC, 2}, // C2 12 + {&DDRC, &PINC, &PORTC, 3}, // C3 13 + {&DDRC, &PINC, &PORTC, 4}, // C4 14 + {&DDRC, &PINC, &PORTC, 5}, // C5 15 + {&DDRC, &PINC, &PORTC, 6}, // C6 16 + {&DDRC, &PINC, &PORTC, 7}, // C7 17 + {&DDRE, &PINE, &PORTE, 6}, // E6 18 + {&DDRE, &PINE, &PORTE, 7}, // E7 19 + {&DDRB, &PINB, &PORTB, 0}, // B0 20 + {&DDRB, &PINB, &PORTB, 1}, // B1 21 + {&DDRB, &PINB, &PORTB, 2}, // B2 22 + {&DDRB, &PINB, &PORTB, 3}, // B3 23 + {&DDRB, &PINB, &PORTB, 4}, // B4 24 + {&DDRB, &PINB, &PORTB, 5}, // B5 25 + {&DDRB, &PINB, &PORTB, 6}, // B6 26 + {&DDRB, &PINB, &PORTB, 7}, // B7 27 + {&DDRA, &PINA, &PORTA, 0}, // A0 28 + {&DDRA, &PINA, &PORTA, 1}, // A1 29 + {&DDRA, &PINA, &PORTA, 2}, // A2 30 + {&DDRA, &PINA, &PORTA, 3}, // A3 31 + {&DDRA, &PINA, &PORTA, 4}, // A4 32 + {&DDRA, &PINA, &PORTA, 5}, // A5 33 + {&DDRA, &PINA, &PORTA, 6}, // A6 34 + {&DDRA, &PINA, &PORTA, 7}, // A7 35 + {&DDRE, &PINE, &PORTE, 4}, // E4 36 + {&DDRE, &PINE, &PORTE, 5}, // E5 37 + {&DDRF, &PINF, &PORTF, 0}, // F0 38 + {&DDRF, &PINF, &PORTF, 1}, // F1 39 + {&DDRF, &PINF, &PORTF, 2}, // F2 40 + {&DDRF, &PINF, &PORTF, 3}, // F3 41 + {&DDRF, &PINF, &PORTF, 4}, // F4 42 + {&DDRF, &PINF, &PORTF, 5}, // F5 43 + {&DDRF, &PINF, &PORTF, 6}, // F6 44 + {&DDRF, &PINF, &PORTF, 7} // F7 45 +}; +//------------------------------------------------------------------------------ +#else // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +// 168 and 328 Arduinos + +// Two Wire (aka I2C) ports +uint8_t const SDA_PIN = 18; +uint8_t const SCL_PIN = 19; + +// SPI port +uint8_t const SS_PIN = 10; +uint8_t const MOSI_PIN = 11; +uint8_t const MISO_PIN = 12; +uint8_t const SCK_PIN = 13; + +static const pin_map_t digitalPinMap[] = { + {&DDRD, &PIND, &PORTD, 0}, // D0 0 + {&DDRD, &PIND, &PORTD, 1}, // D1 1 + {&DDRD, &PIND, &PORTD, 2}, // D2 2 + {&DDRD, &PIND, &PORTD, 3}, // D3 3 + {&DDRD, &PIND, &PORTD, 4}, // D4 4 + {&DDRD, &PIND, &PORTD, 5}, // D5 5 + {&DDRD, &PIND, &PORTD, 6}, // D6 6 + {&DDRD, &PIND, &PORTD, 7}, // D7 7 + {&DDRB, &PINB, &PORTB, 0}, // B0 8 + {&DDRB, &PINB, &PORTB, 1}, // B1 9 + {&DDRB, &PINB, &PORTB, 2}, // B2 10 + {&DDRB, &PINB, &PORTB, 3}, // B3 11 + {&DDRB, &PINB, &PORTB, 4}, // B4 12 + {&DDRB, &PINB, &PORTB, 5}, // B5 13 + {&DDRC, &PINC, &PORTC, 0}, // C0 14 + {&DDRC, &PINC, &PORTC, 1}, // C1 15 + {&DDRC, &PINC, &PORTC, 2}, // C2 16 + {&DDRC, &PINC, &PORTC, 3}, // C3 17 + {&DDRC, &PINC, &PORTC, 4}, // C4 18 + {&DDRC, &PINC, &PORTC, 5} // C5 19 +}; +#endif // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +//------------------------------------------------------------------------------ +static const uint8_t digitalPinCount = sizeof(digitalPinMap)/sizeof(pin_map_t); + +uint8_t badPinNumber(void) + __attribute__((error("Pin number is too large or not a constant"))); + +static inline __attribute__((always_inline)) + uint8_t getPinMode(uint8_t pin) { + if (__builtin_constant_p(pin) && pin < digitalPinCount) { + return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1; + } else { + return badPinNumber(); + } +} +static inline __attribute__((always_inline)) + void setPinMode(uint8_t pin, uint8_t mode) { + if (__builtin_constant_p(pin) && pin < digitalPinCount) { + if (mode) { + *digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit; + } else { + *digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit); + } + } else { + badPinNumber(); + } +} +static inline __attribute__((always_inline)) + uint8_t fastDigitalRead(uint8_t pin) { + if (__builtin_constant_p(pin) && pin < digitalPinCount) { + return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1; + } else { + return badPinNumber(); + } +} +static inline __attribute__((always_inline)) + void fastDigitalWrite(uint8_t pin, uint8_t value) { + if (__builtin_constant_p(pin) && pin < digitalPinCount) { + if (value) { + *digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit; + } else { + *digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit); + } + } else { + badPinNumber(); + } +} +*/ +#endif // Sd2PinMap_h diff --git a/Libmaple/libmaple/libraries/mapleSDfat/SdFat.h b/Libmaple/libmaple/libraries/mapleSDfat/SdFat.h index 6dcf98ea..e1b40118 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/SdFat.h +++ b/Libmaple/libmaple/libraries/mapleSDfat/SdFat.h @@ -1,548 +1,548 @@ -/* Arduino SdFat Library - * Copyright (C) 2009 by William Greiman - * - * This file is part of the Arduino SdFat Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino SdFat Library. If not, see - * . - */ -#ifndef SdFat_h -#define SdFat_h -/** - * \file - * SdFile and SdVolume classes - */ -//#include -#include -#include "Sd2Card.h" -#include "FatStructs.h" -#include "Print.h" -//------------------------------------------------------------------------------ -/** - * Allow use of deprecated functions if non-zero - */ -#define ALLOW_DEPRECATED_FUNCTIONS 1 -//------------------------------------------------------------------------------ -// forward declaration since SdVolume is used in SdFile -class SdVolume; -//============================================================================== -// SdFile class - -// flags for ls() -/** ls() flag to print modify date */ -uint8_t const LS_DATE = 1; -/** ls() flag to print file size */ -uint8_t const LS_SIZE = 2; -/** ls() flag for recursive list of subdirectories */ -uint8_t const LS_R = 4; - -// use the gnu style oflag in open() -/** open() oflag for reading */ -uint8_t const O_READ = 0X01; -/** open() oflag - same as O_READ */ -uint8_t const O_RDONLY = O_READ; -/** open() oflag for write */ -uint8_t const O_WRITE = 0X02; -/** open() oflag - same as O_WRITE */ -uint8_t const O_WRONLY = O_WRITE; -/** open() oflag for reading and writing */ -uint8_t const O_RDWR = (O_READ | O_WRITE); -/** open() oflag mask for access modes */ -uint8_t const O_ACCMODE = (O_READ | O_WRITE); -/** The file offset shall be set to the end of the file prior to each write. */ -uint8_t const O_APPEND = 0X04; -/** synchronous writes - call sync() after each write */ -uint8_t const O_SYNC = 0X08; -/** create the file if nonexistent */ -uint8_t const O_CREAT = 0X10; -/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ -uint8_t const O_EXCL = 0X20; -/** truncate the file to zero length */ -uint8_t const O_TRUNC = 0X40; - -// flags for timestamp -/** set the file's last access date */ -uint8_t const T_ACCESS = 1; -/** set the file's creation date and time */ -uint8_t const T_CREATE = 2; -/** Set the file's write date and time */ -uint8_t const T_WRITE = 4; -// values for type_ -/** This SdFile has not been opened. */ -uint8_t const FAT_FILE_TYPE_CLOSED = 0; -/** SdFile for a file */ -uint8_t const FAT_FILE_TYPE_NORMAL = 1; -/** SdFile for a FAT16 root directory */ -uint8_t const FAT_FILE_TYPE_ROOT16 = 2; -/** SdFile for a FAT32 root directory */ -uint8_t const FAT_FILE_TYPE_ROOT32 = 3; -/** SdFile for a subdirectory */ -uint8_t const FAT_FILE_TYPE_SUBDIR = 4; -/** Test value for directory type */ -uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT16; - -/** date field for FAT directory entry */ -static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { - return (year - 1980) << 9 | month << 5 | day; -} -/** year part of FAT directory date field */ -static inline uint16_t FAT_YEAR(uint16_t fatDate) { - return 1980 + (fatDate >> 9); -} -/** month part of FAT directory date field */ -static inline uint8_t FAT_MONTH(uint16_t fatDate) { - return (fatDate >> 5) & 0XF; -} -/** day part of FAT directory date field */ -static inline uint8_t FAT_DAY(uint16_t fatDate) { - return fatDate & 0X1F; -} -/** time field for FAT directory entry */ -static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { - return hour << 11 | minute << 5 | second >> 1; -} -/** hour part of FAT directory time field */ -static inline uint8_t FAT_HOUR(uint16_t fatTime) { - return fatTime >> 11; -} -/** minute part of FAT directory time field */ -static inline uint8_t FAT_MINUTE(uint16_t fatTime) { - return(fatTime >> 5) & 0X3F; -} -/** second part of FAT directory time field */ -static inline uint8_t FAT_SECOND(uint16_t fatTime) { - return 2*(fatTime & 0X1F); -} -/** Default date for file timestamps is 1 Jan 2000 */ -uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; -/** Default time for file timestamp is 1 am */ -uint16_t const FAT_DEFAULT_TIME = (1 << 11); -//------------------------------------------------------------------------------ -/** - * \class SdFile - * \brief Access FAT16 and FAT32 files on SD and SDHC cards. - */ -class SdFile : public Print { - public: - /** Create an instance of SdFile. */ - SdFile(void) : type_(FAT_FILE_TYPE_CLOSED) {} - /** - * writeError is set to true if an error occurs during a write(). - * Set writeError to false before calling print() and/or write() and check - * for true after calls to print() and/or write(). - */ - bool writeError; - /** - * Cancel unbuffered reads for this file. - * See setUnbufferedRead() - */ - void clearUnbufferedRead(void) { - flags_ &= ~F_FILE_UNBUFFERED_READ; - } - uint8_t close(void); - uint8_t contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); - uint8_t createContiguous(SdFile* dirFile, - const char* fileName, uint32_t size); - /** \return The current cluster number for a file or directory. */ - uint32_t curCluster(void) const {return curCluster_;} - /** \return The current position for a file or directory. */ - uint32_t curPosition(void) const {return curPosition_;} - /** - * Set the date/time callback function - * - * \param[in] dateTime The user's call back function. The callback - * function is of the form: - * - * \code - * void dateTime(uint16_t* date, uint16_t* time) { - * uint16_t year; - * uint8_t month, day, hour, minute, second; - * - * // User gets date and time from GPS or real-time clock here - * - * // return date using FAT_DATE macro to format fields - * *date = FAT_DATE(year, month, day); - * - * // return time using FAT_TIME macro to format fields - * *time = FAT_TIME(hour, minute, second); - * } - * \endcode - * - * Sets the function that is called when a file is created or when - * a file's directory entry is modified by sync(). All timestamps, - * access, creation, and modify, are set when a file is created. - * sync() maintains the last access date and last modify date/time. - * - * See the timestamp() function. - */ - static void dateTimeCallback( - void (*dateTime)(uint16_t* date, uint16_t* time)) { - dateTime_ = dateTime; - } - /** - * Cancel the date/time callback function. - */ - static void dateTimeCallbackCancel(void) { - // use explicit zero since NULL is not defined for Sanguino - dateTime_ = 0; - } - /** \return Address of the block that contains this file's directory. */ - uint32_t dirBlock(void) const {return dirBlock_;} - uint8_t dirEntry(dir_t* dir); - /** \return Index of this file's directory in the block dirBlock. */ - uint8_t dirIndex(void) const {return dirIndex_;} - static void dirName(const dir_t& dir, char* name); - /** \return The total number of bytes in a file or directory. */ - uint32_t fileSize(void) const {return fileSize_;} - /** \return The first cluster number for a file or directory. */ - uint32_t firstCluster(void) const {return firstCluster_;} - /** \return True if this is a SdFile for a directory else false. */ - uint8_t isDir(void) const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} - /** \return True if this is a SdFile for a file else false. */ - uint8_t isFile(void) const {return type_ == FAT_FILE_TYPE_NORMAL;} - /** \return True if this is a SdFile for an open file/directory else false. */ - uint8_t isOpen(void) const {return type_ != FAT_FILE_TYPE_CLOSED;} - /** \return True if this is a SdFile for a subdirectory else false. */ - uint8_t isSubDir(void) const {return type_ == FAT_FILE_TYPE_SUBDIR;} - /** \return True if this is a SdFile for the root directory. */ - uint8_t isRoot(void) const { - return type_ == FAT_FILE_TYPE_ROOT16 || type_ == FAT_FILE_TYPE_ROOT32; - } - void ls(uint8_t flags = 0, uint8_t indent = 0); - uint8_t makeDir(SdFile* dir, const char* dirName); - uint8_t open(SdFile* dirFile, uint16_t index, uint8_t oflag); - uint8_t open(SdFile* dirFile, const char* fileName, uint8_t oflag); - - uint8_t openRoot(SdVolume* vol); - static void printDirName(const dir_t& dir, uint8_t width); - static void printFatDate(uint16_t fatDate); - static void printFatTime(uint16_t fatTime); - static void printTwoDigits(uint8_t v); - /** - * Read the next byte from a file. - * - * \return For success read returns the next byte in the file as an int. - * If an error occurs or end of file is reached -1 is returned. - */ - int16_t read(void) { - uint8_t b; - return read(&b, 1) == 1 ? b : -1; - } - int16_t read(void* buf, uint16_t nbyte); - int8_t readDir(dir_t* dir); - static uint8_t remove(SdFile* dirFile, const char* fileName); - uint8_t remove(void); - /** Set the file's current position to zero. */ - void rewind(void) { - curPosition_ = curCluster_ = 0; - } - uint8_t rmDir(void); - uint8_t rmRfStar(void); - /** Set the files position to current position + \a pos. See seekSet(). */ - uint8_t seekCur(uint32_t pos) { - return seekSet(curPosition_ + pos); - } - /** - * Set the files current position to end of file. Useful to position - * a file for append. See seekSet(). - */ - uint8_t seekEnd(void) {return seekSet(fileSize_);} - uint8_t seekSet(uint32_t pos); - /** - * Use unbuffered reads to access this file. Used with Wave - * Shield ISR. Used with Sd2Card::partialBlockRead() in WaveRP. - * - * Not recommended for normal applications. - */ - void setUnbufferedRead(void) { - if (isFile()) flags_ |= F_FILE_UNBUFFERED_READ; - } - uint8_t timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, - uint8_t hour, uint8_t minute, uint8_t second); - uint8_t sync(void); - /** Type of this SdFile. You should use isFile() or isDir() instead of type() - * if possible. - * - * \return The file or directory type. - */ - uint8_t type(void) const {return type_;} - uint8_t truncate(uint32_t size); - /** \return Unbuffered read flag. */ - uint8_t unbufferedRead(void) const { - return flags_ & F_FILE_UNBUFFERED_READ; - } - /** \return SdVolume that contains this file. */ - SdVolume* volume(void) const {return vol_;} - void write(uint8_t b); - int16_t write(const void* buf, uint16_t nbyte); - void write(const char* str); -// void write_P(PGM_P str); -// void writeln_P(PGM_P str); -//------------------------------------------------------------------------------ -#if ALLOW_DEPRECATED_FUNCTIONS -// Deprecated functions - suppress cpplint warnings with NOLINT comment - /** \deprecated Use: - * uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); - */ - uint8_t contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT - return contiguousRange(&bgnBlock, &endBlock); - } - /** \deprecated Use: - * uint8_t SdFile::createContiguous(SdFile* dirFile, - * const char* fileName, uint32_t size) - */ - uint8_t createContiguous(SdFile& dirFile, // NOLINT - const char* fileName, uint32_t size) { - return createContiguous(&dirFile, fileName, size); - } - - /** - * \deprecated Use: - * static void SdFile::dateTimeCallback( - * void (*dateTime)(uint16_t* date, uint16_t* time)); - */ - static void dateTimeCallback( - void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT - oldDateTime_ = dateTime; - dateTime_ = dateTime ? oldToNew : 0; - } - /** \deprecated Use: uint8_t SdFile::dirEntry(dir_t* dir); */ - uint8_t dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT - /** \deprecated Use: - * uint8_t SdFile::makeDir(SdFile* dir, const char* dirName); - */ - uint8_t makeDir(SdFile& dir, const char* dirName) { // NOLINT - return makeDir(&dir, dirName); - } - /** \deprecated Use: - * uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag); - */ - uint8_t open(SdFile& dirFile, // NOLINT - const char* fileName, uint8_t oflag) { - return open(&dirFile, fileName, oflag); - } - /** \deprecated Do not use in new apps */ - uint8_t open(SdFile& dirFile, const char* fileName) { // NOLINT - return open(dirFile, fileName, O_RDWR); - } - /** \deprecated Use: - * uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag); - */ - uint8_t open(SdFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT - return open(&dirFile, index, oflag); - } - /** \deprecated Use: uint8_t SdFile::openRoot(SdVolume* vol); */ - uint8_t openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT - - /** \deprecated Use: int8_t SdFile::readDir(dir_t* dir); */ - int8_t readDir(dir_t& dir) {return readDir(&dir);} // NOLINT - /** \deprecated Use: - * static uint8_t SdFile::remove(SdFile* dirFile, const char* fileName); - */ - static uint8_t remove(SdFile& dirFile, const char* fileName) { // NOLINT - return remove(&dirFile, fileName); - } -//------------------------------------------------------------------------------ -// rest are private - private: - static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT - static void oldToNew(uint16_t* date, uint16_t* time) { - uint16_t d; - uint16_t t; - oldDateTime_(d, t); - *date = d; - *time = t; - } -#endif // ALLOW_DEPRECATED_FUNCTIONS - private: - // bits defined in flags_ - // should be 0XF - static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); - // available bits - static uint8_t const F_UNUSED = 0X30; - // use unbuffered SD read - static uint8_t const F_FILE_UNBUFFERED_READ = 0X40; - // sync of directory entry required - static uint8_t const F_FILE_DIR_DIRTY = 0X80; - -// make sure F_OFLAG is ok -//#if ((F_UNUSED | F_FILE_UNBUFFERED_READ | F_FILE_DIR_DIRTY) & F_OFLAG) -//#error flags_ bits conflict -//#endif // flags_ bits - - // private data - uint8_t flags_; // See above for definition of flags_ bits - uint8_t type_; // type of file see above for values - uint32_t curCluster_; // cluster for current file position - uint32_t curPosition_; // current file position in bytes from beginning - uint32_t dirBlock_; // SD block that contains directory entry for file - uint8_t dirIndex_; // index of entry in dirBlock 0 <= dirIndex_ <= 0XF - uint32_t fileSize_; // file size in bytes - uint32_t firstCluster_; // first cluster of file - SdVolume* vol_; // volume where file is located - - // private functions - uint8_t addCluster(void); - uint8_t addDirCluster(void); - dir_t* cacheDirEntry(uint8_t action); - static void (*dateTime_)(uint16_t* date, uint16_t* time); - static uint8_t make83Name(const char* str, uint8_t* name); - uint8_t openCachedEntry(uint8_t cacheIndex, uint8_t oflags); - dir_t* readDirCache(void); -}; -//============================================================================== -// SdVolume class -/** - * \brief Cache for an SD data block - */ -union cache_t { - /** Used to access cached file data blocks. */ - uint8_t data[512]; - /** Used to access cached FAT16 entries. */ - uint16_t fat16[256]; - /** Used to access cached FAT32 entries. */ - uint32_t fat32[128]; - /** Used to access cached directory entries. */ - dir_t dir[16]; - /** Used to access a cached MasterBoot Record. */ - mbr_t mbr; - /** Used to access to a cached FAT boot sector. */ - fbs_t fbs; -}; -//------------------------------------------------------------------------------ -/** - * \class SdVolume - * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. - */ -class SdVolume { - public: - /** Create an instance of SdVolume */ - SdVolume(void) :allocSearchStart_(2), fatType_(0) {} - /** Clear the cache and returns a pointer to the cache. Used by the WaveRP - * recorder to do raw write to the SD card. Not for normal apps. - */ - static uint8_t* cacheClear(void) { - cacheFlush(); - cacheBlockNumber_ = 0XFFFFFFFF; - return cacheBuffer_.data; - } - /** - * Initialize a FAT volume. Try partition one first then try super - * floppy format. - * - * \param[in] dev The Sd2Card where the volume is located. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. Reasons for - * failure include not finding a valid partition, not finding a valid - * FAT file system or an I/O error. - */ - uint8_t init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} - uint8_t init(Sd2Card* dev, uint8_t part); - - // inline functions that return volume info - /** \return The volume's cluster size in blocks. */ - uint8_t blocksPerCluster(void) const {return blocksPerCluster_;} - /** \return The number of blocks in one FAT. */ - uint32_t blocksPerFat(void) const {return blocksPerFat_;} - /** \return The total number of clusters in the volume. */ - uint32_t clusterCount(void) const {return clusterCount_;} - /** \return The shift count required to multiply by blocksPerCluster. */ - uint8_t clusterSizeShift(void) const {return clusterSizeShift_;} - /** \return The logical block number for the start of file data. */ - uint32_t dataStartBlock(void) const {return dataStartBlock_;} - /** \return The number of FAT structures on the volume. */ - uint8_t fatCount(void) const { return fatCount_;} - /** \return The logical block number for the start of the first FAT. */ - uint32_t fatStartBlock(void) const {return fatStartBlock_;} - /** \return The FAT type of the volume. Values are 12, 16 or 32. */ - uint8_t fatType(void) const {return fatType_;} - /** \return The number of entries in the root directory for FAT16 volumes. */ - uint32_t rootDirEntryCount(void) const {return rootDirEntryCount_;} - /** \return The logical block number for the start of the root directory - on FAT16 volumes or the first cluster number on FAT32 volumes. */ - uint32_t rootDirStart(void) const {return rootDirStart_;} - /** return a pointer to the Sd2Card object for this volume */ - static Sd2Card* sdCard(void) {return sdCard_;} -//------------------------------------------------------------------------------ -#if ALLOW_DEPRECATED_FUNCTIONS - // Deprecated functions - suppress cpplint warnings with NOLINT comment - /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev); */ - uint8_t init(Sd2Card& dev) {return init(&dev);} // NOLINT - - /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev, uint8_t vol); */ - uint8_t init(Sd2Card& dev, uint8_t part) { // NOLINT - return init(&dev, part); - } -#endif // ALLOW_DEPRECATED_FUNCTIONS -//------------------------------------------------------------------------------ - private: - // Allow SdFile access to SdVolume private data. - friend class SdFile; - - // value for action argument in cacheRawBlock to indicate read from cache - static uint8_t const CACHE_FOR_READ = 0; - // value for action argument in cacheRawBlock to indicate cache dirty - static uint8_t const CACHE_FOR_WRITE = 1; - - static cache_t cacheBuffer_; // 512 byte cache for device blocks - static uint32_t cacheBlockNumber_; // Logical number of block in the cache - static Sd2Card* sdCard_; // Sd2Card object for cache - static uint8_t cacheDirty_; // cacheFlush() will write block if true - static uint32_t cacheMirrorBlock_; // block number for mirror FAT -// - uint32_t allocSearchStart_; // start cluster for alloc search - uint8_t blocksPerCluster_; // cluster size in blocks - uint32_t blocksPerFat_; // FAT size in blocks - uint32_t clusterCount_; // clusters in one FAT - uint8_t clusterSizeShift_; // shift to convert cluster count to block count - uint32_t dataStartBlock_; // first data block number - uint8_t fatCount_; // number of FATs on volume - uint32_t fatStartBlock_; // start block for first FAT - uint8_t fatType_; // volume type (12, 16, OR 32) - uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir - uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 - //---------------------------------------------------------------------------- - uint8_t allocContiguous(uint32_t count, uint32_t* curCluster); - uint8_t blockOfCluster(uint32_t position) const { - return (position >> 9) & (blocksPerCluster_ - 1);} - uint32_t clusterStartBlock(uint32_t cluster) const { - return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);} - uint32_t blockNumber(uint32_t cluster, uint32_t position) const { - return clusterStartBlock(cluster) + blockOfCluster(position);} - static uint8_t cacheFlush(void); - static uint8_t cacheRawBlock(uint32_t blockNumber, uint8_t action); - static void cacheSetDirty(void) {cacheDirty_ |= CACHE_FOR_WRITE;} - static uint8_t cacheZeroBlock(uint32_t blockNumber); - uint8_t chainSize(uint32_t beginCluster, uint32_t* size) const; - uint8_t fatGet(uint32_t cluster, uint32_t* value) const; - uint8_t fatPut(uint32_t cluster, uint32_t value); - uint8_t fatPutEOC(uint32_t cluster) { - return fatPut(cluster, 0x0FFFFFFF); - } - uint8_t freeChain(uint32_t cluster); - uint8_t isEOC(uint32_t cluster) const { - return cluster >= (fatType_ == 16 ? FAT16EOC_MIN : FAT32EOC_MIN); - } - uint8_t readBlock(uint32_t block, uint8_t* dst) { - return sdCard_->readBlock(block, dst);} - uint8_t readData(uint32_t block, uint16_t offset, - uint16_t count, uint8_t* dst) { - return sdCard_->readData(block, offset, count, dst); - } - uint8_t writeBlock(uint32_t block, const uint8_t* dst) { - return sdCard_->writeBlock(block, dst); - } -}; -#endif // SdFat_h +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#ifndef SdFat_h +#define SdFat_h +/** + * \file + * SdFile and SdVolume classes + */ +//#include +#include +#include "Sd2Card.h" +#include "FatStructs.h" +#include "Print.h" +//------------------------------------------------------------------------------ +/** + * Allow use of deprecated functions if non-zero + */ +#define ALLOW_DEPRECATED_FUNCTIONS 1 +//------------------------------------------------------------------------------ +// forward declaration since SdVolume is used in SdFile +class SdVolume; +//============================================================================== +// SdFile class + +// flags for ls() +/** ls() flag to print modify date */ +uint8_t const LS_DATE = 1; +/** ls() flag to print file size */ +uint8_t const LS_SIZE = 2; +/** ls() flag for recursive list of subdirectories */ +uint8_t const LS_R = 4; + +// use the gnu style oflag in open() +/** open() oflag for reading */ +uint8_t const O_READ = 0X01; +/** open() oflag - same as O_READ */ +uint8_t const O_RDONLY = O_READ; +/** open() oflag for write */ +uint8_t const O_WRITE = 0X02; +/** open() oflag - same as O_WRITE */ +uint8_t const O_WRONLY = O_WRITE; +/** open() oflag for reading and writing */ +uint8_t const O_RDWR = (O_READ | O_WRITE); +/** open() oflag mask for access modes */ +uint8_t const O_ACCMODE = (O_READ | O_WRITE); +/** The file offset shall be set to the end of the file prior to each write. */ +uint8_t const O_APPEND = 0X04; +/** synchronous writes - call sync() after each write */ +uint8_t const O_SYNC = 0X08; +/** create the file if nonexistent */ +uint8_t const O_CREAT = 0X10; +/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ +uint8_t const O_EXCL = 0X20; +/** truncate the file to zero length */ +uint8_t const O_TRUNC = 0X40; + +// flags for timestamp +/** set the file's last access date */ +uint8_t const T_ACCESS = 1; +/** set the file's creation date and time */ +uint8_t const T_CREATE = 2; +/** Set the file's write date and time */ +uint8_t const T_WRITE = 4; +// values for type_ +/** This SdFile has not been opened. */ +uint8_t const FAT_FILE_TYPE_CLOSED = 0; +/** SdFile for a file */ +uint8_t const FAT_FILE_TYPE_NORMAL = 1; +/** SdFile for a FAT16 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT16 = 2; +/** SdFile for a FAT32 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT32 = 3; +/** SdFile for a subdirectory */ +uint8_t const FAT_FILE_TYPE_SUBDIR = 4; +/** Test value for directory type */ +uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT16; + +/** date field for FAT directory entry */ +static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { + return (year - 1980) << 9 | month << 5 | day; +} +/** year part of FAT directory date field */ +static inline uint16_t FAT_YEAR(uint16_t fatDate) { + return 1980 + (fatDate >> 9); +} +/** month part of FAT directory date field */ +static inline uint8_t FAT_MONTH(uint16_t fatDate) { + return (fatDate >> 5) & 0XF; +} +/** day part of FAT directory date field */ +static inline uint8_t FAT_DAY(uint16_t fatDate) { + return fatDate & 0X1F; +} +/** time field for FAT directory entry */ +static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { + return hour << 11 | minute << 5 | second >> 1; +} +/** hour part of FAT directory time field */ +static inline uint8_t FAT_HOUR(uint16_t fatTime) { + return fatTime >> 11; +} +/** minute part of FAT directory time field */ +static inline uint8_t FAT_MINUTE(uint16_t fatTime) { + return(fatTime >> 5) & 0X3F; +} +/** second part of FAT directory time field */ +static inline uint8_t FAT_SECOND(uint16_t fatTime) { + return 2*(fatTime & 0X1F); +} +/** Default date for file timestamps is 1 Jan 2000 */ +uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; +/** Default time for file timestamp is 1 am */ +uint16_t const FAT_DEFAULT_TIME = (1 << 11); +//------------------------------------------------------------------------------ +/** + * \class SdFile + * \brief Access FAT16 and FAT32 files on SD and SDHC cards. + */ +class SdFile : public Print { + public: + /** Create an instance of SdFile. */ + SdFile(void) : type_(FAT_FILE_TYPE_CLOSED) {} + /** + * writeError is set to true if an error occurs during a write(). + * Set writeError to false before calling print() and/or write() and check + * for true after calls to print() and/or write(). + */ + bool writeError; + /** + * Cancel unbuffered reads for this file. + * See setUnbufferedRead() + */ + void clearUnbufferedRead(void) { + flags_ &= ~F_FILE_UNBUFFERED_READ; + } + uint8_t close(void); + uint8_t contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + uint8_t createContiguous(SdFile* dirFile, + const char* fileName, uint32_t size); + /** \return The current cluster number for a file or directory. */ + uint32_t curCluster(void) const {return curCluster_;} + /** \return The current position for a file or directory. */ + uint32_t curPosition(void) const {return curPosition_;} + /** + * Set the date/time callback function + * + * \param[in] dateTime The user's call back function. The callback + * function is of the form: + * + * \code + * void dateTime(uint16_t* date, uint16_t* time) { + * uint16_t year; + * uint8_t month, day, hour, minute, second; + * + * // User gets date and time from GPS or real-time clock here + * + * // return date using FAT_DATE macro to format fields + * *date = FAT_DATE(year, month, day); + * + * // return time using FAT_TIME macro to format fields + * *time = FAT_TIME(hour, minute, second); + * } + * \endcode + * + * Sets the function that is called when a file is created or when + * a file's directory entry is modified by sync(). All timestamps, + * access, creation, and modify, are set when a file is created. + * sync() maintains the last access date and last modify date/time. + * + * See the timestamp() function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t* date, uint16_t* time)) { + dateTime_ = dateTime; + } + /** + * Cancel the date/time callback function. + */ + static void dateTimeCallbackCancel(void) { + // use explicit zero since NULL is not defined for Sanguino + dateTime_ = 0; + } + /** \return Address of the block that contains this file's directory. */ + uint32_t dirBlock(void) const {return dirBlock_;} + uint8_t dirEntry(dir_t* dir); + /** \return Index of this file's directory in the block dirBlock. */ + uint8_t dirIndex(void) const {return dirIndex_;} + static void dirName(const dir_t& dir, char* name); + /** \return The total number of bytes in a file or directory. */ + uint32_t fileSize(void) const {return fileSize_;} + /** \return The first cluster number for a file or directory. */ + uint32_t firstCluster(void) const {return firstCluster_;} + /** \return True if this is a SdFile for a directory else false. */ + uint8_t isDir(void) const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} + /** \return True if this is a SdFile for a file else false. */ + uint8_t isFile(void) const {return type_ == FAT_FILE_TYPE_NORMAL;} + /** \return True if this is a SdFile for an open file/directory else false. */ + uint8_t isOpen(void) const {return type_ != FAT_FILE_TYPE_CLOSED;} + /** \return True if this is a SdFile for a subdirectory else false. */ + uint8_t isSubDir(void) const {return type_ == FAT_FILE_TYPE_SUBDIR;} + /** \return True if this is a SdFile for the root directory. */ + uint8_t isRoot(void) const { + return type_ == FAT_FILE_TYPE_ROOT16 || type_ == FAT_FILE_TYPE_ROOT32; + } + void ls(uint8_t flags = 0, uint8_t indent = 0); + uint8_t makeDir(SdFile* dir, const char* dirName); + uint8_t open(SdFile* dirFile, uint16_t index, uint8_t oflag); + uint8_t open(SdFile* dirFile, const char* fileName, uint8_t oflag); + + uint8_t openRoot(SdVolume* vol); + static void printDirName(const dir_t& dir, uint8_t width); + static void printFatDate(uint16_t fatDate); + static void printFatTime(uint16_t fatTime); + static void printTwoDigits(uint8_t v); + /** + * Read the next byte from a file. + * + * \return For success read returns the next byte in the file as an int. + * If an error occurs or end of file is reached -1 is returned. + */ + int16_t read(void) { + uint8_t b; + return read(&b, 1) == 1 ? b : -1; + } + int16_t read(void* buf, uint16_t nbyte); + int8_t readDir(dir_t* dir); + static uint8_t remove(SdFile* dirFile, const char* fileName); + uint8_t remove(void); + /** Set the file's current position to zero. */ + void rewind(void) { + curPosition_ = curCluster_ = 0; + } + uint8_t rmDir(void); + uint8_t rmRfStar(void); + /** Set the files position to current position + \a pos. See seekSet(). */ + uint8_t seekCur(uint32_t pos) { + return seekSet(curPosition_ + pos); + } + /** + * Set the files current position to end of file. Useful to position + * a file for append. See seekSet(). + */ + uint8_t seekEnd(void) {return seekSet(fileSize_);} + uint8_t seekSet(uint32_t pos); + /** + * Use unbuffered reads to access this file. Used with Wave + * Shield ISR. Used with Sd2Card::partialBlockRead() in WaveRP. + * + * Not recommended for normal applications. + */ + void setUnbufferedRead(void) { + if (isFile()) flags_ |= F_FILE_UNBUFFERED_READ; + } + uint8_t timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, + uint8_t hour, uint8_t minute, uint8_t second); + uint8_t sync(void); + /** Type of this SdFile. You should use isFile() or isDir() instead of type() + * if possible. + * + * \return The file or directory type. + */ + uint8_t type(void) const {return type_;} + uint8_t truncate(uint32_t size); + /** \return Unbuffered read flag. */ + uint8_t unbufferedRead(void) const { + return flags_ & F_FILE_UNBUFFERED_READ; + } + /** \return SdVolume that contains this file. */ + SdVolume* volume(void) const {return vol_;} + void write(uint8_t b); + int16_t write(const void* buf, uint16_t nbyte); + void write(const char* str); +// void write_P(PGM_P str); +// void writeln_P(PGM_P str); +//------------------------------------------------------------------------------ +#if ALLOW_DEPRECATED_FUNCTIONS +// Deprecated functions - suppress cpplint warnings with NOLINT comment + /** \deprecated Use: + * uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + */ + uint8_t contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT + return contiguousRange(&bgnBlock, &endBlock); + } + /** \deprecated Use: + * uint8_t SdFile::createContiguous(SdFile* dirFile, + * const char* fileName, uint32_t size) + */ + uint8_t createContiguous(SdFile& dirFile, // NOLINT + const char* fileName, uint32_t size) { + return createContiguous(&dirFile, fileName, size); + } + + /** + * \deprecated Use: + * static void SdFile::dateTimeCallback( + * void (*dateTime)(uint16_t* date, uint16_t* time)); + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT + oldDateTime_ = dateTime; + dateTime_ = dateTime ? oldToNew : 0; + } + /** \deprecated Use: uint8_t SdFile::dirEntry(dir_t* dir); */ + uint8_t dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT + /** \deprecated Use: + * uint8_t SdFile::makeDir(SdFile* dir, const char* dirName); + */ + uint8_t makeDir(SdFile& dir, const char* dirName) { // NOLINT + return makeDir(&dir, dirName); + } + /** \deprecated Use: + * uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag); + */ + uint8_t open(SdFile& dirFile, // NOLINT + const char* fileName, uint8_t oflag) { + return open(&dirFile, fileName, oflag); + } + /** \deprecated Do not use in new apps */ + uint8_t open(SdFile& dirFile, const char* fileName) { // NOLINT + return open(dirFile, fileName, O_RDWR); + } + /** \deprecated Use: + * uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag); + */ + uint8_t open(SdFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT + return open(&dirFile, index, oflag); + } + /** \deprecated Use: uint8_t SdFile::openRoot(SdVolume* vol); */ + uint8_t openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT + + /** \deprecated Use: int8_t SdFile::readDir(dir_t* dir); */ + int8_t readDir(dir_t& dir) {return readDir(&dir);} // NOLINT + /** \deprecated Use: + * static uint8_t SdFile::remove(SdFile* dirFile, const char* fileName); + */ + static uint8_t remove(SdFile& dirFile, const char* fileName) { // NOLINT + return remove(&dirFile, fileName); + } +//------------------------------------------------------------------------------ +// rest are private + private: + static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT + static void oldToNew(uint16_t* date, uint16_t* time) { + uint16_t d; + uint16_t t; + oldDateTime_(d, t); + *date = d; + *time = t; + } +#endif // ALLOW_DEPRECATED_FUNCTIONS + private: + // bits defined in flags_ + // should be 0XF + static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); + // available bits + static uint8_t const F_UNUSED = 0X30; + // use unbuffered SD read + static uint8_t const F_FILE_UNBUFFERED_READ = 0X40; + // sync of directory entry required + static uint8_t const F_FILE_DIR_DIRTY = 0X80; + +// make sure F_OFLAG is ok +//#if ((F_UNUSED | F_FILE_UNBUFFERED_READ | F_FILE_DIR_DIRTY) & F_OFLAG) +//#error flags_ bits conflict +//#endif // flags_ bits + + // private data + uint8_t flags_; // See above for definition of flags_ bits + uint8_t type_; // type of file see above for values + uint32_t curCluster_; // cluster for current file position + uint32_t curPosition_; // current file position in bytes from beginning + uint32_t dirBlock_; // SD block that contains directory entry for file + uint8_t dirIndex_; // index of entry in dirBlock 0 <= dirIndex_ <= 0XF + uint32_t fileSize_; // file size in bytes + uint32_t firstCluster_; // first cluster of file + SdVolume* vol_; // volume where file is located + + // private functions + uint8_t addCluster(void); + uint8_t addDirCluster(void); + dir_t* cacheDirEntry(uint8_t action); + static void (*dateTime_)(uint16_t* date, uint16_t* time); + static uint8_t make83Name(const char* str, uint8_t* name); + uint8_t openCachedEntry(uint8_t cacheIndex, uint8_t oflags); + dir_t* readDirCache(void); +}; +//============================================================================== +// SdVolume class +/** + * \brief Cache for an SD data block + */ +union cache_t { + /** Used to access cached file data blocks. */ + uint8_t data[512]; + /** Used to access cached FAT16 entries. */ + uint16_t fat16[256]; + /** Used to access cached FAT32 entries. */ + uint32_t fat32[128]; + /** Used to access cached directory entries. */ + dir_t dir[16]; + /** Used to access a cached MasterBoot Record. */ + mbr_t mbr; + /** Used to access to a cached FAT boot sector. */ + fbs_t fbs; +}; +//------------------------------------------------------------------------------ +/** + * \class SdVolume + * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. + */ +class SdVolume { + public: + /** Create an instance of SdVolume */ + SdVolume(void) :allocSearchStart_(2), fatType_(0) {} + /** Clear the cache and returns a pointer to the cache. Used by the WaveRP + * recorder to do raw write to the SD card. Not for normal apps. + */ + static uint8_t* cacheClear(void) { + cacheFlush(); + cacheBlockNumber_ = 0XFFFFFFFF; + return cacheBuffer_.data; + } + /** + * Initialize a FAT volume. Try partition one first then try super + * floppy format. + * + * \param[in] dev The Sd2Card where the volume is located. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system or an I/O error. + */ + uint8_t init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} + uint8_t init(Sd2Card* dev, uint8_t part); + + // inline functions that return volume info + /** \return The volume's cluster size in blocks. */ + uint8_t blocksPerCluster(void) const {return blocksPerCluster_;} + /** \return The number of blocks in one FAT. */ + uint32_t blocksPerFat(void) const {return blocksPerFat_;} + /** \return The total number of clusters in the volume. */ + uint32_t clusterCount(void) const {return clusterCount_;} + /** \return The shift count required to multiply by blocksPerCluster. */ + uint8_t clusterSizeShift(void) const {return clusterSizeShift_;} + /** \return The logical block number for the start of file data. */ + uint32_t dataStartBlock(void) const {return dataStartBlock_;} + /** \return The number of FAT structures on the volume. */ + uint8_t fatCount(void) const { return fatCount_;} + /** \return The logical block number for the start of the first FAT. */ + uint32_t fatStartBlock(void) const {return fatStartBlock_;} + /** \return The FAT type of the volume. Values are 12, 16 or 32. */ + uint8_t fatType(void) const {return fatType_;} + /** \return The number of entries in the root directory for FAT16 volumes. */ + uint32_t rootDirEntryCount(void) const {return rootDirEntryCount_;} + /** \return The logical block number for the start of the root directory + on FAT16 volumes or the first cluster number on FAT32 volumes. */ + uint32_t rootDirStart(void) const {return rootDirStart_;} + /** return a pointer to the Sd2Card object for this volume */ + static Sd2Card* sdCard(void) {return sdCard_;} +//------------------------------------------------------------------------------ +#if ALLOW_DEPRECATED_FUNCTIONS + // Deprecated functions - suppress cpplint warnings with NOLINT comment + /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev); */ + uint8_t init(Sd2Card& dev) {return init(&dev);} // NOLINT + + /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev, uint8_t vol); */ + uint8_t init(Sd2Card& dev, uint8_t part) { // NOLINT + return init(&dev, part); + } +#endif // ALLOW_DEPRECATED_FUNCTIONS +//------------------------------------------------------------------------------ + private: + // Allow SdFile access to SdVolume private data. + friend class SdFile; + + // value for action argument in cacheRawBlock to indicate read from cache + static uint8_t const CACHE_FOR_READ = 0; + // value for action argument in cacheRawBlock to indicate cache dirty + static uint8_t const CACHE_FOR_WRITE = 1; + + static cache_t cacheBuffer_; // 512 byte cache for device blocks + static uint32_t cacheBlockNumber_; // Logical number of block in the cache + static Sd2Card* sdCard_; // Sd2Card object for cache + static uint8_t cacheDirty_; // cacheFlush() will write block if true + static uint32_t cacheMirrorBlock_; // block number for mirror FAT +// + uint32_t allocSearchStart_; // start cluster for alloc search + uint8_t blocksPerCluster_; // cluster size in blocks + uint32_t blocksPerFat_; // FAT size in blocks + uint32_t clusterCount_; // clusters in one FAT + uint8_t clusterSizeShift_; // shift to convert cluster count to block count + uint32_t dataStartBlock_; // first data block number + uint8_t fatCount_; // number of FATs on volume + uint32_t fatStartBlock_; // start block for first FAT + uint8_t fatType_; // volume type (12, 16, OR 32) + uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir + uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 + //---------------------------------------------------------------------------- + uint8_t allocContiguous(uint32_t count, uint32_t* curCluster); + uint8_t blockOfCluster(uint32_t position) const { + return (position >> 9) & (blocksPerCluster_ - 1);} + uint32_t clusterStartBlock(uint32_t cluster) const { + return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);} + uint32_t blockNumber(uint32_t cluster, uint32_t position) const { + return clusterStartBlock(cluster) + blockOfCluster(position);} + static uint8_t cacheFlush(void); + static uint8_t cacheRawBlock(uint32_t blockNumber, uint8_t action); + static void cacheSetDirty(void) {cacheDirty_ |= CACHE_FOR_WRITE;} + static uint8_t cacheZeroBlock(uint32_t blockNumber); + uint8_t chainSize(uint32_t beginCluster, uint32_t* size) const; + uint8_t fatGet(uint32_t cluster, uint32_t* value) const; + uint8_t fatPut(uint32_t cluster, uint32_t value); + uint8_t fatPutEOC(uint32_t cluster) { + return fatPut(cluster, 0x0FFFFFFF); + } + uint8_t freeChain(uint32_t cluster); + uint8_t isEOC(uint32_t cluster) const { + return cluster >= (fatType_ == 16 ? FAT16EOC_MIN : FAT32EOC_MIN); + } + uint8_t readBlock(uint32_t block, uint8_t* dst) { + return sdCard_->readBlock(block, dst);} + uint8_t readData(uint32_t block, uint16_t offset, + uint16_t count, uint8_t* dst) { + return sdCard_->readData(block, offset, count, dst); + } + uint8_t writeBlock(uint32_t block, const uint8_t* dst) { + return sdCard_->writeBlock(block, dst); + } +}; +#endif // SdFat_h diff --git a/Libmaple/libmaple/libraries/mapleSDfat/SdFatUtil.h b/Libmaple/libmaple/libraries/mapleSDfat/SdFatUtil.h index cb2e7a0a..a4af739f 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/SdFatUtil.h +++ b/Libmaple/libmaple/libraries/mapleSDfat/SdFatUtil.h @@ -1,55 +1,55 @@ -/* Arduino SdFat Library - * Copyright (C) 2008 by William Greiman - * - * This file is part of the Arduino SdFat Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with the Arduino SdFat Library. If not, see - * . - */ -#ifndef SdFatUtil_h -#define SdFatUtil_h -/** - * \file - * Useful utility functions. - */ -#include -//#include -/** Store and print a string in flash memory.*/ -#define PgmPrint(x) SerialPrint_P(PSTR(x)) -/** Store and print a string in flash memory followed by a CR/LF.*/ -#define PgmPrintln(x) SerialPrintln_P(PSTR(x)) -/** Defined so doxygen works for function definitions. */ -#define NOINLINE __attribute__((noinline)) -//------------------------------------------------------------------------------ - -#if 0 -/** Return the number of bytes currently free in RAM. */ -static int FreeRam(void) { - extern int __bss_end; - extern int* __brkval; - int free_memory; - if (reinterpret_cast(__brkval) == 0) { - // if no heap use from end of bss section - free_memory = reinterpret_cast(&free_memory) - - reinterpret_cast(&__bss_end); - } else { - // use from top of stack to heap - free_memory = reinterpret_cast(&free_memory) - - reinterpret_cast(__brkval); - } - return free_memory; -} -#endif - -#endif // #define SdFatUtil_h +/* Arduino SdFat Library + * Copyright (C) 2008 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#ifndef SdFatUtil_h +#define SdFatUtil_h +/** + * \file + * Useful utility functions. + */ +#include +//#include +/** Store and print a string in flash memory.*/ +#define PgmPrint(x) SerialPrint_P(PSTR(x)) +/** Store and print a string in flash memory followed by a CR/LF.*/ +#define PgmPrintln(x) SerialPrintln_P(PSTR(x)) +/** Defined so doxygen works for function definitions. */ +#define NOINLINE __attribute__((noinline)) +//------------------------------------------------------------------------------ + +#if 0 +/** Return the number of bytes currently free in RAM. */ +static int FreeRam(void) { + extern int __bss_end; + extern int* __brkval; + int free_memory; + if (reinterpret_cast(__brkval) == 0) { + // if no heap use from end of bss section + free_memory = reinterpret_cast(&free_memory) + - reinterpret_cast(&__bss_end); + } else { + // use from top of stack to heap + free_memory = reinterpret_cast(&free_memory) + - reinterpret_cast(__brkval); + } + return free_memory; +} +#endif + +#endif // #define SdFatUtil_h diff --git a/Libmaple/libmaple/libraries/mapleSDfat/SdFatWorks.h b/Libmaple/libmaple/libraries/mapleSDfat/SdFatWorks.h index b865b0dc..b5424bb9 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/SdFatWorks.h +++ b/Libmaple/libmaple/libraries/mapleSDfat/SdFatWorks.h @@ -1,555 +1,555 @@ -/* Arduino SdFat Library - * Copyright (C) 2009 by William Greiman - * - * This file is part of the Arduino SdFat Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino SdFat Library. If not, see - * . - */ -#ifndef SdFat_h -#define SdFat_h -/** - * \file - * SdFile and SdVolume classes - */ -//#include -#include -#include "Sd2Card.h" -#include "FatStructs.h" -#include "Print.h" -//------------------------------------------------------------------------------ -/** - * Allow use of deprecated functions if non-zero - */ -#define ALLOW_DEPRECATED_FUNCTIONS 1 -//------------------------------------------------------------------------------ -// forward declaration since SdVolume is used in SdFile -class SdVolume; -//============================================================================== -// SdFile class - -// flags for ls() -/** ls() flag to print modify date */ -uint8_t const LS_DATE = 1; -/** ls() flag to print file size */ -uint8_t const LS_SIZE = 2; -/** ls() flag for recursive list of subdirectories */ -uint8_t const LS_R = 4; - -// use the gnu style oflag in open() -/** open() oflag for reading */ -uint8_t const O_READ = 0X01; -/** open() oflag - same as O_READ */ -uint8_t const O_RDONLY = O_READ; -/** open() oflag for write */ -uint8_t const O_WRITE = 0X02; -/** open() oflag - same as O_WRITE */ -uint8_t const O_WRONLY = O_WRITE; -/** open() oflag for reading and writing */ -uint8_t const O_RDWR = (O_READ | O_WRITE); -/** open() oflag mask for access modes */ -uint8_t const O_ACCMODE = (O_READ | O_WRITE); -/** The file offset shall be set to the end of the file prior to each write. */ -uint8_t const O_APPEND = 0X04; -/** synchronous writes - call sync() after each write */ -uint8_t const O_SYNC = 0X08; -/** create the file if nonexistent */ -uint8_t const O_CREAT = 0X10; -/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ -uint8_t const O_EXCL = 0X20; -/** truncate the file to zero length */ -uint8_t const O_TRUNC = 0X40; - -// flags for timestamp -/** set the file's last access date */ -uint8_t const T_ACCESS = 1; -/** set the file's creation date and time */ -uint8_t const T_CREATE = 2; -/** Set the file's write date and time */ -uint8_t const T_WRITE = 4; -// values for type_ -/** This SdFile has not been opened. */ -uint8_t const FAT_FILE_TYPE_CLOSED = 0; -/** SdFile for a file */ -uint8_t const FAT_FILE_TYPE_NORMAL = 1; -/** SdFile for a FAT16 root directory */ -uint8_t const FAT_FILE_TYPE_ROOT16 = 2; -/** SdFile for a FAT32 root directory */ -uint8_t const FAT_FILE_TYPE_ROOT32 = 3; -/** SdFile for a subdirectory */ -uint8_t const FAT_FILE_TYPE_SUBDIR = 4; -/** Test value for directory type */ -uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT16; - -/** date field for FAT directory entry */ -static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { - return (year - 1980) << 9 | month << 5 | day; -} -/** year part of FAT directory date field */ -static inline uint16_t FAT_YEAR(uint16_t fatDate) { - return 1980 + (fatDate >> 9); -} -/** month part of FAT directory date field */ -static inline uint8_t FAT_MONTH(uint16_t fatDate) { - return (fatDate >> 5) & 0XF; -} -/** day part of FAT directory date field */ -static inline uint8_t FAT_DAY(uint16_t fatDate) { - return fatDate & 0X1F; -} -/** time field for FAT directory entry */ -static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { - return hour << 11 | minute << 5 | second >> 1; -} -/** hour part of FAT directory time field */ -static inline uint8_t FAT_HOUR(uint16_t fatTime) { - return fatTime >> 11; -} -/** minute part of FAT directory time field */ -static inline uint8_t FAT_MINUTE(uint16_t fatTime) { - return(fatTime >> 5) & 0X3F; -} -/** second part of FAT directory time field */ -static inline uint8_t FAT_SECOND(uint16_t fatTime) { - return 2*(fatTime & 0X1F); -} -/** Default date for file timestamps is 1 Jan 2000 */ -uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; -/** Default time for file timestamp is 1 am */ -uint16_t const FAT_DEFAULT_TIME = (1 << 11); -//------------------------------------------------------------------------------ -/** - * \class SdFile - * \brief Access FAT16 and FAT32 files on SD and SDHC cards. - */ -class SdFile : public Print { - public: - /** Create an instance of SdFile. */ - SdFile(void) : type_(FAT_FILE_TYPE_CLOSED) {} - /** - * writeError is set to true if an error occurs during a write(). - * Set writeError to false before calling print() and/or write() and check - * for true after calls to print() and/or write(). - */ - bool writeError; - /** - * Cancel unbuffered reads for this file. - * See setUnbufferedRead() - */ - void clearUnbufferedRead(void) { - flags_ &= ~F_FILE_UNBUFFERED_READ; - } - uint8_t close(void); - uint8_t contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); - uint8_t createContiguous(SdFile* dirFile, - const char* fileName, uint32_t size); - /** \return The current cluster number for a file or directory. */ - uint32_t curCluster(void) const {return curCluster_;} - /** \return The current position for a file or directory. */ - uint32_t curPosition(void) const {return curPosition_;} - /** - * Set the date/time callback function - * - * \param[in] dateTime The user's call back function. The callback - * function is of the form: - * - * \code - * void dateTime(uint16_t* date, uint16_t* time) { - * uint16_t year; - * uint8_t month, day, hour, minute, second; - * - * // User gets date and time from GPS or real-time clock here - * - * // return date using FAT_DATE macro to format fields - * *date = FAT_DATE(year, month, day); - * - * // return time using FAT_TIME macro to format fields - * *time = FAT_TIME(hour, minute, second); - * } - * \endcode - * - * Sets the function that is called when a file is created or when - * a file's directory entry is modified by sync(). All timestamps, - * access, creation, and modify, are set when a file is created. - * sync() maintains the last access date and last modify date/time. - * - * See the timestamp() function. - */ - static void dateTimeCallback( - void (*dateTime)(uint16_t* date, uint16_t* time)) { - dateTime_ = dateTime; - } - /** - * Cancel the date/time callback function. - */ - static void dateTimeCallbackCancel(void) { - // use explicit zero since NULL is not defined for Sanguino - dateTime_ = 0; - } - /** \return Address of the block that contains this file's directory. */ - uint32_t dirBlock(void) const {return dirBlock_;} - uint8_t dirEntry(dir_t* dir); - /** \return Index of this file's directory in the block dirBlock. */ - uint8_t dirIndex(void) const {return dirIndex_;} - static void dirName(const dir_t& dir, char* name); - /** \return The total number of bytes in a file or directory. */ - uint32_t fileSize(void) const {return fileSize_;} - /** \return The first cluster number for a file or directory. */ - uint32_t firstCluster(void) const {return firstCluster_;} - /** \return True if this is a SdFile for a directory else false. */ - uint8_t isDir(void) const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} - /** \return True if this is a SdFile for a file else false. */ - uint8_t isFile(void) const {return type_ == FAT_FILE_TYPE_NORMAL;} - /** \return True if this is a SdFile for an open file/directory else false. */ - uint8_t isOpen(void) const {return type_ != FAT_FILE_TYPE_CLOSED;} - /** \return True if this is a SdFile for a subdirectory else false. */ - uint8_t isSubDir(void) const {return type_ == FAT_FILE_TYPE_SUBDIR;} - /** \return True if this is a SdFile for the root directory. */ - uint8_t isRoot(void) const { - return type_ == FAT_FILE_TYPE_ROOT16 || type_ == FAT_FILE_TYPE_ROOT32; - } - void ls(uint8_t flags = 0, uint8_t indent = 0); - uint8_t makeDir(SdFile* dir, const char* dirName); - uint8_t open(SdFile* dirFile, uint16_t index, uint8_t oflag); - uint8_t open(SdFile* dirFile, const char* fileName, uint8_t oflag); - - uint8_t openRoot(SdVolume* vol); - static void printDirName(const dir_t& dir, uint8_t width); - static void printFatDate(uint16_t fatDate); - static void printFatTime(uint16_t fatTime); - static void printTwoDigits(uint8_t v); - /** - * Read the next byte from a file. - * - * \return For success read returns the next byte in the file as an int. - * If an error occurs or end of file is reached -1 is returned. - */ - int16_t read(void) { - uint8_t b; - return read(&b, 1) == 1 ? b : -1; - } - int16_t read(void* buf, uint16_t nbyte); - int8_t readDir(dir_t* dir); - static uint8_t remove(SdFile* dirFile, const char* fileName); - uint8_t remove(void); - /** Set the file's current position to zero. */ - void rewind(void) { - curPosition_ = curCluster_ = 0; - } - uint8_t rmDir(void); - uint8_t rmRfStar(void); - /** Set the files position to current position + \a pos. See seekSet(). */ - uint8_t seekCur(uint32_t pos) { - return seekSet(curPosition_ + pos); - } - /** - * Set the files current position to end of file. Useful to position - * a file for append. See seekSet(). - */ - uint8_t seekEnd(void) {return seekSet(fileSize_);} - uint8_t seekSet(uint32_t pos); - /** - * Use unbuffered reads to access this file. Used with Wave - * Shield ISR. Used with Sd2Card::partialBlockRead() in WaveRP. - * - * Not recommended for normal applications. - */ - void setUnbufferedRead(void) { - if (isFile()) flags_ |= F_FILE_UNBUFFERED_READ; - } - uint8_t timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, - uint8_t hour, uint8_t minute, uint8_t second); - uint8_t sync(void); - /** Type of this SdFile. You should use isFile() or isDir() instead of type() - * if possible. - * - * \return The file or directory type. - */ - uint8_t type(void) const {return type_;} - uint8_t truncate(uint32_t size); - /** \return Unbuffered read flag. */ - uint8_t unbufferedRead(void) const { - return flags_ & F_FILE_UNBUFFERED_READ; - } - /** \return SdVolume that contains this file. */ - SdVolume* volume(void) const {return vol_;} - void write(uint8_t b); - int16_t write(const void* buf, uint16_t nbyte); - void write(const char* str); -// void write_P(PGM_P str); -// void writeln_P(PGM_P str); -//------------------------------------------------------------------------------ -#if ALLOW_DEPRECATED_FUNCTIONS -// Deprecated functions - suppress cpplint warnings with NOLINT comment - /** \deprecated Use: - * uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); - */ - uint8_t contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT - return contiguousRange(&bgnBlock, &endBlock); - } - /** \deprecated Use: - * uint8_t SdFile::createContiguous(SdFile* dirFile, - * const char* fileName, uint32_t size) - */ - uint8_t createContiguous(SdFile& dirFile, // NOLINT - const char* fileName, uint32_t size) { - return createContiguous(&dirFile, fileName, size); - } - - /** - * \deprecated Use: - * static void SdFile::dateTimeCallback( - * void (*dateTime)(uint16_t* date, uint16_t* time)); - */ - static void dateTimeCallback( - void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT - oldDateTime_ = dateTime; - dateTime_ = dateTime ? oldToNew : 0; - } - /** \deprecated Use: uint8_t SdFile::dirEntry(dir_t* dir); */ - uint8_t dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT - /** \deprecated Use: - * uint8_t SdFile::makeDir(SdFile* dir, const char* dirName); - */ - uint8_t makeDir(SdFile& dir, const char* dirName) { // NOLINT - return makeDir(&dir, dirName); - } - /** \deprecated Use: - * uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag); - */ - uint8_t open(SdFile& dirFile, // NOLINT - const char* fileName, uint8_t oflag) { - return open(&dirFile, fileName, oflag); - } - /** \deprecated Do not use in new apps */ - uint8_t open(SdFile& dirFile, const char* fileName) { // NOLINT - return open(dirFile, fileName, O_RDWR); - } - /** \deprecated Use: - * uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag); - */ - uint8_t open(SdFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT - return open(&dirFile, index, oflag); - } - /** \deprecated Use: uint8_t SdFile::openRoot(SdVolume* vol); */ - uint8_t openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT - - /** \deprecated Use: int8_t SdFile::readDir(dir_t* dir); */ - int8_t readDir(dir_t& dir) {return readDir(&dir);} // NOLINT - /** \deprecated Use: - * static uint8_t SdFile::remove(SdFile* dirFile, const char* fileName); - */ - static uint8_t remove(SdFile& dirFile, const char* fileName) { // NOLINT - return remove(&dirFile, fileName); - } -//------------------------------------------------------------------------------ -// rest are private - private: - static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT - static void oldToNew(uint16_t* date, uint16_t* time) { - uint16_t d; - uint16_t t; - oldDateTime_(d, t); - *date = d; - *time = t; - } -#endif // ALLOW_DEPRECATED_FUNCTIONS - private: - // bits defined in flags_ - // should be 0XF - static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); - // available bits - static uint8_t const F_UNUSED = 0X30; - // use unbuffered SD read - static uint8_t const F_FILE_UNBUFFERED_READ = 0X40; - // sync of directory entry required - static uint8_t const F_FILE_DIR_DIRTY = 0X80; - -// make sure F_OFLAG is ok -#if ((F_UNUSED | F_FILE_UNBUFFERED_READ | F_FILE_DIR_DIRTY) & F_OFLAG) -#error flags_ bits conflict -#endif // flags_ bits - - // private data - uint8_t flags_; // See above for definition of flags_ bits - uint8_t type_; // type of file see above for values - uint32_t curCluster_; // cluster for current file position - uint32_t curPosition_; // current file position in bytes from beginning - uint32_t dirBlock_; // SD block that contains directory entry for file - uint8_t dirIndex_; // index of entry in dirBlock 0 <= dirIndex_ <= 0XF - uint32_t fileSize_; // file size in bytes - uint32_t firstCluster_; // first cluster of file - SdVolume* vol_; // volume where file is located - - // private functions - uint8_t addCluster(void); - uint8_t addDirCluster(void); - dir_t* cacheDirEntry(uint8_t action); - static void (*dateTime_)(uint16_t* date, uint16_t* time); - static uint8_t make83Name(const char* str, uint8_t* name); - uint8_t openCachedEntry(uint8_t cacheIndex, uint8_t oflags); - dir_t* readDirCache(void); -}; -//============================================================================== -// SdVolume class -/** - * \brief Cache for an SD data block - */ -union cache_t { - /** Used to access cached file data blocks. */ - uint8_t data[512]; - /** Used to access cached FAT16 entries. */ - uint16_t fat16[256]; - /** Used to access cached FAT32 entries. */ - uint32_t fat32[128]; - /** Used to access cached directory entries. */ - dir_t dir[16]; - /** Used to access a cached MasterBoot Record. */ - mbr_t mbr; - /** Used to access to a cached FAT boot sector. */ - fbs_t fbs; -}; -//------------------------------------------------------------------------------ -/** - * \class SdVolume - * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. - */ -class SdVolume { - public: - /** Create an instance of SdVolume */ - SdVolume(void) :allocSearchStart_(2), fatType_(0) {} - /** Clear the cache and returns a pointer to the cache. Used by the WaveRP - * recorder to do raw write to the SD card. Not for normal apps. - */ - static uint8_t* cacheClear(void) { - cacheFlush(); - cacheBlockNumber_ = 0XFFFFFFFF; - return cacheBuffer_.data; - } - /** - * Initialize a FAT volume. Try partition one first then try super - * floppy format. - * - * \param[in] dev The Sd2Card where the volume is located. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. Reasons for - * failure include not finding a valid partition, not finding a valid - * FAT file system or an I/O error. - */ - uint8_t init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} - uint8_t init(Sd2Card* dev, uint8_t part); - - // inline functions that return volume info - /** \return The volume's cluster size in blocks. */ - uint8_t blocksPerCluster(void) const {return blocksPerCluster_;} - /** \return The number of blocks in one FAT. */ - uint32_t blocksPerFat(void) const {return blocksPerFat_;} - /** \return The total number of clusters in the volume. */ - uint32_t clusterCount(void) const {return clusterCount_;} - /** \return The shift count required to multiply by blocksPerCluster. */ - uint8_t clusterSizeShift(void) const {return clusterSizeShift_;} - /** \return The logical block number for the start of file data. */ - uint32_t dataStartBlock(void) const {return dataStartBlock_;} - /** \return The number of FAT structures on the volume. */ - uint8_t fatCount(void) /*const*/ { - - SerialDebug.print("#fatCount_ "); - SerialDebug.print((int)&fatCount_); - SerialDebug.print(" # "); - SerialDebug.print((int)fatCount_); - SerialDebug.print("#"); - return fatCount_;} - /** \return The logical block number for the start of the first FAT. */ - uint32_t fatStartBlock(void) const {return fatStartBlock_;} - /** \return The FAT type of the volume. Values are 12, 16 or 32. */ - uint8_t fatType(void) const {return fatType_;} - /** \return The number of entries in the root directory for FAT16 volumes. */ - uint32_t rootDirEntryCount(void) const {return rootDirEntryCount_;} - /** \return The logical block number for the start of the root directory - on FAT16 volumes or the first cluster number on FAT32 volumes. */ - uint32_t rootDirStart(void) const {return rootDirStart_;} - /** return a pointer to the Sd2Card object for this volume */ - static Sd2Card* sdCard(void) {return sdCard_;} -//------------------------------------------------------------------------------ -#if ALLOW_DEPRECATED_FUNCTIONS - // Deprecated functions - suppress cpplint warnings with NOLINT comment - /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev); */ - uint8_t init(Sd2Card& dev) {return init(&dev);} // NOLINT - - /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev, uint8_t vol); */ - uint8_t init(Sd2Card& dev, uint8_t part) { // NOLINT - return init(&dev, part); - } -#endif // ALLOW_DEPRECATED_FUNCTIONS -//------------------------------------------------------------------------------ - private: - // Allow SdFile access to SdVolume private data. - friend class SdFile; - - // value for action argument in cacheRawBlock to indicate read from cache - static uint8_t const CACHE_FOR_READ = 0; - // value for action argument in cacheRawBlock to indicate cache dirty - static uint8_t const CACHE_FOR_WRITE = 1; - - static cache_t cacheBuffer_; // 512 byte cache for device blocks - static uint32_t cacheBlockNumber_; // Logical number of block in the cache - static Sd2Card* sdCard_; // Sd2Card object for cache - static uint8_t cacheDirty_; // cacheFlush() will write block if true - static uint32_t cacheMirrorBlock_; // block number for mirror FAT -// - uint32_t allocSearchStart_; // start cluster for alloc search - uint32_t blocksPerFat_; // FAT size in blocks - uint32_t clusterCount_; // clusters in one FAT - uint32_t dataStartBlock_; // first data block number - uint32_t fatStartBlock_; // start block for first FAT - uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 - uint8_t fatCount_; // number of FATs on volume - uint8_t fatType_; // volume type (12, 16, OR 32) - uint8_t blocksPerCluster_; // cluster size in blocks - uint8_t clusterSizeShift_; // shift to convert cluster count to block count - uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir - //---------------------------------------------------------------------------- - uint8_t allocContiguous(uint32_t count, uint32_t* curCluster); - uint8_t blockOfCluster(uint32_t position) const { - return (position >> 9) & (blocksPerCluster_ - 1);} - uint32_t clusterStartBlock(uint32_t cluster) const { - return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);} - uint32_t blockNumber(uint32_t cluster, uint32_t position) const { - return clusterStartBlock(cluster) + blockOfCluster(position);} - static uint8_t cacheFlush(void); - static uint8_t cacheRawBlock(uint32_t blockNumber, uint8_t action); - static void cacheSetDirty(void) {cacheDirty_ |= CACHE_FOR_WRITE;} - static uint8_t cacheZeroBlock(uint32_t blockNumber); - uint8_t chainSize(uint32_t beginCluster, uint32_t* size) const; - uint8_t fatGet(uint32_t cluster, uint32_t* value) const; - uint8_t fatPut(uint32_t cluster, uint32_t value); - uint8_t fatPutEOC(uint32_t cluster) { - return fatPut(cluster, 0x0FFFFFFF); - } - uint8_t freeChain(uint32_t cluster); - uint8_t isEOC(uint32_t cluster) const { - return cluster >= (fatType_ == 16 ? FAT16EOC_MIN : FAT32EOC_MIN); - } - uint8_t readBlock(uint32_t block, uint8_t* dst) { - return sdCard_->readBlock(block, dst);} - uint8_t readData(uint32_t block, uint16_t offset, - uint16_t count, uint8_t* dst) { - return sdCard_->readData(block, offset, count, dst); - } - uint8_t writeBlock(uint32_t block, const uint8_t* dst) { - return sdCard_->writeBlock(block, dst); - } -}; -#endif // SdFat_h +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#ifndef SdFat_h +#define SdFat_h +/** + * \file + * SdFile and SdVolume classes + */ +//#include +#include +#include "Sd2Card.h" +#include "FatStructs.h" +#include "Print.h" +//------------------------------------------------------------------------------ +/** + * Allow use of deprecated functions if non-zero + */ +#define ALLOW_DEPRECATED_FUNCTIONS 1 +//------------------------------------------------------------------------------ +// forward declaration since SdVolume is used in SdFile +class SdVolume; +//============================================================================== +// SdFile class + +// flags for ls() +/** ls() flag to print modify date */ +uint8_t const LS_DATE = 1; +/** ls() flag to print file size */ +uint8_t const LS_SIZE = 2; +/** ls() flag for recursive list of subdirectories */ +uint8_t const LS_R = 4; + +// use the gnu style oflag in open() +/** open() oflag for reading */ +uint8_t const O_READ = 0X01; +/** open() oflag - same as O_READ */ +uint8_t const O_RDONLY = O_READ; +/** open() oflag for write */ +uint8_t const O_WRITE = 0X02; +/** open() oflag - same as O_WRITE */ +uint8_t const O_WRONLY = O_WRITE; +/** open() oflag for reading and writing */ +uint8_t const O_RDWR = (O_READ | O_WRITE); +/** open() oflag mask for access modes */ +uint8_t const O_ACCMODE = (O_READ | O_WRITE); +/** The file offset shall be set to the end of the file prior to each write. */ +uint8_t const O_APPEND = 0X04; +/** synchronous writes - call sync() after each write */ +uint8_t const O_SYNC = 0X08; +/** create the file if nonexistent */ +uint8_t const O_CREAT = 0X10; +/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ +uint8_t const O_EXCL = 0X20; +/** truncate the file to zero length */ +uint8_t const O_TRUNC = 0X40; + +// flags for timestamp +/** set the file's last access date */ +uint8_t const T_ACCESS = 1; +/** set the file's creation date and time */ +uint8_t const T_CREATE = 2; +/** Set the file's write date and time */ +uint8_t const T_WRITE = 4; +// values for type_ +/** This SdFile has not been opened. */ +uint8_t const FAT_FILE_TYPE_CLOSED = 0; +/** SdFile for a file */ +uint8_t const FAT_FILE_TYPE_NORMAL = 1; +/** SdFile for a FAT16 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT16 = 2; +/** SdFile for a FAT32 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT32 = 3; +/** SdFile for a subdirectory */ +uint8_t const FAT_FILE_TYPE_SUBDIR = 4; +/** Test value for directory type */ +uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT16; + +/** date field for FAT directory entry */ +static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { + return (year - 1980) << 9 | month << 5 | day; +} +/** year part of FAT directory date field */ +static inline uint16_t FAT_YEAR(uint16_t fatDate) { + return 1980 + (fatDate >> 9); +} +/** month part of FAT directory date field */ +static inline uint8_t FAT_MONTH(uint16_t fatDate) { + return (fatDate >> 5) & 0XF; +} +/** day part of FAT directory date field */ +static inline uint8_t FAT_DAY(uint16_t fatDate) { + return fatDate & 0X1F; +} +/** time field for FAT directory entry */ +static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { + return hour << 11 | minute << 5 | second >> 1; +} +/** hour part of FAT directory time field */ +static inline uint8_t FAT_HOUR(uint16_t fatTime) { + return fatTime >> 11; +} +/** minute part of FAT directory time field */ +static inline uint8_t FAT_MINUTE(uint16_t fatTime) { + return(fatTime >> 5) & 0X3F; +} +/** second part of FAT directory time field */ +static inline uint8_t FAT_SECOND(uint16_t fatTime) { + return 2*(fatTime & 0X1F); +} +/** Default date for file timestamps is 1 Jan 2000 */ +uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; +/** Default time for file timestamp is 1 am */ +uint16_t const FAT_DEFAULT_TIME = (1 << 11); +//------------------------------------------------------------------------------ +/** + * \class SdFile + * \brief Access FAT16 and FAT32 files on SD and SDHC cards. + */ +class SdFile : public Print { + public: + /** Create an instance of SdFile. */ + SdFile(void) : type_(FAT_FILE_TYPE_CLOSED) {} + /** + * writeError is set to true if an error occurs during a write(). + * Set writeError to false before calling print() and/or write() and check + * for true after calls to print() and/or write(). + */ + bool writeError; + /** + * Cancel unbuffered reads for this file. + * See setUnbufferedRead() + */ + void clearUnbufferedRead(void) { + flags_ &= ~F_FILE_UNBUFFERED_READ; + } + uint8_t close(void); + uint8_t contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + uint8_t createContiguous(SdFile* dirFile, + const char* fileName, uint32_t size); + /** \return The current cluster number for a file or directory. */ + uint32_t curCluster(void) const {return curCluster_;} + /** \return The current position for a file or directory. */ + uint32_t curPosition(void) const {return curPosition_;} + /** + * Set the date/time callback function + * + * \param[in] dateTime The user's call back function. The callback + * function is of the form: + * + * \code + * void dateTime(uint16_t* date, uint16_t* time) { + * uint16_t year; + * uint8_t month, day, hour, minute, second; + * + * // User gets date and time from GPS or real-time clock here + * + * // return date using FAT_DATE macro to format fields + * *date = FAT_DATE(year, month, day); + * + * // return time using FAT_TIME macro to format fields + * *time = FAT_TIME(hour, minute, second); + * } + * \endcode + * + * Sets the function that is called when a file is created or when + * a file's directory entry is modified by sync(). All timestamps, + * access, creation, and modify, are set when a file is created. + * sync() maintains the last access date and last modify date/time. + * + * See the timestamp() function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t* date, uint16_t* time)) { + dateTime_ = dateTime; + } + /** + * Cancel the date/time callback function. + */ + static void dateTimeCallbackCancel(void) { + // use explicit zero since NULL is not defined for Sanguino + dateTime_ = 0; + } + /** \return Address of the block that contains this file's directory. */ + uint32_t dirBlock(void) const {return dirBlock_;} + uint8_t dirEntry(dir_t* dir); + /** \return Index of this file's directory in the block dirBlock. */ + uint8_t dirIndex(void) const {return dirIndex_;} + static void dirName(const dir_t& dir, char* name); + /** \return The total number of bytes in a file or directory. */ + uint32_t fileSize(void) const {return fileSize_;} + /** \return The first cluster number for a file or directory. */ + uint32_t firstCluster(void) const {return firstCluster_;} + /** \return True if this is a SdFile for a directory else false. */ + uint8_t isDir(void) const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} + /** \return True if this is a SdFile for a file else false. */ + uint8_t isFile(void) const {return type_ == FAT_FILE_TYPE_NORMAL;} + /** \return True if this is a SdFile for an open file/directory else false. */ + uint8_t isOpen(void) const {return type_ != FAT_FILE_TYPE_CLOSED;} + /** \return True if this is a SdFile for a subdirectory else false. */ + uint8_t isSubDir(void) const {return type_ == FAT_FILE_TYPE_SUBDIR;} + /** \return True if this is a SdFile for the root directory. */ + uint8_t isRoot(void) const { + return type_ == FAT_FILE_TYPE_ROOT16 || type_ == FAT_FILE_TYPE_ROOT32; + } + void ls(uint8_t flags = 0, uint8_t indent = 0); + uint8_t makeDir(SdFile* dir, const char* dirName); + uint8_t open(SdFile* dirFile, uint16_t index, uint8_t oflag); + uint8_t open(SdFile* dirFile, const char* fileName, uint8_t oflag); + + uint8_t openRoot(SdVolume* vol); + static void printDirName(const dir_t& dir, uint8_t width); + static void printFatDate(uint16_t fatDate); + static void printFatTime(uint16_t fatTime); + static void printTwoDigits(uint8_t v); + /** + * Read the next byte from a file. + * + * \return For success read returns the next byte in the file as an int. + * If an error occurs or end of file is reached -1 is returned. + */ + int16_t read(void) { + uint8_t b; + return read(&b, 1) == 1 ? b : -1; + } + int16_t read(void* buf, uint16_t nbyte); + int8_t readDir(dir_t* dir); + static uint8_t remove(SdFile* dirFile, const char* fileName); + uint8_t remove(void); + /** Set the file's current position to zero. */ + void rewind(void) { + curPosition_ = curCluster_ = 0; + } + uint8_t rmDir(void); + uint8_t rmRfStar(void); + /** Set the files position to current position + \a pos. See seekSet(). */ + uint8_t seekCur(uint32_t pos) { + return seekSet(curPosition_ + pos); + } + /** + * Set the files current position to end of file. Useful to position + * a file for append. See seekSet(). + */ + uint8_t seekEnd(void) {return seekSet(fileSize_);} + uint8_t seekSet(uint32_t pos); + /** + * Use unbuffered reads to access this file. Used with Wave + * Shield ISR. Used with Sd2Card::partialBlockRead() in WaveRP. + * + * Not recommended for normal applications. + */ + void setUnbufferedRead(void) { + if (isFile()) flags_ |= F_FILE_UNBUFFERED_READ; + } + uint8_t timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, + uint8_t hour, uint8_t minute, uint8_t second); + uint8_t sync(void); + /** Type of this SdFile. You should use isFile() or isDir() instead of type() + * if possible. + * + * \return The file or directory type. + */ + uint8_t type(void) const {return type_;} + uint8_t truncate(uint32_t size); + /** \return Unbuffered read flag. */ + uint8_t unbufferedRead(void) const { + return flags_ & F_FILE_UNBUFFERED_READ; + } + /** \return SdVolume that contains this file. */ + SdVolume* volume(void) const {return vol_;} + void write(uint8_t b); + int16_t write(const void* buf, uint16_t nbyte); + void write(const char* str); +// void write_P(PGM_P str); +// void writeln_P(PGM_P str); +//------------------------------------------------------------------------------ +#if ALLOW_DEPRECATED_FUNCTIONS +// Deprecated functions - suppress cpplint warnings with NOLINT comment + /** \deprecated Use: + * uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + */ + uint8_t contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT + return contiguousRange(&bgnBlock, &endBlock); + } + /** \deprecated Use: + * uint8_t SdFile::createContiguous(SdFile* dirFile, + * const char* fileName, uint32_t size) + */ + uint8_t createContiguous(SdFile& dirFile, // NOLINT + const char* fileName, uint32_t size) { + return createContiguous(&dirFile, fileName, size); + } + + /** + * \deprecated Use: + * static void SdFile::dateTimeCallback( + * void (*dateTime)(uint16_t* date, uint16_t* time)); + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT + oldDateTime_ = dateTime; + dateTime_ = dateTime ? oldToNew : 0; + } + /** \deprecated Use: uint8_t SdFile::dirEntry(dir_t* dir); */ + uint8_t dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT + /** \deprecated Use: + * uint8_t SdFile::makeDir(SdFile* dir, const char* dirName); + */ + uint8_t makeDir(SdFile& dir, const char* dirName) { // NOLINT + return makeDir(&dir, dirName); + } + /** \deprecated Use: + * uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag); + */ + uint8_t open(SdFile& dirFile, // NOLINT + const char* fileName, uint8_t oflag) { + return open(&dirFile, fileName, oflag); + } + /** \deprecated Do not use in new apps */ + uint8_t open(SdFile& dirFile, const char* fileName) { // NOLINT + return open(dirFile, fileName, O_RDWR); + } + /** \deprecated Use: + * uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag); + */ + uint8_t open(SdFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT + return open(&dirFile, index, oflag); + } + /** \deprecated Use: uint8_t SdFile::openRoot(SdVolume* vol); */ + uint8_t openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT + + /** \deprecated Use: int8_t SdFile::readDir(dir_t* dir); */ + int8_t readDir(dir_t& dir) {return readDir(&dir);} // NOLINT + /** \deprecated Use: + * static uint8_t SdFile::remove(SdFile* dirFile, const char* fileName); + */ + static uint8_t remove(SdFile& dirFile, const char* fileName) { // NOLINT + return remove(&dirFile, fileName); + } +//------------------------------------------------------------------------------ +// rest are private + private: + static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT + static void oldToNew(uint16_t* date, uint16_t* time) { + uint16_t d; + uint16_t t; + oldDateTime_(d, t); + *date = d; + *time = t; + } +#endif // ALLOW_DEPRECATED_FUNCTIONS + private: + // bits defined in flags_ + // should be 0XF + static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); + // available bits + static uint8_t const F_UNUSED = 0X30; + // use unbuffered SD read + static uint8_t const F_FILE_UNBUFFERED_READ = 0X40; + // sync of directory entry required + static uint8_t const F_FILE_DIR_DIRTY = 0X80; + +// make sure F_OFLAG is ok +#if ((F_UNUSED | F_FILE_UNBUFFERED_READ | F_FILE_DIR_DIRTY) & F_OFLAG) +#error flags_ bits conflict +#endif // flags_ bits + + // private data + uint8_t flags_; // See above for definition of flags_ bits + uint8_t type_; // type of file see above for values + uint32_t curCluster_; // cluster for current file position + uint32_t curPosition_; // current file position in bytes from beginning + uint32_t dirBlock_; // SD block that contains directory entry for file + uint8_t dirIndex_; // index of entry in dirBlock 0 <= dirIndex_ <= 0XF + uint32_t fileSize_; // file size in bytes + uint32_t firstCluster_; // first cluster of file + SdVolume* vol_; // volume where file is located + + // private functions + uint8_t addCluster(void); + uint8_t addDirCluster(void); + dir_t* cacheDirEntry(uint8_t action); + static void (*dateTime_)(uint16_t* date, uint16_t* time); + static uint8_t make83Name(const char* str, uint8_t* name); + uint8_t openCachedEntry(uint8_t cacheIndex, uint8_t oflags); + dir_t* readDirCache(void); +}; +//============================================================================== +// SdVolume class +/** + * \brief Cache for an SD data block + */ +union cache_t { + /** Used to access cached file data blocks. */ + uint8_t data[512]; + /** Used to access cached FAT16 entries. */ + uint16_t fat16[256]; + /** Used to access cached FAT32 entries. */ + uint32_t fat32[128]; + /** Used to access cached directory entries. */ + dir_t dir[16]; + /** Used to access a cached MasterBoot Record. */ + mbr_t mbr; + /** Used to access to a cached FAT boot sector. */ + fbs_t fbs; +}; +//------------------------------------------------------------------------------ +/** + * \class SdVolume + * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. + */ +class SdVolume { + public: + /** Create an instance of SdVolume */ + SdVolume(void) :allocSearchStart_(2), fatType_(0) {} + /** Clear the cache and returns a pointer to the cache. Used by the WaveRP + * recorder to do raw write to the SD card. Not for normal apps. + */ + static uint8_t* cacheClear(void) { + cacheFlush(); + cacheBlockNumber_ = 0XFFFFFFFF; + return cacheBuffer_.data; + } + /** + * Initialize a FAT volume. Try partition one first then try super + * floppy format. + * + * \param[in] dev The Sd2Card where the volume is located. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system or an I/O error. + */ + uint8_t init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} + uint8_t init(Sd2Card* dev, uint8_t part); + + // inline functions that return volume info + /** \return The volume's cluster size in blocks. */ + uint8_t blocksPerCluster(void) const {return blocksPerCluster_;} + /** \return The number of blocks in one FAT. */ + uint32_t blocksPerFat(void) const {return blocksPerFat_;} + /** \return The total number of clusters in the volume. */ + uint32_t clusterCount(void) const {return clusterCount_;} + /** \return The shift count required to multiply by blocksPerCluster. */ + uint8_t clusterSizeShift(void) const {return clusterSizeShift_;} + /** \return The logical block number for the start of file data. */ + uint32_t dataStartBlock(void) const {return dataStartBlock_;} + /** \return The number of FAT structures on the volume. */ + uint8_t fatCount(void) /*const*/ { + + SerialDebug.print("#fatCount_ "); + SerialDebug.print((int)&fatCount_); + SerialDebug.print(" # "); + SerialDebug.print((int)fatCount_); + SerialDebug.print("#"); + return fatCount_;} + /** \return The logical block number for the start of the first FAT. */ + uint32_t fatStartBlock(void) const {return fatStartBlock_;} + /** \return The FAT type of the volume. Values are 12, 16 or 32. */ + uint8_t fatType(void) const {return fatType_;} + /** \return The number of entries in the root directory for FAT16 volumes. */ + uint32_t rootDirEntryCount(void) const {return rootDirEntryCount_;} + /** \return The logical block number for the start of the root directory + on FAT16 volumes or the first cluster number on FAT32 volumes. */ + uint32_t rootDirStart(void) const {return rootDirStart_;} + /** return a pointer to the Sd2Card object for this volume */ + static Sd2Card* sdCard(void) {return sdCard_;} +//------------------------------------------------------------------------------ +#if ALLOW_DEPRECATED_FUNCTIONS + // Deprecated functions - suppress cpplint warnings with NOLINT comment + /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev); */ + uint8_t init(Sd2Card& dev) {return init(&dev);} // NOLINT + + /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev, uint8_t vol); */ + uint8_t init(Sd2Card& dev, uint8_t part) { // NOLINT + return init(&dev, part); + } +#endif // ALLOW_DEPRECATED_FUNCTIONS +//------------------------------------------------------------------------------ + private: + // Allow SdFile access to SdVolume private data. + friend class SdFile; + + // value for action argument in cacheRawBlock to indicate read from cache + static uint8_t const CACHE_FOR_READ = 0; + // value for action argument in cacheRawBlock to indicate cache dirty + static uint8_t const CACHE_FOR_WRITE = 1; + + static cache_t cacheBuffer_; // 512 byte cache for device blocks + static uint32_t cacheBlockNumber_; // Logical number of block in the cache + static Sd2Card* sdCard_; // Sd2Card object for cache + static uint8_t cacheDirty_; // cacheFlush() will write block if true + static uint32_t cacheMirrorBlock_; // block number for mirror FAT +// + uint32_t allocSearchStart_; // start cluster for alloc search + uint32_t blocksPerFat_; // FAT size in blocks + uint32_t clusterCount_; // clusters in one FAT + uint32_t dataStartBlock_; // first data block number + uint32_t fatStartBlock_; // start block for first FAT + uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 + uint8_t fatCount_; // number of FATs on volume + uint8_t fatType_; // volume type (12, 16, OR 32) + uint8_t blocksPerCluster_; // cluster size in blocks + uint8_t clusterSizeShift_; // shift to convert cluster count to block count + uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir + //---------------------------------------------------------------------------- + uint8_t allocContiguous(uint32_t count, uint32_t* curCluster); + uint8_t blockOfCluster(uint32_t position) const { + return (position >> 9) & (blocksPerCluster_ - 1);} + uint32_t clusterStartBlock(uint32_t cluster) const { + return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);} + uint32_t blockNumber(uint32_t cluster, uint32_t position) const { + return clusterStartBlock(cluster) + blockOfCluster(position);} + static uint8_t cacheFlush(void); + static uint8_t cacheRawBlock(uint32_t blockNumber, uint8_t action); + static void cacheSetDirty(void) {cacheDirty_ |= CACHE_FOR_WRITE;} + static uint8_t cacheZeroBlock(uint32_t blockNumber); + uint8_t chainSize(uint32_t beginCluster, uint32_t* size) const; + uint8_t fatGet(uint32_t cluster, uint32_t* value) const; + uint8_t fatPut(uint32_t cluster, uint32_t value); + uint8_t fatPutEOC(uint32_t cluster) { + return fatPut(cluster, 0x0FFFFFFF); + } + uint8_t freeChain(uint32_t cluster); + uint8_t isEOC(uint32_t cluster) const { + return cluster >= (fatType_ == 16 ? FAT16EOC_MIN : FAT32EOC_MIN); + } + uint8_t readBlock(uint32_t block, uint8_t* dst) { + return sdCard_->readBlock(block, dst);} + uint8_t readData(uint32_t block, uint16_t offset, + uint16_t count, uint8_t* dst) { + return sdCard_->readData(block, offset, count, dst); + } + uint8_t writeBlock(uint32_t block, const uint8_t* dst) { + return sdCard_->writeBlock(block, dst); + } +}; +#endif // SdFat_h diff --git a/Libmaple/libmaple/libraries/mapleSDfat/SdFatmainpage.h b/Libmaple/libmaple/libraries/mapleSDfat/SdFatmainpage.h index 73b3b63b..d26cb854 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/SdFatmainpage.h +++ b/Libmaple/libmaple/libraries/mapleSDfat/SdFatmainpage.h @@ -1,202 +1,202 @@ -/* Arduino SdFat Library - * Copyright (C) 2009 by William Greiman - * - * This file is part of the Arduino SdFat Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino SdFat Library. If not, see - * . - */ - -/** -\mainpage Arduino SdFat Library -
Copyright © 2009 by William Greiman -
- -\section Intro Introduction -The Arduino SdFat Library is a minimal implementation of FAT16 and FAT32 -file systems on SD flash memory cards. Standard SD and high capacity -SDHC cards are supported. - -The SdFat only supports short 8.3 names. - -The main classes in SdFat are Sd2Card, SdVolume, and SdFile. - -The Sd2Card class supports access to standard SD cards and SDHC cards. Most -applications will only need to call the Sd2Card::init() member function. - -The SdVolume class supports FAT16 and FAT32 partitions. Most applications -will only need to call the SdVolume::init() member function. - -The SdFile class provides file access functions such as open(), read(), -remove(), write(), close() and sync(). This class supports access to the root -directory and subdirectories. - -A number of example are provided in the SdFat/examples folder. These were -developed to test SdFat and illustrate its use. - -SdFat was developed for high speed data recording. SdFat was used to implement -an audio record/play class, WaveRP, for the Adafruit Wave Shield. This -application uses special Sd2Card calls to write to contiguous files in raw mode. -These functions reduce write latency so that audio can be recorded with the -small amount of RAM in the Arduino. - -\section SDcard SD\SDHC Cards - -Arduinos access SD cards using the cards SPI protocol. PCs, Macs, and -most consumer devices use the 4-bit parallel SD protocol. A card that -functions well on A PC or Mac may not work well on the Arduino. - -Most cards have good SPI read performance but cards vary widely in SPI -write performance. Write performance is limited by how efficiently the -card manages internal erase/remapping operations. The Arduino cannot -optimize writes to reduce erase operations because of its limit RAM. - -SanDisk cards generally have good write performance. They seem to have -more internal RAM buffering than other cards and therefore can limit -the number of flash erase operations that the Arduino forces due to its -limited RAM. - -\section Hardware Hardware Configuration - -SdFat was developed using an - Adafruit Industries - Wave Shield. - -The hardware interface to the SD card should not use a resistor based level -shifter. SdFat sets the SPI bus frequency to 8 MHz which results in signal -rise times that are too slow for the edge detectors in many newer SD card -controllers when resistor voltage dividers are used. - -The 5 to 3.3 V level shifter for 5 V Arduinos should be IC based like the -74HC4050N based circuit shown in the file SdLevel.png. The Adafruit Wave Shield -uses a 74AHC125N. Gravitech sells SD and MicroSD Card Adapters based on the -74LCX245. - -If you are using a resistor based level shifter and are having problems try -setting the SPI bus frequency to 4 MHz. This can be done by using -card.init(SPI_HALF_SPEED) to initialize the SD card. - -\section comment Bugs and Comments - -If you wish to report bugs or have comments, send email to fat16lib@sbcglobal.net. - -\section SdFatClass SdFat Usage - -SdFat uses a slightly restricted form of short names. -Only printable ASCII characters are supported. No characters with code point -values greater than 127 are allowed. Space is not allowed even though space -was allowed in the API of early versions of DOS. - -Short names are limited to 8 characters followed by an optional period (.) -and extension of up to 3 characters. The characters may be any combination -of letters and digits. The following special characters are also allowed: - -$ % ' - _ @ ~ ` ! ( ) { } ^ # & - -Short names are always converted to upper case and their original case -value is lost. - -\note - The Arduino Print class uses character -at a time writes so it was necessary to use a \link SdFile::sync() sync() \endlink -function to control when data is written to the SD card. - -\par -An application which writes to a file using \link Print::print() print()\endlink, -\link Print::println() println() \endlink -or \link SdFile::write write() \endlink must call \link SdFile::sync() sync() \endlink -at the appropriate time to force data and directory information to be written -to the SD Card. Data and directory information are also written to the SD card -when \link SdFile::close() close() \endlink is called. - -\par -Applications must use care calling \link SdFile::sync() sync() \endlink -since 2048 bytes of I/O is required to update file and -directory information. This includes writing the current data block, reading -the block that contains the directory entry for update, writing the directory -block back and reading back the current data block. - -It is possible to open a file with two or more instances of SdFile. A file may -be corrupted if data is written to the file by more than one instance of SdFile. - -\section HowTo How to format SD Cards as FAT Volumes - -You should use a freshly formatted SD card for best performance. FAT -file systems become slower if many files have been created and deleted. -This is because the directory entry for a deleted file is marked as deleted, -but is not deleted. When a new file is created, these entries must be scanned -before creating the file, a flaw in the FAT design. Also files can become -fragmented which causes reads and writes to be slower. - -Microsoft operating systems support removable media formatted with a -Master Boot Record, MBR, or formatted as a super floppy with a FAT Boot Sector -in block zero. - -Microsoft operating systems expect MBR formatted removable media -to have only one partition. The first partition should be used. - -Microsoft operating systems do not support partitioning SD flash cards. -If you erase an SD card with a program like KillDisk, Most versions of -Windows will format the card as a super floppy. - -The best way to restore an SD card's format is to use SDFormatter -which can be downloaded from: - -http://www.sdcard.org/consumers/formatter/ - -SDFormatter aligns flash erase boundaries with file -system structures which reduces write latency and file system overhead. - -SDFormatter does not have an option for FAT type so it may format -small cards as FAT12. - -After the MBR is restored by SDFormatter you may need to reformat small -cards that have been formatted FAT12 to force the volume type to be FAT16. - -If you reformat the SD card with an OS utility, choose a cluster size that -will result in: - -4084 < CountOfClusters && CountOfClusters < 65525 - -The volume will then be FAT16. - -If you are formatting an SD card on OS X or Linux, be sure to use the first -partition. Format this partition with a cluster count in above range. - -\section References References - -Adafruit Industries: - -http://www.adafruit.com/ - -http://www.ladyada.net/make/waveshield/ - -The Arduino site: - -http://www.arduino.cc/ - -For more information about FAT file systems see: - -http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - -For information about using SD cards as SPI devices see: - -http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf - -The ATmega328 datasheet: - -http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf - - - */ +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ + +/** +\mainpage Arduino SdFat Library +
Copyright © 2009 by William Greiman +
+ +\section Intro Introduction +The Arduino SdFat Library is a minimal implementation of FAT16 and FAT32 +file systems on SD flash memory cards. Standard SD and high capacity +SDHC cards are supported. + +The SdFat only supports short 8.3 names. + +The main classes in SdFat are Sd2Card, SdVolume, and SdFile. + +The Sd2Card class supports access to standard SD cards and SDHC cards. Most +applications will only need to call the Sd2Card::init() member function. + +The SdVolume class supports FAT16 and FAT32 partitions. Most applications +will only need to call the SdVolume::init() member function. + +The SdFile class provides file access functions such as open(), read(), +remove(), write(), close() and sync(). This class supports access to the root +directory and subdirectories. + +A number of example are provided in the SdFat/examples folder. These were +developed to test SdFat and illustrate its use. + +SdFat was developed for high speed data recording. SdFat was used to implement +an audio record/play class, WaveRP, for the Adafruit Wave Shield. This +application uses special Sd2Card calls to write to contiguous files in raw mode. +These functions reduce write latency so that audio can be recorded with the +small amount of RAM in the Arduino. + +\section SDcard SD\SDHC Cards + +Arduinos access SD cards using the cards SPI protocol. PCs, Macs, and +most consumer devices use the 4-bit parallel SD protocol. A card that +functions well on A PC or Mac may not work well on the Arduino. + +Most cards have good SPI read performance but cards vary widely in SPI +write performance. Write performance is limited by how efficiently the +card manages internal erase/remapping operations. The Arduino cannot +optimize writes to reduce erase operations because of its limit RAM. + +SanDisk cards generally have good write performance. They seem to have +more internal RAM buffering than other cards and therefore can limit +the number of flash erase operations that the Arduino forces due to its +limited RAM. + +\section Hardware Hardware Configuration + +SdFat was developed using an + Adafruit Industries + Wave Shield. + +The hardware interface to the SD card should not use a resistor based level +shifter. SdFat sets the SPI bus frequency to 8 MHz which results in signal +rise times that are too slow for the edge detectors in many newer SD card +controllers when resistor voltage dividers are used. + +The 5 to 3.3 V level shifter for 5 V Arduinos should be IC based like the +74HC4050N based circuit shown in the file SdLevel.png. The Adafruit Wave Shield +uses a 74AHC125N. Gravitech sells SD and MicroSD Card Adapters based on the +74LCX245. + +If you are using a resistor based level shifter and are having problems try +setting the SPI bus frequency to 4 MHz. This can be done by using +card.init(SPI_HALF_SPEED) to initialize the SD card. + +\section comment Bugs and Comments + +If you wish to report bugs or have comments, send email to fat16lib@sbcglobal.net. + +\section SdFatClass SdFat Usage + +SdFat uses a slightly restricted form of short names. +Only printable ASCII characters are supported. No characters with code point +values greater than 127 are allowed. Space is not allowed even though space +was allowed in the API of early versions of DOS. + +Short names are limited to 8 characters followed by an optional period (.) +and extension of up to 3 characters. The characters may be any combination +of letters and digits. The following special characters are also allowed: + +$ % ' - _ @ ~ ` ! ( ) { } ^ # & + +Short names are always converted to upper case and their original case +value is lost. + +\note + The Arduino Print class uses character +at a time writes so it was necessary to use a \link SdFile::sync() sync() \endlink +function to control when data is written to the SD card. + +\par +An application which writes to a file using \link Print::print() print()\endlink, +\link Print::println() println() \endlink +or \link SdFile::write write() \endlink must call \link SdFile::sync() sync() \endlink +at the appropriate time to force data and directory information to be written +to the SD Card. Data and directory information are also written to the SD card +when \link SdFile::close() close() \endlink is called. + +\par +Applications must use care calling \link SdFile::sync() sync() \endlink +since 2048 bytes of I/O is required to update file and +directory information. This includes writing the current data block, reading +the block that contains the directory entry for update, writing the directory +block back and reading back the current data block. + +It is possible to open a file with two or more instances of SdFile. A file may +be corrupted if data is written to the file by more than one instance of SdFile. + +\section HowTo How to format SD Cards as FAT Volumes + +You should use a freshly formatted SD card for best performance. FAT +file systems become slower if many files have been created and deleted. +This is because the directory entry for a deleted file is marked as deleted, +but is not deleted. When a new file is created, these entries must be scanned +before creating the file, a flaw in the FAT design. Also files can become +fragmented which causes reads and writes to be slower. + +Microsoft operating systems support removable media formatted with a +Master Boot Record, MBR, or formatted as a super floppy with a FAT Boot Sector +in block zero. + +Microsoft operating systems expect MBR formatted removable media +to have only one partition. The first partition should be used. + +Microsoft operating systems do not support partitioning SD flash cards. +If you erase an SD card with a program like KillDisk, Most versions of +Windows will format the card as a super floppy. + +The best way to restore an SD card's format is to use SDFormatter +which can be downloaded from: + +http://www.sdcard.org/consumers/formatter/ + +SDFormatter aligns flash erase boundaries with file +system structures which reduces write latency and file system overhead. + +SDFormatter does not have an option for FAT type so it may format +small cards as FAT12. + +After the MBR is restored by SDFormatter you may need to reformat small +cards that have been formatted FAT12 to force the volume type to be FAT16. + +If you reformat the SD card with an OS utility, choose a cluster size that +will result in: + +4084 < CountOfClusters && CountOfClusters < 65525 + +The volume will then be FAT16. + +If you are formatting an SD card on OS X or Linux, be sure to use the first +partition. Format this partition with a cluster count in above range. + +\section References References + +Adafruit Industries: + +http://www.adafruit.com/ + +http://www.ladyada.net/make/waveshield/ + +The Arduino site: + +http://www.arduino.cc/ + +For more information about FAT file systems see: + +http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + +For information about using SD cards as SPI devices see: + +http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf + +The ATmega328 datasheet: + +http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf + + + */ diff --git a/Libmaple/libmaple/libraries/mapleSDfat/SdFile.cpp b/Libmaple/libmaple/libraries/mapleSDfat/SdFile.cpp index fd5f8d6d..e9d98152 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/SdFile.cpp +++ b/Libmaple/libmaple/libraries/mapleSDfat/SdFile.cpp @@ -1,1267 +1,1267 @@ -/* Arduino SdFat Library - * Copyright (C) 2009 by William Greiman - * - * This file is part of the Arduino SdFat Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino SdFat Library. If not, see - * . - */ -#include -#include "SdFat.h" -//#include -#include -#include "HardwareSPI.h" -#include - -//------------------------------------------------------------------------------ -// callback function for date/time -void (*SdFile::dateTime_)(uint16_t* date, uint16_t* time) = NULL; - -#if ALLOW_DEPRECATED_FUNCTIONS -// suppress cpplint warnings with NOLINT comment -void (*SdFile::oldDateTime_)(uint16_t& date, uint16_t& time) = NULL; // NOLINT -#endif // ALLOW_DEPRECATED_FUNCTIONS -//------------------------------------------------------------------------------ -// add a cluster to a file -uint8_t SdFile::addCluster() { - if (!vol_->allocContiguous(1, &curCluster_)) return false; - - // if first cluster of file link to directory entry - if (firstCluster_ == 0) { - firstCluster_ = curCluster_; - flags_ |= F_FILE_DIR_DIRTY; - } - return true; -} -//------------------------------------------------------------------------------ -// Add a cluster to a directory file and zero the cluster. -// return with first block of cluster in the cache -uint8_t SdFile::addDirCluster(void) { - if (!addCluster()) return false; - - // zero data in cluster insure first cluster is in cache - uint32_t block = vol_->clusterStartBlock(curCluster_); - for (uint8_t i = vol_->blocksPerCluster_; i != 0; i--) { - if (!SdVolume::cacheZeroBlock(block + i - 1)) return false; - } - // Increase directory file size by cluster size - fileSize_ += 512UL << vol_->clusterSizeShift_; - return true; -} -//------------------------------------------------------------------------------ -// cache a file's directory entry -// return pointer to cached entry or null for failure -dir_t* SdFile::cacheDirEntry(uint8_t action) { - if (!SdVolume::cacheRawBlock(dirBlock_, action)) return NULL; - return SdVolume::cacheBuffer_.dir + dirIndex_; -} -//------------------------------------------------------------------------------ -/** - * Close a file and force cached data and directory information - * to be written to the storage device. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include no file is open or an I/O error. - */ -uint8_t SdFile::close(void) { - if (!sync())return false; - type_ = FAT_FILE_TYPE_CLOSED; - return true; -} -//------------------------------------------------------------------------------ -/** - * Check for contiguous file and return its raw block range. - * - * \param[out] bgnBlock the first block address for the file. - * \param[out] endBlock the last block address for the file. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include file is not contiguous, file has zero length - * or an I/O error occurred. - */ -uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { - // error if no blocks - if (firstCluster_ == 0) return false; - - for (uint32_t c = firstCluster_; ; c++) { - uint32_t next; - if (!vol_->fatGet(c, &next)) return false; - - // check for contiguous - if (next != (c + 1)) { - // error if not end of chain - if (!vol_->isEOC(next)) return false; - *bgnBlock = vol_->clusterStartBlock(firstCluster_); - *endBlock = vol_->clusterStartBlock(c) - + vol_->blocksPerCluster_ - 1; - return true; - } - } -} -//------------------------------------------------------------------------------ -/** - * Create and open a new contiguous file of a specified size. - * - * \note This function only supports short DOS 8.3 names. - * See open() for more information. - * - * \param[in] dirFile The directory where the file will be created. - * \param[in] fileName A valid DOS 8.3 file name. - * \param[in] size The desired file size. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include \a fileName contains - * an invalid DOS 8.3 file name, the FAT volume has not been initialized, - * a file is already open, the file already exists, the root - * directory is full or an I/O error. - * - */ -uint8_t SdFile::createContiguous(SdFile* dirFile, - const char* fileName, uint32_t size) { - // don't allow zero length file - if (size == 0) return false; - if (!open(dirFile, fileName, O_CREAT | O_EXCL | O_RDWR)) return false; - - // calculate number of clusters needed - uint32_t count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1; - - // allocate clusters - if (!vol_->allocContiguous(count, &firstCluster_)) { - remove(); - return false; - } - fileSize_ = size; - - // insure sync() will update dir entry - flags_ |= F_FILE_DIR_DIRTY; - return sync(); -} -//------------------------------------------------------------------------------ -/** - * Return a files directory entry - * - * \param[out] dir Location for return of the files directory entry. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - */ -uint8_t SdFile::dirEntry(dir_t* dir) { - // make sure fields on SD are correct - if (!sync()) return false; - - // read entry - dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_READ); - if (!p) return false; - - // copy to caller's struct - memcpy(dir, p, sizeof(dir_t)); - return true; -} -//------------------------------------------------------------------------------ -/** - * Format the name field of \a dir into the 13 byte array - * \a name in standard 8.3 short name format. - * - * \param[in] dir The directory structure containing the name. - * \param[out] name A 13 byte char array for the formatted name. - */ -void SdFile::dirName(const dir_t& dir, char* name) { - uint8_t j = 0; - for (uint8_t i = 0; i < 11; i++) { - if (dir.name[i] == ' ')continue; - if (i == 8) name[j++] = '.'; - name[j++] = dir.name[i]; - } - name[j] = 0; -} -//------------------------------------------------------------------------------ -/** List directory contents to Serial. - * - * \param[in] flags The inclusive OR of - * - * LS_DATE - %Print file modification date - * - * LS_SIZE - %Print file size. - * - * LS_R - Recursive list of subdirectories. - * - * \param[in] indent Amount of space before file name. Used for recursive - * list to indicate subdirectory level. - */ -void SdFile::ls(uint8_t flags, uint8_t indent) { - dir_t* p; - - rewind(); - while ((p = readDirCache())) { - // done if past last used entry - if (p->name[0] == DIR_NAME_FREE) break; - - // skip deleted entry and entries for . and .. - if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; - - // only list subdirectories and files - if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; - - // print any indent spaces - for (int8_t i = 0; i < indent; i++) SerialDebug.print(' '); - - // print file name with possible blank fill - printDirName(*p, flags & (LS_DATE | LS_SIZE) ? 14 : 0); - - // print modify date/time if requested - if (flags & LS_DATE) { - printFatDate(p->lastWriteDate); - SerialDebug.print(' '); - printFatTime(p->lastWriteTime); - } - // print size if requested - if (!DIR_IS_SUBDIR(p) && (flags & LS_SIZE)) { - SerialDebug.print(' '); - SerialDebug.print(p->fileSize); - } - SerialDebug.println(); - - // list subdirectory content if requested - if ((flags & LS_R) && DIR_IS_SUBDIR(p)) { - uint16_t index = curPosition()/32 - 1; - SdFile s; - if (s.open(this, index, O_READ)) s.ls(flags, indent + 2); - seekSet(32 * (index + 1)); - } - } -} -//------------------------------------------------------------------------------ -// format directory name field from a 8.3 name string -uint8_t SdFile::make83Name(const char* str, uint8_t* name) { - uint8_t c; - uint8_t n = 7; // max index for part before dot - uint8_t i = 0; - // blank fill name and extension - while (i < 11) name[i++] = ' '; - i = 0; - while ((c = *str++) != '\0') { - if (c == '.') { - if (n == 10) return false; // only one dot allowed - n = 10; // max index for full 8.3 name - i = 8; // place for extension - } else { - // illegal FAT characters -// PGM_P p = PSTR("|<>^+=?/[];,*\"\\"); - char p[17] = {"|<>^+=?/[];,*\"\\"}; - char *ptr = p; - uint8_t b; - while ((b = *(ptr++))) - if (b == c) - return false; - // check size and only allow ASCII printable characters - if (i > n || c < 0X21 || c > 0X7E)return false; - // only upper case allowed in 8.3 names - convert lower to upper - name[i++] = c < 'a' || c > 'z' ? c : c + ('A' - 'a'); - } - } - // must have a file name, extension is optional - return name[0] != ' '; -} -//------------------------------------------------------------------------------ -/** Make a new directory. - * - * \param[in] dir An open SdFat instance for the directory that will containing - * the new directory. - * - * \param[in] dirName A valid 8.3 DOS name for the new directory. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include this SdFile is already open, \a dir is not a - * directory, \a dirName is invalid or already exists in \a dir. - */ -uint8_t SdFile::makeDir(SdFile* dir, const char* dirName) { - dir_t d; - - // create a normal file - if (!open(dir, dirName, O_CREAT | O_EXCL | O_RDWR)) return false; - - // convert SdFile to directory - flags_ = O_READ; - type_ = FAT_FILE_TYPE_SUBDIR; - - // allocate and zero first cluster - if (!addDirCluster())return false; - - // force entry to SD - if (!sync()) return false; - - // cache entry - should already be in cache due to sync() call - dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!p) return false; - - // change directory entry attribute - p->attributes = DIR_ATT_DIRECTORY; - - // make entry for '.' - memcpy(&d, p, sizeof(d)); - for (uint8_t i = 1; i < 11; i++) d.name[i] = ' '; - d.name[0] = '.'; - - // cache block for '.' and '..' - uint32_t block = vol_->clusterStartBlock(firstCluster_); - if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) return false; - - // copy '.' to block - memcpy(&SdVolume::cacheBuffer_.dir[0], &d, sizeof(d)); - - // make entry for '..' - d.name[1] = '.'; - if (dir->isRoot()) { - d.firstClusterLow = 0; - d.firstClusterHigh = 0; - } else { - d.firstClusterLow = dir->firstCluster_ & 0XFFFF; - d.firstClusterHigh = dir->firstCluster_ >> 16; - } - // copy '..' to block - memcpy(&SdVolume::cacheBuffer_.dir[1], &d, sizeof(d)); - - // set position after '..' - curPosition_ = 2 * sizeof(d); - - // write first block - return SdVolume::cacheFlush(); -} -//------------------------------------------------------------------------------ -/** - * Open a file or directory by name. - * - * \param[in] dirFile An open SdFat instance for the directory containing the - * file to be opened. - * - * \param[in] fileName A valid 8.3 DOS name for a file to be opened. - * - * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive - * OR of flags from the following list - * - * O_READ - Open for reading. - * - * O_RDONLY - Same as O_READ. - * - * O_WRITE - Open for writing. - * - * O_WRONLY - Same as O_WRITE. - * - * O_RDWR - Open for reading and writing. - * - * O_APPEND - If set, the file offset shall be set to the end of the - * file prior to each write. - * - * O_CREAT - If the file exists, this flag has no effect except as noted - * under O_EXCL below. Otherwise, the file shall be created - * - * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists. - * - * O_SYNC - Call sync() after each write. This flag should not be used with - * write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class. - * These functions do character at a time writes so sync() will be called - * after each byte. - * - * O_TRUNC - If the file exists and is a regular file, and the file is - * successfully opened and is not read only, its length shall be truncated to 0. - * - * \note Directory files must be opened read only. Write and truncation is - * not allowed for directory files. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include this SdFile is already open, \a difFile is not - * a directory, \a fileName is invalid, the file does not exist - * or can't be opened in the access mode specified by oflag. - */ -uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag) { - uint8_t dname[11]; - dir_t* p; - - // error if already open - if (isOpen())return false; - - if (!make83Name(fileName, dname)) return false; - vol_ = dirFile->vol_; - dirFile->rewind(); - - // bool for empty entry found - uint8_t emptyFound = false; - - // search for file - while (dirFile->curPosition_ < dirFile->fileSize_) { - uint8_t index = 0XF & (dirFile->curPosition_ >> 5); - p = dirFile->readDirCache(); - if (p == NULL) return false; - - if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) { - // remember first empty slot - if (!emptyFound) { - emptyFound = true; - dirIndex_ = index; - dirBlock_ = SdVolume::cacheBlockNumber_; - } - // done if no entries follow - if (p->name[0] == DIR_NAME_FREE) break; - } else if (!memcmp(dname, p->name, 11)) { - // don't open existing file if O_CREAT and O_EXCL - if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false; - - // open found file - return openCachedEntry(0XF & index, oflag); - } - } - // only create file if O_CREAT and O_WRITE - if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false; - - // cache found slot or add cluster if end of file - if (emptyFound) { - p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!p) return false; - } else { - if (dirFile->type_ == FAT_FILE_TYPE_ROOT16) return false; - - // add and zero cluster for dirFile - first cluster is in cache for write - if (!dirFile->addDirCluster()) return false; - - // use first entry in cluster - dirIndex_ = 0; - p = SdVolume::cacheBuffer_.dir; - } - // initialize as empty file - memset(p, 0, sizeof(dir_t)); - memcpy(p->name, dname, 11); - - // set timestamps - if (dateTime_) { - // call user function - dateTime_(&p->creationDate, &p->creationTime); - } else { - // use default date/time - p->creationDate = FAT_DEFAULT_DATE; - p->creationTime = FAT_DEFAULT_TIME; - } - p->lastAccessDate = p->creationDate; - p->lastWriteDate = p->creationDate; - p->lastWriteTime = p->creationTime; - - // force write of entry to SD - if (!SdVolume::cacheFlush()) return false; - - // open entry in cache - return openCachedEntry(dirIndex_, oflag); -} -//------------------------------------------------------------------------------ -/** - * Open a file by index. - * - * \param[in] dirFile An open SdFat instance for the directory. - * - * \param[in] index The \a index of the directory entry for the file to be - * opened. The value for \a index is (directory file position)/32. - * - * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive - * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. - * - * See open() by fileName for definition of flags and return values. - * - */ -uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag) { - // error if already open - if (isOpen())return false; - - // don't open existing file if O_CREAT and O_EXCL - user call error - if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false; - - vol_ = dirFile->vol_; - - // seek to location of entry - if (!dirFile->seekSet(32 * index)) return false; - - // read entry into cache - dir_t* p = dirFile->readDirCache(); - if (p == NULL) return false; - - // error if empty slot or '.' or '..' - if (p->name[0] == DIR_NAME_FREE || - p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { - return false; - } - // open cached entry - return openCachedEntry(index & 0XF, oflag); -} -//------------------------------------------------------------------------------ -// open a cached directory entry. Assumes vol_ is initializes -uint8_t SdFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) { - // location of entry in cache - dir_t* p = SdVolume::cacheBuffer_.dir + dirIndex; - - // write or truncate is an error for a directory or read-only file - if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) { - if (oflag & (O_WRITE | O_TRUNC)) return false; - } - // remember location of directory entry on SD - dirIndex_ = dirIndex; - dirBlock_ = SdVolume::cacheBlockNumber_; - - // copy first cluster number for directory fields - firstCluster_ = (uint32_t)p->firstClusterHigh << 16; - firstCluster_ |= p->firstClusterLow; - - // make sure it is a normal file or subdirectory - if (DIR_IS_FILE(p)) { - fileSize_ = p->fileSize; - type_ = FAT_FILE_TYPE_NORMAL; - } else if (DIR_IS_SUBDIR(p)) { - if (!vol_->chainSize(firstCluster_, &fileSize_)) return false; - type_ = FAT_FILE_TYPE_SUBDIR; - } else { - return false; - } - // save open flags for read/write - flags_ = oflag & (O_ACCMODE | O_SYNC | O_APPEND); - - // set to start of file - curCluster_ = 0; - curPosition_ = 0; - - // truncate file to zero length if requested - if (oflag & O_TRUNC) return truncate(0); - return true; -} -//------------------------------------------------------------------------------ -/** - * Open a volume's root directory. - * - * \param[in] vol The FAT volume containing the root directory to be opened. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include the FAT volume has not been initialized - * or it a FAT12 volume. - */ -uint8_t SdFile::openRoot(SdVolume* vol) { - // error if file is already open - if (isOpen()) return false; - - if (vol->fatType() == 16) { - type_ = FAT_FILE_TYPE_ROOT16; - firstCluster_ = 0; - fileSize_ = 32 * vol->rootDirEntryCount(); - } else if (vol->fatType() == 32) { - type_ = FAT_FILE_TYPE_ROOT32; - firstCluster_ = vol->rootDirStart(); - if (!vol->chainSize(firstCluster_, &fileSize_)) return false; - } else { - // volume is not initialized or FAT12 - return false; - } - vol_ = vol; - // read only - flags_ = O_READ; - - // set to start of file - curCluster_ = 0; - curPosition_ = 0; - - // root has no directory entry - dirBlock_ = 0; - dirIndex_ = 0; - return true; -} -//------------------------------------------------------------------------------ -/** %Print the name field of a directory entry in 8.3 format to Serial. - * - * \param[in] dir The directory structure containing the name. - * \param[in] width Blank fill name if length is less than \a width. - */ -void SdFile::printDirName(const dir_t& dir, uint8_t width) { - uint8_t w = 0; - for (uint8_t i = 0; i < 11; i++) { - if (dir.name[i] == ' ')continue; - if (i == 8) { - SerialDebug.print('.'); - w++; - } - SerialDebug.print((char)dir.name[i]); - w++; - } - if (DIR_IS_SUBDIR(&dir)) { - SerialDebug.print('/'); - w++; - } - while (w < width) { - SerialDebug.print(' '); - w++; - } -} -//------------------------------------------------------------------------------ -/** %Print a directory date field to Serial. - * - * Format is yyyy-mm-dd. - * - * \param[in] fatDate The date field from a directory entry. - */ -void SdFile::printFatDate(uint16_t fatDate) { - SerialDebug.print(FAT_YEAR(fatDate)); - SerialDebug.print('-'); - printTwoDigits(FAT_MONTH(fatDate)); - SerialDebug.print('-'); - printTwoDigits(FAT_DAY(fatDate)); -} -//------------------------------------------------------------------------------ -/** %Print a directory time field to Serial. - * - * Format is hh:mm:ss. - * - * \param[in] fatTime The time field from a directory entry. - */ -void SdFile::printFatTime(uint16_t fatTime) { - printTwoDigits(FAT_HOUR(fatTime)); - SerialDebug.print(':'); - printTwoDigits(FAT_MINUTE(fatTime)); - SerialDebug.print(':'); - printTwoDigits(FAT_SECOND(fatTime)); -} -//------------------------------------------------------------------------------ -/** %Print a value as two digits to Serial. - * - * \param[in] v Value to be printed, 0 <= \a v <= 99 - */ -void SdFile::printTwoDigits(uint8_t v) { - char str[3]; - str[0] = '0' + v/10; - str[1] = '0' + v % 10; - str[2] = 0; - SerialDebug.print(str); -} -//------------------------------------------------------------------------------ -/** - * Read data from a file starting at the current position. - * - * \param[out] buf Pointer to the location that will receive the data. - * - * \param[in] nbyte Maximum number of bytes to read. - * - * \return For success read() returns the number of bytes read. - * A value less than \a nbyte, including zero, will be returned - * if end of file is reached. - * If an error occurs, read() returns -1. Possible errors include - * read() called before a file has been opened, corrupt file system - * or an I/O error occurred. - */ -int16_t SdFile::read(void* buf, uint16_t nbyte) { - uint8_t* dst = reinterpret_cast(buf); - - // error if not open or write only - if (!isOpen() || !(flags_ & O_READ)) return -1; - - // max bytes left in file - if (nbyte > (fileSize_ - curPosition_)) nbyte = fileSize_ - curPosition_; - - // amount left to read - uint16_t toRead = nbyte; - while (toRead > 0) { - uint32_t block; // raw device block number - uint16_t offset = curPosition_ & 0X1FF; // offset in block - if (type_ == FAT_FILE_TYPE_ROOT16) { - block = vol_->rootDirStart() + (curPosition_ >> 9); - } else { - uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); - if (offset == 0 && blockOfCluster == 0) { - // start of new cluster - if (curPosition_ == 0) { - // use first cluster in file - curCluster_ = firstCluster_; - } else { - // get next cluster from FAT - if (!vol_->fatGet(curCluster_, &curCluster_)) return -1; - } - } - block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; - } - uint16_t n = toRead; - - // amount to be read from current block - if (n > (512 - offset)) n = 512 - offset; - -#if 0 - SerialDebug.print("block "); - SerialDebug.print(block); - SerialDebug.print(" n "); - SerialDebug.println(n); -#endif - // no buffering needed if n == 512 or user requests no buffering - if ((unbufferedRead() || n == 512) && block != SdVolume::cacheBlockNumber_) { - if (!vol_->readData(block, offset, n, dst)) return -1; - dst += n; - } else { - // read block to cache and copy data to caller - if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) return -1; - uint8_t* src = SdVolume::cacheBuffer_.data + offset; - uint8_t* end = src + n; - while (src != end) *dst++ = *src++; - } - curPosition_ += n; - toRead -= n; - } - return nbyte; -} -//------------------------------------------------------------------------------ -/** - * Read the next directory entry from a directory file. - * - * \param[out] dir The dir_t struct that will receive the data. - * - * \return For success readDir() returns the number of bytes read. - * A value of zero will be returned if end of file is reached. - * If an error occurs, readDir() returns -1. Possible errors include - * readDir() called before a directory has been opened, this is not - * a directory file or an I/O error occurred. - */ -int8_t SdFile::readDir(dir_t* dir) { - int8_t n; - // if not a directory file or miss-positioned return an error - if (!isDir() || (0X1F & curPosition_)) return -1; - - while ((n = read(dir, sizeof(dir_t))) == sizeof(dir_t)) { - // last entry if DIR_NAME_FREE - if (dir->name[0] == DIR_NAME_FREE) break; - // skip empty entries and entry for . and .. - if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') continue; - // return if normal file or subdirectory - if (DIR_IS_FILE_OR_SUBDIR(dir)) return n; - } - // error, end of file, or past last entry - return n < 0 ? -1 : 0; -} -//------------------------------------------------------------------------------ -// Read next directory entry into the cache -// Assumes file is correctly positioned -dir_t* SdFile::readDirCache(void) { - // error if not directory - if (!isDir()) return NULL; - - // index of entry in cache - uint8_t i = (curPosition_ >> 5) & 0XF; - - // use read to locate and cache block - if (read() < 0) return NULL; - - // advance to next entry - curPosition_ += 31; - - // return pointer to entry - return (SdVolume::cacheBuffer_.dir + i); -} -//------------------------------------------------------------------------------ -/** - * Remove a file. - * - * The directory entry and all data for the file are deleted. - * - * \note This function should not be used to delete the 8.3 version of a - * file that has a long name. For example if a file has the long name - * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include the file read-only, is a directory, - * or an I/O error occurred. - */ -uint8_t SdFile::remove(void) { - // free any clusters - will fail if read-only or directory - if (!truncate(0)) return false; - - // cache directory entry - dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!d) return false; - - // mark entry deleted - d->name[0] = DIR_NAME_DELETED; - - // set this SdFile closed - type_ = FAT_FILE_TYPE_CLOSED; - - // write entry to SD - return SdVolume::cacheFlush(); -} -//------------------------------------------------------------------------------ -/** - * Remove a file. - * - * The directory entry and all data for the file are deleted. - * - * \param[in] dirFile The directory that contains the file. - * \param[in] fileName The name of the file to be removed. - * - * \note This function should not be used to delete the 8.3 version of a - * file that has a long name. For example if a file has the long name - * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include the file is a directory, is read only, - * \a dirFile is not a directory, \a fileName is not found - * or an I/O error occurred. - */ -uint8_t SdFile::remove(SdFile* dirFile, const char* fileName) { - SdFile file; - if (!file.open(dirFile, fileName, O_WRITE)) return false; - return file.remove(); -} -//------------------------------------------------------------------------------ -/** Remove a directory file. - * - * The directory file will be removed only if it is empty and is not the - * root directory. rmDir() follows DOS and Windows and ignores the - * read-only attribute for the directory. - * - * \note This function should not be used to delete the 8.3 version of a - * directory that has a long name. For example if a directory has the - * long name "New folder" you should not delete the 8.3 name "NEWFOL~1". - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include the file is not a directory, is the root - * directory, is not empty, or an I/O error occurred. - */ -uint8_t SdFile::rmDir(void) { - // must be open subdirectory - if (!isSubDir()) return false; - - rewind(); - - // make sure directory is empty - while (curPosition_ < fileSize_) { - dir_t* p = readDirCache(); - if (p == NULL) return false; - // done if past last used entry - if (p->name[0] == DIR_NAME_FREE) break; - // skip empty slot or '.' or '..' - if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; - // error not empty - if (DIR_IS_FILE_OR_SUBDIR(p)) return false; - } - // convert empty directory to normal file for remove - type_ = FAT_FILE_TYPE_NORMAL; - flags_ |= O_WRITE; - return remove(); -} -//------------------------------------------------------------------------------ -/** Recursively delete a directory and all contained files. - * - * This is like the Unix/Linux 'rm -rf *' if called with the root directory - * hence the name. - * - * Warning - This will remove all contents of the directory including - * subdirectories. The directory will then be removed if it is not root. - * The read-only attribute for files will be ignored. - * - * \note This function should not be used to delete the 8.3 version of - * a directory that has a long name. See remove() and rmDir(). - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - */ -uint8_t SdFile::rmRfStar(void) { - rewind(); - while (curPosition_ < fileSize_) { - SdFile f; - - // remember position - uint16_t index = curPosition_/32; - - dir_t* p = readDirCache(); - if (!p) return false; - - // done if past last entry - if (p->name[0] == DIR_NAME_FREE) break; - - // skip empty slot or '.' or '..' - if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; - - // skip if part of long file name or volume label in root - if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; - - if (!f.open(this, index, O_READ)) return false; - if (f.isSubDir()) { - // recursively delete - if (!f.rmRfStar()) return false; - } else { - // ignore read-only - f.flags_ |= O_WRITE; - if (!f.remove()) return false; - } - // position to next entry if required - if (curPosition_ != (32*(index + 1))) { - if (!seekSet(32*(index + 1))) return false; - } - } - // don't try to delete root - if (isRoot()) return true; - return rmDir(); -} -//------------------------------------------------------------------------------ -/** - * Sets a file's position. - * - * \param[in] pos The new position in bytes from the beginning of the file. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - */ -uint8_t SdFile::seekSet(uint32_t pos) { - // error if file not open or seek past end of file - if (!isOpen() || pos > fileSize_) return false; - - if (type_ == FAT_FILE_TYPE_ROOT16) { - curPosition_ = pos; - return true; - } - if (pos == 0) { - // set position to start of file - curCluster_ = 0; - curPosition_ = 0; - return true; - } - // calculate cluster index for cur and new position - uint32_t nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9); - uint32_t nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9); - - if (nNew < nCur || curPosition_ == 0) { - // must follow chain from first cluster - curCluster_ = firstCluster_; - } else { - // advance from curPosition - nNew -= nCur; - } - while (nNew--) { - if (!vol_->fatGet(curCluster_, &curCluster_)) return false; - } - curPosition_ = pos; - return true; -} -//------------------------------------------------------------------------------ -/** - * The sync() call causes all modified data and directory fields - * to be written to the storage device. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include a call to sync() before a file has been - * opened or an I/O error. - */ -uint8_t SdFile::sync(void) { - // only allow open files and directories - if (!isOpen()) return false; - - if (flags_ & F_FILE_DIR_DIRTY) { - dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!d) return false; - - // do not set filesize for dir files - if (!isDir()) d->fileSize = fileSize_; - - // update first cluster fields - d->firstClusterLow = firstCluster_ & 0XFFFF; - d->firstClusterHigh = firstCluster_ >> 16; - - // set modify time if user supplied a callback date/time function - if (dateTime_) { - dateTime_(&d->lastWriteDate, &d->lastWriteTime); - d->lastAccessDate = d->lastWriteDate; - } - // clear directory dirty - flags_ &= ~F_FILE_DIR_DIRTY; - } - return SdVolume::cacheFlush(); -} -//------------------------------------------------------------------------------ -/** - * Set a file's timestamps in its directory entry. - * - * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive - * OR of flags from the following list - * - * T_ACCESS - Set the file's last access date. - * - * T_CREATE - Set the file's creation date and time. - * - * T_WRITE - Set the file's last write/modification date and time. - * - * \param[in] year Valid range 1980 - 2107 inclusive. - * - * \param[in] month Valid range 1 - 12 inclusive. - * - * \param[in] day Valid range 1 - 31 inclusive. - * - * \param[in] hour Valid range 0 - 23 inclusive. - * - * \param[in] minute Valid range 0 - 59 inclusive. - * - * \param[in] second Valid range 0 - 59 inclusive - * - * \note It is possible to set an invalid date since there is no check for - * the number of days in a month. - * - * \note - * Modify and access timestamps may be overwritten if a date time callback - * function has been set by dateTimeCallback(). - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - */ -uint8_t SdFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, - uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { - if (!isOpen() - || year < 1980 - || year > 2107 - || month < 1 - || month > 12 - || day < 1 - || day > 31 - || hour > 23 - || minute > 59 - || second > 59) { - return false; - } - dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!d) return false; - - uint16_t dirDate = FAT_DATE(year, month, day); - uint16_t dirTime = FAT_TIME(hour, minute, second); - if (flags & T_ACCESS) { - d->lastAccessDate = dirDate; - } - if (flags & T_CREATE) { - d->creationDate = dirDate; - d->creationTime = dirTime; - // seems to be units of 1/100 second not 1/10 as Microsoft states - d->creationTimeTenths = second & 1 ? 100 : 0; - } - if (flags & T_WRITE) { - d->lastWriteDate = dirDate; - d->lastWriteTime = dirTime; - } - SdVolume::cacheSetDirty(); - return sync(); -} -//------------------------------------------------------------------------------ -/** - * Truncate a file to a specified length. The current file position - * will be maintained if it is less than or equal to \a length otherwise - * it will be set to end of file. - * - * \param[in] length The desired length for the file. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. - * Reasons for failure include file is read only, file is a directory, - * \a length is greater than the current file size or an I/O error occurs. - */ -uint8_t SdFile::truncate(uint32_t length) { -// error if not a normal file or read-only - if (!isFile() || !(flags_ & O_WRITE)) return false; - - // error if length is greater than current size - if (length > fileSize_) return false; - - // fileSize and length are zero - nothing to do - if (fileSize_ == 0) return true; - - // remember position for seek after truncation - uint32_t newPos = curPosition_ > length ? length : curPosition_; - - // position to last cluster in truncated file - if (!seekSet(length)) return false; - - if (length == 0) { - // free all clusters - if (!vol_->freeChain(firstCluster_)) return false; - firstCluster_ = 0; - } else { - uint32_t toFree; - if (!vol_->fatGet(curCluster_, &toFree)) return false; - - if (!vol_->isEOC(toFree)) { - // free extra clusters - if (!vol_->freeChain(toFree)) return false; - - // current cluster is end of chain - if (!vol_->fatPutEOC(curCluster_)) return false; - } - } - fileSize_ = length; - - // need to update directory entry - flags_ |= F_FILE_DIR_DIRTY; - - if (!sync()) return false; - - // set file to correct position - return seekSet(newPos); -} -//------------------------------------------------------------------------------ -/** - * Write data to an open file. - * - * \note Data is moved to the cache but may not be written to the - * storage device until sync() is called. - * - * \param[in] buf Pointer to the location of the data to be written. - * - * \param[in] nbyte Number of bytes to write. - * - * \return For success write() returns the number of bytes written, always - * \a nbyte. If an error occurs, write() returns -1. Possible errors - * include write() is called before a file has been opened, write is called - * for a read-only file, device is full, a corrupt file system or an I/O error. - * - */ -int16_t SdFile::write(const void* buf, uint16_t nbyte) { - // convert void* to uint8_t* - must be before goto statements - const uint8_t* src = reinterpret_cast(buf); - - // number of bytes left to write - must be before goto statements - uint16_t nToWrite = nbyte; - - // error if not a normal file or is read-only - if (!isFile() || !(flags_ & O_WRITE)) goto writeErrorReturn; - - // seek to end of file if append flag - if ((flags_ & O_APPEND) && curPosition_ != fileSize_) { - if (!seekEnd()) goto writeErrorReturn; - } - - while (nToWrite > 0) { - uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); - uint16_t blockOffset = curPosition_ & 0X1FF; - if (blockOfCluster == 0 && blockOffset == 0) { - // start of new cluster - if (curCluster_ == 0) { - if (firstCluster_ == 0) { - // allocate first cluster of file - if (!addCluster()) goto writeErrorReturn; - } else { - curCluster_ = firstCluster_; - } - } else { - uint32_t next; - if (!vol_->fatGet(curCluster_, &next)) return false; - if (vol_->isEOC(next)) { - // add cluster if at end of chain - if (!addCluster()) goto writeErrorReturn; - } else { - curCluster_ = next; - } - } - } - // max space in block - uint16_t n = 512 - blockOffset; - - // lesser of space and amount to write - if (n > nToWrite) n = nToWrite; - - // block for data write - uint32_t block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; - if (n == 512) { - // full block - don't need to use cache - // invalidate cache if block is in cache - if (SdVolume::cacheBlockNumber_ == block) { - SdVolume::cacheBlockNumber_ = 0XFFFFFFFF; - } - if (!vol_->writeBlock(block, src)) goto writeErrorReturn; - src += 512; - } else { - if (blockOffset == 0 && curPosition_ >= fileSize_) { - // start of new block don't need to read into cache - if (!SdVolume::cacheFlush()) goto writeErrorReturn; - SdVolume::cacheBlockNumber_ = block; - SdVolume::cacheSetDirty(); - } else { - // rewrite part of block - if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) { - goto writeErrorReturn; - } - } - uint8_t* dst = SdVolume::cacheBuffer_.data + blockOffset; - uint8_t* end = dst + n; - while (dst != end) *dst++ = *src++; - } - nToWrite -= n; - curPosition_ += n; - } - if (curPosition_ > fileSize_) { - // update fileSize and insure sync will update dir entry - fileSize_ = curPosition_; - flags_ |= F_FILE_DIR_DIRTY; - } else if (dateTime_ && nbyte) { - // insure sync will update modified date and time - flags_ |= F_FILE_DIR_DIRTY; - } - - if (flags_ & O_SYNC) { - if (!sync()) goto writeErrorReturn; - } - return nbyte; - - writeErrorReturn: - // return for write error - writeError = true; - return -1; -} -//------------------------------------------------------------------------------ -/** - * Write a byte to a file. Required by the Arduino Print class. - * - * Use SdFile::writeError to check for errors. - */ -void SdFile::write(uint8_t b) { - write(&b, 1); -} -//------------------------------------------------------------------------------ -/** - * Write a string to a file. Used by the Arduino Print class. - * - * Use SdFile::writeError to check for errors. - */ -void SdFile::write(const char* str) { - write(str, strlen(str)); -} -//------------------------------------------------------------------------------ -/** - * Write a PROGMEM string to a file. - * - * Use SdFile::writeError to check for errors. - -void SdFile::write_P(PGM_P str) { - for (uint8_t c; (c = pgm_read_byte(str)); str++) write(c); -} -*/ -//------------------------------------------------------------------------------ -/** - * Write a PROGMEM string followed by CR/LF to a file. - * - * Use SdFile::writeError to check for errors. - -void SdFile::writeln_P(PGM_P str) { - write_P(str); - println(); -} +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#include +#include "SdFat.h" +//#include +#include +#include "HardwareSPI.h" +#include + +//------------------------------------------------------------------------------ +// callback function for date/time +void (*SdFile::dateTime_)(uint16_t* date, uint16_t* time) = NULL; + +#if ALLOW_DEPRECATED_FUNCTIONS +// suppress cpplint warnings with NOLINT comment +void (*SdFile::oldDateTime_)(uint16_t& date, uint16_t& time) = NULL; // NOLINT +#endif // ALLOW_DEPRECATED_FUNCTIONS +//------------------------------------------------------------------------------ +// add a cluster to a file +uint8_t SdFile::addCluster() { + if (!vol_->allocContiguous(1, &curCluster_)) return false; + + // if first cluster of file link to directory entry + if (firstCluster_ == 0) { + firstCluster_ = curCluster_; + flags_ |= F_FILE_DIR_DIRTY; + } + return true; +} +//------------------------------------------------------------------------------ +// Add a cluster to a directory file and zero the cluster. +// return with first block of cluster in the cache +uint8_t SdFile::addDirCluster(void) { + if (!addCluster()) return false; + + // zero data in cluster insure first cluster is in cache + uint32_t block = vol_->clusterStartBlock(curCluster_); + for (uint8_t i = vol_->blocksPerCluster_; i != 0; i--) { + if (!SdVolume::cacheZeroBlock(block + i - 1)) return false; + } + // Increase directory file size by cluster size + fileSize_ += 512UL << vol_->clusterSizeShift_; + return true; +} +//------------------------------------------------------------------------------ +// cache a file's directory entry +// return pointer to cached entry or null for failure +dir_t* SdFile::cacheDirEntry(uint8_t action) { + if (!SdVolume::cacheRawBlock(dirBlock_, action)) return NULL; + return SdVolume::cacheBuffer_.dir + dirIndex_; +} +//------------------------------------------------------------------------------ +/** + * Close a file and force cached data and directory information + * to be written to the storage device. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include no file is open or an I/O error. + */ +uint8_t SdFile::close(void) { + if (!sync())return false; + type_ = FAT_FILE_TYPE_CLOSED; + return true; +} +//------------------------------------------------------------------------------ +/** + * Check for contiguous file and return its raw block range. + * + * \param[out] bgnBlock the first block address for the file. + * \param[out] endBlock the last block address for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is not contiguous, file has zero length + * or an I/O error occurred. + */ +uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { + // error if no blocks + if (firstCluster_ == 0) return false; + + for (uint32_t c = firstCluster_; ; c++) { + uint32_t next; + if (!vol_->fatGet(c, &next)) return false; + + // check for contiguous + if (next != (c + 1)) { + // error if not end of chain + if (!vol_->isEOC(next)) return false; + *bgnBlock = vol_->clusterStartBlock(firstCluster_); + *endBlock = vol_->clusterStartBlock(c) + + vol_->blocksPerCluster_ - 1; + return true; + } + } +} +//------------------------------------------------------------------------------ +/** + * Create and open a new contiguous file of a specified size. + * + * \note This function only supports short DOS 8.3 names. + * See open() for more information. + * + * \param[in] dirFile The directory where the file will be created. + * \param[in] fileName A valid DOS 8.3 file name. + * \param[in] size The desired file size. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include \a fileName contains + * an invalid DOS 8.3 file name, the FAT volume has not been initialized, + * a file is already open, the file already exists, the root + * directory is full or an I/O error. + * + */ +uint8_t SdFile::createContiguous(SdFile* dirFile, + const char* fileName, uint32_t size) { + // don't allow zero length file + if (size == 0) return false; + if (!open(dirFile, fileName, O_CREAT | O_EXCL | O_RDWR)) return false; + + // calculate number of clusters needed + uint32_t count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1; + + // allocate clusters + if (!vol_->allocContiguous(count, &firstCluster_)) { + remove(); + return false; + } + fileSize_ = size; + + // insure sync() will update dir entry + flags_ |= F_FILE_DIR_DIRTY; + return sync(); +} +//------------------------------------------------------------------------------ +/** + * Return a files directory entry + * + * \param[out] dir Location for return of the files directory entry. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t SdFile::dirEntry(dir_t* dir) { + // make sure fields on SD are correct + if (!sync()) return false; + + // read entry + dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_READ); + if (!p) return false; + + // copy to caller's struct + memcpy(dir, p, sizeof(dir_t)); + return true; +} +//------------------------------------------------------------------------------ +/** + * Format the name field of \a dir into the 13 byte array + * \a name in standard 8.3 short name format. + * + * \param[in] dir The directory structure containing the name. + * \param[out] name A 13 byte char array for the formatted name. + */ +void SdFile::dirName(const dir_t& dir, char* name) { + uint8_t j = 0; + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) name[j++] = '.'; + name[j++] = dir.name[i]; + } + name[j] = 0; +} +//------------------------------------------------------------------------------ +/** List directory contents to Serial. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + * + * \param[in] indent Amount of space before file name. Used for recursive + * list to indicate subdirectory level. + */ +void SdFile::ls(uint8_t flags, uint8_t indent) { + dir_t* p; + + rewind(); + while ((p = readDirCache())) { + // done if past last used entry + if (p->name[0] == DIR_NAME_FREE) break; + + // skip deleted entry and entries for . and .. + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + + // only list subdirectories and files + if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; + + // print any indent spaces + for (int8_t i = 0; i < indent; i++) SerialDebug.print(' '); + + // print file name with possible blank fill + printDirName(*p, flags & (LS_DATE | LS_SIZE) ? 14 : 0); + + // print modify date/time if requested + if (flags & LS_DATE) { + printFatDate(p->lastWriteDate); + SerialDebug.print(' '); + printFatTime(p->lastWriteTime); + } + // print size if requested + if (!DIR_IS_SUBDIR(p) && (flags & LS_SIZE)) { + SerialDebug.print(' '); + SerialDebug.print(p->fileSize); + } + SerialDebug.println(); + + // list subdirectory content if requested + if ((flags & LS_R) && DIR_IS_SUBDIR(p)) { + uint16_t index = curPosition()/32 - 1; + SdFile s; + if (s.open(this, index, O_READ)) s.ls(flags, indent + 2); + seekSet(32 * (index + 1)); + } + } +} +//------------------------------------------------------------------------------ +// format directory name field from a 8.3 name string +uint8_t SdFile::make83Name(const char* str, uint8_t* name) { + uint8_t c; + uint8_t n = 7; // max index for part before dot + uint8_t i = 0; + // blank fill name and extension + while (i < 11) name[i++] = ' '; + i = 0; + while ((c = *str++) != '\0') { + if (c == '.') { + if (n == 10) return false; // only one dot allowed + n = 10; // max index for full 8.3 name + i = 8; // place for extension + } else { + // illegal FAT characters +// PGM_P p = PSTR("|<>^+=?/[];,*\"\\"); + char p[17] = {"|<>^+=?/[];,*\"\\"}; + char *ptr = p; + uint8_t b; + while ((b = *(ptr++))) + if (b == c) + return false; + // check size and only allow ASCII printable characters + if (i > n || c < 0X21 || c > 0X7E)return false; + // only upper case allowed in 8.3 names - convert lower to upper + name[i++] = c < 'a' || c > 'z' ? c : c + ('A' - 'a'); + } + } + // must have a file name, extension is optional + return name[0] != ' '; +} +//------------------------------------------------------------------------------ +/** Make a new directory. + * + * \param[in] dir An open SdFat instance for the directory that will containing + * the new directory. + * + * \param[in] dirName A valid 8.3 DOS name for the new directory. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include this SdFile is already open, \a dir is not a + * directory, \a dirName is invalid or already exists in \a dir. + */ +uint8_t SdFile::makeDir(SdFile* dir, const char* dirName) { + dir_t d; + + // create a normal file + if (!open(dir, dirName, O_CREAT | O_EXCL | O_RDWR)) return false; + + // convert SdFile to directory + flags_ = O_READ; + type_ = FAT_FILE_TYPE_SUBDIR; + + // allocate and zero first cluster + if (!addDirCluster())return false; + + // force entry to SD + if (!sync()) return false; + + // cache entry - should already be in cache due to sync() call + dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!p) return false; + + // change directory entry attribute + p->attributes = DIR_ATT_DIRECTORY; + + // make entry for '.' + memcpy(&d, p, sizeof(d)); + for (uint8_t i = 1; i < 11; i++) d.name[i] = ' '; + d.name[0] = '.'; + + // cache block for '.' and '..' + uint32_t block = vol_->clusterStartBlock(firstCluster_); + if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) return false; + + // copy '.' to block + memcpy(&SdVolume::cacheBuffer_.dir[0], &d, sizeof(d)); + + // make entry for '..' + d.name[1] = '.'; + if (dir->isRoot()) { + d.firstClusterLow = 0; + d.firstClusterHigh = 0; + } else { + d.firstClusterLow = dir->firstCluster_ & 0XFFFF; + d.firstClusterHigh = dir->firstCluster_ >> 16; + } + // copy '..' to block + memcpy(&SdVolume::cacheBuffer_.dir[1], &d, sizeof(d)); + + // set position after '..' + curPosition_ = 2 * sizeof(d); + + // write first block + return SdVolume::cacheFlush(); +} +//------------------------------------------------------------------------------ +/** + * Open a file or directory by name. + * + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * + * \param[in] fileName A valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * O_READ - Open for reading. + * + * O_RDONLY - Same as O_READ. + * + * O_WRITE - Open for writing. + * + * O_WRONLY - Same as O_WRITE. + * + * O_RDWR - Open for reading and writing. + * + * O_APPEND - If set, the file offset shall be set to the end of the + * file prior to each write. + * + * O_CREAT - If the file exists, this flag has no effect except as noted + * under O_EXCL below. Otherwise, the file shall be created + * + * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists. + * + * O_SYNC - Call sync() after each write. This flag should not be used with + * write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class. + * These functions do character at a time writes so sync() will be called + * after each byte. + * + * O_TRUNC - If the file exists and is a regular file, and the file is + * successfully opened and is not read only, its length shall be truncated to 0. + * + * \note Directory files must be opened read only. Write and truncation is + * not allowed for directory files. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include this SdFile is already open, \a difFile is not + * a directory, \a fileName is invalid, the file does not exist + * or can't be opened in the access mode specified by oflag. + */ +uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag) { + uint8_t dname[11]; + dir_t* p; + + // error if already open + if (isOpen())return false; + + if (!make83Name(fileName, dname)) return false; + vol_ = dirFile->vol_; + dirFile->rewind(); + + // bool for empty entry found + uint8_t emptyFound = false; + + // search for file + while (dirFile->curPosition_ < dirFile->fileSize_) { + uint8_t index = 0XF & (dirFile->curPosition_ >> 5); + p = dirFile->readDirCache(); + if (p == NULL) return false; + + if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) { + // remember first empty slot + if (!emptyFound) { + emptyFound = true; + dirIndex_ = index; + dirBlock_ = SdVolume::cacheBlockNumber_; + } + // done if no entries follow + if (p->name[0] == DIR_NAME_FREE) break; + } else if (!memcmp(dname, p->name, 11)) { + // don't open existing file if O_CREAT and O_EXCL + if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false; + + // open found file + return openCachedEntry(0XF & index, oflag); + } + } + // only create file if O_CREAT and O_WRITE + if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false; + + // cache found slot or add cluster if end of file + if (emptyFound) { + p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!p) return false; + } else { + if (dirFile->type_ == FAT_FILE_TYPE_ROOT16) return false; + + // add and zero cluster for dirFile - first cluster is in cache for write + if (!dirFile->addDirCluster()) return false; + + // use first entry in cluster + dirIndex_ = 0; + p = SdVolume::cacheBuffer_.dir; + } + // initialize as empty file + memset(p, 0, sizeof(dir_t)); + memcpy(p->name, dname, 11); + + // set timestamps + if (dateTime_) { + // call user function + dateTime_(&p->creationDate, &p->creationTime); + } else { + // use default date/time + p->creationDate = FAT_DEFAULT_DATE; + p->creationTime = FAT_DEFAULT_TIME; + } + p->lastAccessDate = p->creationDate; + p->lastWriteDate = p->creationDate; + p->lastWriteTime = p->creationTime; + + // force write of entry to SD + if (!SdVolume::cacheFlush()) return false; + + // open entry in cache + return openCachedEntry(dirIndex_, oflag); +} +//------------------------------------------------------------------------------ +/** + * Open a file by index. + * + * \param[in] dirFile An open SdFat instance for the directory. + * + * \param[in] index The \a index of the directory entry for the file to be + * opened. The value for \a index is (directory file position)/32. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * + * See open() by fileName for definition of flags and return values. + * + */ +uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag) { + // error if already open + if (isOpen())return false; + + // don't open existing file if O_CREAT and O_EXCL - user call error + if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false; + + vol_ = dirFile->vol_; + + // seek to location of entry + if (!dirFile->seekSet(32 * index)) return false; + + // read entry into cache + dir_t* p = dirFile->readDirCache(); + if (p == NULL) return false; + + // error if empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_FREE || + p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { + return false; + } + // open cached entry + return openCachedEntry(index & 0XF, oflag); +} +//------------------------------------------------------------------------------ +// open a cached directory entry. Assumes vol_ is initializes +uint8_t SdFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) { + // location of entry in cache + dir_t* p = SdVolume::cacheBuffer_.dir + dirIndex; + + // write or truncate is an error for a directory or read-only file + if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) { + if (oflag & (O_WRITE | O_TRUNC)) return false; + } + // remember location of directory entry on SD + dirIndex_ = dirIndex; + dirBlock_ = SdVolume::cacheBlockNumber_; + + // copy first cluster number for directory fields + firstCluster_ = (uint32_t)p->firstClusterHigh << 16; + firstCluster_ |= p->firstClusterLow; + + // make sure it is a normal file or subdirectory + if (DIR_IS_FILE(p)) { + fileSize_ = p->fileSize; + type_ = FAT_FILE_TYPE_NORMAL; + } else if (DIR_IS_SUBDIR(p)) { + if (!vol_->chainSize(firstCluster_, &fileSize_)) return false; + type_ = FAT_FILE_TYPE_SUBDIR; + } else { + return false; + } + // save open flags for read/write + flags_ = oflag & (O_ACCMODE | O_SYNC | O_APPEND); + + // set to start of file + curCluster_ = 0; + curPosition_ = 0; + + // truncate file to zero length if requested + if (oflag & O_TRUNC) return truncate(0); + return true; +} +//------------------------------------------------------------------------------ +/** + * Open a volume's root directory. + * + * \param[in] vol The FAT volume containing the root directory to be opened. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the FAT volume has not been initialized + * or it a FAT12 volume. + */ +uint8_t SdFile::openRoot(SdVolume* vol) { + // error if file is already open + if (isOpen()) return false; + + if (vol->fatType() == 16) { + type_ = FAT_FILE_TYPE_ROOT16; + firstCluster_ = 0; + fileSize_ = 32 * vol->rootDirEntryCount(); + } else if (vol->fatType() == 32) { + type_ = FAT_FILE_TYPE_ROOT32; + firstCluster_ = vol->rootDirStart(); + if (!vol->chainSize(firstCluster_, &fileSize_)) return false; + } else { + // volume is not initialized or FAT12 + return false; + } + vol_ = vol; + // read only + flags_ = O_READ; + + // set to start of file + curCluster_ = 0; + curPosition_ = 0; + + // root has no directory entry + dirBlock_ = 0; + dirIndex_ = 0; + return true; +} +//------------------------------------------------------------------------------ +/** %Print the name field of a directory entry in 8.3 format to Serial. + * + * \param[in] dir The directory structure containing the name. + * \param[in] width Blank fill name if length is less than \a width. + */ +void SdFile::printDirName(const dir_t& dir, uint8_t width) { + uint8_t w = 0; + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) { + SerialDebug.print('.'); + w++; + } + SerialDebug.print((char)dir.name[i]); + w++; + } + if (DIR_IS_SUBDIR(&dir)) { + SerialDebug.print('/'); + w++; + } + while (w < width) { + SerialDebug.print(' '); + w++; + } +} +//------------------------------------------------------------------------------ +/** %Print a directory date field to Serial. + * + * Format is yyyy-mm-dd. + * + * \param[in] fatDate The date field from a directory entry. + */ +void SdFile::printFatDate(uint16_t fatDate) { + SerialDebug.print(FAT_YEAR(fatDate)); + SerialDebug.print('-'); + printTwoDigits(FAT_MONTH(fatDate)); + SerialDebug.print('-'); + printTwoDigits(FAT_DAY(fatDate)); +} +//------------------------------------------------------------------------------ +/** %Print a directory time field to Serial. + * + * Format is hh:mm:ss. + * + * \param[in] fatTime The time field from a directory entry. + */ +void SdFile::printFatTime(uint16_t fatTime) { + printTwoDigits(FAT_HOUR(fatTime)); + SerialDebug.print(':'); + printTwoDigits(FAT_MINUTE(fatTime)); + SerialDebug.print(':'); + printTwoDigits(FAT_SECOND(fatTime)); +} +//------------------------------------------------------------------------------ +/** %Print a value as two digits to Serial. + * + * \param[in] v Value to be printed, 0 <= \a v <= 99 + */ +void SdFile::printTwoDigits(uint8_t v) { + char str[3]; + str[0] = '0' + v/10; + str[1] = '0' + v % 10; + str[2] = 0; + SerialDebug.print(str); +} +//------------------------------------------------------------------------------ +/** + * Read data from a file starting at the current position. + * + * \param[out] buf Pointer to the location that will receive the data. + * + * \param[in] nbyte Maximum number of bytes to read. + * + * \return For success read() returns the number of bytes read. + * A value less than \a nbyte, including zero, will be returned + * if end of file is reached. + * If an error occurs, read() returns -1. Possible errors include + * read() called before a file has been opened, corrupt file system + * or an I/O error occurred. + */ +int16_t SdFile::read(void* buf, uint16_t nbyte) { + uint8_t* dst = reinterpret_cast(buf); + + // error if not open or write only + if (!isOpen() || !(flags_ & O_READ)) return -1; + + // max bytes left in file + if (nbyte > (fileSize_ - curPosition_)) nbyte = fileSize_ - curPosition_; + + // amount left to read + uint16_t toRead = nbyte; + while (toRead > 0) { + uint32_t block; // raw device block number + uint16_t offset = curPosition_ & 0X1FF; // offset in block + if (type_ == FAT_FILE_TYPE_ROOT16) { + block = vol_->rootDirStart() + (curPosition_ >> 9); + } else { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + if (offset == 0 && blockOfCluster == 0) { + // start of new cluster + if (curPosition_ == 0) { + // use first cluster in file + curCluster_ = firstCluster_; + } else { + // get next cluster from FAT + if (!vol_->fatGet(curCluster_, &curCluster_)) return -1; + } + } + block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + } + uint16_t n = toRead; + + // amount to be read from current block + if (n > (512 - offset)) n = 512 - offset; + +#if 0 + SerialDebug.print("block "); + SerialDebug.print(block); + SerialDebug.print(" n "); + SerialDebug.println(n); +#endif + // no buffering needed if n == 512 or user requests no buffering + if ((unbufferedRead() || n == 512) && block != SdVolume::cacheBlockNumber_) { + if (!vol_->readData(block, offset, n, dst)) return -1; + dst += n; + } else { + // read block to cache and copy data to caller + if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) return -1; + uint8_t* src = SdVolume::cacheBuffer_.data + offset; + uint8_t* end = src + n; + while (src != end) *dst++ = *src++; + } + curPosition_ += n; + toRead -= n; + } + return nbyte; +} +//------------------------------------------------------------------------------ +/** + * Read the next directory entry from a directory file. + * + * \param[out] dir The dir_t struct that will receive the data. + * + * \return For success readDir() returns the number of bytes read. + * A value of zero will be returned if end of file is reached. + * If an error occurs, readDir() returns -1. Possible errors include + * readDir() called before a directory has been opened, this is not + * a directory file or an I/O error occurred. + */ +int8_t SdFile::readDir(dir_t* dir) { + int8_t n; + // if not a directory file or miss-positioned return an error + if (!isDir() || (0X1F & curPosition_)) return -1; + + while ((n = read(dir, sizeof(dir_t))) == sizeof(dir_t)) { + // last entry if DIR_NAME_FREE + if (dir->name[0] == DIR_NAME_FREE) break; + // skip empty entries and entry for . and .. + if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') continue; + // return if normal file or subdirectory + if (DIR_IS_FILE_OR_SUBDIR(dir)) return n; + } + // error, end of file, or past last entry + return n < 0 ? -1 : 0; +} +//------------------------------------------------------------------------------ +// Read next directory entry into the cache +// Assumes file is correctly positioned +dir_t* SdFile::readDirCache(void) { + // error if not directory + if (!isDir()) return NULL; + + // index of entry in cache + uint8_t i = (curPosition_ >> 5) & 0XF; + + // use read to locate and cache block + if (read() < 0) return NULL; + + // advance to next entry + curPosition_ += 31; + + // return pointer to entry + return (SdVolume::cacheBuffer_.dir + i); +} +//------------------------------------------------------------------------------ +/** + * Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file read-only, is a directory, + * or an I/O error occurred. + */ +uint8_t SdFile::remove(void) { + // free any clusters - will fail if read-only or directory + if (!truncate(0)) return false; + + // cache directory entry + dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) return false; + + // mark entry deleted + d->name[0] = DIR_NAME_DELETED; + + // set this SdFile closed + type_ = FAT_FILE_TYPE_CLOSED; + + // write entry to SD + return SdVolume::cacheFlush(); +} +//------------------------------------------------------------------------------ +/** + * Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \param[in] dirFile The directory that contains the file. + * \param[in] fileName The name of the file to be removed. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is a directory, is read only, + * \a dirFile is not a directory, \a fileName is not found + * or an I/O error occurred. + */ +uint8_t SdFile::remove(SdFile* dirFile, const char* fileName) { + SdFile file; + if (!file.open(dirFile, fileName, O_WRITE)) return false; + return file.remove(); +} +//------------------------------------------------------------------------------ +/** Remove a directory file. + * + * The directory file will be removed only if it is empty and is not the + * root directory. rmDir() follows DOS and Windows and ignores the + * read-only attribute for the directory. + * + * \note This function should not be used to delete the 8.3 version of a + * directory that has a long name. For example if a directory has the + * long name "New folder" you should not delete the 8.3 name "NEWFOL~1". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is not a directory, is the root + * directory, is not empty, or an I/O error occurred. + */ +uint8_t SdFile::rmDir(void) { + // must be open subdirectory + if (!isSubDir()) return false; + + rewind(); + + // make sure directory is empty + while (curPosition_ < fileSize_) { + dir_t* p = readDirCache(); + if (p == NULL) return false; + // done if past last used entry + if (p->name[0] == DIR_NAME_FREE) break; + // skip empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + // error not empty + if (DIR_IS_FILE_OR_SUBDIR(p)) return false; + } + // convert empty directory to normal file for remove + type_ = FAT_FILE_TYPE_NORMAL; + flags_ |= O_WRITE; + return remove(); +} +//------------------------------------------------------------------------------ +/** Recursively delete a directory and all contained files. + * + * This is like the Unix/Linux 'rm -rf *' if called with the root directory + * hence the name. + * + * Warning - This will remove all contents of the directory including + * subdirectories. The directory will then be removed if it is not root. + * The read-only attribute for files will be ignored. + * + * \note This function should not be used to delete the 8.3 version of + * a directory that has a long name. See remove() and rmDir(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t SdFile::rmRfStar(void) { + rewind(); + while (curPosition_ < fileSize_) { + SdFile f; + + // remember position + uint16_t index = curPosition_/32; + + dir_t* p = readDirCache(); + if (!p) return false; + + // done if past last entry + if (p->name[0] == DIR_NAME_FREE) break; + + // skip empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + + // skip if part of long file name or volume label in root + if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; + + if (!f.open(this, index, O_READ)) return false; + if (f.isSubDir()) { + // recursively delete + if (!f.rmRfStar()) return false; + } else { + // ignore read-only + f.flags_ |= O_WRITE; + if (!f.remove()) return false; + } + // position to next entry if required + if (curPosition_ != (32*(index + 1))) { + if (!seekSet(32*(index + 1))) return false; + } + } + // don't try to delete root + if (isRoot()) return true; + return rmDir(); +} +//------------------------------------------------------------------------------ +/** + * Sets a file's position. + * + * \param[in] pos The new position in bytes from the beginning of the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t SdFile::seekSet(uint32_t pos) { + // error if file not open or seek past end of file + if (!isOpen() || pos > fileSize_) return false; + + if (type_ == FAT_FILE_TYPE_ROOT16) { + curPosition_ = pos; + return true; + } + if (pos == 0) { + // set position to start of file + curCluster_ = 0; + curPosition_ = 0; + return true; + } + // calculate cluster index for cur and new position + uint32_t nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9); + uint32_t nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9); + + if (nNew < nCur || curPosition_ == 0) { + // must follow chain from first cluster + curCluster_ = firstCluster_; + } else { + // advance from curPosition + nNew -= nCur; + } + while (nNew--) { + if (!vol_->fatGet(curCluster_, &curCluster_)) return false; + } + curPosition_ = pos; + return true; +} +//------------------------------------------------------------------------------ +/** + * The sync() call causes all modified data and directory fields + * to be written to the storage device. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include a call to sync() before a file has been + * opened or an I/O error. + */ +uint8_t SdFile::sync(void) { + // only allow open files and directories + if (!isOpen()) return false; + + if (flags_ & F_FILE_DIR_DIRTY) { + dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) return false; + + // do not set filesize for dir files + if (!isDir()) d->fileSize = fileSize_; + + // update first cluster fields + d->firstClusterLow = firstCluster_ & 0XFFFF; + d->firstClusterHigh = firstCluster_ >> 16; + + // set modify time if user supplied a callback date/time function + if (dateTime_) { + dateTime_(&d->lastWriteDate, &d->lastWriteTime); + d->lastAccessDate = d->lastWriteDate; + } + // clear directory dirty + flags_ &= ~F_FILE_DIR_DIRTY; + } + return SdVolume::cacheFlush(); +} +//------------------------------------------------------------------------------ +/** + * Set a file's timestamps in its directory entry. + * + * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * T_ACCESS - Set the file's last access date. + * + * T_CREATE - Set the file's creation date and time. + * + * T_WRITE - Set the file's last write/modification date and time. + * + * \param[in] year Valid range 1980 - 2107 inclusive. + * + * \param[in] month Valid range 1 - 12 inclusive. + * + * \param[in] day Valid range 1 - 31 inclusive. + * + * \param[in] hour Valid range 0 - 23 inclusive. + * + * \param[in] minute Valid range 0 - 59 inclusive. + * + * \param[in] second Valid range 0 - 59 inclusive + * + * \note It is possible to set an invalid date since there is no check for + * the number of days in a month. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t SdFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, + uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { + if (!isOpen() + || year < 1980 + || year > 2107 + || month < 1 + || month > 12 + || day < 1 + || day > 31 + || hour > 23 + || minute > 59 + || second > 59) { + return false; + } + dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) return false; + + uint16_t dirDate = FAT_DATE(year, month, day); + uint16_t dirTime = FAT_TIME(hour, minute, second); + if (flags & T_ACCESS) { + d->lastAccessDate = dirDate; + } + if (flags & T_CREATE) { + d->creationDate = dirDate; + d->creationTime = dirTime; + // seems to be units of 1/100 second not 1/10 as Microsoft states + d->creationTimeTenths = second & 1 ? 100 : 0; + } + if (flags & T_WRITE) { + d->lastWriteDate = dirDate; + d->lastWriteTime = dirTime; + } + SdVolume::cacheSetDirty(); + return sync(); +} +//------------------------------------------------------------------------------ +/** + * Truncate a file to a specified length. The current file position + * will be maintained if it is less than or equal to \a length otherwise + * it will be set to end of file. + * + * \param[in] length The desired length for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is read only, file is a directory, + * \a length is greater than the current file size or an I/O error occurs. + */ +uint8_t SdFile::truncate(uint32_t length) { +// error if not a normal file or read-only + if (!isFile() || !(flags_ & O_WRITE)) return false; + + // error if length is greater than current size + if (length > fileSize_) return false; + + // fileSize and length are zero - nothing to do + if (fileSize_ == 0) return true; + + // remember position for seek after truncation + uint32_t newPos = curPosition_ > length ? length : curPosition_; + + // position to last cluster in truncated file + if (!seekSet(length)) return false; + + if (length == 0) { + // free all clusters + if (!vol_->freeChain(firstCluster_)) return false; + firstCluster_ = 0; + } else { + uint32_t toFree; + if (!vol_->fatGet(curCluster_, &toFree)) return false; + + if (!vol_->isEOC(toFree)) { + // free extra clusters + if (!vol_->freeChain(toFree)) return false; + + // current cluster is end of chain + if (!vol_->fatPutEOC(curCluster_)) return false; + } + } + fileSize_ = length; + + // need to update directory entry + flags_ |= F_FILE_DIR_DIRTY; + + if (!sync()) return false; + + // set file to correct position + return seekSet(newPos); +} +//------------------------------------------------------------------------------ +/** + * Write data to an open file. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] nbyte Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \a nbyte. If an error occurs, write() returns -1. Possible errors + * include write() is called before a file has been opened, write is called + * for a read-only file, device is full, a corrupt file system or an I/O error. + * + */ +int16_t SdFile::write(const void* buf, uint16_t nbyte) { + // convert void* to uint8_t* - must be before goto statements + const uint8_t* src = reinterpret_cast(buf); + + // number of bytes left to write - must be before goto statements + uint16_t nToWrite = nbyte; + + // error if not a normal file or is read-only + if (!isFile() || !(flags_ & O_WRITE)) goto writeErrorReturn; + + // seek to end of file if append flag + if ((flags_ & O_APPEND) && curPosition_ != fileSize_) { + if (!seekEnd()) goto writeErrorReturn; + } + + while (nToWrite > 0) { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + uint16_t blockOffset = curPosition_ & 0X1FF; + if (blockOfCluster == 0 && blockOffset == 0) { + // start of new cluster + if (curCluster_ == 0) { + if (firstCluster_ == 0) { + // allocate first cluster of file + if (!addCluster()) goto writeErrorReturn; + } else { + curCluster_ = firstCluster_; + } + } else { + uint32_t next; + if (!vol_->fatGet(curCluster_, &next)) return false; + if (vol_->isEOC(next)) { + // add cluster if at end of chain + if (!addCluster()) goto writeErrorReturn; + } else { + curCluster_ = next; + } + } + } + // max space in block + uint16_t n = 512 - blockOffset; + + // lesser of space and amount to write + if (n > nToWrite) n = nToWrite; + + // block for data write + uint32_t block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + if (n == 512) { + // full block - don't need to use cache + // invalidate cache if block is in cache + if (SdVolume::cacheBlockNumber_ == block) { + SdVolume::cacheBlockNumber_ = 0XFFFFFFFF; + } + if (!vol_->writeBlock(block, src)) goto writeErrorReturn; + src += 512; + } else { + if (blockOffset == 0 && curPosition_ >= fileSize_) { + // start of new block don't need to read into cache + if (!SdVolume::cacheFlush()) goto writeErrorReturn; + SdVolume::cacheBlockNumber_ = block; + SdVolume::cacheSetDirty(); + } else { + // rewrite part of block + if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) { + goto writeErrorReturn; + } + } + uint8_t* dst = SdVolume::cacheBuffer_.data + blockOffset; + uint8_t* end = dst + n; + while (dst != end) *dst++ = *src++; + } + nToWrite -= n; + curPosition_ += n; + } + if (curPosition_ > fileSize_) { + // update fileSize and insure sync will update dir entry + fileSize_ = curPosition_; + flags_ |= F_FILE_DIR_DIRTY; + } else if (dateTime_ && nbyte) { + // insure sync will update modified date and time + flags_ |= F_FILE_DIR_DIRTY; + } + + if (flags_ & O_SYNC) { + if (!sync()) goto writeErrorReturn; + } + return nbyte; + + writeErrorReturn: + // return for write error + writeError = true; + return -1; +} +//------------------------------------------------------------------------------ +/** + * Write a byte to a file. Required by the Arduino Print class. + * + * Use SdFile::writeError to check for errors. + */ +void SdFile::write(uint8_t b) { + write(&b, 1); +} +//------------------------------------------------------------------------------ +/** + * Write a string to a file. Used by the Arduino Print class. + * + * Use SdFile::writeError to check for errors. + */ +void SdFile::write(const char* str) { + write(str, strlen(str)); +} +//------------------------------------------------------------------------------ +/** + * Write a PROGMEM string to a file. + * + * Use SdFile::writeError to check for errors. + +void SdFile::write_P(PGM_P str) { + for (uint8_t c; (c = pgm_read_byte(str)); str++) write(c); +} +*/ +//------------------------------------------------------------------------------ +/** + * Write a PROGMEM string followed by CR/LF to a file. + * + * Use SdFile::writeError to check for errors. + +void SdFile::writeln_P(PGM_P str) { + write_P(str); + println(); +} */ \ No newline at end of file diff --git a/Libmaple/libmaple/libraries/mapleSDfat/SdInfo.h b/Libmaple/libmaple/libraries/mapleSDfat/SdInfo.h index acde74d9..bc4c6137 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/SdInfo.h +++ b/Libmaple/libmaple/libraries/mapleSDfat/SdInfo.h @@ -1,232 +1,232 @@ -/* Arduino Sd2Card Library - * Copyright (C) 2009 by William Greiman - * - * This file is part of the Arduino Sd2Card Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino Sd2Card Library. If not, see - * . - */ -#ifndef SdInfo_h -#define SdInfo_h -#include -// Based on the document: -// -// SD Specifications -// Part 1 -// Physical Layer -// Simplified Specification -// Version 2.00 -// September 25, 2006 -// -// www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf -//------------------------------------------------------------------------------ -// SD card commands -/** GO_IDLE_STATE - init card in spi mode if CS low */ -uint8_t const CMD0 = 0X00; -/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ -uint8_t const CMD8 = 0X08; -/** SEND_CSD - read the Card Specific Data (CSD register) */ -uint8_t const CMD9 = 0X09; -/** SEND_CID - read the card identification information (CID register) */ -uint8_t const CMD10 = 0X0A; -/** SEND_STATUS - read the card status register */ -uint8_t const CMD13 = 0X0D; -/** READ_BLOCK - read a single data block from the card */ -uint8_t const CMD17 = 0X11; -/** WRITE_BLOCK - write a single data block to the card */ -uint8_t const CMD24 = 0X18; -/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ -uint8_t const CMD25 = 0X19; -/** ERASE_WR_BLK_START - sets the address of the first block to be erased */ -uint8_t const CMD32 = 0X20; -/** ERASE_WR_BLK_END - sets the address of the last block of the continuous - range to be erased*/ -uint8_t const CMD33 = 0X21; -/** ERASE - erase all previously selected blocks */ -uint8_t const CMD38 = 0X26; -/** APP_CMD - escape for application specific command */ -uint8_t const CMD55 = 0X37; -/** READ_OCR - read the OCR register of a card */ -uint8_t const CMD58 = 0X3A; -/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be - pre-erased before writing */ -uint8_t const ACMD23 = 0X17; -/** SD_SEND_OP_COMD - Sends host capacity support information and - activates the card's initialization process */ -uint8_t const ACMD41 = 0X29; -//------------------------------------------------------------------------------ -/** status for card in the ready state */ -uint8_t const R1_READY_STATE = 0X00; -/** status for card in the idle state */ -uint8_t const R1_IDLE_STATE = 0X01; -/** status bit for illegal command */ -uint8_t const R1_ILLEGAL_COMMAND = 0X04; -/** start data token for read or write single block*/ -uint8_t const DATA_START_BLOCK = 0XFE; -/** stop token for write multiple blocks*/ -uint8_t const STOP_TRAN_TOKEN = 0XFD; -/** start data token for write multiple blocks*/ -uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC; -/** mask for data response tokens after a write block operation */ -uint8_t const DATA_RES_MASK = 0X1F; -/** write data accepted token */ -uint8_t const DATA_RES_ACCEPTED = 0X05; -//------------------------------------------------------------------------------ -typedef struct CID { - // byte 0 - uint8_t mid; // Manufacturer ID - // byte 1-2 - char oid[2]; // OEM/Application ID - // byte 3-7 - char pnm[5]; // Product name - // byte 8 - unsigned prv_m : 4; // Product revision n.m - unsigned prv_n : 4; - // byte 9-12 - uint32_t psn; // Product serial number - // byte 13 - unsigned mdt_year_high : 4; // Manufacturing date - unsigned reserved : 4; - // byte 14 - unsigned mdt_month : 4; - unsigned mdt_year_low :4; - // byte 15 - unsigned always1 : 1; - unsigned crc : 7; -}cid_t; -//------------------------------------------------------------------------------ -// CSD for version 1.00 cards -typedef struct CSDV1 { - // byte 0 - unsigned reserved1 : 6; - unsigned csd_ver : 2; - // byte 1 - uint8_t taac; - // byte 2 - uint8_t nsac; - // byte 3 - uint8_t tran_speed; - // byte 4 - uint8_t ccc_high; - // byte 5 - unsigned read_bl_len : 4; - unsigned ccc_low : 4; - // byte 6 - unsigned c_size_high : 2; - unsigned reserved2 : 2; - unsigned dsr_imp : 1; - unsigned read_blk_misalign :1; - unsigned write_blk_misalign : 1; - unsigned read_bl_partial : 1; - // byte 7 - uint8_t c_size_mid; - // byte 8 - unsigned vdd_r_curr_max : 3; - unsigned vdd_r_curr_min : 3; - unsigned c_size_low :2; - // byte 9 - unsigned c_size_mult_high : 2; - unsigned vdd_w_cur_max : 3; - unsigned vdd_w_curr_min : 3; - // byte 10 - unsigned sector_size_high : 6; - unsigned erase_blk_en : 1; - unsigned c_size_mult_low : 1; - // byte 11 - unsigned wp_grp_size : 7; - unsigned sector_size_low : 1; - // byte 12 - unsigned write_bl_len_high : 2; - unsigned r2w_factor : 3; - unsigned reserved3 : 2; - unsigned wp_grp_enable : 1; - // byte 13 - unsigned reserved4 : 5; - unsigned write_partial : 1; - unsigned write_bl_len_low : 2; - // byte 14 - unsigned reserved5: 2; - unsigned file_format : 2; - unsigned tmp_write_protect : 1; - unsigned perm_write_protect : 1; - unsigned copy : 1; - unsigned file_format_grp : 1; - // byte 15 - unsigned always1 : 1; - unsigned crc : 7; -}csd1_t; -//------------------------------------------------------------------------------ -// CSD for version 2.00 cards -typedef struct CSDV2 { - // byte 0 - unsigned reserved1 : 6; - unsigned csd_ver : 2; - // byte 1 - uint8_t taac; - // byte 2 - uint8_t nsac; - // byte 3 - uint8_t tran_speed; - // byte 4 - uint8_t ccc_high; - // byte 5 - unsigned read_bl_len : 4; - unsigned ccc_low : 4; - // byte 6 - unsigned reserved2 : 4; - unsigned dsr_imp : 1; - unsigned read_blk_misalign :1; - unsigned write_blk_misalign : 1; - unsigned read_bl_partial : 1; - // byte 7 - unsigned reserved3 : 2; - unsigned c_size_high : 6; - // byte 8 - uint8_t c_size_mid; - // byte 9 - uint8_t c_size_low; - // byte 10 - unsigned sector_size_high : 6; - unsigned erase_blk_en : 1; - unsigned reserved4 : 1; - // byte 11 - unsigned wp_grp_size : 7; - unsigned sector_size_low : 1; - // byte 12 - unsigned write_bl_len_high : 2; - unsigned r2w_factor : 3; - unsigned reserved5 : 2; - unsigned wp_grp_enable : 1; - // byte 13 - unsigned reserved6 : 5; - unsigned write_partial : 1; - unsigned write_bl_len_low : 2; - // byte 14 - unsigned reserved7: 2; - unsigned file_format : 2; - unsigned tmp_write_protect : 1; - unsigned perm_write_protect : 1; - unsigned copy : 1; - unsigned file_format_grp : 1; - // byte 15 - unsigned always1 : 1; - unsigned crc : 7; -}csd2_t; -//------------------------------------------------------------------------------ -// union of old and new style CSD register -union csd_t { - csd1_t v1; - csd2_t v2; -}; -#endif // SdInfo_h +/* Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino Sd2Card Library. If not, see + * . + */ +#ifndef SdInfo_h +#define SdInfo_h +#include +// Based on the document: +// +// SD Specifications +// Part 1 +// Physical Layer +// Simplified Specification +// Version 2.00 +// September 25, 2006 +// +// www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf +//------------------------------------------------------------------------------ +// SD card commands +/** GO_IDLE_STATE - init card in spi mode if CS low */ +uint8_t const CMD0 = 0X00; +/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ +uint8_t const CMD8 = 0X08; +/** SEND_CSD - read the Card Specific Data (CSD register) */ +uint8_t const CMD9 = 0X09; +/** SEND_CID - read the card identification information (CID register) */ +uint8_t const CMD10 = 0X0A; +/** SEND_STATUS - read the card status register */ +uint8_t const CMD13 = 0X0D; +/** READ_BLOCK - read a single data block from the card */ +uint8_t const CMD17 = 0X11; +/** WRITE_BLOCK - write a single data block to the card */ +uint8_t const CMD24 = 0X18; +/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ +uint8_t const CMD25 = 0X19; +/** ERASE_WR_BLK_START - sets the address of the first block to be erased */ +uint8_t const CMD32 = 0X20; +/** ERASE_WR_BLK_END - sets the address of the last block of the continuous + range to be erased*/ +uint8_t const CMD33 = 0X21; +/** ERASE - erase all previously selected blocks */ +uint8_t const CMD38 = 0X26; +/** APP_CMD - escape for application specific command */ +uint8_t const CMD55 = 0X37; +/** READ_OCR - read the OCR register of a card */ +uint8_t const CMD58 = 0X3A; +/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be + pre-erased before writing */ +uint8_t const ACMD23 = 0X17; +/** SD_SEND_OP_COMD - Sends host capacity support information and + activates the card's initialization process */ +uint8_t const ACMD41 = 0X29; +//------------------------------------------------------------------------------ +/** status for card in the ready state */ +uint8_t const R1_READY_STATE = 0X00; +/** status for card in the idle state */ +uint8_t const R1_IDLE_STATE = 0X01; +/** status bit for illegal command */ +uint8_t const R1_ILLEGAL_COMMAND = 0X04; +/** start data token for read or write single block*/ +uint8_t const DATA_START_BLOCK = 0XFE; +/** stop token for write multiple blocks*/ +uint8_t const STOP_TRAN_TOKEN = 0XFD; +/** start data token for write multiple blocks*/ +uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC; +/** mask for data response tokens after a write block operation */ +uint8_t const DATA_RES_MASK = 0X1F; +/** write data accepted token */ +uint8_t const DATA_RES_ACCEPTED = 0X05; +//------------------------------------------------------------------------------ +typedef struct CID { + // byte 0 + uint8_t mid; // Manufacturer ID + // byte 1-2 + char oid[2]; // OEM/Application ID + // byte 3-7 + char pnm[5]; // Product name + // byte 8 + unsigned prv_m : 4; // Product revision n.m + unsigned prv_n : 4; + // byte 9-12 + uint32_t psn; // Product serial number + // byte 13 + unsigned mdt_year_high : 4; // Manufacturing date + unsigned reserved : 4; + // byte 14 + unsigned mdt_month : 4; + unsigned mdt_year_low :4; + // byte 15 + unsigned always1 : 1; + unsigned crc : 7; +}cid_t; +//------------------------------------------------------------------------------ +// CSD for version 1.00 cards +typedef struct CSDV1 { + // byte 0 + unsigned reserved1 : 6; + unsigned csd_ver : 2; + // byte 1 + uint8_t taac; + // byte 2 + uint8_t nsac; + // byte 3 + uint8_t tran_speed; + // byte 4 + uint8_t ccc_high; + // byte 5 + unsigned read_bl_len : 4; + unsigned ccc_low : 4; + // byte 6 + unsigned c_size_high : 2; + unsigned reserved2 : 2; + unsigned dsr_imp : 1; + unsigned read_blk_misalign :1; + unsigned write_blk_misalign : 1; + unsigned read_bl_partial : 1; + // byte 7 + uint8_t c_size_mid; + // byte 8 + unsigned vdd_r_curr_max : 3; + unsigned vdd_r_curr_min : 3; + unsigned c_size_low :2; + // byte 9 + unsigned c_size_mult_high : 2; + unsigned vdd_w_cur_max : 3; + unsigned vdd_w_curr_min : 3; + // byte 10 + unsigned sector_size_high : 6; + unsigned erase_blk_en : 1; + unsigned c_size_mult_low : 1; + // byte 11 + unsigned wp_grp_size : 7; + unsigned sector_size_low : 1; + // byte 12 + unsigned write_bl_len_high : 2; + unsigned r2w_factor : 3; + unsigned reserved3 : 2; + unsigned wp_grp_enable : 1; + // byte 13 + unsigned reserved4 : 5; + unsigned write_partial : 1; + unsigned write_bl_len_low : 2; + // byte 14 + unsigned reserved5: 2; + unsigned file_format : 2; + unsigned tmp_write_protect : 1; + unsigned perm_write_protect : 1; + unsigned copy : 1; + unsigned file_format_grp : 1; + // byte 15 + unsigned always1 : 1; + unsigned crc : 7; +}csd1_t; +//------------------------------------------------------------------------------ +// CSD for version 2.00 cards +typedef struct CSDV2 { + // byte 0 + unsigned reserved1 : 6; + unsigned csd_ver : 2; + // byte 1 + uint8_t taac; + // byte 2 + uint8_t nsac; + // byte 3 + uint8_t tran_speed; + // byte 4 + uint8_t ccc_high; + // byte 5 + unsigned read_bl_len : 4; + unsigned ccc_low : 4; + // byte 6 + unsigned reserved2 : 4; + unsigned dsr_imp : 1; + unsigned read_blk_misalign :1; + unsigned write_blk_misalign : 1; + unsigned read_bl_partial : 1; + // byte 7 + unsigned reserved3 : 2; + unsigned c_size_high : 6; + // byte 8 + uint8_t c_size_mid; + // byte 9 + uint8_t c_size_low; + // byte 10 + unsigned sector_size_high : 6; + unsigned erase_blk_en : 1; + unsigned reserved4 : 1; + // byte 11 + unsigned wp_grp_size : 7; + unsigned sector_size_low : 1; + // byte 12 + unsigned write_bl_len_high : 2; + unsigned r2w_factor : 3; + unsigned reserved5 : 2; + unsigned wp_grp_enable : 1; + // byte 13 + unsigned reserved6 : 5; + unsigned write_partial : 1; + unsigned write_bl_len_low : 2; + // byte 14 + unsigned reserved7: 2; + unsigned file_format : 2; + unsigned tmp_write_protect : 1; + unsigned perm_write_protect : 1; + unsigned copy : 1; + unsigned file_format_grp : 1; + // byte 15 + unsigned always1 : 1; + unsigned crc : 7; +}csd2_t; +//------------------------------------------------------------------------------ +// union of old and new style CSD register +union csd_t { + csd1_t v1; + csd2_t v2; +}; +#endif // SdInfo_h diff --git a/Libmaple/libmaple/libraries/mapleSDfat/SdVolume.cpp b/Libmaple/libmaple/libraries/mapleSDfat/SdVolume.cpp index d3934791..ebcb1ad3 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/SdVolume.cpp +++ b/Libmaple/libmaple/libraries/mapleSDfat/SdVolume.cpp @@ -1,393 +1,393 @@ -/* Arduino SdFat Library - * Copyright (C) 2009 by William Greiman - * - * This file is part of the Arduino SdFat Library - * - * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino SdFat Library. If not, see - * . - */ -#include -#include -#include -#include "SdFat.h" - -//------------------------------------------------------------------------------ -// raw block cache -// init cacheBlockNumber_to invalid SD block number -uint32_t SdVolume::cacheBlockNumber_ = 0XFFFFFFFF; -cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card -Sd2Card* SdVolume::sdCard_; // pointer to SD card object -uint8_t SdVolume::cacheDirty_ = 0; // cacheFlush() will write block if true -uint32_t SdVolume::cacheMirrorBlock_ = 0; // mirror block for second FAT -//------------------------------------------------------------------------------ -// find a contiguous group of clusters -uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) -{ - // start of group - uint32_t bgnCluster; - - // flag to save place to start next search - uint8_t setStart; - - // set search start cluster - if (*curCluster) - { - // try to make file contiguous - bgnCluster = *curCluster + 1; - - // don't save new start location - setStart = false; - } - else - { - // start at likely place for free cluster - bgnCluster = allocSearchStart_; - - // save next search start if one cluster - setStart = 1 == count; - } - // end of group - uint32_t endCluster = bgnCluster; - - // last cluster of FAT - uint32_t fatEnd = clusterCount_ + 1; - - // search the FAT for free clusters - for (uint32_t n = 0;; n++, endCluster++) - { - // can't find space checked all clusters - if (n >= clusterCount_) return false; - - // past end - start from beginning of FAT - if (endCluster > fatEnd) - { - bgnCluster = endCluster = 2; - } - uint32_t f; - if (!fatGet(endCluster, &f)) return false; - - if (f != 0) - { - // cluster in use try next cluster as bgnCluster - bgnCluster = endCluster + 1; - } - else if ((endCluster - bgnCluster + 1) == count) - { - // done - found space - break; - } - } - // mark end of chain - if (!fatPutEOC(endCluster)) - return false; - - // link clusters - while (endCluster > bgnCluster) - { - if (!fatPut(endCluster - 1, endCluster)) - return false; - endCluster--; - } - if (*curCluster != 0) - { - // connect chains - if (!fatPut(*curCluster, bgnCluster)) - return false; - } - // return first cluster number to caller - *curCluster = bgnCluster; - - // remember possible next free cluster - if (setStart) - allocSearchStart_ = bgnCluster + 1; - - return true; -} -//------------------------------------------------------------------------------ -uint8_t SdVolume::cacheFlush(void) { - if (cacheDirty_) - { - if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) - { - return false; - } - // mirror FAT tables - if (cacheMirrorBlock_) - { - if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) - { - return false; - } - cacheMirrorBlock_ = 0; - } - cacheDirty_ = 0; - } - return true; -} -//------------------------------------------------------------------------------ -uint8_t SdVolume::cacheRawBlock(uint32_t blockNumber, uint8_t action) -{ - if (cacheBlockNumber_ != blockNumber) - { - if (!cacheFlush()) - return false; - if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) - return false; - cacheBlockNumber_ = blockNumber; - } - cacheDirty_ |= action; - return true; -} -//------------------------------------------------------------------------------ -// cache a zero block for blockNumber -uint8_t SdVolume::cacheZeroBlock(uint32_t blockNumber) -{ - if (!cacheFlush()) return false; - - // loop take less flash than memset(cacheBuffer_.data, 0, 512); - for (uint16_t i = 0; i < 512; i++) - { - cacheBuffer_.data[i] = 0; - } - cacheBlockNumber_ = blockNumber; - cacheSetDirty(); - return true; -} -//------------------------------------------------------------------------------ -// return the size in bytes of a cluster chain -uint8_t SdVolume::chainSize(uint32_t cluster, uint32_t* size) const -{ - uint32_t s = 0; - do - { - if (!fatGet(cluster, &cluster)) return false; - s += 512UL << clusterSizeShift_; - } while (!isEOC(cluster)); - *size = s; - return true; -} -//------------------------------------------------------------------------------ -// Fetch a FAT entry -uint8_t SdVolume::fatGet(uint32_t cluster, uint32_t* value) const -{ - if (cluster > (clusterCount_ + 1)) return false; - uint32_t lba = fatStartBlock_; - lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7; - if (lba != cacheBlockNumber_) - { - if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; - } - if (fatType_ == 16) - { - *value = cacheBuffer_.fat16[cluster & 0XFF]; - } - else - { - *value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK; - } - return true; -} -//------------------------------------------------------------------------------ -// Store a FAT entry -uint8_t SdVolume::fatPut(uint32_t cluster, uint32_t value) { - // error if reserved cluster - if (cluster < 2) - return false; - - // error if not in FAT - if (cluster > (clusterCount_ + 1)) - return false; - - // calculate block address for entry - uint32_t lba = fatStartBlock_; - lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7; - - if (lba != cacheBlockNumber_) - { - if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; - } - // store entry - if (fatType_ == 16) - { - cacheBuffer_.fat16[cluster & 0XFF] = value; - } - else - { - cacheBuffer_.fat32[cluster & 0X7F] = value; - } - cacheSetDirty(); - - // mirror second FAT - if (fatCount_ > 1) - cacheMirrorBlock_ = lba + blocksPerFat_; - return true; -} -//------------------------------------------------------------------------------ -// free a cluster chain -uint8_t SdVolume::freeChain(uint32_t cluster) -{ - // clear free cluster location - allocSearchStart_ = 2; - - do - { - uint32_t next; - if (!fatGet(cluster, &next)) return false; - - // free cluster - if (!fatPut(cluster, 0)) return false; - - cluster = next; - } while (!isEOC(cluster)); - - return true; -} -//------------------------------------------------------------------------------ -/** - * Initialize a FAT volume. - * - * \param[in] dev The SD card where the volume is located. - * - * \param[in] part The partition to be used. Legal values for \a part are - * 1-4 to use the corresponding partition on a device formatted with - * a MBR, Master Boot Record, or zero if the device is formatted as - * a super floppy with the FAT boot sector in block zero. - * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. Reasons for - * failure include not finding a valid partition, not finding a valid - * FAT file system in the specified partition or an I/O error. - */ -uint8_t SdVolume::init(Sd2Card* dev, uint8_t part) -{ - uint32_t volumeStartBlock = 0; - sdCard_ = dev; - - // if part == 0 assume super floppy with FAT boot sector in block zero - // if part > 0 assume mbr volume with partition table - if (part) - { - if (part > 4) - { - SerialDebug.println("Error: SdVolume::init() MBR"); - return false; - } - - if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) - { - SerialDebug.println("Error: SdVolume::init() Cache for read"); - return false; - } - - part_t* p = &cacheBuffer_.mbr.part[part-1]; - - if ((p->boot & 0X7F) !=0 || - p->totalSectors < 100 || - p->firstSector == 0) - { - // not a valid partition - - SerialDebug.println("Error: SdVolume::init() Invalid partition"); - return false; - } - volumeStartBlock = p->firstSector; - } - if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) - { - SerialDebug.println("Error: SdVolume::init() Cache for read2"); - return false; - } - -#if 0 - uint8_t *data = &cacheBuffer_.data[0]; - for(int i=0; i<512; i++) { - if(i % 16 == 0) { - SerialDebug.print(i, HEX); - SerialDebug.print(" "); - //delay(10); - } - SerialDebug.print(data[i], HEX); - SerialDebug.print(" "); - if(i % 16 == 15) { - SerialDebug.println(); - //delay(10); - } - } -#endif - - bpb_t* bpb = &cacheBuffer_.fbs.bpb; - - if (bpb->bytesPerSector != 512 || - bpb->fatCount == 0 || - bpb->reservedSectorCount == 0 || - bpb->sectorsPerCluster == 0) - { - // not valid FAT volume - SerialDebug.println("Error: SdVolume::init() invalid FAT volume"); - return false; - } - fatCount_ = bpb->fatCount; - blocksPerCluster_ = bpb->sectorsPerCluster; - - // determine shift that is same as multiply by blocksPerCluster_ - clusterSizeShift_ = 0; - while (blocksPerCluster_ != (1 << clusterSizeShift_)) - { - // error if not power of 2 - if (clusterSizeShift_++ > 7) - { - return false; - SerialDebug.println("Error: SdVolume::init() not power of 2"); - } - } - blocksPerFat_ = bpb->sectorsPerFat16 ? - bpb->sectorsPerFat16 : bpb->sectorsPerFat32; - - fatStartBlock_ = volumeStartBlock + bpb->reservedSectorCount; - - // count for FAT16 zero for FAT32 - rootDirEntryCount_ = bpb->rootDirEntryCount; - - // directory start for FAT16 dataStart for FAT32 - rootDirStart_ = fatStartBlock_ + bpb->fatCount * blocksPerFat_; - - // data start for FAT16 and FAT32 - dataStartBlock_ = rootDirStart_ + ((32 * bpb->rootDirEntryCount + 511)/512); - - // total blocks for FAT16 or FAT32 - uint32_t totalBlocks = bpb->totalSectors16 ? - bpb->totalSectors16 : bpb->totalSectors32; - // total data blocks - clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock); - - // divide by cluster size to get cluster count - clusterCount_ >>= clusterSizeShift_; - - // FAT type is determined by cluster count - if (clusterCount_ < 4085) - { - fatType_ = 12; - } - else if (clusterCount_ < 65525) - { - fatType_ = 16; - } - else - { - rootDirStart_ = bpb->fat32RootCluster; - fatType_ = 32; - } - - return true; -} +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can 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 Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#include +#include +#include +#include "SdFat.h" + +//------------------------------------------------------------------------------ +// raw block cache +// init cacheBlockNumber_to invalid SD block number +uint32_t SdVolume::cacheBlockNumber_ = 0XFFFFFFFF; +cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card +Sd2Card* SdVolume::sdCard_; // pointer to SD card object +uint8_t SdVolume::cacheDirty_ = 0; // cacheFlush() will write block if true +uint32_t SdVolume::cacheMirrorBlock_ = 0; // mirror block for second FAT +//------------------------------------------------------------------------------ +// find a contiguous group of clusters +uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) +{ + // start of group + uint32_t bgnCluster; + + // flag to save place to start next search + uint8_t setStart; + + // set search start cluster + if (*curCluster) + { + // try to make file contiguous + bgnCluster = *curCluster + 1; + + // don't save new start location + setStart = false; + } + else + { + // start at likely place for free cluster + bgnCluster = allocSearchStart_; + + // save next search start if one cluster + setStart = 1 == count; + } + // end of group + uint32_t endCluster = bgnCluster; + + // last cluster of FAT + uint32_t fatEnd = clusterCount_ + 1; + + // search the FAT for free clusters + for (uint32_t n = 0;; n++, endCluster++) + { + // can't find space checked all clusters + if (n >= clusterCount_) return false; + + // past end - start from beginning of FAT + if (endCluster > fatEnd) + { + bgnCluster = endCluster = 2; + } + uint32_t f; + if (!fatGet(endCluster, &f)) return false; + + if (f != 0) + { + // cluster in use try next cluster as bgnCluster + bgnCluster = endCluster + 1; + } + else if ((endCluster - bgnCluster + 1) == count) + { + // done - found space + break; + } + } + // mark end of chain + if (!fatPutEOC(endCluster)) + return false; + + // link clusters + while (endCluster > bgnCluster) + { + if (!fatPut(endCluster - 1, endCluster)) + return false; + endCluster--; + } + if (*curCluster != 0) + { + // connect chains + if (!fatPut(*curCluster, bgnCluster)) + return false; + } + // return first cluster number to caller + *curCluster = bgnCluster; + + // remember possible next free cluster + if (setStart) + allocSearchStart_ = bgnCluster + 1; + + return true; +} +//------------------------------------------------------------------------------ +uint8_t SdVolume::cacheFlush(void) { + if (cacheDirty_) + { + if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) + { + return false; + } + // mirror FAT tables + if (cacheMirrorBlock_) + { + if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) + { + return false; + } + cacheMirrorBlock_ = 0; + } + cacheDirty_ = 0; + } + return true; +} +//------------------------------------------------------------------------------ +uint8_t SdVolume::cacheRawBlock(uint32_t blockNumber, uint8_t action) +{ + if (cacheBlockNumber_ != blockNumber) + { + if (!cacheFlush()) + return false; + if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) + return false; + cacheBlockNumber_ = blockNumber; + } + cacheDirty_ |= action; + return true; +} +//------------------------------------------------------------------------------ +// cache a zero block for blockNumber +uint8_t SdVolume::cacheZeroBlock(uint32_t blockNumber) +{ + if (!cacheFlush()) return false; + + // loop take less flash than memset(cacheBuffer_.data, 0, 512); + for (uint16_t i = 0; i < 512; i++) + { + cacheBuffer_.data[i] = 0; + } + cacheBlockNumber_ = blockNumber; + cacheSetDirty(); + return true; +} +//------------------------------------------------------------------------------ +// return the size in bytes of a cluster chain +uint8_t SdVolume::chainSize(uint32_t cluster, uint32_t* size) const +{ + uint32_t s = 0; + do + { + if (!fatGet(cluster, &cluster)) return false; + s += 512UL << clusterSizeShift_; + } while (!isEOC(cluster)); + *size = s; + return true; +} +//------------------------------------------------------------------------------ +// Fetch a FAT entry +uint8_t SdVolume::fatGet(uint32_t cluster, uint32_t* value) const +{ + if (cluster > (clusterCount_ + 1)) return false; + uint32_t lba = fatStartBlock_; + lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7; + if (lba != cacheBlockNumber_) + { + if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; + } + if (fatType_ == 16) + { + *value = cacheBuffer_.fat16[cluster & 0XFF]; + } + else + { + *value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK; + } + return true; +} +//------------------------------------------------------------------------------ +// Store a FAT entry +uint8_t SdVolume::fatPut(uint32_t cluster, uint32_t value) { + // error if reserved cluster + if (cluster < 2) + return false; + + // error if not in FAT + if (cluster > (clusterCount_ + 1)) + return false; + + // calculate block address for entry + uint32_t lba = fatStartBlock_; + lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7; + + if (lba != cacheBlockNumber_) + { + if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; + } + // store entry + if (fatType_ == 16) + { + cacheBuffer_.fat16[cluster & 0XFF] = value; + } + else + { + cacheBuffer_.fat32[cluster & 0X7F] = value; + } + cacheSetDirty(); + + // mirror second FAT + if (fatCount_ > 1) + cacheMirrorBlock_ = lba + blocksPerFat_; + return true; +} +//------------------------------------------------------------------------------ +// free a cluster chain +uint8_t SdVolume::freeChain(uint32_t cluster) +{ + // clear free cluster location + allocSearchStart_ = 2; + + do + { + uint32_t next; + if (!fatGet(cluster, &next)) return false; + + // free cluster + if (!fatPut(cluster, 0)) return false; + + cluster = next; + } while (!isEOC(cluster)); + + return true; +} +//------------------------------------------------------------------------------ +/** + * Initialize a FAT volume. + * + * \param[in] dev The SD card where the volume is located. + * + * \param[in] part The partition to be used. Legal values for \a part are + * 1-4 to use the corresponding partition on a device formatted with + * a MBR, Master Boot Record, or zero if the device is formatted as + * a super floppy with the FAT boot sector in block zero. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system in the specified partition or an I/O error. + */ +uint8_t SdVolume::init(Sd2Card* dev, uint8_t part) +{ + uint32_t volumeStartBlock = 0; + sdCard_ = dev; + + // if part == 0 assume super floppy with FAT boot sector in block zero + // if part > 0 assume mbr volume with partition table + if (part) + { + if (part > 4) + { + SerialDebug.println("Error: SdVolume::init() MBR"); + return false; + } + + if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) + { + SerialDebug.println("Error: SdVolume::init() Cache for read"); + return false; + } + + part_t* p = &cacheBuffer_.mbr.part[part-1]; + + if ((p->boot & 0X7F) !=0 || + p->totalSectors < 100 || + p->firstSector == 0) + { + // not a valid partition + + SerialDebug.println("Error: SdVolume::init() Invalid partition"); + return false; + } + volumeStartBlock = p->firstSector; + } + if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) + { + SerialDebug.println("Error: SdVolume::init() Cache for read2"); + return false; + } + +#if 0 + uint8_t *data = &cacheBuffer_.data[0]; + for(int i=0; i<512; i++) { + if(i % 16 == 0) { + SerialDebug.print(i, HEX); + SerialDebug.print(" "); + //delay(10); + } + SerialDebug.print(data[i], HEX); + SerialDebug.print(" "); + if(i % 16 == 15) { + SerialDebug.println(); + //delay(10); + } + } +#endif + + bpb_t* bpb = &cacheBuffer_.fbs.bpb; + + if (bpb->bytesPerSector != 512 || + bpb->fatCount == 0 || + bpb->reservedSectorCount == 0 || + bpb->sectorsPerCluster == 0) + { + // not valid FAT volume + SerialDebug.println("Error: SdVolume::init() invalid FAT volume"); + return false; + } + fatCount_ = bpb->fatCount; + blocksPerCluster_ = bpb->sectorsPerCluster; + + // determine shift that is same as multiply by blocksPerCluster_ + clusterSizeShift_ = 0; + while (blocksPerCluster_ != (1 << clusterSizeShift_)) + { + // error if not power of 2 + if (clusterSizeShift_++ > 7) + { + return false; + SerialDebug.println("Error: SdVolume::init() not power of 2"); + } + } + blocksPerFat_ = bpb->sectorsPerFat16 ? + bpb->sectorsPerFat16 : bpb->sectorsPerFat32; + + fatStartBlock_ = volumeStartBlock + bpb->reservedSectorCount; + + // count for FAT16 zero for FAT32 + rootDirEntryCount_ = bpb->rootDirEntryCount; + + // directory start for FAT16 dataStart for FAT32 + rootDirStart_ = fatStartBlock_ + bpb->fatCount * blocksPerFat_; + + // data start for FAT16 and FAT32 + dataStartBlock_ = rootDirStart_ + ((32 * bpb->rootDirEntryCount + 511)/512); + + // total blocks for FAT16 or FAT32 + uint32_t totalBlocks = bpb->totalSectors16 ? + bpb->totalSectors16 : bpb->totalSectors32; + // total data blocks + clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock); + + // divide by cluster size to get cluster count + clusterCount_ >>= clusterSizeShift_; + + // FAT type is determined by cluster count + if (clusterCount_ < 4085) + { + fatType_ = 12; + } + else if (clusterCount_ < 65525) + { + fatType_ = 16; + } + else + { + rootDirStart_ = bpb->fat32RootCluster; + fatType_ = 32; + } + + return true; +} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatAnalogLogger/SdFatAnalogLogger.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatAnalogLogger/SdFatAnalogLogger.pde index bc2190c3..c409b74d 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatAnalogLogger/SdFatAnalogLogger.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatAnalogLogger/SdFatAnalogLogger.pde @@ -1,122 +1,122 @@ -// A simple data logger for the Arduino analog pins -#define LOG_INTERVAL 1000 // mills between entries -#define SENSOR_COUNT 3 // number of analog pins to log -#define ECHO_TO_SERIAL 1 // echo data to serial port -#define WAIT_TO_START 1 // Wait for serial input in setup() -#define SYNC_INTERVAL 1000 // mills between calls to sync() -uint32_t syncTime = 0; // time of last sync() - -#include -#include - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - -#if WAIT_TO_START - Serial.println("Type any character to start"); - while (!Serial.available()); -#endif //WAIT_TO_START - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - // create a new file - char name[] = "LOGGER00.CSV"; - for (uint8_t i = 0; i < 100; i++) { - name[6] = i/10 + '0'; - name[7] = i%10 + '0'; - if (file.open(&root, name, O_CREAT | O_EXCL | O_WRITE)) break; - } - if (!file.isOpen()) error ("file.create"); - Serial.print("Logging to: "); - Serial.println(name); - - // write header - file.writeError = 0; - file.print("millis"); -#if ECHO_TO_SERIAL - Serial.print("millis"); -#endif //ECHO_TO_SERIAL - -#if SENSOR_COUNT > 6 -#error SENSOR_COUNT too large -#endif //SENSOR_COUNT - - for (uint8_t i = 0; i < SENSOR_COUNT; i++) { - file.print(",sens");file.print(i, DEC); -#if ECHO_TO_SERIAL - Serial.print(",sens");Serial.print(i, DEC); -#endif //ECHO_TO_SERIAL - } - file.println(); -#if ECHO_TO_SERIAL - Serial.println(); -#endif //ECHO_TO_SERIAL - - if (file.writeError || !file.sync()) { - error("write header failed"); - } -} - -void loop(void) { - // clear print error - file.writeError = 0; - delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL)); - - // log time - uint32_t m = millis(); - file.print(m); -#if ECHO_TO_SERIAL - Serial.print(m); -#endif //ECHO_TO_SERIAL - - // add sensor data - for (uint8_t ia = 0; ia < SENSOR_COUNT; ia++) { - uint16_t data = analogRead(ia); - file.print(','); - file.print(data); -#if ECHO_TO_SERIAL - Serial.print(','); - Serial.print(data); -#endif //ECHO_TO_SERIAL - } - file.println(); -#if ECHO_TO_SERIAL - Serial.println(); -#endif //ECHO_TO_SERIAL - - if (file.writeError) error("write data failed"); - - //don't sync too often - requires 2048 bytes of I/O to SD card - if ((millis() - syncTime) < SYNC_INTERVAL) return; - syncTime = millis(); - if (!file.sync()) error("sync failed"); -} +// A simple data logger for the Arduino analog pins +#define LOG_INTERVAL 1000 // mills between entries +#define SENSOR_COUNT 3 // number of analog pins to log +#define ECHO_TO_SERIAL 1 // echo data to serial port +#define WAIT_TO_START 1 // Wait for serial input in setup() +#define SYNC_INTERVAL 1000 // mills between calls to sync() +uint32_t syncTime = 0; // time of last sync() + +#include +#include + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + +#if WAIT_TO_START + Serial.println("Type any character to start"); + while (!Serial.available()); +#endif //WAIT_TO_START + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + // create a new file + char name[] = "LOGGER00.CSV"; + for (uint8_t i = 0; i < 100; i++) { + name[6] = i/10 + '0'; + name[7] = i%10 + '0'; + if (file.open(&root, name, O_CREAT | O_EXCL | O_WRITE)) break; + } + if (!file.isOpen()) error ("file.create"); + Serial.print("Logging to: "); + Serial.println(name); + + // write header + file.writeError = 0; + file.print("millis"); +#if ECHO_TO_SERIAL + Serial.print("millis"); +#endif //ECHO_TO_SERIAL + +#if SENSOR_COUNT > 6 +#error SENSOR_COUNT too large +#endif //SENSOR_COUNT + + for (uint8_t i = 0; i < SENSOR_COUNT; i++) { + file.print(",sens");file.print(i, DEC); +#if ECHO_TO_SERIAL + Serial.print(",sens");Serial.print(i, DEC); +#endif //ECHO_TO_SERIAL + } + file.println(); +#if ECHO_TO_SERIAL + Serial.println(); +#endif //ECHO_TO_SERIAL + + if (file.writeError || !file.sync()) { + error("write header failed"); + } +} + +void loop(void) { + // clear print error + file.writeError = 0; + delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL)); + + // log time + uint32_t m = millis(); + file.print(m); +#if ECHO_TO_SERIAL + Serial.print(m); +#endif //ECHO_TO_SERIAL + + // add sensor data + for (uint8_t ia = 0; ia < SENSOR_COUNT; ia++) { + uint16_t data = analogRead(ia); + file.print(','); + file.print(data); +#if ECHO_TO_SERIAL + Serial.print(','); + Serial.print(data); +#endif //ECHO_TO_SERIAL + } + file.println(); +#if ECHO_TO_SERIAL + Serial.println(); +#endif //ECHO_TO_SERIAL + + if (file.writeError) error("write data failed"); + + //don't sync too often - requires 2048 bytes of I/O to SD card + if ((millis() - syncTime) < SYNC_INTERVAL) return; + syncTime = millis(); + if (!file.sync()) error("sync failed"); +} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatAppend/SdFatAppend.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatAppend/SdFatAppend.pde index ce22264f..5c2e1f78 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatAppend/SdFatAppend.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatAppend/SdFatAppend.pde @@ -1,77 +1,77 @@ -/* - * Append Example - * - * This sketch shows how to use open for append and the Arduino Print class - * with SdFat. - */ -#include -#include // use functions to print strings from flash memory - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - char name[] = "APPEND.TXT"; - PgmPrint("Appending to: "); - Serial.println(name); - - // clear write error - file.writeError = false; - - for (uint8_t i = 0; i < 100; i++) { - // O_CREAT - create the file if it does not exist - // O_APPEND - seek to the end of the file prior to each write - // O_WRITE - open for write - if (!file.open(&root, name, O_CREAT | O_APPEND | O_WRITE)) { - error("open failed"); - } - // print 100 lines to file - for (uint8_t j = 0; j < 100; j++) { - file.print("line "); - file.print(j, DEC); - file.print(" of pass "); - file.print(i, DEC); - file.print(" millis = "); - file.println(millis()); - } - if (file.writeError) error("write failed"); - if (!file.close()) error("close failed"); - if (i > 0 && i%25 == 0)Serial.println(); - Serial.print('.'); - } - Serial.println(); - Serial.println("Done"); -} -void loop(void){} +/* + * Append Example + * + * This sketch shows how to use open for append and the Arduino Print class + * with SdFat. + */ +#include +#include // use functions to print strings from flash memory + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + char name[] = "APPEND.TXT"; + PgmPrint("Appending to: "); + Serial.println(name); + + // clear write error + file.writeError = false; + + for (uint8_t i = 0; i < 100; i++) { + // O_CREAT - create the file if it does not exist + // O_APPEND - seek to the end of the file prior to each write + // O_WRITE - open for write + if (!file.open(&root, name, O_CREAT | O_APPEND | O_WRITE)) { + error("open failed"); + } + // print 100 lines to file + for (uint8_t j = 0; j < 100; j++) { + file.print("line "); + file.print(j, DEC); + file.print(" of pass "); + file.print(i, DEC); + file.print(" millis = "); + file.println(millis()); + } + if (file.writeError) error("write failed"); + if (!file.close()) error("close failed"); + if (i > 0 && i%25 == 0)Serial.println(); + Serial.print('.'); + } + Serial.println(); + Serial.println("Done"); +} +void loop(void){} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatBench/SdFatBench.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatBench/SdFatBench.pde index 4fd98f4d..f48f1296 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatBench/SdFatBench.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatBench/SdFatBench.pde @@ -1,104 +1,104 @@ -/* - * This sketch is a simple write/read benchmark. - */ -#include -#include - -#define FILE_SIZE_MB 5 -#define FILE_SIZE (1000000UL*FILE_SIZE_MB) -#define BUF_SIZE 100 - -uint8_t buf[BUF_SIZE]; - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) -{ - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup() { - Serial.begin(9600); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - PgmPrint("Free RAM: "); - Serial.println(FreeRam()); - - // initialize the SD card at SPI_FULL_SPEED for best performance. - // try SPI_HALF_SPEED if bus errors occur. - if (!card.init(SPI_FULL_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed!"); - - PgmPrint("Type is FAT"); - Serial.println(volume.fatType(), DEC); - - if (!root.openRoot(&volume)) error("openRoot failed"); - - // open or create file - truncate existing file. - if (!file.open(&root, "BENCH.DAT", O_CREAT | O_TRUNC | O_RDWR)) { - error("open failed"); - } - - // fill buf with known data - for (uint16_t i = 0; i < (BUF_SIZE-2); i++) { - buf[i] = 'A' + (i % 26); - } - buf[BUF_SIZE-2] = '\r'; - buf[BUF_SIZE-1] = '\n'; - - PgmPrint("File size "); - Serial.print(FILE_SIZE_MB); - PgmPrintln(" MB"); - PgmPrintln("Starting write test. Please wait up to a minute"); - - // do write test - uint32_t n = FILE_SIZE/sizeof(buf); - uint32_t t = millis(); - for (uint32_t i = 0; i < n; i++) { - if (file.write(buf, sizeof(buf)) != sizeof(buf)) { - error("write failed"); - } - } - t = millis() - t; - file.sync(); - double r = (double)file.fileSize()/t; - PgmPrint("Write "); - Serial.print(r); - PgmPrintln(" KB/sec"); - Serial.println(); - PgmPrintln("Starting read test. Please wait up to a minute"); - - // do read test - file.rewind(); - t = millis(); - for (uint32_t i = 0; i < n; i++) { - if (file.read(buf, sizeof(buf)) != sizeof(buf)) { - error("read failed"); - } - } - t = millis() - t; - r = (double)file.fileSize()/t; - PgmPrint("Read "); - Serial.print(r); - PgmPrintln(" KB/sec"); - PgmPrintln("Done"); -} - -void loop() { } +/* + * This sketch is a simple write/read benchmark. + */ +#include +#include + +#define FILE_SIZE_MB 5 +#define FILE_SIZE (1000000UL*FILE_SIZE_MB) +#define BUF_SIZE 100 + +uint8_t buf[BUF_SIZE]; + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) +{ + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup() { + Serial.begin(9600); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + PgmPrint("Free RAM: "); + Serial.println(FreeRam()); + + // initialize the SD card at SPI_FULL_SPEED for best performance. + // try SPI_HALF_SPEED if bus errors occur. + if (!card.init(SPI_FULL_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed!"); + + PgmPrint("Type is FAT"); + Serial.println(volume.fatType(), DEC); + + if (!root.openRoot(&volume)) error("openRoot failed"); + + // open or create file - truncate existing file. + if (!file.open(&root, "BENCH.DAT", O_CREAT | O_TRUNC | O_RDWR)) { + error("open failed"); + } + + // fill buf with known data + for (uint16_t i = 0; i < (BUF_SIZE-2); i++) { + buf[i] = 'A' + (i % 26); + } + buf[BUF_SIZE-2] = '\r'; + buf[BUF_SIZE-1] = '\n'; + + PgmPrint("File size "); + Serial.print(FILE_SIZE_MB); + PgmPrintln(" MB"); + PgmPrintln("Starting write test. Please wait up to a minute"); + + // do write test + uint32_t n = FILE_SIZE/sizeof(buf); + uint32_t t = millis(); + for (uint32_t i = 0; i < n; i++) { + if (file.write(buf, sizeof(buf)) != sizeof(buf)) { + error("write failed"); + } + } + t = millis() - t; + file.sync(); + double r = (double)file.fileSize()/t; + PgmPrint("Write "); + Serial.print(r); + PgmPrintln(" KB/sec"); + Serial.println(); + PgmPrintln("Starting read test. Please wait up to a minute"); + + // do read test + file.rewind(); + t = millis(); + for (uint32_t i = 0; i < n; i++) { + if (file.read(buf, sizeof(buf)) != sizeof(buf)) { + error("read failed"); + } + } + t = millis() - t; + r = (double)file.fileSize()/t; + PgmPrint("Read "); + Serial.print(r); + PgmPrintln(" KB/sec"); + PgmPrintln("Done"); +} + +void loop() { } diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatCopy/SdFatCopy.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatCopy/SdFatCopy.pde index 356340a4..6b105bd1 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatCopy/SdFatCopy.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatCopy/SdFatCopy.pde @@ -1,82 +1,82 @@ -/* - * Copy Example - only runs on chips with 2K or more RAM - * - * This sketch copies the file APPEND.TXT, created by the - * SdFatAppend.pde example, to the file ACOPY.TXT. - */ -#include -#include // use functions to print strings from flash memory - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile from; // read file -SdFile copy; // write file - -// large buffer to test for bugs. 512 bytes runs much faster. -char buf[600]; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - PgmPrint("FreeRam: "); - Serial.println(FreeRam()); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - strcpy_P(buf, PSTR("APPEND.TXT")); - // open for read - if (!from.open(&root, buf, O_READ)) { - PgmPrint("Can't open "); - Serial.println(buf); - PgmPrintln("Run the append example to create the file."); - error("from.open failed"); - } - strcpy_P(buf, PSTR("ACOPY.TXT")); - // create if needed, truncate to zero length, open for write - if (!copy.open(&root, buf, O_CREAT | O_TRUNC | O_WRITE)) { - error("copy.open failed"); - } - // count for printing periods - uint16_t p = 0; - int16_t n; - while ((n = from.read(buf, sizeof(buf))) > 0) { - if (copy.write(buf, n) != n) error("write failed"); - // print progress periods - if (!(p++ % 25)) Serial.print('.'); - if (!(p % 500)) Serial.println(); - } - Serial.println(); - if (n != 0) error ("read"); - // force write of directory entry and last data - if (!copy.close()) error("copy.close failed"); - PgmPrintln("Copy done."); -} - -void loop(void) {} +/* + * Copy Example - only runs on chips with 2K or more RAM + * + * This sketch copies the file APPEND.TXT, created by the + * SdFatAppend.pde example, to the file ACOPY.TXT. + */ +#include +#include // use functions to print strings from flash memory + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile from; // read file +SdFile copy; // write file + +// large buffer to test for bugs. 512 bytes runs much faster. +char buf[600]; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + PgmPrint("FreeRam: "); + Serial.println(FreeRam()); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + strcpy_P(buf, PSTR("APPEND.TXT")); + // open for read + if (!from.open(&root, buf, O_READ)) { + PgmPrint("Can't open "); + Serial.println(buf); + PgmPrintln("Run the append example to create the file."); + error("from.open failed"); + } + strcpy_P(buf, PSTR("ACOPY.TXT")); + // create if needed, truncate to zero length, open for write + if (!copy.open(&root, buf, O_CREAT | O_TRUNC | O_WRITE)) { + error("copy.open failed"); + } + // count for printing periods + uint16_t p = 0; + int16_t n; + while ((n = from.read(buf, sizeof(buf))) > 0) { + if (copy.write(buf, n) != n) error("write failed"); + // print progress periods + if (!(p++ % 25)) Serial.print('.'); + if (!(p % 500)) Serial.println(); + } + Serial.println(); + if (n != 0) error ("read"); + // force write of directory entry and last data + if (!copy.close()) error("copy.close failed"); + PgmPrintln("Copy done."); +} + +void loop(void) {} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatGPSLogger_v3/SdFatGPSLogger_v3.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatGPSLogger_v3/SdFatGPSLogger_v3.pde index ea3a3126..afab2d1b 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatGPSLogger_v3/SdFatGPSLogger_v3.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatGPSLogger_v3/SdFatGPSLogger_v3.pde @@ -1,340 +1,340 @@ -// Ladyada's logger modified by Bill Greiman to use the SdFat library - -// this is a generic logger that does checksum testing so the data written should be always good -// Assumes a sirf III chipset logger attached to pin 0 and 1 - -#include -#include -#include - -// macros to use PSTR -#define putstring(str) SerialPrint_P(PSTR(str)) -#define putstring_nl(str) SerialPrintln_P(PSTR(str)) - -// power saving modes -#define SLEEPDELAY 0 -#define TURNOFFGPS 0 -#define LOG_RMC_FIXONLY 1 - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile f; - -#define led1Pin 4 -#define led2Pin 3 -#define powerPin 2 - -#define BUFFSIZE 75 -char buffer[BUFFSIZE]; -uint8_t bufferidx = 0; -uint8_t fix = 0; // current fix data -uint8_t i; - -/* EXAMPLE - -$PSRF103,,,,*CKSUM - - 00=GGA,01=GLL,02=GSA,03=GSV,04=RMC,05=VTG - 00=SetRate,01=Query - Output every seconds, off=00,max=255 - 00=disable Checksum,01=Enable checksum for specified message -Note: checksum is required - -Example 1: Query the GGA message with checksum enabled -$PSRF103,00,01,00,01*25 - -Example 2: Enable VTG message for a 1Hz constant output with checksum enabled -$PSRF103,05,00,01,01*20 - -Example 3: Disable VTG message -$PSRF103,05,00,00,01*21 - -*/ - -#define SERIAL_SET "$PSRF100,01,4800,08,01,00*0E\r\n" - -// GGA-Global Positioning System Fixed Data, message 103,00 -#define LOG_GGA 0 -#define GGA_ON "$PSRF103,00,00,01,01*25\r\n" -#define GGA_OFF "$PSRF103,00,00,00,01*24\r\n" - -// GLL-Geographic Position-Latitude/Longitude, message 103,01 -#define LOG_GLL 0 -#define GLL_ON "$PSRF103,01,00,01,01*26\r\n" -#define GLL_OFF "$PSRF103,01,00,00,01*27\r\n" - -// GSA-GNSS DOP and Active Satellites, message 103,02 -#define LOG_GSA 0 -#define GSA_ON "$PSRF103,02,00,01,01*27\r\n" -#define GSA_OFF "$PSRF103,02,00,00,01*26\r\n" - -// GSV-GNSS Satellites in View, message 103,03 -#define LOG_GSV 0 -#define GSV_ON "$PSRF103,03,00,01,01*26\r\n" -#define GSV_OFF "$PSRF103,03,00,00,01*27\r\n" - -// RMC-Recommended Minimum Specific GNSS Data, message 103,04 -#define LOG_RMC 1 -#define RMC_ON "$PSRF103,04,00,01,01*21\r\n" -#define RMC_OFF "$PSRF103,04,00,00,01*20\r\n" - -// VTG-Course Over Ground and Ground Speed, message 103,05 -#define LOG_VTG 0 -#define VTG_ON "$PSRF103,05,00,01,01*20\r\n" -#define VTG_OFF "$PSRF103,05,00,00,01*21\r\n" - -// Switch Development Data Messages On/Off, message 105 -#define LOG_DDM 1 -#define DDM_ON "$PSRF105,01*3E\r\n" -#define DDM_OFF "$PSRF105,00*3F\r\n" - -#define USE_WAAS 0 // useful in US, but slower fix -#define WAAS_ON "$PSRF151,01*3F\r\n" // the command for turning on WAAS -#define WAAS_OFF "$PSRF151,00*3E\r\n" // the command for turning off WAAS - -// read a Hex value and return the decimal equivalent -uint8_t parseHex(char c) { - if (c < '0') - return 0; - if (c <= '9') - return c - '0'; - if (c < 'A') - return 0; - if (c <= 'F') - return (c - 'A')+10; -} - -// blink out an error code -void error(uint8_t errno) { - if (card.errorCode()) { - putstring("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1) { - for (i=0; i +#include +#include + +// macros to use PSTR +#define putstring(str) SerialPrint_P(PSTR(str)) +#define putstring_nl(str) SerialPrintln_P(PSTR(str)) + +// power saving modes +#define SLEEPDELAY 0 +#define TURNOFFGPS 0 +#define LOG_RMC_FIXONLY 1 + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile f; + +#define led1Pin 4 +#define led2Pin 3 +#define powerPin 2 + +#define BUFFSIZE 75 +char buffer[BUFFSIZE]; +uint8_t bufferidx = 0; +uint8_t fix = 0; // current fix data +uint8_t i; + +/* EXAMPLE + +$PSRF103,,,,*CKSUM + + 00=GGA,01=GLL,02=GSA,03=GSV,04=RMC,05=VTG + 00=SetRate,01=Query + Output every seconds, off=00,max=255 + 00=disable Checksum,01=Enable checksum for specified message +Note: checksum is required + +Example 1: Query the GGA message with checksum enabled +$PSRF103,00,01,00,01*25 + +Example 2: Enable VTG message for a 1Hz constant output with checksum enabled +$PSRF103,05,00,01,01*20 + +Example 3: Disable VTG message +$PSRF103,05,00,00,01*21 + +*/ + +#define SERIAL_SET "$PSRF100,01,4800,08,01,00*0E\r\n" + +// GGA-Global Positioning System Fixed Data, message 103,00 +#define LOG_GGA 0 +#define GGA_ON "$PSRF103,00,00,01,01*25\r\n" +#define GGA_OFF "$PSRF103,00,00,00,01*24\r\n" + +// GLL-Geographic Position-Latitude/Longitude, message 103,01 +#define LOG_GLL 0 +#define GLL_ON "$PSRF103,01,00,01,01*26\r\n" +#define GLL_OFF "$PSRF103,01,00,00,01*27\r\n" + +// GSA-GNSS DOP and Active Satellites, message 103,02 +#define LOG_GSA 0 +#define GSA_ON "$PSRF103,02,00,01,01*27\r\n" +#define GSA_OFF "$PSRF103,02,00,00,01*26\r\n" + +// GSV-GNSS Satellites in View, message 103,03 +#define LOG_GSV 0 +#define GSV_ON "$PSRF103,03,00,01,01*26\r\n" +#define GSV_OFF "$PSRF103,03,00,00,01*27\r\n" + +// RMC-Recommended Minimum Specific GNSS Data, message 103,04 +#define LOG_RMC 1 +#define RMC_ON "$PSRF103,04,00,01,01*21\r\n" +#define RMC_OFF "$PSRF103,04,00,00,01*20\r\n" + +// VTG-Course Over Ground and Ground Speed, message 103,05 +#define LOG_VTG 0 +#define VTG_ON "$PSRF103,05,00,01,01*20\r\n" +#define VTG_OFF "$PSRF103,05,00,00,01*21\r\n" + +// Switch Development Data Messages On/Off, message 105 +#define LOG_DDM 1 +#define DDM_ON "$PSRF105,01*3E\r\n" +#define DDM_OFF "$PSRF105,00*3F\r\n" + +#define USE_WAAS 0 // useful in US, but slower fix +#define WAAS_ON "$PSRF151,01*3F\r\n" // the command for turning on WAAS +#define WAAS_OFF "$PSRF151,00*3E\r\n" // the command for turning off WAAS + +// read a Hex value and return the decimal equivalent +uint8_t parseHex(char c) { + if (c < '0') + return 0; + if (c <= '9') + return c - '0'; + if (c < 'A') + return 0; + if (c <= 'F') + return (c - 'A')+10; +} + +// blink out an error code +void error(uint8_t errno) { + if (card.errorCode()) { + putstring("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1) { + for (i=0; i -#include -#include - -#define isdigit(x) ( x >= '0' && x <= '9') - -//extern uint16_t _end; - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile f; - -#define led1Pin 4 // LED1 connected to digital pin 4 -#define led2Pin 3 // LED2 connected to digital pin 3 -#define powerpin 2 // GPS power control - -// set the RX_BUFFER_SIZE to 32! -#define BUFFSIZE 73 // we buffer one NMEA sentence at a time, 83 bytes is longer than the max length -char buffer[BUFFSIZE]; // this is the double buffer -char buffer2[12]; - -uint8_t bufferidx = 0; -uint32_t tmp; -#define LOG_RMC 1 // essential location data -#define RMC_ON "$PSRF103,4,0,1,1*21\r\n" // the command we send to turn RMC on (1 hz rate) -#define RMC_OFF "$PSRF103,4,0,0,1*20\r\n" // the command we send to turn RMC off - -#define LOG_GGA 0 // contains fix, hdop & vdop data -#define GGA_ON "$PSRF103,0,0,1,1*25\r\n" // the command we send to turn GGA on (1 hz rate) -#define GGA_OFF "$PSRF103,0,0,0,1*24\r\n" // the command we send to turn GGA off - -#define LOG_GSA 0 // satellite data -#define GSA_ON "$PSRF103,2,0,1,1*27\r\n" // the command we send to turn GSA on (1 hz rate) -#define GSA_OFF "$PSRF103,2,0,0,1*26\r\n" // the command we send to turn GSA off - -#define LOG_GSV 0 // detailed satellite data -#define GSV_ON "$PSRF103,3,0,1,1*26\r\n" // the command we send to turn GSV on (1 hz rate) -#define GSV_OFF "$PSRF103,3,0,0,1*27\r\n" // the command we send to turn GSV off - -#define LOG_GLL 0 // Loran-compatibility data -// this isnt output by default - -#define USE_WAAS 1 // useful in US, but slower fix -#define WAAS_ON "$PSRF151,1*3F\r\n" // the command for turning on WAAS -#define WAAS_OFF "$PSRF151,0*3E\r\n" // the command for turning off WAAS - -#define LOG_RMC_FIXONLY 1 // log only when we get RMC's with fix? -uint8_t fix = 0; // current fix data - -// macros to use PSTR -#define putstring(str) SerialPrint_P(PSTR(str)) -#define putstring_nl(str) SerialPrintln_P(PSTR(str)) - -// read a Hex value and return the decimal equivalent -uint8_t parseHex(char c) { - if (c < '0') - return 0; - if (c <= '9') - return c - '0'; - if (c < 'A') - return 0; - if (c <= 'F') - return (c - 'A')+10; -} - -uint8_t i; - -// blink out an error code -void error(uint8_t errno) { - if (card.errorCode()) { - putstring("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1) { - for (i=0; i 6) sensorCount = 6; - strncpy_P(buffer, PSTR("time,lat,long,speed,date,sens0,sens1,sens2,sens3,sens4,sens5"), 24 + 6*sensorCount); - Serial.println(buffer); - // clear print error - f.writeError = 0; - f.println(buffer); - if (f.writeError || !f.sync()) { - putstring_nl("can't write header!"); - error(5); - } - - delay(1000); - - putstring("\r\n"); -#if USE_WAAS == 1 - putstring(WAAS_ON); // turn on WAAS -#else - putstring(WAAS_OFF); // turn on WAAS -#endif - -#if LOG_RMC == 1 - putstring(RMC_ON); // turn on RMC -#else - putstring(RMC_OFF); // turn off RMC -#endif - -#if LOG_GSV == 1 - putstring(GSV_ON); // turn on GSV -#else - putstring(GSV_OFF); // turn off GSV -#endif - -#if LOG_GSA == 1 - putstring(GSA_ON); // turn on GSA -#else - putstring(GSA_OFF); // turn off GSA -#endif - -#if LOG_GGA == 1 - putstring(GGA_ON); // turn on GGA -#else - putstring(GGA_OFF); // turn off GGA -#endif -} - -void loop() { // run over and over again - - //Serial.println(Serial.available(), DEC); - char c; - uint8_t sum; - - // read one 'line' - if (Serial.available()) { - c = Serial.read(); - //Serial.print(c, BYTE); - if (bufferidx == 0) { - while (c != '$') - c = Serial.read(); // wait till we get a $ - } - buffer[bufferidx] = c; - - //Serial.print(c, BYTE); - if (c == '\n') { - //putstring_nl("EOL"); - //Serial.print(buffer); - buffer[bufferidx+1] = 0; // terminate it - - if (buffer[bufferidx-4] != '*') { - // no checksum? - Serial.print('*', BYTE); - bufferidx = 0; - return; - } - // get checksum - sum = parseHex(buffer[bufferidx-3]) * 16; - sum += parseHex(buffer[bufferidx-2]); - - // check checksum - for (i=1; i < (bufferidx-4); i++) { - sum ^= buffer[i]; - } - if (sum != 0) { - //putstring_nl("Cxsum mismatch"); - Serial.print('~', BYTE); - bufferidx = 0; - return; - } - // got good data! - - if (strstr(buffer, "GPRMC")) { - // find out if we got a fix - char *p = buffer; - p = strchr(p, ',')+1; - p = strchr(p, ',')+1; // skip to 3rd item - - if (p[0] == 'V') { - digitalWrite(led1Pin, LOW); - fix = 0; - } else { - digitalWrite(led1Pin, HIGH); - fix = 1; - } - } else { - // not GPRMC - bufferidx = 0; - return; - } -#if LOG_RMC_FIXONLY - if (!fix) { - Serial.print('_', BYTE); - bufferidx = 0; - return; - } -#endif - // rad. lets print it! - - Serial.print(buffer); - - // time to clean up the string - // find time - char *p = buffer; - p = strchr(p, ',')+1; - buffer[0] = p[0]; - buffer[1] = p[1]; - buffer[2] = ':'; - buffer[3] = p[2]; - buffer[4] = p[3]; - buffer[5] = ':'; - buffer[6] = p[4]; - buffer[7] = p[5]; - // we ignore milliseconds - buffer[8] = ','; - - p = strchr(buffer+8, ',')+1; - // skip past 'active' flag - p = strchr(p, ',')+1; - // find lat - p = strchr(p, ',')+1; - - buffer[9] = '+'; - buffer[10] = p[0]; - buffer[11] = p[1]; - buffer[12] = ' '; - strncpy(buffer+13, p+2, 7); - buffer[20] = ','; - - p = strchr(buffer+21, ',')+1; - if (p[0] == 'S') - buffer[9] = '-'; - - // find long - p = strchr(p, ',')+1; - buffer[21] = '+'; - buffer[22] = p[0]; - buffer[23] = p[1]; - buffer[24] = p[2]; - buffer[25] = ' '; - strncpy(buffer+26, p+3, 7); - buffer[33] = ','; - - p = strchr(buffer+34, ',')+1; - if (p[0] == 'W') - buffer[21] = '-'; - - // find speed - p = strchr(p, ',')+1; - tmp = 0; - if (p[0] != ',') { - // ok there is some sort of speed - while (p[0] != '.' && p[0] != ',') { - tmp *= 10; - tmp += p[0] - '0'; - p++; - } - tmp *= 10; - if (isdigit(p[1])) - tmp += p[1] - '0'; // tenths - tmp *= 10; - if (isdigit(p[2])) - tmp += p[2] - '0'; // hundredths - - // tmp is knots * 100 - // convert to mph (1.15 mph = 1 knot) - tmp *= 115; - // -OR- convert km/h - // tmp *= 185 - } - tmp /= 100; - - buffer[34] = (tmp / 10000) + '0'; - tmp %= 10000; - buffer[35] = (tmp / 1000) + '0'; - tmp %= 1000; - buffer[36] = (tmp / 100) + '0'; - tmp %= 100; - buffer[37] = '.'; - buffer[38] = (tmp / 10) + '0'; - tmp %= 10; - buffer[39] = tmp + '0'; - - buffer[40] = ','; - p = strchr(p, ',')+1; - // skip past bearing - p = strchr(p, ',')+1; - //mod for bug when speed,bearing are missing (bill greiman) - uint8_t date[6]; - for (uint8_t id = 0; id < 6; id++) date[id] = p[id]; - // get date into 2001-01-31 style - buffer[41] = '2'; - buffer[42] = '0'; - buffer[43] = date[4]; - buffer[44] = date[5]; - buffer[45] = '-'; - buffer[46] = date[2]; - buffer[47] = date[3]; - buffer[48] = '-'; - buffer[49] = date[0]; - buffer[50] = date[1]; - buffer[51] = 0; - digitalWrite(led2Pin, HIGH); - if(f.write((uint8_t *) buffer, 51) != 51) { - putstring_nl("can't write fix!"); - return; - } - Serial.print(buffer); - // clear print error - f.writeError = 0; - // add sensor data - for (uint8_t ia = 0; ia < sensorCount; ia++) { - Serial.print(','); - f.print(','); - uint16_t data = analogRead(ia); - Serial.print(data); - f.print(data); - } - Serial.println(); - f.println(); - if (f.writeError || !f.sync()) { - putstring_nl("can't write data!"); - error(4); - } - digitalWrite(led2Pin, LOW); - bufferidx = 0; - return; - } - bufferidx++; - if (bufferidx == BUFFSIZE-1) { - Serial.print('!', BYTE); - bufferidx = 0; - } - } -} - +// Ladyada's logger modified by Bill Greiman to use the SdFat library +// this is a generic logger that does checksum testing so the data written should be always good +// Assumes a sirf III chipset logger attached to pin 0 and 1 + +uint8_t sensorCount = 3; //number of analog pins to log + +#include +#include +#include + +#define isdigit(x) ( x >= '0' && x <= '9') + +//extern uint16_t _end; + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile f; + +#define led1Pin 4 // LED1 connected to digital pin 4 +#define led2Pin 3 // LED2 connected to digital pin 3 +#define powerpin 2 // GPS power control + +// set the RX_BUFFER_SIZE to 32! +#define BUFFSIZE 73 // we buffer one NMEA sentence at a time, 83 bytes is longer than the max length +char buffer[BUFFSIZE]; // this is the double buffer +char buffer2[12]; + +uint8_t bufferidx = 0; +uint32_t tmp; +#define LOG_RMC 1 // essential location data +#define RMC_ON "$PSRF103,4,0,1,1*21\r\n" // the command we send to turn RMC on (1 hz rate) +#define RMC_OFF "$PSRF103,4,0,0,1*20\r\n" // the command we send to turn RMC off + +#define LOG_GGA 0 // contains fix, hdop & vdop data +#define GGA_ON "$PSRF103,0,0,1,1*25\r\n" // the command we send to turn GGA on (1 hz rate) +#define GGA_OFF "$PSRF103,0,0,0,1*24\r\n" // the command we send to turn GGA off + +#define LOG_GSA 0 // satellite data +#define GSA_ON "$PSRF103,2,0,1,1*27\r\n" // the command we send to turn GSA on (1 hz rate) +#define GSA_OFF "$PSRF103,2,0,0,1*26\r\n" // the command we send to turn GSA off + +#define LOG_GSV 0 // detailed satellite data +#define GSV_ON "$PSRF103,3,0,1,1*26\r\n" // the command we send to turn GSV on (1 hz rate) +#define GSV_OFF "$PSRF103,3,0,0,1*27\r\n" // the command we send to turn GSV off + +#define LOG_GLL 0 // Loran-compatibility data +// this isnt output by default + +#define USE_WAAS 1 // useful in US, but slower fix +#define WAAS_ON "$PSRF151,1*3F\r\n" // the command for turning on WAAS +#define WAAS_OFF "$PSRF151,0*3E\r\n" // the command for turning off WAAS + +#define LOG_RMC_FIXONLY 1 // log only when we get RMC's with fix? +uint8_t fix = 0; // current fix data + +// macros to use PSTR +#define putstring(str) SerialPrint_P(PSTR(str)) +#define putstring_nl(str) SerialPrintln_P(PSTR(str)) + +// read a Hex value and return the decimal equivalent +uint8_t parseHex(char c) { + if (c < '0') + return 0; + if (c <= '9') + return c - '0'; + if (c < 'A') + return 0; + if (c <= 'F') + return (c - 'A')+10; +} + +uint8_t i; + +// blink out an error code +void error(uint8_t errno) { + if (card.errorCode()) { + putstring("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1) { + for (i=0; i 6) sensorCount = 6; + strncpy_P(buffer, PSTR("time,lat,long,speed,date,sens0,sens1,sens2,sens3,sens4,sens5"), 24 + 6*sensorCount); + Serial.println(buffer); + // clear print error + f.writeError = 0; + f.println(buffer); + if (f.writeError || !f.sync()) { + putstring_nl("can't write header!"); + error(5); + } + + delay(1000); + + putstring("\r\n"); +#if USE_WAAS == 1 + putstring(WAAS_ON); // turn on WAAS +#else + putstring(WAAS_OFF); // turn on WAAS +#endif + +#if LOG_RMC == 1 + putstring(RMC_ON); // turn on RMC +#else + putstring(RMC_OFF); // turn off RMC +#endif + +#if LOG_GSV == 1 + putstring(GSV_ON); // turn on GSV +#else + putstring(GSV_OFF); // turn off GSV +#endif + +#if LOG_GSA == 1 + putstring(GSA_ON); // turn on GSA +#else + putstring(GSA_OFF); // turn off GSA +#endif + +#if LOG_GGA == 1 + putstring(GGA_ON); // turn on GGA +#else + putstring(GGA_OFF); // turn off GGA +#endif +} + +void loop() { // run over and over again + + //Serial.println(Serial.available(), DEC); + char c; + uint8_t sum; + + // read one 'line' + if (Serial.available()) { + c = Serial.read(); + //Serial.print(c, BYTE); + if (bufferidx == 0) { + while (c != '$') + c = Serial.read(); // wait till we get a $ + } + buffer[bufferidx] = c; + + //Serial.print(c, BYTE); + if (c == '\n') { + //putstring_nl("EOL"); + //Serial.print(buffer); + buffer[bufferidx+1] = 0; // terminate it + + if (buffer[bufferidx-4] != '*') { + // no checksum? + Serial.print('*', BYTE); + bufferidx = 0; + return; + } + // get checksum + sum = parseHex(buffer[bufferidx-3]) * 16; + sum += parseHex(buffer[bufferidx-2]); + + // check checksum + for (i=1; i < (bufferidx-4); i++) { + sum ^= buffer[i]; + } + if (sum != 0) { + //putstring_nl("Cxsum mismatch"); + Serial.print('~', BYTE); + bufferidx = 0; + return; + } + // got good data! + + if (strstr(buffer, "GPRMC")) { + // find out if we got a fix + char *p = buffer; + p = strchr(p, ',')+1; + p = strchr(p, ',')+1; // skip to 3rd item + + if (p[0] == 'V') { + digitalWrite(led1Pin, LOW); + fix = 0; + } else { + digitalWrite(led1Pin, HIGH); + fix = 1; + } + } else { + // not GPRMC + bufferidx = 0; + return; + } +#if LOG_RMC_FIXONLY + if (!fix) { + Serial.print('_', BYTE); + bufferidx = 0; + return; + } +#endif + // rad. lets print it! + + Serial.print(buffer); + + // time to clean up the string + // find time + char *p = buffer; + p = strchr(p, ',')+1; + buffer[0] = p[0]; + buffer[1] = p[1]; + buffer[2] = ':'; + buffer[3] = p[2]; + buffer[4] = p[3]; + buffer[5] = ':'; + buffer[6] = p[4]; + buffer[7] = p[5]; + // we ignore milliseconds + buffer[8] = ','; + + p = strchr(buffer+8, ',')+1; + // skip past 'active' flag + p = strchr(p, ',')+1; + // find lat + p = strchr(p, ',')+1; + + buffer[9] = '+'; + buffer[10] = p[0]; + buffer[11] = p[1]; + buffer[12] = ' '; + strncpy(buffer+13, p+2, 7); + buffer[20] = ','; + + p = strchr(buffer+21, ',')+1; + if (p[0] == 'S') + buffer[9] = '-'; + + // find long + p = strchr(p, ',')+1; + buffer[21] = '+'; + buffer[22] = p[0]; + buffer[23] = p[1]; + buffer[24] = p[2]; + buffer[25] = ' '; + strncpy(buffer+26, p+3, 7); + buffer[33] = ','; + + p = strchr(buffer+34, ',')+1; + if (p[0] == 'W') + buffer[21] = '-'; + + // find speed + p = strchr(p, ',')+1; + tmp = 0; + if (p[0] != ',') { + // ok there is some sort of speed + while (p[0] != '.' && p[0] != ',') { + tmp *= 10; + tmp += p[0] - '0'; + p++; + } + tmp *= 10; + if (isdigit(p[1])) + tmp += p[1] - '0'; // tenths + tmp *= 10; + if (isdigit(p[2])) + tmp += p[2] - '0'; // hundredths + + // tmp is knots * 100 + // convert to mph (1.15 mph = 1 knot) + tmp *= 115; + // -OR- convert km/h + // tmp *= 185 + } + tmp /= 100; + + buffer[34] = (tmp / 10000) + '0'; + tmp %= 10000; + buffer[35] = (tmp / 1000) + '0'; + tmp %= 1000; + buffer[36] = (tmp / 100) + '0'; + tmp %= 100; + buffer[37] = '.'; + buffer[38] = (tmp / 10) + '0'; + tmp %= 10; + buffer[39] = tmp + '0'; + + buffer[40] = ','; + p = strchr(p, ',')+1; + // skip past bearing + p = strchr(p, ',')+1; + //mod for bug when speed,bearing are missing (bill greiman) + uint8_t date[6]; + for (uint8_t id = 0; id < 6; id++) date[id] = p[id]; + // get date into 2001-01-31 style + buffer[41] = '2'; + buffer[42] = '0'; + buffer[43] = date[4]; + buffer[44] = date[5]; + buffer[45] = '-'; + buffer[46] = date[2]; + buffer[47] = date[3]; + buffer[48] = '-'; + buffer[49] = date[0]; + buffer[50] = date[1]; + buffer[51] = 0; + digitalWrite(led2Pin, HIGH); + if(f.write((uint8_t *) buffer, 51) != 51) { + putstring_nl("can't write fix!"); + return; + } + Serial.print(buffer); + // clear print error + f.writeError = 0; + // add sensor data + for (uint8_t ia = 0; ia < sensorCount; ia++) { + Serial.print(','); + f.print(','); + uint16_t data = analogRead(ia); + Serial.print(data); + f.print(data); + } + Serial.println(); + f.println(); + if (f.writeError || !f.sync()) { + putstring_nl("can't write data!"); + error(4); + } + digitalWrite(led2Pin, LOW); + bufferidx = 0; + return; + } + bufferidx++; + if (bufferidx == BUFFSIZE-1) { + Serial.print('!', BYTE); + bufferidx = 0; + } + } +} + diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatInfo/SdFatInfo.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatInfo/SdFatInfo.pde index a48280f6..94048ac3 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatInfo/SdFatInfo.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatInfo/SdFatInfo.pde @@ -1,180 +1,180 @@ -/* - * This sketch attempts to initialize a SD card and analyze its structure. - */ -#include -#include - -// offset to partition table -#define PART_OFFSET (512-64-2) - -Sd2Card card; -SdVolume vol; - -//global for card erase sector size -uint32_t sectorSize; - -void sdError(void) { - PgmPrintln("SD error"); - PgmPrint("errorCode: "); - Serial.println(card.errorCode(), HEX); - PgmPrint("errorData: "); - Serial.println(card.errorData(), HEX); - return; -} - -uint8_t cidDmp(void) { - cid_t cid; - if (!card.readCID(&cid)) { - PgmPrint("readCID failed"); - sdError(); - return false; - } - PgmPrint("\nManufacturer ID: "); - Serial.println(cid.mid, HEX); - PgmPrint("OEM ID: "); - Serial.print(cid.oid[0]); - Serial.println(cid.oid[1]); - PgmPrint("Product: "); - for (uint8_t i = 0; i < 5; i++) { - Serial.print(cid.pnm[i]); - } - PgmPrint("\nVersion: "); - Serial.print(cid.prv_n, DEC); - Serial.print('.'); - Serial.println(cid.prv_m, DEC); - PgmPrint("Serial number: "); - Serial.println(cid.psn); - PgmPrint("Manufacturing date: "); - Serial.print(cid.mdt_month); - Serial.print('/'); - Serial.println(2000 + cid.mdt_year_low + (cid.mdt_year_high <<4)); - Serial.println(); - return true; -} - -uint8_t csdDmp(void) { - csd_t csd; - uint8_t eraseSingleBlock; - uint32_t cardSize = card.cardSize(); - if (cardSize == 0 || !card.readCSD(&csd)) { - PgmPrintln("readCSD failed"); - sdError(); - return false; - } - if (csd.v1.csd_ver == 0) { - eraseSingleBlock = csd.v1.erase_blk_en; - sectorSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; - } - else if (csd.v2.csd_ver == 1) { - eraseSingleBlock = csd.v2.erase_blk_en; - sectorSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low; - } - else { - PgmPrintln("csd version error"); - return false; - } - sectorSize++; - PgmPrint("cardSize: "); - Serial.print(cardSize); - PgmPrintln(" (512 byte blocks)"); - PgmPrint("flashEraseSize: "); - Serial.print(sectorSize, DEC); - PgmPrintln(" blocks"); - PgmPrint("eraseSingleBlock: "); - if (eraseSingleBlock) { - PgmPrintln("true"); - } - else { - PgmPrintln("false"); - } - return true; -} -// print partition table -uint8_t partDmp(void) { - part_t pt; - PgmPrintln("\npart,boot,type,start,length"); - for (uint8_t ip = 1; ip < 5; ip++) { - if (!card.readData(0, PART_OFFSET + 16*(ip-1), 16, (uint8_t *)&pt)) { - PgmPrint("read partition table failed"); - sdError(); - return false; - } - Serial.print(ip, DEC); - Serial.print(','); - Serial.print(pt.boot,HEX); - Serial.print(','); - Serial.print(pt.type, HEX); - Serial.print(','); - Serial.print(pt.firstSector); - Serial.print(','); - Serial.println(pt.totalSectors); - } - return true; -} - -void volDmp(void) { - PgmPrint("\nVolume is FAT"); - Serial.println(vol.fatType(), DEC); - PgmPrint("blocksPerCluster: "); - Serial.println(vol.blocksPerCluster(), DEC); - PgmPrint("clusterCount: "); - Serial.println(vol.clusterCount()); - PgmPrint("fatStartBlock: "); - Serial.println(vol.fatStartBlock()); - PgmPrint("fatCount: "); - Serial.println(vol.fatCount(), DEC); - PgmPrint("blocksPerFat: "); - Serial.println(vol.blocksPerFat()); - PgmPrint("rootDirStart: "); - Serial.println(vol.rootDirStart()); - PgmPrint("dataStartBlock: "); - Serial.println(vol.dataStartBlock()); - if (vol.dataStartBlock()%sectorSize) { - PgmPrintln("Data area is not aligned on flash erase boundaries!"); - } -} - -void setup() { - Serial.begin(9600); -} - -void loop() { - PgmPrintln("\ntype any character to start"); - while (!Serial.available()); - Serial.flush(); - uint32_t t = millis(); - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - uint8_t r = card.init(SPI_HALF_SPEED); - t = millis() - t; - if (!r) { - PgmPrintln("\ncard.init failed"); - sdError(); - return; - } - PgmPrint("\ninit time: "); - Serial.println(t); - PgmPrint("\nCard type: "); - switch(card.type()) { - case SD_CARD_TYPE_SD1: - PgmPrintln("SD1"); - break; - case SD_CARD_TYPE_SD2: - PgmPrintln("SD2"); - break; - case SD_CARD_TYPE_SDHC: - PgmPrintln("SDHC"); - break; - default: - PgmPrintln("Unknown"); - } - if(!cidDmp()) return; - if(!csdDmp()) return; - if(!partDmp()) return; - if (!vol.init(&card)) { - PgmPrintln("\nvol.init failed"); - sdError(); - return; - } - volDmp(); -} +/* + * This sketch attempts to initialize a SD card and analyze its structure. + */ +#include +#include + +// offset to partition table +#define PART_OFFSET (512-64-2) + +Sd2Card card; +SdVolume vol; + +//global for card erase sector size +uint32_t sectorSize; + +void sdError(void) { + PgmPrintln("SD error"); + PgmPrint("errorCode: "); + Serial.println(card.errorCode(), HEX); + PgmPrint("errorData: "); + Serial.println(card.errorData(), HEX); + return; +} + +uint8_t cidDmp(void) { + cid_t cid; + if (!card.readCID(&cid)) { + PgmPrint("readCID failed"); + sdError(); + return false; + } + PgmPrint("\nManufacturer ID: "); + Serial.println(cid.mid, HEX); + PgmPrint("OEM ID: "); + Serial.print(cid.oid[0]); + Serial.println(cid.oid[1]); + PgmPrint("Product: "); + for (uint8_t i = 0; i < 5; i++) { + Serial.print(cid.pnm[i]); + } + PgmPrint("\nVersion: "); + Serial.print(cid.prv_n, DEC); + Serial.print('.'); + Serial.println(cid.prv_m, DEC); + PgmPrint("Serial number: "); + Serial.println(cid.psn); + PgmPrint("Manufacturing date: "); + Serial.print(cid.mdt_month); + Serial.print('/'); + Serial.println(2000 + cid.mdt_year_low + (cid.mdt_year_high <<4)); + Serial.println(); + return true; +} + +uint8_t csdDmp(void) { + csd_t csd; + uint8_t eraseSingleBlock; + uint32_t cardSize = card.cardSize(); + if (cardSize == 0 || !card.readCSD(&csd)) { + PgmPrintln("readCSD failed"); + sdError(); + return false; + } + if (csd.v1.csd_ver == 0) { + eraseSingleBlock = csd.v1.erase_blk_en; + sectorSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; + } + else if (csd.v2.csd_ver == 1) { + eraseSingleBlock = csd.v2.erase_blk_en; + sectorSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low; + } + else { + PgmPrintln("csd version error"); + return false; + } + sectorSize++; + PgmPrint("cardSize: "); + Serial.print(cardSize); + PgmPrintln(" (512 byte blocks)"); + PgmPrint("flashEraseSize: "); + Serial.print(sectorSize, DEC); + PgmPrintln(" blocks"); + PgmPrint("eraseSingleBlock: "); + if (eraseSingleBlock) { + PgmPrintln("true"); + } + else { + PgmPrintln("false"); + } + return true; +} +// print partition table +uint8_t partDmp(void) { + part_t pt; + PgmPrintln("\npart,boot,type,start,length"); + for (uint8_t ip = 1; ip < 5; ip++) { + if (!card.readData(0, PART_OFFSET + 16*(ip-1), 16, (uint8_t *)&pt)) { + PgmPrint("read partition table failed"); + sdError(); + return false; + } + Serial.print(ip, DEC); + Serial.print(','); + Serial.print(pt.boot,HEX); + Serial.print(','); + Serial.print(pt.type, HEX); + Serial.print(','); + Serial.print(pt.firstSector); + Serial.print(','); + Serial.println(pt.totalSectors); + } + return true; +} + +void volDmp(void) { + PgmPrint("\nVolume is FAT"); + Serial.println(vol.fatType(), DEC); + PgmPrint("blocksPerCluster: "); + Serial.println(vol.blocksPerCluster(), DEC); + PgmPrint("clusterCount: "); + Serial.println(vol.clusterCount()); + PgmPrint("fatStartBlock: "); + Serial.println(vol.fatStartBlock()); + PgmPrint("fatCount: "); + Serial.println(vol.fatCount(), DEC); + PgmPrint("blocksPerFat: "); + Serial.println(vol.blocksPerFat()); + PgmPrint("rootDirStart: "); + Serial.println(vol.rootDirStart()); + PgmPrint("dataStartBlock: "); + Serial.println(vol.dataStartBlock()); + if (vol.dataStartBlock()%sectorSize) { + PgmPrintln("Data area is not aligned on flash erase boundaries!"); + } +} + +void setup() { + Serial.begin(9600); +} + +void loop() { + PgmPrintln("\ntype any character to start"); + while (!Serial.available()); + Serial.flush(); + uint32_t t = millis(); + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + uint8_t r = card.init(SPI_HALF_SPEED); + t = millis() - t; + if (!r) { + PgmPrintln("\ncard.init failed"); + sdError(); + return; + } + PgmPrint("\ninit time: "); + Serial.println(t); + PgmPrint("\nCard type: "); + switch(card.type()) { + case SD_CARD_TYPE_SD1: + PgmPrintln("SD1"); + break; + case SD_CARD_TYPE_SD2: + PgmPrintln("SD2"); + break; + case SD_CARD_TYPE_SDHC: + PgmPrintln("SDHC"); + break; + default: + PgmPrintln("Unknown"); + } + if(!cidDmp()) return; + if(!csdDmp()) return; + if(!partDmp()) return; + if (!vol.init(&card)) { + PgmPrintln("\nvol.init failed"); + sdError(); + return; + } + volDmp(); +} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatLs/SdFatLs.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatLs/SdFatLs.pde index dc142340..76b0a16b 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatLs/SdFatLs.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatLs/SdFatLs.pde @@ -1,63 +1,63 @@ -/* - * This sketch will list all files in the root directory and - * then do a recursive list of all directories on the SD card. - * - */ - -#include -#include - -Sd2Card card; -SdVolume volume; -SdFile root; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup() { - Serial.begin(9600); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - PgmPrint("Free RAM: "); - Serial.println(FreeRam()); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed!"); - - // initialize a FAT volume - if (!volume.init(&card)) error("vol.init failed!"); - - PgmPrint("Volume is FAT"); - Serial.println(volume.fatType(),DEC); - Serial.println(); - - if (!root.openRoot(&volume)) error("openRoot failed"); - - // list file in root with date and size - PgmPrintln("Files found in root:"); - root.ls(LS_DATE | LS_SIZE); - Serial.println(); - - // Recursive list of all directories - PgmPrintln("Files found in all dirs:"); - root.ls(LS_R); - - Serial.println(); - PgmPrintln("Done"); -} - -void loop() { } +/* + * This sketch will list all files in the root directory and + * then do a recursive list of all directories on the SD card. + * + */ + +#include +#include + +Sd2Card card; +SdVolume volume; +SdFile root; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup() { + Serial.begin(9600); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + PgmPrint("Free RAM: "); + Serial.println(FreeRam()); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed!"); + + // initialize a FAT volume + if (!volume.init(&card)) error("vol.init failed!"); + + PgmPrint("Volume is FAT"); + Serial.println(volume.fatType(),DEC); + Serial.println(); + + if (!root.openRoot(&volume)) error("openRoot failed"); + + // list file in root with date and size + PgmPrintln("Files found in root:"); + root.ls(LS_DATE | LS_SIZE); + Serial.println(); + + // Recursive list of all directories + PgmPrintln("Files found in all dirs:"); + root.ls(LS_R); + + Serial.println(); + PgmPrintln("Done"); +} + +void loop() { } diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatMakeDir/SdFatMakeDir.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatMakeDir/SdFatMakeDir.pde index a6c4cfec..43a36cb8 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatMakeDir/SdFatMakeDir.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatMakeDir/SdFatMakeDir.pde @@ -1,150 +1,150 @@ -/* - * This sketch is a test of subdirectory and file creation. - * It also tests allocation of clusters to directories. - * - * It will create two subdirectories and create enough files - * to force the allocation of a cluster to each directory. - * - * More than 3000 files may be created on a FAT32 volume. - * - * Note: Some cards may 'stutter' others just get slow due - * to the number of flash erases this program causes. - */ -#include -#include - -Sd2Card card; -SdVolume volume; -SdFile root; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} -/* - * create enough files to force a cluster to be allocated to dir. - */ -void dirAllocTest(SdFile &dir) { - char buf[13], name[13]; - SdFile file; - uint16_t n; - uint32_t size = dir.fileSize(); - - // create files and write name to file - for (n = 0; ; n++){ - // make file name - sprintf(name, "%u.TXT", n); - - // open start time - uint32_t t0 = millis(); - if (!file.open(&dir, name, O_WRITE | O_CREAT | O_EXCL)) { - error("open for write failed"); - } - - // open end time and write start time - uint32_t t1 = millis(); - // write file name to file - file.print(name); - if (!file.close()) error("close write"); - - // write end time - uint32_t t2 = millis(); - PgmPrint("WR "); - Serial.print(n); - Serial.print(' '); - - // print time to create file - Serial.print(t1 - t0); - Serial.print(' '); - - // print time to write file - Serial.println(t2 - t1); - - // directory size will change when a cluster is added - if (dir.fileSize() != size) break; - } - - // read files and check content - for (uint16_t i = 0; i <= n; i++) { - sprintf(name, "%u.TXT", i); - - // open start time - uint32_t t0 = millis(); - if (!file.open(&dir, name, O_READ)) { - error("open for read failed"); - } - - // open end time and read start time - uint32_t t1 = millis(); - int16_t nr = file.read(buf, 13); - if (nr < 5) error("file.read failed"); - - // read end time - uint32_t t2 = millis(); - - // check file content - if (strlen(name) != nr || strncmp(name, buf, nr)) { - error("content compare failed"); - } - if (!file.close()) error("close read failed"); - - PgmPrint("RD "); - Serial.print(i); - Serial.print(' '); - - // print open time - Serial.print(t1 - t0); - Serial.print(' '); - - // print read time - Serial.println(t2 - t1); - } -} - -void setup() { - Serial.begin(9600); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - // initialize the SD card at SPI_FULL_SPEED for best performance. - // try SPI_HALF_SPEED if bus errors occur. - if (!card.init(SPI_FULL_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - // write files to root if FAT32 - if (volume.fatType() == 32) { - PgmPrintln("Writing files to root"); - dirAllocTest(root); - } - - // create sub1 and write files - SdFile sub1; - if (!sub1.makeDir(&root, "SUB1")) error("makdeDir SUB1 failed"); - PgmPrintln("Writing files to SUB1"); - dirAllocTest(sub1); - - // create sub2 and write files - SdFile sub2; - if (!sub2.makeDir(&sub1, "SUB2")) error("makeDir SUB2 failed"); - PgmPrintln("Writing files to SUB2"); - dirAllocTest(sub2); - - PgmPrintln("Done"); -} - -void loop() { } +/* + * This sketch is a test of subdirectory and file creation. + * It also tests allocation of clusters to directories. + * + * It will create two subdirectories and create enough files + * to force the allocation of a cluster to each directory. + * + * More than 3000 files may be created on a FAT32 volume. + * + * Note: Some cards may 'stutter' others just get slow due + * to the number of flash erases this program causes. + */ +#include +#include + +Sd2Card card; +SdVolume volume; +SdFile root; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} +/* + * create enough files to force a cluster to be allocated to dir. + */ +void dirAllocTest(SdFile &dir) { + char buf[13], name[13]; + SdFile file; + uint16_t n; + uint32_t size = dir.fileSize(); + + // create files and write name to file + for (n = 0; ; n++){ + // make file name + sprintf(name, "%u.TXT", n); + + // open start time + uint32_t t0 = millis(); + if (!file.open(&dir, name, O_WRITE | O_CREAT | O_EXCL)) { + error("open for write failed"); + } + + // open end time and write start time + uint32_t t1 = millis(); + // write file name to file + file.print(name); + if (!file.close()) error("close write"); + + // write end time + uint32_t t2 = millis(); + PgmPrint("WR "); + Serial.print(n); + Serial.print(' '); + + // print time to create file + Serial.print(t1 - t0); + Serial.print(' '); + + // print time to write file + Serial.println(t2 - t1); + + // directory size will change when a cluster is added + if (dir.fileSize() != size) break; + } + + // read files and check content + for (uint16_t i = 0; i <= n; i++) { + sprintf(name, "%u.TXT", i); + + // open start time + uint32_t t0 = millis(); + if (!file.open(&dir, name, O_READ)) { + error("open for read failed"); + } + + // open end time and read start time + uint32_t t1 = millis(); + int16_t nr = file.read(buf, 13); + if (nr < 5) error("file.read failed"); + + // read end time + uint32_t t2 = millis(); + + // check file content + if (strlen(name) != nr || strncmp(name, buf, nr)) { + error("content compare failed"); + } + if (!file.close()) error("close read failed"); + + PgmPrint("RD "); + Serial.print(i); + Serial.print(' '); + + // print open time + Serial.print(t1 - t0); + Serial.print(' '); + + // print read time + Serial.println(t2 - t1); + } +} + +void setup() { + Serial.begin(9600); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + // initialize the SD card at SPI_FULL_SPEED for best performance. + // try SPI_HALF_SPEED if bus errors occur. + if (!card.init(SPI_FULL_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + // write files to root if FAT32 + if (volume.fatType() == 32) { + PgmPrintln("Writing files to root"); + dirAllocTest(root); + } + + // create sub1 and write files + SdFile sub1; + if (!sub1.makeDir(&root, "SUB1")) error("makdeDir SUB1 failed"); + PgmPrintln("Writing files to SUB1"); + dirAllocTest(sub1); + + // create sub2 and write files + SdFile sub2; + if (!sub2.makeDir(&sub1, "SUB2")) error("makeDir SUB2 failed"); + PgmPrintln("Writing files to SUB2"); + dirAllocTest(sub2); + + PgmPrintln("Done"); +} + +void loop() { } diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatPrint/SdFatPrint.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatPrint/SdFatPrint.pde index e01c49cb..518b8172 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatPrint/SdFatPrint.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatPrint/SdFatPrint.pde @@ -1,71 +1,71 @@ -/* - * Print Example - * - * This sketch shows how to use the Arduino Print class with SdFat. - */ -#include -#include // use functions to print strings from flash memory - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - // create a new file - char name[] = "PRINT00.TXT"; - for (uint8_t i = 0; i < 100; i++) { - name[5] = i/10 + '0'; - name[6] = i%10 + '0'; - // only create new file for write - if (file.open(&root, name, O_CREAT | O_EXCL | O_WRITE)) break; - } - if (!file.isOpen()) error ("file.create"); - PgmPrintln("Printing to: "); - Serial.println(name); - - // clear print error - file.writeError = 0; - - // print 100 line to file - for (uint8_t i = 0; i < 100; i++) { - file.print("line "); - file.print(i, DEC); - file.print(" millis = "); - file.println(millis()); - } - // force write of all data to the SD card - if (file.writeError || !file.sync()) error ("print or sync"); - PgmPrintln("Done"); -} -void loop(void){} +/* + * Print Example + * + * This sketch shows how to use the Arduino Print class with SdFat. + */ +#include +#include // use functions to print strings from flash memory + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + // create a new file + char name[] = "PRINT00.TXT"; + for (uint8_t i = 0; i < 100; i++) { + name[5] = i/10 + '0'; + name[6] = i%10 + '0'; + // only create new file for write + if (file.open(&root, name, O_CREAT | O_EXCL | O_WRITE)) break; + } + if (!file.isOpen()) error ("file.create"); + PgmPrintln("Printing to: "); + Serial.println(name); + + // clear print error + file.writeError = 0; + + // print 100 line to file + for (uint8_t i = 0; i < 100; i++) { + file.print("line "); + file.print(i, DEC); + file.print(" millis = "); + file.println(millis()); + } + // force write of all data to the SD card + if (file.writeError || !file.sync()) error ("print or sync"); + PgmPrintln("Done"); +} +void loop(void){} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRawWrite/SdFatRawWrite.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRawWrite/SdFatRawWrite.pde index f2db00e2..fe4b57ef 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRawWrite/SdFatRawWrite.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRawWrite/SdFatRawWrite.pde @@ -1,186 +1,186 @@ -/* - * This sketch illustrates raw write functions in SdFat that - * can be used for high speed data logging. These functions - * are used in the WaveRP library to record audio with the - * Adafruit Wave Shield using the built-in Arduino ADC. - * - * The WaveRP library captures data from the ADC in an ISR - * that is driven driven by timer one. Data is collected in - * two 512 byte buffers and written to the SD card. - * - * This sketch simulates logging from a source that produces - * data at a constant rate of one block every MILLIS_PER_BLOCK. - * - * If a high quality SanDisk card is used with this sketch - * no overruns occur and the maximum block write time is - * 2 millis. - * - * Note: WaveRP creates a very large file then truncates it - * to the length that is used for a recording. It only takes - * a few seconds to erase a 500 MB file since the card only - * marks the blocks as erased; no data transfer is required. - */ - -#include -#include - -// number of blocks in the contiguous file -#define BLOCK_COUNT 10000UL - -// time to produce a block of data -#define MILLIS_PER_BLOCK 10 - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -uint32_t bgnBlock, endBlock; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup(void) { - Serial.begin(9600); -} - -void loop(void) { - Serial.flush(); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - // initialize the SD card - uint32_t t = millis(); - - // initialize the SD card at SPI_FULL_SPEED for best performance. - // try SPI_HALF_SPEED if bus errors occur. - if (!card.init(SPI_FULL_SPEED)) error("card.init failed"); - - t = millis() - t; - - PgmPrint("Card init time: "); - Serial.print(t); - PgmPrintln(" millis"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - // delete possible existing file - SdFile::remove(&root, "RAW.TXT"); - - // create a contiguous file - if (!file.createContiguous(&root, "RAW.TXT", 512UL*BLOCK_COUNT)) { - error("createContiguous failed"); - } - // get the location of the file's blocks - if (!file.contiguousRange(&bgnBlock, &endBlock)) { - error("contiguousRange failed"); - } - //*********************NOTE************************************** - // NO SdFile calls are allowed while cache is used for raw writes - //*************************************************************** - - // clear the cache and use it as a 512 byte buffer - uint8_t* pCache = volume.cacheClear(); - - // fill cache with eight lines of 64 bytes each - memset(pCache, ' ', 512); - for (uint16_t i = 0; i < 512; i += 64) { - // put line number at end of line then CR/LF - pCache[i + 61] = '0' + (i/64); - pCache[i + 62] = '\r'; - pCache[i + 63] = '\n'; - } - - PgmPrint("Start raw write of "); - Serial.print(file.fileSize()); - PgmPrintln(" bytes at"); - - Serial.print(512000UL/MILLIS_PER_BLOCK); - PgmPrintln(" bytes per second"); - - PgmPrint("Please wait "); - Serial.print((BLOCK_COUNT*MILLIS_PER_BLOCK)/1000UL); - PgmPrintln(" seconds"); - - // tell card to setup for multiple block write with pre-erase - if (!card.erase(bgnBlock, endBlock)) error("card.erase failed"); - if (!card.writeStart(bgnBlock, BLOCK_COUNT)) { - error("writeStart failed"); - } - // init stats - uint16_t overruns = 0; - uint16_t maxWriteTime = 0; - t = millis(); - uint32_t tNext = t; - - // write data - for (uint32_t b = 0; b < BLOCK_COUNT; b++) { - // write must be done by this time - tNext += MILLIS_PER_BLOCK; - - // put block number at start of first line in block - uint32_t n = b; - for (int8_t d = 5; d >= 0; d--){ - pCache[d] = n || d == 5 ? n % 10 + '0' : ' '; - n /= 10; - } - // write a 512 byte block - uint32_t tw = micros(); - if (!card.writeData(pCache)) error("writeData failed"); - tw = micros() - tw; - - // check for max write time - if (tw > maxWriteTime) { - maxWriteTime = tw; - } - // check for overrun - if (millis() > tNext) { - overruns++; - // advance time to reflect overrun - tNext = millis(); - } - else { - // wait for time to write next block - while(millis() < tNext); - } - } - // total write time - t = millis() - t; - - // end multiple block write mode - if (!card.writeStop()) error("writeStop failed"); - - PgmPrintln("Done"); - - PgmPrint("Overruns: "); - Serial.println(overruns); - - PgmPrint("Elapsed time: "); - Serial.print(t); - PgmPrintln(" millis"); - - PgmPrint("Max write time: "); - Serial.print(maxWriteTime); - PgmPrintln(" micros"); - - // close files for next pass of loop - root.close(); - file.close(); - Serial.println(); -} +/* + * This sketch illustrates raw write functions in SdFat that + * can be used for high speed data logging. These functions + * are used in the WaveRP library to record audio with the + * Adafruit Wave Shield using the built-in Arduino ADC. + * + * The WaveRP library captures data from the ADC in an ISR + * that is driven driven by timer one. Data is collected in + * two 512 byte buffers and written to the SD card. + * + * This sketch simulates logging from a source that produces + * data at a constant rate of one block every MILLIS_PER_BLOCK. + * + * If a high quality SanDisk card is used with this sketch + * no overruns occur and the maximum block write time is + * 2 millis. + * + * Note: WaveRP creates a very large file then truncates it + * to the length that is used for a recording. It only takes + * a few seconds to erase a 500 MB file since the card only + * marks the blocks as erased; no data transfer is required. + */ + +#include +#include + +// number of blocks in the contiguous file +#define BLOCK_COUNT 10000UL + +// time to produce a block of data +#define MILLIS_PER_BLOCK 10 + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +uint32_t bgnBlock, endBlock; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup(void) { + Serial.begin(9600); +} + +void loop(void) { + Serial.flush(); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + // initialize the SD card + uint32_t t = millis(); + + // initialize the SD card at SPI_FULL_SPEED for best performance. + // try SPI_HALF_SPEED if bus errors occur. + if (!card.init(SPI_FULL_SPEED)) error("card.init failed"); + + t = millis() - t; + + PgmPrint("Card init time: "); + Serial.print(t); + PgmPrintln(" millis"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + // delete possible existing file + SdFile::remove(&root, "RAW.TXT"); + + // create a contiguous file + if (!file.createContiguous(&root, "RAW.TXT", 512UL*BLOCK_COUNT)) { + error("createContiguous failed"); + } + // get the location of the file's blocks + if (!file.contiguousRange(&bgnBlock, &endBlock)) { + error("contiguousRange failed"); + } + //*********************NOTE************************************** + // NO SdFile calls are allowed while cache is used for raw writes + //*************************************************************** + + // clear the cache and use it as a 512 byte buffer + uint8_t* pCache = volume.cacheClear(); + + // fill cache with eight lines of 64 bytes each + memset(pCache, ' ', 512); + for (uint16_t i = 0; i < 512; i += 64) { + // put line number at end of line then CR/LF + pCache[i + 61] = '0' + (i/64); + pCache[i + 62] = '\r'; + pCache[i + 63] = '\n'; + } + + PgmPrint("Start raw write of "); + Serial.print(file.fileSize()); + PgmPrintln(" bytes at"); + + Serial.print(512000UL/MILLIS_PER_BLOCK); + PgmPrintln(" bytes per second"); + + PgmPrint("Please wait "); + Serial.print((BLOCK_COUNT*MILLIS_PER_BLOCK)/1000UL); + PgmPrintln(" seconds"); + + // tell card to setup for multiple block write with pre-erase + if (!card.erase(bgnBlock, endBlock)) error("card.erase failed"); + if (!card.writeStart(bgnBlock, BLOCK_COUNT)) { + error("writeStart failed"); + } + // init stats + uint16_t overruns = 0; + uint16_t maxWriteTime = 0; + t = millis(); + uint32_t tNext = t; + + // write data + for (uint32_t b = 0; b < BLOCK_COUNT; b++) { + // write must be done by this time + tNext += MILLIS_PER_BLOCK; + + // put block number at start of first line in block + uint32_t n = b; + for (int8_t d = 5; d >= 0; d--){ + pCache[d] = n || d == 5 ? n % 10 + '0' : ' '; + n /= 10; + } + // write a 512 byte block + uint32_t tw = micros(); + if (!card.writeData(pCache)) error("writeData failed"); + tw = micros() - tw; + + // check for max write time + if (tw > maxWriteTime) { + maxWriteTime = tw; + } + // check for overrun + if (millis() > tNext) { + overruns++; + // advance time to reflect overrun + tNext = millis(); + } + else { + // wait for time to write next block + while(millis() < tNext); + } + } + // total write time + t = millis() - t; + + // end multiple block write mode + if (!card.writeStop()) error("writeStop failed"); + + PgmPrintln("Done"); + + PgmPrint("Overruns: "); + Serial.println(overruns); + + PgmPrint("Elapsed time: "); + Serial.print(t); + PgmPrintln(" millis"); + + PgmPrint("Max write time: "); + Serial.print(maxWriteTime); + PgmPrintln(" micros"); + + // close files for next pass of loop + root.close(); + file.close(); + Serial.println(); +} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRead/SdFatRead.c b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRead/SdFatRead.c index 81d325bb..0c93bd75 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRead/SdFatRead.c +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRead/SdFatRead.c @@ -1,71 +1,71 @@ -/* - * This sketch reads and prints the file - * PRINT00.TXT created by SdFatPrint.pde or - * WRITE00.TXT created by SdFatWrite.pde - */ -#include -#include - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - Serial.println("type any character to start"); - while (!Serial.available()); - Serial.println(); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - // open a file - if (file.open(&root, "PRINT00.TXT", O_READ)) { - Serial.println("Opened PRINT00.TXT"); - } - else if (file.open(&root, "WRITE00.TXT", O_READ)) { - Serial.println("Opened WRITE00.TXT"); - } - else{ - error("file.open failed"); - } - Serial.println(); - - // copy file to serial port - int16_t n; - uint8_t buf[7];// nothing special about 7, just a lucky number. - while ((n = file.read(buf, sizeof(buf))) > 0) { - for (uint8_t i = 0; i < n; i++) Serial.print(buf[i]); - } - /* easier way - int16_t c; - while ((c = file.read()) > 0) Serial.print((char)c); - */ - Serial.println("\nDone"); -} - -void loop(void) {} +/* + * This sketch reads and prints the file + * PRINT00.TXT created by SdFatPrint.pde or + * WRITE00.TXT created by SdFatWrite.pde + */ +#include +#include + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + Serial.println("type any character to start"); + while (!Serial.available()); + Serial.println(); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + // open a file + if (file.open(&root, "PRINT00.TXT", O_READ)) { + Serial.println("Opened PRINT00.TXT"); + } + else if (file.open(&root, "WRITE00.TXT", O_READ)) { + Serial.println("Opened WRITE00.TXT"); + } + else{ + error("file.open failed"); + } + Serial.println(); + + // copy file to serial port + int16_t n; + uint8_t buf[7];// nothing special about 7, just a lucky number. + while ((n = file.read(buf, sizeof(buf))) > 0) { + for (uint8_t i = 0; i < n; i++) Serial.print(buf[i]); + } + /* easier way + int16_t c; + while ((c = file.read()) > 0) Serial.print((char)c); + */ + Serial.println("\nDone"); +} + +void loop(void) {} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRemove/SdFatRemove.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRemove/SdFatRemove.pde index 88183e67..2db4f51e 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRemove/SdFatRemove.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRemove/SdFatRemove.pde @@ -1,58 +1,58 @@ -/* - * Remove Example - * - * This sketch shows how to use remove() to delete - * the file created by the SdFatAppend.pde example. - */ -#include -#include // use functions to print strings from flash memory - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - char name[] = "APPEND.TXT"; - if (!file.open(&root, name, O_WRITE)) { - PgmPrint("Can't open "); - Serial.println(name); - PgmPrintln("Run the append example to create the file."); - error("file.open failed"); - } - if (!file.remove()) error("file.remove failed"); - Serial.print(name); - PgmPrintln(" deleted."); -} - -void loop(void) {} +/* + * Remove Example + * + * This sketch shows how to use remove() to delete + * the file created by the SdFatAppend.pde example. + */ +#include +#include // use functions to print strings from flash memory + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + char name[] = "APPEND.TXT"; + if (!file.open(&root, name, O_WRITE)) { + PgmPrint("Can't open "); + Serial.println(name); + PgmPrintln("Run the append example to create the file."); + error("file.open failed"); + } + if (!file.remove()) error("file.remove failed"); + Serial.print(name); + PgmPrintln(" deleted."); +} + +void loop(void) {} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRewrite/SdFatRewrite.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRewrite/SdFatRewrite.pde index 19b836cc..bd115a8f 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRewrite/SdFatRewrite.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRewrite/SdFatRewrite.pde @@ -1,72 +1,72 @@ -/* - * Rewrite Example - * - * This sketch shows how to rewrite part of a line in the middle - * of the file created by the SdFatAppend.pde example. - * - * Check around line 30 of pass 50 of APPEND.TXT after running this sketch. - */ -#include -#include // use functions to print strings from flash memory - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - char name[] = "APPEND.TXT"; - // open for read and write - if (!file.open(&root, name, O_RDWR)) { - PgmPrint("Can't open "); - Serial.println(name); - PgmPrintln("Run the append example to create the file."); - error("file.open failed"); - } - // seek to middle of file - if (!file.seekSet(file.fileSize()/2)) error("file.seekSet failed"); - // find end of line - int16_t c; - while ((c = file.read()) > 0 && c != '\n'); - if (c < 0) error("file.read failed"); - // clear write error flag - file.writeError = false; - // rewrite the begining of the line at the current position - file.write("**rewrite**"); - if (file.writeError) error("file.write failed"); - if (!file.close()) error("file.close failed"); - Serial.print(name); - PgmPrintln(" rewrite done."); -} - -void loop(void) {} +/* + * Rewrite Example + * + * This sketch shows how to rewrite part of a line in the middle + * of the file created by the SdFatAppend.pde example. + * + * Check around line 30 of pass 50 of APPEND.TXT after running this sketch. + */ +#include +#include // use functions to print strings from flash memory + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + char name[] = "APPEND.TXT"; + // open for read and write + if (!file.open(&root, name, O_RDWR)) { + PgmPrint("Can't open "); + Serial.println(name); + PgmPrintln("Run the append example to create the file."); + error("file.open failed"); + } + // seek to middle of file + if (!file.seekSet(file.fileSize()/2)) error("file.seekSet failed"); + // find end of line + int16_t c; + while ((c = file.read()) > 0 && c != '\n'); + if (c < 0) error("file.read failed"); + // clear write error flag + file.writeError = false; + // rewrite the begining of the line at the current position + file.write("**rewrite**"); + if (file.writeError) error("file.write failed"); + if (!file.close()) error("file.close failed"); + Serial.print(name); + PgmPrintln(" rewrite done."); +} + +void loop(void) {} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRmDir/SdFatRmDir.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRmDir/SdFatRmDir.pde index db88a41d..7a9265d6 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRmDir/SdFatRmDir.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatRmDir/SdFatRmDir.pde @@ -1,111 +1,111 @@ -/* - * This sketch will remove the files and directories - * created by the SdFatMakeDir.pde sketch. - * - * Performance is erratic due to the large number - * of flash erase operations caused by many random - * writes to file structures. - */ -#include -#include - -Sd2Card card; -SdVolume volume; -SdFile root; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} -/* - * remove all files in dir. - */ -void deleteFiles(SdFile &dir) { - char name[13]; - SdFile file; - - // open and delete files - for (uint16_t n = 0; ; n++){ - sprintf(name, "%u.TXT", n); - - // open start time - uint32_t t0 = millis(); - - // assume done if open fails - if (!file.open(&dir, name, O_WRITE)) return; - - // open end time and remove start time - uint32_t t1 = millis(); - if (!file.remove()) error("file.remove failed"); - - // remove end time - uint32_t t2 = millis(); - - PgmPrint("RM "); - Serial.print(n); - Serial.print(' '); - - // open time - Serial.print(t1 - t0); - Serial.print(' '); - - // remove time - Serial.println(t2 - t1); - } -} - -void setup() { - Serial.begin(9600); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - // initialize the SD card at SPI_FULL_SPEED for best performance. - // try SPI_HALF_SPEED if bus errors occur. - if (!card.init(SPI_FULL_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - // delete files in root if FAT32 - if (volume.fatType() == 32) { - PgmPrintln("Remove files in root"); - deleteFiles(root); - } - - // open SUB1 and delete files - SdFile sub1; - if (!sub1.open(&root, "SUB1", O_READ)) error("open SUB1 failed"); - PgmPrintln("Remove files in SUB1"); - deleteFiles(sub1); - - // open SUB2 and delete files - SdFile sub2; - if (!sub2.open(&sub1, "SUB2", O_READ)) error("open SUB2 failed"); - PgmPrintln("Remove files in SUB2"); - deleteFiles(sub2); - - // remove SUB2 - if (!sub2.rmDir()) error("sub2.rmDir failed"); - PgmPrintln("SUB2 removed"); - - // remove SUB1 - if (!sub1.rmDir()) error("sub1.rmDir failed"); - PgmPrintln("SUB1 removed"); - - PgmPrintln("Done"); -} - -void loop() { } +/* + * This sketch will remove the files and directories + * created by the SdFatMakeDir.pde sketch. + * + * Performance is erratic due to the large number + * of flash erase operations caused by many random + * writes to file structures. + */ +#include +#include + +Sd2Card card; +SdVolume volume; +SdFile root; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} +/* + * remove all files in dir. + */ +void deleteFiles(SdFile &dir) { + char name[13]; + SdFile file; + + // open and delete files + for (uint16_t n = 0; ; n++){ + sprintf(name, "%u.TXT", n); + + // open start time + uint32_t t0 = millis(); + + // assume done if open fails + if (!file.open(&dir, name, O_WRITE)) return; + + // open end time and remove start time + uint32_t t1 = millis(); + if (!file.remove()) error("file.remove failed"); + + // remove end time + uint32_t t2 = millis(); + + PgmPrint("RM "); + Serial.print(n); + Serial.print(' '); + + // open time + Serial.print(t1 - t0); + Serial.print(' '); + + // remove time + Serial.println(t2 - t1); + } +} + +void setup() { + Serial.begin(9600); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + // initialize the SD card at SPI_FULL_SPEED for best performance. + // try SPI_HALF_SPEED if bus errors occur. + if (!card.init(SPI_FULL_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + // delete files in root if FAT32 + if (volume.fatType() == 32) { + PgmPrintln("Remove files in root"); + deleteFiles(root); + } + + // open SUB1 and delete files + SdFile sub1; + if (!sub1.open(&root, "SUB1", O_READ)) error("open SUB1 failed"); + PgmPrintln("Remove files in SUB1"); + deleteFiles(sub1); + + // open SUB2 and delete files + SdFile sub2; + if (!sub2.open(&sub1, "SUB2", O_READ)) error("open SUB2 failed"); + PgmPrintln("Remove files in SUB2"); + deleteFiles(sub2); + + // remove SUB2 + if (!sub2.rmDir()) error("sub2.rmDir failed"); + PgmPrintln("SUB2 removed"); + + // remove SUB1 + if (!sub1.rmDir()) error("sub1.rmDir failed"); + PgmPrintln("SUB1 removed"); + + PgmPrintln("Done"); +} + +void loop() { } diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTail/SdFatTail.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTail/SdFatTail.pde index 95b84f52..025d8907 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTail/SdFatTail.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTail/SdFatTail.pde @@ -1,98 +1,98 @@ -/* - * This sketch reads and prints the tail of all files - * created by SdFatAppend.pde, SdFatPrint.pde, and - * SdFatWrite.pde. - */ -#include -#include - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - Serial.println("type any character to start"); - while (!Serial.available()); - Serial.println(); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); -} - -/* - * Print tail of all SdFat example files - */ -void loop(void) { - dir_t dir; - char name[13]; - - // read next directory entry - if (root.readDir(&dir) != sizeof(dir)) { - Serial.println("End of Directory"); - while(1); - } - - // check for file name "APPEND.TXT", "PRINT*.TXT" - // or "WRITE*.TXT" - // first 8 bytes are blank filled name - // last three bytes are blank filled extension - if ((strncmp((char *)dir.name, "APPEND ", 8) && - strncmp((char *)dir.name, "PRINT", 5) && - strncmp((char *)dir.name, "WRITE", 5)) || - strncmp((char *)&dir.name[8], "TXT", 3)) { - return; - } - // format file name - SdFile::dirName(dir, name); - - // remember position in root dir - uint32_t pos = root.curPosition(); - - // open file - if (!file.open(&root, name, O_READ)) error("file.open failed"); - - // restore root position - if (!root.seekSet(pos)) error("root.seekSet failed"); - - // print file name message - Serial.print("Tail of: "); - Serial.println(name); - - // position to tail of file - if (file.fileSize() > 100) { - if (!file.seekSet(file.fileSize() - 100)) error("file.seekSet failed"); - } - int16_t c; - // find end of line - while ((c = file.read()) > 0 && c != '\n'); - - // print rest of file - while ((c = file.read()) > 0) Serial.print((char)c); - file.close(); - Serial.println(); -} +/* + * This sketch reads and prints the tail of all files + * created by SdFatAppend.pde, SdFatPrint.pde, and + * SdFatWrite.pde. + */ +#include +#include + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + Serial.println("type any character to start"); + while (!Serial.available()); + Serial.println(); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); +} + +/* + * Print tail of all SdFat example files + */ +void loop(void) { + dir_t dir; + char name[13]; + + // read next directory entry + if (root.readDir(&dir) != sizeof(dir)) { + Serial.println("End of Directory"); + while(1); + } + + // check for file name "APPEND.TXT", "PRINT*.TXT" + // or "WRITE*.TXT" + // first 8 bytes are blank filled name + // last three bytes are blank filled extension + if ((strncmp((char *)dir.name, "APPEND ", 8) && + strncmp((char *)dir.name, "PRINT", 5) && + strncmp((char *)dir.name, "WRITE", 5)) || + strncmp((char *)&dir.name[8], "TXT", 3)) { + return; + } + // format file name + SdFile::dirName(dir, name); + + // remember position in root dir + uint32_t pos = root.curPosition(); + + // open file + if (!file.open(&root, name, O_READ)) error("file.open failed"); + + // restore root position + if (!root.seekSet(pos)) error("root.seekSet failed"); + + // print file name message + Serial.print("Tail of: "); + Serial.println(name); + + // position to tail of file + if (file.fileSize() > 100) { + if (!file.seekSet(file.fileSize() - 100)) error("file.seekSet failed"); + } + int16_t c; + // find end of line + while ((c = file.read()) > 0 && c != '\n'); + + // print rest of file + while ((c = file.read()) > 0) Serial.print((char)c); + file.close(); + Serial.println(); +} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTimestamp/SdFatTimestamp.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTimestamp/SdFatTimestamp.pde index 869bf255..157e5118 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTimestamp/SdFatTimestamp.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTimestamp/SdFatTimestamp.pde @@ -1,182 +1,182 @@ -/* - * This sketch tests the dateTimeCallback() function - * and the timestamp() function. - */ -#include -#include // use PgmPrint -/* - * date/time values for debug - * normally supplied by a real-time clock or GPS - */ -// date 2009-10-01 1-Oct-09 -uint16_t year = 2009; -uint8_t month = 10; -uint8_t day = 1; - -// time 20:30:40 -uint8_t hour = 20; -uint8_t minute = 30; -uint8_t second = 40; -/* - * User provided date time callback function. - * See SdFile::dateTimeCallback() for usage. - */ -void dateTime(uint16_t* date, uint16_t* time) { - // User gets date and time from GPS or real-time - // clock in real callback function - - // return date using FAT_DATE macro to format fields - *date = FAT_DATE(year, month, day); - - // return time using FAT_TIME macro to format fields - *time = FAT_TIME(hour, minute, second); -} - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} -/* - * Function to print all timestamps. - */ -void printTimestamps(SdFile& f) { - dir_t d; - if (!f.dirEntry(&d)) error("f.dirEntry failed"); - - PgmPrint("Creation: "); - f.printFatDate(d.creationDate); - Serial.print(' '); - f.printFatTime(d.creationTime); - Serial.println(); - - PgmPrint("Modify: "); - f.printFatDate(d.lastWriteDate); - Serial.print(' '); - f.printFatTime(d.lastWriteTime); - Serial.println(); - - PgmPrint("Access: "); - f.printFatDate(d.lastAccessDate); - Serial.println(); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - // remove files if they exist - SdFile::remove(&root, "CALLBACK.TXT"); - SdFile::remove(&root, "DEFAULT.TXT"); - SdFile::remove(&root, "STAMP.TXT"); - - // create a new file with default timestamps - if (!file.open(&root, "DEFAULT.TXT", O_CREAT | O_WRITE)) { - error("open DEFAULT.TXT failed"); - } - Serial.println(); - PgmPrintln("Open with default times"); - printTimestamps(file); - - // close file - file.close(); - /* - * Test the date time callback function. - * - * dateTimeCallback() sets the function - * that is called when a file is created - * or when a file's directory entry is - * modified by sync(). - * - * The callback can be disabled by the call - * SdFile::dateTimeCallbackCancel() - */ - // set date time callback function - SdFile::dateTimeCallback(dateTime); - - // create a new file with callback timestamps - if (!file.open(&root, "CALLBACK.TXT", O_CREAT | O_WRITE)) { - error("open CALLBACK.TXT failed"); - } - Serial.println(); - PgmPrintln("Open with callback times"); - printTimestamps(file); - - // change call back date - day += 1; - - // must add two to see change since FAT second field is 5-bits - second += 2; - - // modify file by writing a byte - file.write('t'); - - // force dir update - file.sync(); - - Serial.println(); - PgmPrintln("Times after write"); - printTimestamps(file); - - // close file - file.close(); - /* - * Test timestamp() function - * - * Cancel callback so sync will not - * change access/modify timestamp - */ - SdFile::dateTimeCallbackCancel(); - - // create a new file with default timestamps - if (!file.open(&root, "STAMP.TXT", O_CREAT | O_WRITE)) { - error("open STAMP.TXT failed"); - } - // set creation date time - if (!file.timestamp(T_CREATE, 2009, 11, 10, 1, 2, 3)) { - error("set create time failed"); - } - // set write/modification date time - if (!file.timestamp(T_WRITE, 2009, 11, 11, 4, 5, 6)) { - error("set write time failed"); - } - // set access date - if (!file.timestamp(T_ACCESS, 2009, 11, 12, 7, 8, 9)) { - error("set access time failed"); - } - Serial.println(); - PgmPrintln("Times after timestamp() calls"); - printTimestamps(file); - - file.close(); - Serial.println(); - PgmPrintln("Done"); -} - -void loop(void){} +/* + * This sketch tests the dateTimeCallback() function + * and the timestamp() function. + */ +#include +#include // use PgmPrint +/* + * date/time values for debug + * normally supplied by a real-time clock or GPS + */ +// date 2009-10-01 1-Oct-09 +uint16_t year = 2009; +uint8_t month = 10; +uint8_t day = 1; + +// time 20:30:40 +uint8_t hour = 20; +uint8_t minute = 30; +uint8_t second = 40; +/* + * User provided date time callback function. + * See SdFile::dateTimeCallback() for usage. + */ +void dateTime(uint16_t* date, uint16_t* time) { + // User gets date and time from GPS or real-time + // clock in real callback function + + // return date using FAT_DATE macro to format fields + *date = FAT_DATE(year, month, day); + + // return time using FAT_TIME macro to format fields + *time = FAT_TIME(hour, minute, second); +} + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} +/* + * Function to print all timestamps. + */ +void printTimestamps(SdFile& f) { + dir_t d; + if (!f.dirEntry(&d)) error("f.dirEntry failed"); + + PgmPrint("Creation: "); + f.printFatDate(d.creationDate); + Serial.print(' '); + f.printFatTime(d.creationTime); + Serial.println(); + + PgmPrint("Modify: "); + f.printFatDate(d.lastWriteDate); + Serial.print(' '); + f.printFatTime(d.lastWriteTime); + Serial.println(); + + PgmPrint("Access: "); + f.printFatDate(d.lastAccessDate); + Serial.println(); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + // remove files if they exist + SdFile::remove(&root, "CALLBACK.TXT"); + SdFile::remove(&root, "DEFAULT.TXT"); + SdFile::remove(&root, "STAMP.TXT"); + + // create a new file with default timestamps + if (!file.open(&root, "DEFAULT.TXT", O_CREAT | O_WRITE)) { + error("open DEFAULT.TXT failed"); + } + Serial.println(); + PgmPrintln("Open with default times"); + printTimestamps(file); + + // close file + file.close(); + /* + * Test the date time callback function. + * + * dateTimeCallback() sets the function + * that is called when a file is created + * or when a file's directory entry is + * modified by sync(). + * + * The callback can be disabled by the call + * SdFile::dateTimeCallbackCancel() + */ + // set date time callback function + SdFile::dateTimeCallback(dateTime); + + // create a new file with callback timestamps + if (!file.open(&root, "CALLBACK.TXT", O_CREAT | O_WRITE)) { + error("open CALLBACK.TXT failed"); + } + Serial.println(); + PgmPrintln("Open with callback times"); + printTimestamps(file); + + // change call back date + day += 1; + + // must add two to see change since FAT second field is 5-bits + second += 2; + + // modify file by writing a byte + file.write('t'); + + // force dir update + file.sync(); + + Serial.println(); + PgmPrintln("Times after write"); + printTimestamps(file); + + // close file + file.close(); + /* + * Test timestamp() function + * + * Cancel callback so sync will not + * change access/modify timestamp + */ + SdFile::dateTimeCallbackCancel(); + + // create a new file with default timestamps + if (!file.open(&root, "STAMP.TXT", O_CREAT | O_WRITE)) { + error("open STAMP.TXT failed"); + } + // set creation date time + if (!file.timestamp(T_CREATE, 2009, 11, 10, 1, 2, 3)) { + error("set create time failed"); + } + // set write/modification date time + if (!file.timestamp(T_WRITE, 2009, 11, 11, 4, 5, 6)) { + error("set write time failed"); + } + // set access date + if (!file.timestamp(T_ACCESS, 2009, 11, 12, 7, 8, 9)) { + error("set access time failed"); + } + Serial.println(); + PgmPrintln("Times after timestamp() calls"); + printTimestamps(file); + + file.close(); + Serial.println(); + PgmPrintln("Done"); +} + +void loop(void){} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTruncate/SdFatTruncate.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTruncate/SdFatTruncate.pde index 5faff2cc..5d799693 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTruncate/SdFatTruncate.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatTruncate/SdFatTruncate.pde @@ -1,66 +1,66 @@ -/* - * Truncate Example - * - * This sketch shows how to use truncate() to remove the last - * half of the file created by the SdFatAppend.pde example. - */ -#include -#include // use functions to print strings from flash memory - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - PgmPrintln("Type any character to start"); - while (!Serial.available()); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - char name[] = "APPEND.TXT"; - // open for read and write - if (!file.open(&root, name, O_RDWR)) { - PgmPrint("Can't open "); - Serial.println(name); - PgmPrintln("Run the append example to create the file."); - error("file.open failed"); - } - // seek to middle of file - if (!file.seekSet(file.fileSize()/2)) error("file.seekSet failed"); - // find end of line - int16_t c; - while ((c = file.read()) > 0 && c != '\n'); - if (c < 0) error("file.read failed"); - // truncate at current position - if (!file.truncate(file.curPosition())) error("file.truncate failed"); - Serial.print(name); - PgmPrintln(" truncated."); -} - -void loop(void) {} +/* + * Truncate Example + * + * This sketch shows how to use truncate() to remove the last + * half of the file created by the SdFatAppend.pde example. + */ +#include +#include // use functions to print strings from flash memory + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + PgmPrintln("Type any character to start"); + while (!Serial.available()); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + char name[] = "APPEND.TXT"; + // open for read and write + if (!file.open(&root, name, O_RDWR)) { + PgmPrint("Can't open "); + Serial.println(name); + PgmPrintln("Run the append example to create the file."); + error("file.open failed"); + } + // seek to middle of file + if (!file.seekSet(file.fileSize()/2)) error("file.seekSet failed"); + // find end of line + int16_t c; + while ((c = file.read()) > 0 && c != '\n'); + if (c < 0) error("file.read failed"); + // truncate at current position + if (!file.truncate(file.curPosition())) error("file.truncate failed"); + Serial.print(name); + PgmPrintln(" truncated."); +} + +void loop(void) {} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatWrite/SdFatWrite.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatWrite/SdFatWrite.pde index 48876dbc..d554d5ef 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatWrite/SdFatWrite.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/Arduino Examples/SdFatWrite/SdFatWrite.pde @@ -1,98 +1,98 @@ -/* - * Write Example - * - * This sketch creates a new file and writes 100 lines to the file. - * No error checks on write in this example. - */ - -#include -#include - -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; - -// store error strings in flash to save RAM -#define error(s) error_P(PSTR(s)) - -void error_P(const char* str) { - PgmPrint("error: "); - SerialPrintln_P(str); - if (card.errorCode()) { - PgmPrint("SD error: "); - Serial.print(card.errorCode(), HEX); - Serial.print(','); - Serial.println(card.errorData(), HEX); - } - while(1); -} -/* - * Write CR LF to a file - */ -void writeCRLF(SdFile& f) { - f.write((uint8_t*)"\r\n", 2); -} -/* - * Write an unsigned number to a file - */ -void writeNumber(SdFile& f, uint32_t n) { - uint8_t buf[10]; - uint8_t i = 0; - do { - i++; - buf[sizeof(buf) - i] = n%10 + '0'; - n /= 10; - } while (n); - f.write(&buf[sizeof(buf) - i], i); -} -/* - * Write a string to a file - */ -void writeString(SdFile& f, char *str) { - uint8_t n; - for (n = 0; str[n]; n++); - f.write((uint8_t *)str, n); -} - -void setup(void) { - Serial.begin(9600); - Serial.println(); - Serial.println("Type any character to start"); - while (!Serial.available()); - - // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with - // breadboards. use SPI_FULL_SPEED for better performance. - if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); - - // initialize a FAT volume - if (!volume.init(&card)) error("volume.init failed"); - - // open the root directory - if (!root.openRoot(&volume)) error("openRoot failed"); - - // create a new file - char name[] = "WRITE00.TXT"; - for (uint8_t i = 0; i < 100; i++) { - name[5] = i/10 + '0'; - name[6] = i%10 + '0'; - if (file.open(&root, name, O_CREAT | O_EXCL | O_WRITE)) break; - } - if (!file.isOpen()) error ("file.create"); - Serial.print("Writing to: "); - Serial.println(name); - - // write 100 line to file - for (uint8_t i = 0; i < 100; i++) { - writeString(file, "line "); - writeNumber(file, i); - writeString(file, " millis = "); - writeNumber(file, millis()); - writeCRLF(file); - } - // close file and force write of all data to the SD card - file.close(); - Serial.println("Done"); -} - -void loop(void) {} +/* + * Write Example + * + * This sketch creates a new file and writes 100 lines to the file. + * No error checks on write in this example. + */ + +#include +#include + +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; + +// store error strings in flash to save RAM +#define error(s) error_P(PSTR(s)) + +void error_P(const char* str) { + PgmPrint("error: "); + SerialPrintln_P(str); + if (card.errorCode()) { + PgmPrint("SD error: "); + Serial.print(card.errorCode(), HEX); + Serial.print(','); + Serial.println(card.errorData(), HEX); + } + while(1); +} +/* + * Write CR LF to a file + */ +void writeCRLF(SdFile& f) { + f.write((uint8_t*)"\r\n", 2); +} +/* + * Write an unsigned number to a file + */ +void writeNumber(SdFile& f, uint32_t n) { + uint8_t buf[10]; + uint8_t i = 0; + do { + i++; + buf[sizeof(buf) - i] = n%10 + '0'; + n /= 10; + } while (n); + f.write(&buf[sizeof(buf) - i], i); +} +/* + * Write a string to a file + */ +void writeString(SdFile& f, char *str) { + uint8_t n; + for (n = 0; str[n]; n++); + f.write((uint8_t *)str, n); +} + +void setup(void) { + Serial.begin(9600); + Serial.println(); + Serial.println("Type any character to start"); + while (!Serial.available()); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED)) error("card.init failed"); + + // initialize a FAT volume + if (!volume.init(&card)) error("volume.init failed"); + + // open the root directory + if (!root.openRoot(&volume)) error("openRoot failed"); + + // create a new file + char name[] = "WRITE00.TXT"; + for (uint8_t i = 0; i < 100; i++) { + name[5] = i/10 + '0'; + name[6] = i%10 + '0'; + if (file.open(&root, name, O_CREAT | O_EXCL | O_WRITE)) break; + } + if (!file.isOpen()) error ("file.create"); + Serial.print("Writing to: "); + Serial.println(name); + + // write 100 line to file + for (uint8_t i = 0; i < 100; i++) { + writeString(file, "line "); + writeNumber(file, i); + writeString(file, " millis = "); + writeNumber(file, millis()); + writeCRLF(file); + } + // close file and force write of all data to the SD card + file.close(); + Serial.println("Done"); +} + +void loop(void) {} diff --git a/Libmaple/libmaple/libraries/mapleSDfat/examples/FileSys/FileSys.pde b/Libmaple/libmaple/libraries/mapleSDfat/examples/FileSys/FileSys.pde index 7a40cbd8..06a2a3df 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/examples/FileSys/FileSys.pde +++ b/Libmaple/libmaple/libraries/mapleSDfat/examples/FileSys/FileSys.pde @@ -83,4 +83,4 @@ void loop() { } - + diff --git a/Libmaple/libmaple/libraries/mapleSDfat/rules.mk b/Libmaple/libmaple/libraries/mapleSDfat/rules.mk index a51d0508..b1c6f360 100644 --- a/Libmaple/libmaple/libraries/mapleSDfat/rules.mk +++ b/Libmaple/libmaple/libraries/mapleSDfat/rules.mk @@ -1,29 +1,29 @@ -# Standard things -sp := $(sp).x -dirstack_$(sp) := $(d) -d := $(dir) -BUILDDIRS += $(BUILD_PATH)/$(d) - -# Local flags -CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) - -# Local rules and targets -cSRCS_$(d) := - -cppSRCS_$(d) := Sd2Card.cpp SdFile.cpp SdVolume.cpp - -cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) -cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) - -OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ - $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) -DEPS_$(d) := $(OBJS_$(d):%.o=%.d) - -$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) - -TGT_BIN += $(OBJS_$(d)) - -# Standard things --include $(DEPS_$(d)) -d := $(dirstack_$(sp)) +# Standard things +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) +BUILDDIRS += $(BUILD_PATH)/$(d) + +# Local flags +CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) + +# Local rules and targets +cSRCS_$(d) := + +cppSRCS_$(d) := Sd2Card.cpp SdFile.cpp SdVolume.cpp + +cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) + +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ + $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) +DEPS_$(d) := $(OBJS_$(d):%.o=%.d) + +$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) + +TGT_BIN += $(OBJS_$(d)) + +# Standard things +-include $(DEPS_$(d)) +d := $(dirstack_$(sp)) sp := $(basename $(sp)) \ No newline at end of file diff --git a/Libmaple/libmaple/main.cpp.example b/Libmaple/libmaple/main.cpp.example index 28442719..23d55407 100644 --- a/Libmaple/libmaple/main.cpp.example +++ b/Libmaple/libmaple/main.cpp.example @@ -1,43 +1,43 @@ -// Sample main.cpp file. Blinks the built-in LED, sends a message out -// USART2, and turns on PWM on pin 2. - -#include "wirish.h" - -#define PWM_PIN 2 - -void setup() { - /* Set up the LED to blink */ - pinMode(BOARD_LED_PIN, OUTPUT); - - /* Turn on PWM on pin PWM_PIN */ - pinMode(PWM_PIN, PWM); - pwmWrite(PWM_PIN, 0x8000); - - /* Send a message out USART2 */ - Serial2.begin(9600); - Serial2.println("Hello world!"); - - /* Send a message out the usb virtual serial port */ - SerialUSB.println("Hello!"); -} - -void loop() { - toggleLED(); - delay(100); -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - - return 0; -} +// Sample main.cpp file. Blinks the built-in LED, sends a message out +// USART2, and turns on PWM on pin 2. + +#include "wirish.h" + +#define PWM_PIN 2 + +void setup() { + /* Set up the LED to blink */ + pinMode(BOARD_LED_PIN, OUTPUT); + + /* Turn on PWM on pin PWM_PIN */ + pinMode(PWM_PIN, PWM); + pwmWrite(PWM_PIN, 0x8000); + + /* Send a message out USART2 */ + Serial2.begin(9600); + Serial2.println("Hello world!"); + + /* Send a message out the usb virtual serial port */ + SerialUSB.println("Hello!"); +} + +void loop() { + toggleLED(); + delay(100); +} + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + setup(); + + while (true) { + loop(); + } + + return 0; +} diff --git a/Libmaple/libmaple/notes/dac.txt b/Libmaple/libmaple/notes/dac.txt index b82cb076..32929360 100644 --- a/Libmaple/libmaple/notes/dac.txt +++ b/Libmaple/libmaple/notes/dac.txt @@ -1,67 +1,67 @@ -DAC -------------------------------------------------------------------------------- - -There is an ST application note for the DACs; it provides a lot of -context but doesn't help setup the peripheral very much. - -For the first code iteration we'll just use 12-bit right-aligned -single writes, or DAC_DHR12Rx. - -Once data is loaded into the digital registers, there are a number of -possible triggers to start conversion to analog output: external -interrupts, software control, and timer events. We'll just use -software triggering for now. - -There is (obviously) DMA support for DAC output. - -There are noise (via LFSR) output and triangle wave output features -with variable amplitude. - -There are eleven modes to trigger output to both channels at the same -time, as follows: - - - Independent trigger: - (1) No wave generation - (2) Same LFSR - (3) Different LFSR - (4) Same triangle - (5) Different triangle - - (6) Simultaneous software start - - Simultaneous trigger: - (7) Without wave generation - (8) Same LFSR - (9) Different LFSR - (10) Same triangle - (11) Different triangle - -Buffering is enabled by default. - -Triangle Wave HOWTO -------------------------------------------------------------------------------- - -In order to generate a full-amplitude triangle wave: - - - Make the following settings in DAC_BASE->CR, for the DAC channel you - want: set MAMP to 1011 (amplitude 4095), WAVE to 10 (triangle), - TSEL to 111 (software trigger), TEN to 1 (trigger enabled), and - EN to 1 (chanel enabled). - - - Set dac->DHR12Rx to 0 (where x is your channel). This gets added - to the triangle wave value at each trigger step. - - - Now, forever: set DAC_SWTRIGR_SWTRIGx in dac->SWTRIGR, and wait - for it to get cleared by hardware. - -You can do something similar for noise (by setting WAVE to 01 -instead). You can also cause the waves to advance due to timer events -or external line 9, by making appropriate settings to TSEL. - -TODO -------------------------------------------------------------------------------- - -- Sine wave demo (using timer interrupts?) -- Wirish implementation -- Official docs -- Higher performance modes? -- Signal quality testing -- DMA output +DAC +------------------------------------------------------------------------------- + +There is an ST application note for the DACs; it provides a lot of +context but doesn't help setup the peripheral very much. + +For the first code iteration we'll just use 12-bit right-aligned +single writes, or DAC_DHR12Rx. + +Once data is loaded into the digital registers, there are a number of +possible triggers to start conversion to analog output: external +interrupts, software control, and timer events. We'll just use +software triggering for now. + +There is (obviously) DMA support for DAC output. + +There are noise (via LFSR) output and triangle wave output features +with variable amplitude. + +There are eleven modes to trigger output to both channels at the same +time, as follows: + + - Independent trigger: + (1) No wave generation + (2) Same LFSR + (3) Different LFSR + (4) Same triangle + (5) Different triangle + - (6) Simultaneous software start + - Simultaneous trigger: + (7) Without wave generation + (8) Same LFSR + (9) Different LFSR + (10) Same triangle + (11) Different triangle + +Buffering is enabled by default. + +Triangle Wave HOWTO +------------------------------------------------------------------------------- + +In order to generate a full-amplitude triangle wave: + + - Make the following settings in DAC_BASE->CR, for the DAC channel you + want: set MAMP to 1011 (amplitude 4095), WAVE to 10 (triangle), + TSEL to 111 (software trigger), TEN to 1 (trigger enabled), and + EN to 1 (chanel enabled). + + - Set dac->DHR12Rx to 0 (where x is your channel). This gets added + to the triangle wave value at each trigger step. + + - Now, forever: set DAC_SWTRIGR_SWTRIGx in dac->SWTRIGR, and wait + for it to get cleared by hardware. + +You can do something similar for noise (by setting WAVE to 01 +instead). You can also cause the waves to advance due to timer events +or external line 9, by making appropriate settings to TSEL. + +TODO +------------------------------------------------------------------------------- + +- Sine wave demo (using timer interrupts?) +- Wirish implementation +- Official docs +- Higher performance modes? +- Signal quality testing +- DMA output diff --git a/Libmaple/libmaple/notes/dma.txt b/Libmaple/libmaple/notes/dma.txt index 4d5a6364..97b23a0a 100644 --- a/Libmaple/libmaple/notes/dma.txt +++ b/Libmaple/libmaple/notes/dma.txt @@ -1,99 +1,99 @@ -DMA Notes -========= - -Medium-density devices have one DMA controller, DMA1. High-density -devices and up also have DMA2. DMA1 has 7 channels; DMA2 has 5. Each -channel multiplexes DMA requests from various peripherals, like so: - -Channel Capabilities --------------------- - -DMA1: - - * Channel 1: ADC1, TIM2_CH3, TIM4_CH1 - * Channel 2: USART3_TX, TIM1_CH1, TIM2_UP, TIM3_CH3, SPI1_RX - * Channel 3: USART3_RX, TIM1_CH2, TIM3_CH4, TIM3_UP, SPI1_TX - * Channel 4: USART1_TX, TIM1_CH4, TIM1_TRIG, TIM1_COM, TIM4_CH2, - SPI2/I2S2_RX, I2C2_TX - * Channel 5: USART1_RX, TIM1_UP, TIM2_CH1, TIM4_CH3, - SPI2/I2S2_TX, I2C2_RX - * Channel 6: USART2_RX, TIM1_CH3, TIM3_CH1, TIM3_TRIG, I2C1_TX - * Channel 7: USART2_TX, TIM2_CH2, TIM2_CH4, TIM4_UP, I2C1_RX - -DMA2: - - * Channel 1: TIM5_CH4, TIM5_TRIG, TIM8_CH3, TIM8_UP, SPI/I2S3_RX - * Channel 2: TIM8_CH4, TIM8_TRIG, TIM8_COM, TIM5_CH3, TIM5_UP, SPI/I2S3_TX - * Channel 3: TIM8_CH1, UART4_RX, TIM6_UP/DAC_CH1 - * Channel 4: TIM5_CH2, SDIO, TIM7_UP/DAC_CH2 - * Channel 5: ADC3, TIM8_CH2, TIM5_CH1, UART4_TX - -An example usage: via DMA1, channel 1, you can have ADC1 periodically -dump converted data into an array in memory. The DMA controller can -then interrupt you when the array is half-full and full, and if any -error occurred. - -Since channels are multiplexed in hardware, you can't simultaneously -use the same DMA channel to serve requests from two of its peripherals -at the same time. For example, if you are using DMA 1 channel 1 to -serve DMA requests from ADC1, you can't also serve requests from Timer -2 channel 3. - -Channel Priority ----------------- - -An arbiter prioritizes simultaneous channel DMA requests. Channel -priority levels are configurable (4 levels of priority). Ties within -a DMA controller are broken by choosing the lower channel number; -between the controllers, DMA1 has higher priority than DMA2. - -Interrupts ----------- - -You can cause an interrupt to fire once half the transfers are -complete, when all the transfers are complete, if an error occurs -during transfer, or any combination of the three. - -If an error occurs, the transfer is automatically disabled. - -Configuration -------------- - -In order to configure a DMA transfer for DMA controller n, channel x, -ST RM0008 says you should do the following: - - A. Set the peripheral register address in DMAn_BASE->CPARx. - B. Set the memory address in DMAn_BASE->CMARx. - C. Set the number of data to be transferred in DMAn_BASE->CNDTRx. - D. Set the channel priority via the PL bits in DMAn_BASE->CCRx. - E. Configure various other things (e.g. data transfer sizes, what - events cause channel interrupts) in DMAn_BASE->CCRx as desired. - F. Activate the channel by setting ENABLE bit in DMAn_BASE->CCRx. - -The channel will start serving DMA requests as soon as it's activated. - -The DMA library lets you accomplish these tasks as follows: - - **Setup transfer** - - Do (A), (B), and (E) using dma_setup_transfer(). - - This also does (D), but chooses the lowest priority by default. - - **Perform any other desired configuration** - - You can do (C) using dma_set_num_transfers(). - - You can do (D) using dma_set_priority(). - - You can attach interrupt handlers with dma_attach_interrupt(). - - **Activate the channel** - - Do (F) with dma_enable(). - -Once you're all done, you can dma_disable() the channel. If you -dma_detach_interrupt() an interrupt handler, the channel interrupts -will stop firing, but the transfer itself won't stop until it's done -(which never happens if you set the DMA_CIRC_MODE flag when you called -dma_setup_transfer()). +DMA Notes +========= + +Medium-density devices have one DMA controller, DMA1. High-density +devices and up also have DMA2. DMA1 has 7 channels; DMA2 has 5. Each +channel multiplexes DMA requests from various peripherals, like so: + +Channel Capabilities +-------------------- + +DMA1: + + * Channel 1: ADC1, TIM2_CH3, TIM4_CH1 + * Channel 2: USART3_TX, TIM1_CH1, TIM2_UP, TIM3_CH3, SPI1_RX + * Channel 3: USART3_RX, TIM1_CH2, TIM3_CH4, TIM3_UP, SPI1_TX + * Channel 4: USART1_TX, TIM1_CH4, TIM1_TRIG, TIM1_COM, TIM4_CH2, + SPI2/I2S2_RX, I2C2_TX + * Channel 5: USART1_RX, TIM1_UP, TIM2_CH1, TIM4_CH3, + SPI2/I2S2_TX, I2C2_RX + * Channel 6: USART2_RX, TIM1_CH3, TIM3_CH1, TIM3_TRIG, I2C1_TX + * Channel 7: USART2_TX, TIM2_CH2, TIM2_CH4, TIM4_UP, I2C1_RX + +DMA2: + + * Channel 1: TIM5_CH4, TIM5_TRIG, TIM8_CH3, TIM8_UP, SPI/I2S3_RX + * Channel 2: TIM8_CH4, TIM8_TRIG, TIM8_COM, TIM5_CH3, TIM5_UP, SPI/I2S3_TX + * Channel 3: TIM8_CH1, UART4_RX, TIM6_UP/DAC_CH1 + * Channel 4: TIM5_CH2, SDIO, TIM7_UP/DAC_CH2 + * Channel 5: ADC3, TIM8_CH2, TIM5_CH1, UART4_TX + +An example usage: via DMA1, channel 1, you can have ADC1 periodically +dump converted data into an array in memory. The DMA controller can +then interrupt you when the array is half-full and full, and if any +error occurred. + +Since channels are multiplexed in hardware, you can't simultaneously +use the same DMA channel to serve requests from two of its peripherals +at the same time. For example, if you are using DMA 1 channel 1 to +serve DMA requests from ADC1, you can't also serve requests from Timer +2 channel 3. + +Channel Priority +---------------- + +An arbiter prioritizes simultaneous channel DMA requests. Channel +priority levels are configurable (4 levels of priority). Ties within +a DMA controller are broken by choosing the lower channel number; +between the controllers, DMA1 has higher priority than DMA2. + +Interrupts +---------- + +You can cause an interrupt to fire once half the transfers are +complete, when all the transfers are complete, if an error occurs +during transfer, or any combination of the three. + +If an error occurs, the transfer is automatically disabled. + +Configuration +------------- + +In order to configure a DMA transfer for DMA controller n, channel x, +ST RM0008 says you should do the following: + + A. Set the peripheral register address in DMAn_BASE->CPARx. + B. Set the memory address in DMAn_BASE->CMARx. + C. Set the number of data to be transferred in DMAn_BASE->CNDTRx. + D. Set the channel priority via the PL bits in DMAn_BASE->CCRx. + E. Configure various other things (e.g. data transfer sizes, what + events cause channel interrupts) in DMAn_BASE->CCRx as desired. + F. Activate the channel by setting ENABLE bit in DMAn_BASE->CCRx. + +The channel will start serving DMA requests as soon as it's activated. + +The DMA library lets you accomplish these tasks as follows: + + **Setup transfer** + + Do (A), (B), and (E) using dma_setup_transfer(). + + This also does (D), but chooses the lowest priority by default. + + **Perform any other desired configuration** + + You can do (C) using dma_set_num_transfers(). + + You can do (D) using dma_set_priority(). + + You can attach interrupt handlers with dma_attach_interrupt(). + + **Activate the channel** + + Do (F) with dma_enable(). + +Once you're all done, you can dma_disable() the channel. If you +dma_detach_interrupt() an interrupt handler, the channel interrupts +will stop firing, but the transfer itself won't stop until it's done +(which never happens if you set the DMA_CIRC_MODE flag when you called +dma_setup_transfer()). diff --git a/Libmaple/libmaple/notes/exti.txt b/Libmaple/libmaple/notes/exti.txt index 40a689cb..df930e55 100644 --- a/Libmaple/libmaple/notes/exti.txt +++ b/Libmaple/libmaple/notes/exti.txt @@ -1,41 +1,41 @@ -External interrupt notes. - -To generate the interrupt, the interrupt line should be configured -and enabled. This is done by programming the two trigger registers -with the desired edge detection and by enabling the interrupt -request by writing a '1' to the corresponding bit in the interrupt -mask register. When the selected edge occurs on the external -interrupt line, an interrupt request is generated. The pending bit -corresponding to the interrupt line is also set. This request is -reset by writing a '1' in the pending register. - -Hardware interrupt selection: - -To configure the 20 lines as interrupt sources, use the following -procedure: - -1) Configure AFIO_EXTICR[y] to select the source input for EXTIx - external interrupt -2) Configure the mask bits of the 20 interrupt lines (EXTI_IMR) -3) Configure the trigger selection bits of the interrupt lines - (EXTI_RTSR and EXTI_FTSR) -4) Configure the enable and mask bits that control the NVIC_IRQ - channel mapped to the External Interrupt Controller (EXTI) so - that an inerrupt coming from one of the 20 lines can be - correctly acknowledged. - -AFIO clock must be on. - -RM0008, page 107: "PD0, PD1 cannot be used for external -interrupt/event generation on 36, 48, 64-bin packages." - -The 16 EXTI interrupts are mapped to 7 interrupt handlers. - -EXTI Lines to Interrupt Mapping: -EXTI0 -> EXTI0 -EXTI1 -> EXTI1 -EXTI2 -> EXTI2 -EXTI3 -> EXTI3 -EXTI4 -> EXTI4 -EXTI[5-9] -> EXT9_5 -EXTI[10-15] -> EXT15_10 +External interrupt notes. + +To generate the interrupt, the interrupt line should be configured +and enabled. This is done by programming the two trigger registers +with the desired edge detection and by enabling the interrupt +request by writing a '1' to the corresponding bit in the interrupt +mask register. When the selected edge occurs on the external +interrupt line, an interrupt request is generated. The pending bit +corresponding to the interrupt line is also set. This request is +reset by writing a '1' in the pending register. + +Hardware interrupt selection: + +To configure the 20 lines as interrupt sources, use the following +procedure: + +1) Configure AFIO_EXTICR[y] to select the source input for EXTIx + external interrupt +2) Configure the mask bits of the 20 interrupt lines (EXTI_IMR) +3) Configure the trigger selection bits of the interrupt lines + (EXTI_RTSR and EXTI_FTSR) +4) Configure the enable and mask bits that control the NVIC_IRQ + channel mapped to the External Interrupt Controller (EXTI) so + that an inerrupt coming from one of the 20 lines can be + correctly acknowledged. + +AFIO clock must be on. + +RM0008, page 107: "PD0, PD1 cannot be used for external +interrupt/event generation on 36, 48, 64-bin packages." + +The 16 EXTI interrupts are mapped to 7 interrupt handlers. + +EXTI Lines to Interrupt Mapping: +EXTI0 -> EXTI0 +EXTI1 -> EXTI1 +EXTI2 -> EXTI2 +EXTI3 -> EXTI3 +EXTI4 -> EXTI4 +EXTI[5-9] -> EXT9_5 +EXTI[10-15] -> EXT15_10 diff --git a/Libmaple/libmaple/notes/fsmc.txt b/Libmaple/libmaple/notes/fsmc.txt index 9f50135f..1f707605 100644 --- a/Libmaple/libmaple/notes/fsmc.txt +++ b/Libmaple/libmaple/notes/fsmc.txt @@ -1,64 +1,64 @@ - -FSMC notes (for maple native and other "high density" STM32 devices) -------------------------------------------------------------------------------- - -There is an application note for all this which is helpful; see the ST website. - -SRAM chip details - IS62WV51216BLL - 512k x 16 - 19 address input - 16 data inputs - t_wc (write cycle) = 55ns - t_rc (write cycle) = 55ns - t_pwe1 (write enable low pulse) = 40ns - t_aa (address access) = 55ns - - -The FSMC nomenclature is very confusing. There are three separate -"banks" (which I will call "peripheral banks") each specialized for -different types of external memory (NOR flash, NAND flash, SRAM, -etc). We use the one for "PSRAM" with our SRAM chip; it's bank #1. The -SRAM peripheral bank is further split into 4 "banks" (which I will -call "channels") to support multiple external devices with chip select -pins. I think what's going on is that there are 4 hardware peripherals -and many sections of RAM; the docs are confusing about what's a "block -of memeory" and what's an "FSMC block". - -Anyways, this all takes place on the AHB memory bus. - -I'm going to use not-extended mode 1 for read/write. - -Steps from application note: - -- enable bank3: BCR3_MBKEN = '1' -- memory type is SRAM: BCR3_MTYP = '00' -- databuse weidth is 16bits: BCR3_MWID = '01' -- memory is nonmultiplexed: BCR3_MEXEN is reset (= '0') -- everything else is cleared - -But not true! Actually write enable needs to be set. - -Using the application note, which is based around a very similar chip (with -faster timing), I calculated an ADDSET (address setup) value of 0x0 and a -DATAST (data setup) value of 0x3. - -Using channel1, NOR/PSRAM1 memory starts at 0x60000000. - -Have to turn on the RCC clock for all those GPIO pins, but don't need to use -any interrupts. - -Not-super-helpful-link: -http://www.keil.com/support/man/docs/mcbstm32e/mcbstm32e_to_xmemory.htm - -Note the possible confusion with address spaces, bitwidths, rollovers, etc. - - -TODO -------------------------------------------------------------------------------- -- more rigorous testing: throughput, latency, bounds checking, bitwidth, data - resiliance, etc. -- update .ld scripts to transparently make use of this external memory -- test/demo using a seperate external SRAM chip or screen -- write up documentation - + +FSMC notes (for maple native and other "high density" STM32 devices) +------------------------------------------------------------------------------- + +There is an application note for all this which is helpful; see the ST website. + +SRAM chip details + IS62WV51216BLL + 512k x 16 + 19 address input + 16 data inputs + t_wc (write cycle) = 55ns + t_rc (write cycle) = 55ns + t_pwe1 (write enable low pulse) = 40ns + t_aa (address access) = 55ns + + +The FSMC nomenclature is very confusing. There are three separate +"banks" (which I will call "peripheral banks") each specialized for +different types of external memory (NOR flash, NAND flash, SRAM, +etc). We use the one for "PSRAM" with our SRAM chip; it's bank #1. The +SRAM peripheral bank is further split into 4 "banks" (which I will +call "channels") to support multiple external devices with chip select +pins. I think what's going on is that there are 4 hardware peripherals +and many sections of RAM; the docs are confusing about what's a "block +of memeory" and what's an "FSMC block". + +Anyways, this all takes place on the AHB memory bus. + +I'm going to use not-extended mode 1 for read/write. + +Steps from application note: + +- enable bank3: BCR3_MBKEN = '1' +- memory type is SRAM: BCR3_MTYP = '00' +- databuse weidth is 16bits: BCR3_MWID = '01' +- memory is nonmultiplexed: BCR3_MEXEN is reset (= '0') +- everything else is cleared + +But not true! Actually write enable needs to be set. + +Using the application note, which is based around a very similar chip (with +faster timing), I calculated an ADDSET (address setup) value of 0x0 and a +DATAST (data setup) value of 0x3. + +Using channel1, NOR/PSRAM1 memory starts at 0x60000000. + +Have to turn on the RCC clock for all those GPIO pins, but don't need to use +any interrupts. + +Not-super-helpful-link: +http://www.keil.com/support/man/docs/mcbstm32e/mcbstm32e_to_xmemory.htm + +Note the possible confusion with address spaces, bitwidths, rollovers, etc. + + +TODO +------------------------------------------------------------------------------- +- more rigorous testing: throughput, latency, bounds checking, bitwidth, data + resiliance, etc. +- update .ld scripts to transparently make use of this external memory +- test/demo using a seperate external SRAM chip or screen +- write up documentation + diff --git a/Libmaple/libmaple/notes/pin-definitions.txt b/Libmaple/libmaple/notes/pin-definitions.txt index b11bd733..9b77b72e 100644 --- a/Libmaple/libmaple/notes/pin-definitions.txt +++ b/Libmaple/libmaple/notes/pin-definitions.txt @@ -1,226 +1,226 @@ -Pin definitions by GPIO bank. - -Source: ST DOC ID 14611, Datasheet for STM32F103xC, STM32F103xD, -STM32F103xE, Table 5, pp. 30--35. - -Some additional peripheral GPIO information is given in the "Other" -section following each bank's main table. - -This document was prepared carefully and is believed to be correct, -but the final arbiter of truth is the ST datasheet. - -*** NB: UART 4 and 5 are NOT USART (columns are labeled appropriately). - ---------------------------------------------------------------------------- -GPIO ADC Timer FSMC I2S I2C USART SPI DAC 5v? ---------------------------------------------------------------------------- -PA0 123in0 2ch1etr - - - 2cts - - - - 5ch1 - 8etr -PA1 123in1 5ch2 - - - 2rts - - - - 2ch2 -PA2 123in2 5ch3 - - - 2tx - - - - 2ch3 -PA3 123in3 5ch4 - - - 2rx - - - - 2ch4 ---------------------------------------------------------------------------- -PA4 12in4 - - - - 2ck 1nss out1 - -PA5 12in5 - - - - - 1sck out2 - -PA6 12in6 8bkin - - - - 1miso - - - 3ch1 -PA7 12in7 8ch1n - - - - 1mosi - - - 3ch2 ---------------------------------------------------------------------------- -PA8 - 1ch1 - - - 1ck - - Y -PA9 - 1ch2 - - - 1tx - - Y -PA10 - 1ch3 - - - 1rx - - Y -PA11 - 1ch4 - - - 1cts - - Y ---------------------------------------------------------------------------- -PA12 - 1etr - - - 1rts - - Y -PA13 - - - - - - - - Y -PA14 - - - - - - - - Y -PA15 - - - 3ws - - 3nss - Y ---------------------------------------------------------------------------- - -Other: - -PA0: WKUP -PA8: MCO -PA11: USBDM, CAN_RX -PA12: USBDP, CAN_TX -PA13: JTMS-SWDIO (default) -PA14: JTCK-SWCLK (default) -PA15: JTDI (default) - -------------------------------------------------------------------------------- -GPIO ADC Timer FSMC I2S I2C USART SPI DAC 5v? SDIO -------------------------------------------------------------------------------- -PB0 12in8 3ch3 - - - - - - - - - 8ch2n -PB1 12in9 3ch4 - - - - - - - - - 8ch3n -PB2 - - - - - - - - Y - -PB3 - - - 3ck - - 3sck - Y - ---------------------------------------------------------------------------- -PB4 - - - - - - 3miso - Y - -PB5 - - - 3sd 1smba - 3mosi - - - -PB6 - 4ch1 - - 1scl - - - Y - -PB7 - 4ch2 NADV - 1sda - - - Y - ---------------------------------------------------------------------------- -PB8 - 4ch3 - - - - - - Y D4 -PB9 - 4ch4 - - - - - - Y D5 -PB10 - - - - 2scl 3tx - - Y - -PB11 - - - - 2sda 3rx - - Y - ---------------------------------------------------------------------------- -PB12 - 1bkin - 2ws 2smba 3ck 2nss - Y - -PB13 - 1ch1n - 2ck - 3cts 2sck - Y - -PB14 - 1ch2n - - - 3rts 2miso - Y - -PB15 - 1ch3n - 2sd - - 2mosi - Y - ---------------------------------------------------------------------------- - -Other: - -PB2: BOOT1 -PB3: JTDO (default) -PB4: NJTRST (default) - -------------------------------------------------------------------------------- -GPIO ADC Timer FSMC I2S I2C UART SPI DAC 5v? SDIO -------------------------------------------------------------------------------- -PC0 123in10 - - - - - - - - - -PC1 123in11 - - - - - - - - - -PC2 123in12 - - - - - - - - - -PC3 123in13 - - - - - - - - - -------------------------------------------------------------------------------- -PC4 12in14 - - - - - - - - - -PC5 12in15 - - - - - - - - - -PC6 - 8ch1 - 2mck - - - - Y D6 -PC7 - 8ch2 - 3mck - - - - Y D7 -------------------------------------------------------------------------------- -PC8 - 8ch3 - - - - - - Y D0 -PC9 - 8ch4 - - - - - - Y D1 -PC10 - - - - - 4tx - - Y D2 -PC11 - - - - - 4rx - - Y D3 -------------------------------------------------------------------------------- -PC12 - - - - - 5tx - - Y CK -PC13 - - - - - - - - - - -PC14 - - - - - - - - - - -PC15 - - - - - - - - - - -------------------------------------------------------------------------------- - -Other: - -PC13: TAMPER_RTC -PC14: OSC32_IN -PC15: OSC32_OUT - -------------------------------------------------------------------------------- -GPIO ADC Timer FSMC I2S I2C UART SPI DAC 5v? SDIO -------------------------------------------------------------------------------- -PD0 - - D2 - - - - - Y - -PD1 - - D3 - - - - - Y - -PD2 - 3etr - - - 5rx - - Y CMD -PD3 - - CLK - - - - - Y - -------------------------------------------------------------------------------- -PD4 - - NOE - - - - - Y - -PD5 - - NWE - - - - - Y - -PD6 - - NWAIT - - - - - Y - -PD7 - - NE1 - - - - - Y - - NCE2 -------------------------------------------------------------------------------- -PD8 - - D13 - - - - - Y - -PD9 - - D14 - - - - - Y - -PD10 - - D15 - - - - - Y - -PD11 - - A16 - - - - - Y - -------------------------------------------------------------------------------- -PD12 - - A17 - - - - - Y - -PD13 - - A18 - - - - - Y - -PD14 - - D0 - - - - - Y - -PD15 - - D1 - - - - - Y - -------------------------------------------------------------------------------- - -Other: - -PD0: OSC_IN (default) -PD1: OSC_OUT (default) - ---------------------------------------------------------------------------- -GPIO ADC Timer FSMC I2S I2C USART SPI DAC 5v? ---------------------------------------------------------------------------- -PE0 - 4etr NBL0 - - - - - Y -PE1 - - NBL1 - - - - - Y -PE2 - - A23 - - - - - Y -PE3 - - A19 - - - - - Y ---------------------------------------------------------------------------- -PE4 - - A20 - - - - - Y -PE5 - - A21 - - - - - Y -PE6 - - A22 - - - - - Y -PE7 - - D4 - - - - - Y ---------------------------------------------------------------------------- -PE8 - - D5 - - - - - Y -PE9 - - D6 - - - - - Y -PE10 - - D7 - - - - - Y -PE11 - - D8 - - - - - Y ---------------------------------------------------------------------------- -PE12 - - D9 - - - - - Y -PE13 - - D10 - - - - - Y -PE14 - - D11 - - - - - Y -PE15 - - D12 - - - - - Y ---------------------------------------------------------------------------- - -Other: -PE2: TRACECK -PE3: TRACED0 -PE4: TRACED1 -PE5: TRACED2 -PE6: TRACED3 - ---------------------------------------------------------------------------- -GPIO ADC Timer FSMC I2S I2C USART SPI DAC 5v? ---------------------------------------------------------------------------- -PF0 - - A0 - - - - - Y -PF1 - - A1 - - - - - Y -PF2 - - A2 - - - - - Y -PF3 - - A3 - - - - - Y ---------------------------------------------------------------------------- -PF4 - - A4 - - - - - Y -PF5 - - A5 - - - - - Y -PF6 3in4 - NIORD - - - - - - -PF7 3in5 - NREG - - - - - - ---------------------------------------------------------------------------- -PF8 3in6 - NIOWR - - - - - - -PF9 3in7 - CD - - - - - - -PF10 3in8 - INTR - - - - - - -PF11 - - NIOS16 - - - - - Y ---------------------------------------------------------------------------- -PF12 - - A6 - - - - - Y -PF13 - - A7 - - - - - Y -PF14 - - A8 - - - - - Y -PF15 - - A9 - - - - - Y ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- -GPIO ADC Timer FSMC I2S I2C USART SPI DAC 5v? ---------------------------------------------------------------------------- -PG0 - - A10 - - - - - Y -PG1 - - A11 - - - - - Y -PG2 - - A12 - - - - - Y -PG3 - - A13 - - - - - Y ---------------------------------------------------------------------------- -PG4 - - A14 - - - - - Y -PG5 - - A15 - - - - - Y -PG6 - - INT2 - - - - - Y -PG7 - - INT3 - - - - - Y ---------------------------------------------------------------------------- -PG8 - - - - - - - - Y -PG9 - - NE2 - - - - - Y - NCE3 -PG10 - - NCE4_1 - - - - - Y - NE3 -PG11 - - NCE4_2 - - - - - Y ---------------------------------------------------------------------------- -PG12 - - NE4 - - - - - Y -PG13 - - A24 - - - - - Y -PG14 - - A25 - - - - - Y -PG15 - - - - - - - - Y ---------------------------------------------------------------------------- +Pin definitions by GPIO bank. + +Source: ST DOC ID 14611, Datasheet for STM32F103xC, STM32F103xD, +STM32F103xE, Table 5, pp. 30--35. + +Some additional peripheral GPIO information is given in the "Other" +section following each bank's main table. + +This document was prepared carefully and is believed to be correct, +but the final arbiter of truth is the ST datasheet. + +*** NB: UART 4 and 5 are NOT USART (columns are labeled appropriately). + +--------------------------------------------------------------------------- +GPIO ADC Timer FSMC I2S I2C USART SPI DAC 5v? +--------------------------------------------------------------------------- +PA0 123in0 2ch1etr - - - 2cts - - - + 5ch1 + 8etr +PA1 123in1 5ch2 - - - 2rts - - - + 2ch2 +PA2 123in2 5ch3 - - - 2tx - - - + 2ch3 +PA3 123in3 5ch4 - - - 2rx - - - + 2ch4 +--------------------------------------------------------------------------- +PA4 12in4 - - - - 2ck 1nss out1 - +PA5 12in5 - - - - - 1sck out2 - +PA6 12in6 8bkin - - - - 1miso - - + 3ch1 +PA7 12in7 8ch1n - - - - 1mosi - - + 3ch2 +--------------------------------------------------------------------------- +PA8 - 1ch1 - - - 1ck - - Y +PA9 - 1ch2 - - - 1tx - - Y +PA10 - 1ch3 - - - 1rx - - Y +PA11 - 1ch4 - - - 1cts - - Y +--------------------------------------------------------------------------- +PA12 - 1etr - - - 1rts - - Y +PA13 - - - - - - - - Y +PA14 - - - - - - - - Y +PA15 - - - 3ws - - 3nss - Y +--------------------------------------------------------------------------- + +Other: + +PA0: WKUP +PA8: MCO +PA11: USBDM, CAN_RX +PA12: USBDP, CAN_TX +PA13: JTMS-SWDIO (default) +PA14: JTCK-SWCLK (default) +PA15: JTDI (default) + +------------------------------------------------------------------------------- +GPIO ADC Timer FSMC I2S I2C USART SPI DAC 5v? SDIO +------------------------------------------------------------------------------- +PB0 12in8 3ch3 - - - - - - - - + 8ch2n +PB1 12in9 3ch4 - - - - - - - - + 8ch3n +PB2 - - - - - - - - Y - +PB3 - - - 3ck - - 3sck - Y - +--------------------------------------------------------------------------- +PB4 - - - - - - 3miso - Y - +PB5 - - - 3sd 1smba - 3mosi - - - +PB6 - 4ch1 - - 1scl - - - Y - +PB7 - 4ch2 NADV - 1sda - - - Y - +--------------------------------------------------------------------------- +PB8 - 4ch3 - - - - - - Y D4 +PB9 - 4ch4 - - - - - - Y D5 +PB10 - - - - 2scl 3tx - - Y - +PB11 - - - - 2sda 3rx - - Y - +--------------------------------------------------------------------------- +PB12 - 1bkin - 2ws 2smba 3ck 2nss - Y - +PB13 - 1ch1n - 2ck - 3cts 2sck - Y - +PB14 - 1ch2n - - - 3rts 2miso - Y - +PB15 - 1ch3n - 2sd - - 2mosi - Y - +--------------------------------------------------------------------------- + +Other: + +PB2: BOOT1 +PB3: JTDO (default) +PB4: NJTRST (default) + +------------------------------------------------------------------------------- +GPIO ADC Timer FSMC I2S I2C UART SPI DAC 5v? SDIO +------------------------------------------------------------------------------- +PC0 123in10 - - - - - - - - - +PC1 123in11 - - - - - - - - - +PC2 123in12 - - - - - - - - - +PC3 123in13 - - - - - - - - - +------------------------------------------------------------------------------- +PC4 12in14 - - - - - - - - - +PC5 12in15 - - - - - - - - - +PC6 - 8ch1 - 2mck - - - - Y D6 +PC7 - 8ch2 - 3mck - - - - Y D7 +------------------------------------------------------------------------------- +PC8 - 8ch3 - - - - - - Y D0 +PC9 - 8ch4 - - - - - - Y D1 +PC10 - - - - - 4tx - - Y D2 +PC11 - - - - - 4rx - - Y D3 +------------------------------------------------------------------------------- +PC12 - - - - - 5tx - - Y CK +PC13 - - - - - - - - - - +PC14 - - - - - - - - - - +PC15 - - - - - - - - - - +------------------------------------------------------------------------------- + +Other: + +PC13: TAMPER_RTC +PC14: OSC32_IN +PC15: OSC32_OUT + +------------------------------------------------------------------------------- +GPIO ADC Timer FSMC I2S I2C UART SPI DAC 5v? SDIO +------------------------------------------------------------------------------- +PD0 - - D2 - - - - - Y - +PD1 - - D3 - - - - - Y - +PD2 - 3etr - - - 5rx - - Y CMD +PD3 - - CLK - - - - - Y - +------------------------------------------------------------------------------- +PD4 - - NOE - - - - - Y - +PD5 - - NWE - - - - - Y - +PD6 - - NWAIT - - - - - Y - +PD7 - - NE1 - - - - - Y - + NCE2 +------------------------------------------------------------------------------- +PD8 - - D13 - - - - - Y - +PD9 - - D14 - - - - - Y - +PD10 - - D15 - - - - - Y - +PD11 - - A16 - - - - - Y - +------------------------------------------------------------------------------- +PD12 - - A17 - - - - - Y - +PD13 - - A18 - - - - - Y - +PD14 - - D0 - - - - - Y - +PD15 - - D1 - - - - - Y - +------------------------------------------------------------------------------- + +Other: + +PD0: OSC_IN (default) +PD1: OSC_OUT (default) + +--------------------------------------------------------------------------- +GPIO ADC Timer FSMC I2S I2C USART SPI DAC 5v? +--------------------------------------------------------------------------- +PE0 - 4etr NBL0 - - - - - Y +PE1 - - NBL1 - - - - - Y +PE2 - - A23 - - - - - Y +PE3 - - A19 - - - - - Y +--------------------------------------------------------------------------- +PE4 - - A20 - - - - - Y +PE5 - - A21 - - - - - Y +PE6 - - A22 - - - - - Y +PE7 - - D4 - - - - - Y +--------------------------------------------------------------------------- +PE8 - - D5 - - - - - Y +PE9 - - D6 - - - - - Y +PE10 - - D7 - - - - - Y +PE11 - - D8 - - - - - Y +--------------------------------------------------------------------------- +PE12 - - D9 - - - - - Y +PE13 - - D10 - - - - - Y +PE14 - - D11 - - - - - Y +PE15 - - D12 - - - - - Y +--------------------------------------------------------------------------- + +Other: +PE2: TRACECK +PE3: TRACED0 +PE4: TRACED1 +PE5: TRACED2 +PE6: TRACED3 + +--------------------------------------------------------------------------- +GPIO ADC Timer FSMC I2S I2C USART SPI DAC 5v? +--------------------------------------------------------------------------- +PF0 - - A0 - - - - - Y +PF1 - - A1 - - - - - Y +PF2 - - A2 - - - - - Y +PF3 - - A3 - - - - - Y +--------------------------------------------------------------------------- +PF4 - - A4 - - - - - Y +PF5 - - A5 - - - - - Y +PF6 3in4 - NIORD - - - - - - +PF7 3in5 - NREG - - - - - - +--------------------------------------------------------------------------- +PF8 3in6 - NIOWR - - - - - - +PF9 3in7 - CD - - - - - - +PF10 3in8 - INTR - - - - - - +PF11 - - NIOS16 - - - - - Y +--------------------------------------------------------------------------- +PF12 - - A6 - - - - - Y +PF13 - - A7 - - - - - Y +PF14 - - A8 - - - - - Y +PF15 - - A9 - - - - - Y +--------------------------------------------------------------------------- + +--------------------------------------------------------------------------- +GPIO ADC Timer FSMC I2S I2C USART SPI DAC 5v? +--------------------------------------------------------------------------- +PG0 - - A10 - - - - - Y +PG1 - - A11 - - - - - Y +PG2 - - A12 - - - - - Y +PG3 - - A13 - - - - - Y +--------------------------------------------------------------------------- +PG4 - - A14 - - - - - Y +PG5 - - A15 - - - - - Y +PG6 - - INT2 - - - - - Y +PG7 - - INT3 - - - - - Y +--------------------------------------------------------------------------- +PG8 - - - - - - - - Y +PG9 - - NE2 - - - - - Y + NCE3 +PG10 - - NCE4_1 - - - - - Y + NE3 +PG11 - - NCE4_2 - - - - - Y +--------------------------------------------------------------------------- +PG12 - - NE4 - - - - - Y +PG13 - - A24 - - - - - Y +PG14 - - A25 - - - - - Y +PG15 - - - - - - - - Y +--------------------------------------------------------------------------- diff --git a/Libmaple/libmaple/notes/portable.txt b/Libmaple/libmaple/notes/portable.txt index c800a0e7..549f4fb6 100644 --- a/Libmaple/libmaple/notes/portable.txt +++ b/Libmaple/libmaple/notes/portable.txt @@ -1,33 +1,33 @@ -libmaple was previously very restricted to LeafLabs boards. However, -the contents of libmaple proper are now fairly portable across medium- -and high-density STM32F1xx chips (though there are some caveats). The -current design is expected to accomodate new chips straightforwardly -and well into the future. - -The library's configuration is based around the files wirish/boards.h -(and .cpp), wirish/boards/*, and libmaple/stm32.h, as well as some -#defines it expects the environment to handle during compilation. - -If you want to use libmaple proper, you must define one of -STM32_MEDIUM_DENSITY or STM32_HIGH_DENSITY during compilation. -Defining one of these allows libmaple to decide what processor -features to expose to you (e.g., definitions related to ADC3 aren't -compiled in when STM32_MEDIUM_DENSITY is defined). There's no support -for low-density chips. XL-density is planned but not done (we don't -have one to test on); patches (and samples) are welcome! See: - - http://leaflabs.com/docs/libmaple/contributing.html - -There are some other useful #defines the environment can provide when -compiling libmaple. They aren't as crucial, though. See the Makefile -for more information. - -If you want to use Wirish, you'll need to define a BOARD_foo -(e.g. BOARD_maple, BOARD_maple_mini, etc.). This determines which -board files get loaded from wirish/boards/. See /wirish/boards.h and -/wirish/boards.cpp for more details. See /wirish/boards/maple.h and -/wirish/boards/maple.cpp for well-commented examples on how to add a -new board configuration. - -The code in libmaple/usb/ is not very portable at all right now; -expect this to change in the future. +libmaple was previously very restricted to LeafLabs boards. However, +the contents of libmaple proper are now fairly portable across medium- +and high-density STM32F1xx chips (though there are some caveats). The +current design is expected to accomodate new chips straightforwardly +and well into the future. + +The library's configuration is based around the files wirish/boards.h +(and .cpp), wirish/boards/*, and libmaple/stm32.h, as well as some +#defines it expects the environment to handle during compilation. + +If you want to use libmaple proper, you must define one of +STM32_MEDIUM_DENSITY or STM32_HIGH_DENSITY during compilation. +Defining one of these allows libmaple to decide what processor +features to expose to you (e.g., definitions related to ADC3 aren't +compiled in when STM32_MEDIUM_DENSITY is defined). There's no support +for low-density chips. XL-density is planned but not done (we don't +have one to test on); patches (and samples) are welcome! See: + + http://leaflabs.com/docs/libmaple/contributing.html + +There are some other useful #defines the environment can provide when +compiling libmaple. They aren't as crucial, though. See the Makefile +for more information. + +If you want to use Wirish, you'll need to define a BOARD_foo +(e.g. BOARD_maple, BOARD_maple_mini, etc.). This determines which +board files get loaded from wirish/boards/. See /wirish/boards.h and +/wirish/boards.cpp for more details. See /wirish/boards/maple.h and +/wirish/boards/maple.cpp for well-commented examples on how to add a +new board configuration. + +The code in libmaple/usb/ is not very portable at all right now; +expect this to change in the future. diff --git a/Libmaple/libmaple/notes/timers.txt b/Libmaple/libmaple/notes/timers.txt index e8ffa601..647e92e0 100644 --- a/Libmaple/libmaple/notes/timers.txt +++ b/Libmaple/libmaple/notes/timers.txt @@ -1,96 +1,96 @@ -Timers -====== - -Medium-density chips have timers 1 through 4. High- and XL-density -chips additionally have timers 5 through 8. XL-density chips -additionally have timers 9--14, which we don't support yet. - -Timer Capabilities ------------------- - -Each of timers 1--4 has 4 capture/compare (C/C) channels (also numbered -1--4). These are directly used by PWM, but may serve other purposes as -well (including handling user-specified periodic interrupts). The -STM32 implementation is particularly featureful, with, e.g., the -ability to chain together timers. - -Timers 1 and 8 are an advanced timers, with many more features. -Wirish just uses just their capture/compare interrupts and enables MOE -during initialization, essentially treating them as general purpose -timers (like timers 2--5). Advanced timers also have separate break, -update, and trigger interrupts that we only provide low-level -(i.e. libmaple proper) support for. - -Timers 6 and 7 are basic timers, without C/C channels. They are still -useful for interrupts (via NVIC_TIMER6, NVIC_TIMER7 IRQs, which can -fire upon an update event), but they're most useful for controlling -periodic DAC output. - -Known Issues and Other Caveats ------------------------------- - -There are some conflicts between timer C/C outputs and USART 1 and 2 -TX/RX. Wirish tries to handle this gracefully, but (as of 7 April -2011) not all the bugs are sorted yet. In particular, if you call -HardwareSerial::disable(), then try to use PWM, the USART TX pins -don't cooperate. - -Resetting the prescaler or reload value only takes effect at the next -update event. You can use timer_generate_update() to generate an -update event via software. - -Other interrupts (SysTick, USB, Serial, etc.) can interfere with -timing-critical applications. If your program requires precise -timing, you should probably at least disable USB and SysTick. Note -that this also disables the bootloader and stops millis()/micros() -from counting. - -Getting really good timing is a bit of an art. If things don't work -at first, you need to fiddle with an oscilloscope and the exact -overflow/compare numbers to get precise behavior. - -TODO ----- - -- Document more carefully (e.g., determine clock-wise and - overflow-wise behavior for each function). - -- Track down and handle pin conflicts. - -- Input capture interface. DON'T WRITE pulseIn() IN TERMS OF THIS. - Do that as a simple, Arduino style implementation that just - busy-waits and uses micros(), to allow a pulseIn() on arbitrary - pins. Eventually, expose the more precise/harder to use timer-based - API via a convenience library. - -- Complementary outputs, with convenient break/dead time interface. - -- Additional modes (center-aligned PWM, one pulse mode, etc.) and - count configuration (down, up/down). - -Alternative Wirish Implementations ----------------------------------- - -The current Wirish API is big and clunky. Its inclusion by default -also threatens making everyone's sketches bigger unnecessarily. We -need to deprecate the parts of it that are bad for 0.0.10, and remove -them when 0.1.0 comes out. - -Current implementation was inspired by Timer1 Library for Arduino: - -http://arduino.cc/pipermail/developers_arduino.cc/2010-June/002845.html - -Here's one of the more standard libaries out there: - -http://www.arduino.cc/playground/Code/Timer1 - - void initialize(long microseconds=1000000); - void start(); - void stop(); - void restart(); - void setPeriod(long microseconds); - void pwm(char pin, int duty, long microseconds=-1); - void setPwmDuty(char pin, int duty); - void disablePwm(char pin); - void attachInterrupt(void (*isr)(), long microseconds=-1); - void detachInterrupt(); +Timers +====== + +Medium-density chips have timers 1 through 4. High- and XL-density +chips additionally have timers 5 through 8. XL-density chips +additionally have timers 9--14, which we don't support yet. + +Timer Capabilities +------------------ + +Each of timers 1--4 has 4 capture/compare (C/C) channels (also numbered +1--4). These are directly used by PWM, but may serve other purposes as +well (including handling user-specified periodic interrupts). The +STM32 implementation is particularly featureful, with, e.g., the +ability to chain together timers. + +Timers 1 and 8 are an advanced timers, with many more features. +Wirish just uses just their capture/compare interrupts and enables MOE +during initialization, essentially treating them as general purpose +timers (like timers 2--5). Advanced timers also have separate break, +update, and trigger interrupts that we only provide low-level +(i.e. libmaple proper) support for. + +Timers 6 and 7 are basic timers, without C/C channels. They are still +useful for interrupts (via NVIC_TIMER6, NVIC_TIMER7 IRQs, which can +fire upon an update event), but they're most useful for controlling +periodic DAC output. + +Known Issues and Other Caveats +------------------------------ + +There are some conflicts between timer C/C outputs and USART 1 and 2 +TX/RX. Wirish tries to handle this gracefully, but (as of 7 April +2011) not all the bugs are sorted yet. In particular, if you call +HardwareSerial::disable(), then try to use PWM, the USART TX pins +don't cooperate. + +Resetting the prescaler or reload value only takes effect at the next +update event. You can use timer_generate_update() to generate an +update event via software. + +Other interrupts (SysTick, USB, Serial, etc.) can interfere with +timing-critical applications. If your program requires precise +timing, you should probably at least disable USB and SysTick. Note +that this also disables the bootloader and stops millis()/micros() +from counting. + +Getting really good timing is a bit of an art. If things don't work +at first, you need to fiddle with an oscilloscope and the exact +overflow/compare numbers to get precise behavior. + +TODO +---- + +- Document more carefully (e.g., determine clock-wise and + overflow-wise behavior for each function). + +- Track down and handle pin conflicts. + +- Input capture interface. DON'T WRITE pulseIn() IN TERMS OF THIS. + Do that as a simple, Arduino style implementation that just + busy-waits and uses micros(), to allow a pulseIn() on arbitrary + pins. Eventually, expose the more precise/harder to use timer-based + API via a convenience library. + +- Complementary outputs, with convenient break/dead time interface. + +- Additional modes (center-aligned PWM, one pulse mode, etc.) and + count configuration (down, up/down). + +Alternative Wirish Implementations +---------------------------------- + +The current Wirish API is big and clunky. Its inclusion by default +also threatens making everyone's sketches bigger unnecessarily. We +need to deprecate the parts of it that are bad for 0.0.10, and remove +them when 0.1.0 comes out. + +Current implementation was inspired by Timer1 Library for Arduino: + +http://arduino.cc/pipermail/developers_arduino.cc/2010-June/002845.html + +Here's one of the more standard libaries out there: + +http://www.arduino.cc/playground/Code/Timer1 + + void initialize(long microseconds=1000000); + void start(); + void stop(); + void restart(); + void setPeriod(long microseconds); + void pwm(char pin, int duty, long microseconds=-1); + void setPwmDuty(char pin, int duty); + void disablePwm(char pin); + void attachInterrupt(void (*isr)(), long microseconds=-1); + void detachInterrupt(); diff --git a/Libmaple/libmaple/notes/usb.txt b/Libmaple/libmaple/notes/usb.txt index 99b04c0a..9552b9f4 100644 --- a/Libmaple/libmaple/notes/usb.txt +++ b/Libmaple/libmaple/notes/usb.txt @@ -1,72 +1,72 @@ -XXX -XXX This file may be out of date! -XXX - -[NOTE: this is a long term proposal. The current implementation just does a -2ms TIMEOUT] - -SerialUSB Implementation -------------------------------------------------------------------------------- -The low-level serial USB implementation (in libmaple, written in C) is always -non-blocking. A blocking implementation which polls with an optional timeout -is in wirish (written in C++). - -begin() sets mode (and timeout if appropriate) -end() disables the endpoint and hardware peripheral -flush() clears the RX and TX buffers -available() gives # of bytes in RX buffer -pending() gives # of bytes in TX buffer -read() gets one byte from RX buffer (or ??? if empty) -getRTS()/getDTR() return control line status -write(), print(), println(), see below - -there is nothing preventing the implementation of setTimeout(), -flushTX/flushRX, etc, except for code size. - -NONBLOCKING (-1) - print() returns immediately with information about how much data was - transmitted. 64 bytes is the maximum that can be sent at a time, and - possibly less if buffer isn't empty. it's up to usercode to chunk up - larger datablocks, see if the buffer is full, etc - - returns pending (max 64) if bytes got put in the TX buffer - returns 0 if buffer was full - -BLOCKING (0) - print() will block INDEFINATELY waiting for an open connection to send - an arbitrarily long array of bytes through with up to 64 bytes per packet. - - returns sent (# of bytes added to the TX buffer successfully; all but the - last 64 or so will have been fully transmitted) - -TIMEOUT (the default, with 10ms. timeout period in ms) - print() will behave as in BLOCKING mode, except that it will timeout after - a given number of milliseconds. the timeout is not reset after every packet - is sent, so the device should be set with a large timeout if many packets - are going to be sent in one go, or the transmission will get cut off. - - returns sent (# of bytes added to the TX buffer successfully; all but the - last 64 or so will have been fully transmitted) - returns 0 if buffer was full - -SerialUSB Design Decisions -------------------------------------------------------------------------------- -The USB port behaves differently from other serial interfaces, making a clean -and simple "println()" implementation difficult. Data to be sent to the host is -written into a small 64byte endpoint buffer, which the host may (or may not!) -read from at any time. The RTS and DTR control lines /should/ indicate whether -the host will empty out the endpoint buffer in a reasonable amount of time, -but this is not reliable. - -From the usercode side, we want the println() function to accept strings up to -hundreds of characters long (longer than the buffer) and get them sent out as -quickly as possible, returning to code execution as quickly as possible. At the -same time we don't want want to generate a large buffer because this will -quickly eat up RAM. When the host device is not connected or not recieving -bytes, the behavior of println can be undefined; it should return quickly and -usercode should be able to determine if bytes were queued or not, but it isn't -important what happens to the bytes. On the other hand, when the device /is/ -connected, we want to guarentee that bytes get sent in the appropriate order -and none are missed. - - +XXX +XXX This file may be out of date! +XXX + +[NOTE: this is a long term proposal. The current implementation just does a +2ms TIMEOUT] + +SerialUSB Implementation +------------------------------------------------------------------------------- +The low-level serial USB implementation (in libmaple, written in C) is always +non-blocking. A blocking implementation which polls with an optional timeout +is in wirish (written in C++). + +begin() sets mode (and timeout if appropriate) +end() disables the endpoint and hardware peripheral +flush() clears the RX and TX buffers +available() gives # of bytes in RX buffer +pending() gives # of bytes in TX buffer +read() gets one byte from RX buffer (or ??? if empty) +getRTS()/getDTR() return control line status +write(), print(), println(), see below + +there is nothing preventing the implementation of setTimeout(), +flushTX/flushRX, etc, except for code size. + +NONBLOCKING (-1) + print() returns immediately with information about how much data was + transmitted. 64 bytes is the maximum that can be sent at a time, and + possibly less if buffer isn't empty. it's up to usercode to chunk up + larger datablocks, see if the buffer is full, etc + + returns pending (max 64) if bytes got put in the TX buffer + returns 0 if buffer was full + +BLOCKING (0) + print() will block INDEFINATELY waiting for an open connection to send + an arbitrarily long array of bytes through with up to 64 bytes per packet. + + returns sent (# of bytes added to the TX buffer successfully; all but the + last 64 or so will have been fully transmitted) + +TIMEOUT (the default, with 10ms. timeout period in ms) + print() will behave as in BLOCKING mode, except that it will timeout after + a given number of milliseconds. the timeout is not reset after every packet + is sent, so the device should be set with a large timeout if many packets + are going to be sent in one go, or the transmission will get cut off. + + returns sent (# of bytes added to the TX buffer successfully; all but the + last 64 or so will have been fully transmitted) + returns 0 if buffer was full + +SerialUSB Design Decisions +------------------------------------------------------------------------------- +The USB port behaves differently from other serial interfaces, making a clean +and simple "println()" implementation difficult. Data to be sent to the host is +written into a small 64byte endpoint buffer, which the host may (or may not!) +read from at any time. The RTS and DTR control lines /should/ indicate whether +the host will empty out the endpoint buffer in a reasonable amount of time, +but this is not reliable. + +From the usercode side, we want the println() function to accept strings up to +hundreds of characters long (longer than the buffer) and get them sent out as +quickly as possible, returning to code execution as quickly as possible. At the +same time we don't want want to generate a large buffer because this will +quickly eat up RAM. When the host device is not connected or not recieving +bytes, the behavior of println can be undefined; it should return quickly and +usercode should be able to determine if bytes were queued or not, but it isn't +important what happens to the bytes. On the other hand, when the device /is/ +connected, we want to guarentee that bytes get sent in the appropriate order +and none are missed. + + diff --git a/Libmaple/libmaple/notes/vga.txt b/Libmaple/libmaple/notes/vga.txt index ac7c7f23..43b6830e 100644 --- a/Libmaple/libmaple/notes/vga.txt +++ b/Libmaple/libmaple/notes/vga.txt @@ -1,35 +1,35 @@ - -Notes on GPIO Writing ------------------------------------------------------------------------------- -Classic digitalWrite() gives ~500ns pulse time (2MHz) - -gpio_write_bit() is about 360ns (2.78MHz) - -Writing to GPIO?_BASE is about 60ns (16.6MHz -> 18MHz) - -PWM write 0x0001 is about 14ns (72MHz) with prescaler as 0 (!) - -VGA Timing ------------------------------------------------------------------------------- -1/25.125MHz = 39.72ns (640x480 pixel clock) - -Crude 640x480 directions: - From www.epanorama.net/documents/pc/vga_timing.html - 480 lines - 31.77 us horizontal line length -> 2287.44 clock cycles -> 2287 - 3.77 us sync period -> 271 clocks -> 271 - 1.89 us front porch? -> 136 clocks -> 136 - 25.17 us video -> 1812.24 clocks -> 1812 - - So... - 2287 reload - 271 1: Hsync high - 407 2: Video on - 2219 3: Video off - 2287 4: Hsync low - - Vertically, it's - 480 lines active video - 11 lines front porch - 2 lines Vsync (low) - 31 lines back porch + +Notes on GPIO Writing +------------------------------------------------------------------------------ +Classic digitalWrite() gives ~500ns pulse time (2MHz) + +gpio_write_bit() is about 360ns (2.78MHz) + +Writing to GPIO?_BASE is about 60ns (16.6MHz -> 18MHz) + +PWM write 0x0001 is about 14ns (72MHz) with prescaler as 0 (!) + +VGA Timing +------------------------------------------------------------------------------ +1/25.125MHz = 39.72ns (640x480 pixel clock) + +Crude 640x480 directions: + From www.epanorama.net/documents/pc/vga_timing.html + 480 lines + 31.77 us horizontal line length -> 2287.44 clock cycles -> 2287 + 3.77 us sync period -> 271 clocks -> 271 + 1.89 us front porch? -> 136 clocks -> 136 + 25.17 us video -> 1812.24 clocks -> 1812 + + So... + 2287 reload + 271 1: Hsync high + 407 2: Video on + 2219 3: Video off + 2287 4: Hsync low + + Vertically, it's + 480 lines active video + 11 lines front porch + 2 lines Vsync (low) + 31 lines back porch diff --git a/Libmaple/libmaple/support/gdb/gpio/gpio.gdb b/Libmaple/libmaple/support/gdb/gpio/gpio.gdb index c4a99a29..4376cfde 100644 --- a/Libmaple/libmaple/support/gdb/gpio/gpio.gdb +++ b/Libmaple/libmaple/support/gdb/gpio/gpio.gdb @@ -1,12 +1,12 @@ -set print pretty on - -print "GPIOA registers:" -p/x *GPIOA->regs -print "GPIOB registers:" -p/x *GPIOB->regs -print "GPIOC registers:" -p/x *GPIOC->regs -print "GPIOD registers:" -p/x *GPIOD->regs -print "AFIO registers:" -p/x *(struct afio_reg_map*)0x40010000 +set print pretty on + +print "GPIOA registers:" +p/x *GPIOA->regs +print "GPIOB registers:" +p/x *GPIOB->regs +print "GPIOC registers:" +p/x *GPIOC->regs +print "GPIOD registers:" +p/x *GPIOD->regs +print "AFIO registers:" +p/x *(struct afio_reg_map*)0x40010000 diff --git a/Libmaple/libmaple/support/gdb/i2c/test.gdb b/Libmaple/libmaple/support/gdb/i2c/test.gdb index 5744cb1e..8b71320a 100644 --- a/Libmaple/libmaple/support/gdb/i2c/test.gdb +++ b/Libmaple/libmaple/support/gdb/i2c/test.gdb @@ -1,112 +1,112 @@ -define i2c_sr1_flags -set $s = $arg0 -printf "SR1: " - -if (($s & (1 << 15))) - printf "SMBALERT " -end - -if (($s & (1 << 14))) - printf "TIMEOUT " -end - -if (($s & (1 << 12))) - printf "PECERR " -end - -if (($s & (1 << 11))) - printf "OVR " -end - -if (($s & (1 << 10))) - printf "AF " -end - -if (($s & (1 << 9))) - printf "ARLO " -end - -if (($s & (1 << 8))) - printf "BERR " -end - -if (($s & (1 << 7))) - printf "TXE " -end - -if (($s & (1 << 6))) - printf "RXNE " -end - -if (($s & (1 << 4))) - printf "STOPF " -end - -if (($s & (1 << 3))) - printf "ADD10 " -end - -if (($s & (1 << 2))) - printf "BTF " -end - -if (($s & (1 << 1))) - printf "ADDR " -end - -if (($s & (1 << 0))) - printf "SB " -end -end - -define i2c_sr2_flags -set $s = $arg0 -printf "SR2: " - -if (($s & (1 << 7))) - printf "DUALF " -end - -if (($s & (1 << 6))) - printf "SMBHOST " -end - -if (($s & (1 << 5))) - printf "SMBDEFAULT " -end - -if (($s & (1 << 4))) - printf "GENCALL " -end - - -if (($s & (1 << 2))) - printf "TRA " -end - -if (($s & (1 << 1))) - printf "BUSY " -end - -if (($s & (1 << 0))) - printf "MSL " -end - -end - -define pbc -set $c = crumbs -while ($c->event) - if ($c->event != 0) - printf "Event: %d ", $c->event - if ($c->event == 1) - i2c_sr1_flags $c->sr1 - printf "\t" - i2c_sr2_flags $c->sr2 - end - printf "\n" - end - set $c = $c + 1 -end - - +define i2c_sr1_flags +set $s = $arg0 +printf "SR1: " + +if (($s & (1 << 15))) + printf "SMBALERT " +end + +if (($s & (1 << 14))) + printf "TIMEOUT " +end + +if (($s & (1 << 12))) + printf "PECERR " +end + +if (($s & (1 << 11))) + printf "OVR " +end + +if (($s & (1 << 10))) + printf "AF " +end + +if (($s & (1 << 9))) + printf "ARLO " +end + +if (($s & (1 << 8))) + printf "BERR " +end + +if (($s & (1 << 7))) + printf "TXE " +end + +if (($s & (1 << 6))) + printf "RXNE " +end + +if (($s & (1 << 4))) + printf "STOPF " +end + +if (($s & (1 << 3))) + printf "ADD10 " +end + +if (($s & (1 << 2))) + printf "BTF " +end + +if (($s & (1 << 1))) + printf "ADDR " +end + +if (($s & (1 << 0))) + printf "SB " +end +end + +define i2c_sr2_flags +set $s = $arg0 +printf "SR2: " + +if (($s & (1 << 7))) + printf "DUALF " +end + +if (($s & (1 << 6))) + printf "SMBHOST " +end + +if (($s & (1 << 5))) + printf "SMBDEFAULT " +end + +if (($s & (1 << 4))) + printf "GENCALL " +end + + +if (($s & (1 << 2))) + printf "TRA " +end + +if (($s & (1 << 1))) + printf "BUSY " +end + +if (($s & (1 << 0))) + printf "MSL " +end + +end + +define pbc +set $c = crumbs +while ($c->event) + if ($c->event != 0) + printf "Event: %d ", $c->event + if ($c->event == 1) + i2c_sr1_flags $c->sr1 + printf "\t" + i2c_sr2_flags $c->sr2 + end + printf "\n" + end + set $c = $c + 1 +end + + diff --git a/Libmaple/libmaple/support/ld/aeroquad32/flash.ld b/Libmaple/libmaple/support/ld/aeroquad32/flash.ld index accc86d3..eb52b7d1 100644 --- a/Libmaple/libmaple/support/ld/aeroquad32/flash.ld +++ b/Libmaple/libmaple/support/ld/aeroquad32/flash.ld @@ -1,20 +1,20 @@ -/* - * aeroquad32 (STM32F405VGT6, high density) linker script for - * Flash builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 125K - rom (rx) : ORIGIN = 0x08010000, LENGTH = 960K /* ala42 */ -} - -GROUP(libcs4_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * aeroquad32 (STM32F405VGT6, high density) linker script for + * Flash builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 125K + rom (rx) : ORIGIN = 0x08010000, LENGTH = 960K /* ala42 */ +} + +GROUP(libcs4_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/aeroquad32/jtag.ld b/Libmaple/libmaple/support/ld/aeroquad32/jtag.ld index 1a162d90..2fabdc93 100644 --- a/Libmaple/libmaple/support/ld/aeroquad32/jtag.ld +++ b/Libmaple/libmaple/support/ld/aeroquad32/jtag.ld @@ -1,20 +1,20 @@ -/* - * aeroquad32 (STM32F103VET6, high density) linker script for - * JTAG (bare metal, no bootloader) builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K -} - -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * aeroquad32 (STM32F103VET6, high density) linker script for + * JTAG (bare metal, no bootloader) builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/aeroquad32/ram.ld b/Libmaple/libmaple/support/ld/aeroquad32/ram.ld index d58188d3..0928b94d 100644 --- a/Libmaple/libmaple/support/ld/aeroquad32/ram.ld +++ b/Libmaple/libmaple/support/ld/aeroquad32/ram.ld @@ -1,20 +1,20 @@ -/* - * aeroquad32 (STM32F103VET6, high density) linker script for - * RAM builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K - /* rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K ala42 */ - rom (rx) : ORIGIN = 0x08010000, LENGTH = 0K /* ala42 */ -} - -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", ram); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", ram); - -INCLUDE common.inc +/* + * aeroquad32 (STM32F103VET6, high density) linker script for + * RAM builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + /* rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K ala42 */ + rom (rx) : ORIGIN = 0x08010000, LENGTH = 0K /* ala42 */ +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/aeroquad32f1/flash.ld b/Libmaple/libmaple/support/ld/aeroquad32f1/flash.ld index 7a07b471..728a54d9 100644 --- a/Libmaple/libmaple/support/ld/aeroquad32f1/flash.ld +++ b/Libmaple/libmaple/support/ld/aeroquad32f1/flash.ld @@ -1,21 +1,21 @@ -/* - * aeroquad32 (STM32F103VET6, high density) linker script for - * Flash builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K - /* rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K */ /* ala42 */ - rom (rx) : ORIGIN = 0x08010000, LENGTH = 448K /* ala42 */ -} - -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * aeroquad32 (STM32F103VET6, high density) linker script for + * Flash builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + /* rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K */ /* ala42 */ + rom (rx) : ORIGIN = 0x08010000, LENGTH = 448K /* ala42 */ +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/aeroquad32f1/jtag.ld b/Libmaple/libmaple/support/ld/aeroquad32f1/jtag.ld index 1a162d90..2fabdc93 100644 --- a/Libmaple/libmaple/support/ld/aeroquad32f1/jtag.ld +++ b/Libmaple/libmaple/support/ld/aeroquad32f1/jtag.ld @@ -1,20 +1,20 @@ -/* - * aeroquad32 (STM32F103VET6, high density) linker script for - * JTAG (bare metal, no bootloader) builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K -} - -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * aeroquad32 (STM32F103VET6, high density) linker script for + * JTAG (bare metal, no bootloader) builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/aeroquad32f1/ram.ld b/Libmaple/libmaple/support/ld/aeroquad32f1/ram.ld index d58188d3..0928b94d 100644 --- a/Libmaple/libmaple/support/ld/aeroquad32f1/ram.ld +++ b/Libmaple/libmaple/support/ld/aeroquad32f1/ram.ld @@ -1,20 +1,20 @@ -/* - * aeroquad32 (STM32F103VET6, high density) linker script for - * RAM builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K - /* rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K ala42 */ - rom (rx) : ORIGIN = 0x08010000, LENGTH = 0K /* ala42 */ -} - -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", ram); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", ram); - -INCLUDE common.inc +/* + * aeroquad32 (STM32F103VET6, high density) linker script for + * RAM builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + /* rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K ala42 */ + rom (rx) : ORIGIN = 0x08010000, LENGTH = 0K /* ala42 */ +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/aeroquad32mini/flash.ld b/Libmaple/libmaple/support/ld/aeroquad32mini/flash.ld index 587ced44..ab032076 100644 --- a/Libmaple/libmaple/support/ld/aeroquad32mini/flash.ld +++ b/Libmaple/libmaple/support/ld/aeroquad32mini/flash.ld @@ -1,28 +1,28 @@ -/* - * Maple Mini (STM32F103CBT6, medium density) linker script for Flash builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -/* - * Define the rest of the sections - */ -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Maple Mini (STM32F103CBT6, medium density) linker script for Flash builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* + * Define the rest of the sections + */ +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/aeroquad32mini/jtag.ld b/Libmaple/libmaple/support/ld/aeroquad32mini/jtag.ld index b0f9c8fe..2f9cf319 100644 --- a/Libmaple/libmaple/support/ld/aeroquad32mini/jtag.ld +++ b/Libmaple/libmaple/support/ld/aeroquad32mini/jtag.ld @@ -1,29 +1,29 @@ -/* - * Maple Mini (STM32F103CBT6, medium density) linker script for JTAG - * (bare metal, no bootloader) builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -/* - * Define the rest of the sections - */ -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Maple Mini (STM32F103CBT6, medium density) linker script for JTAG + * (bare metal, no bootloader) builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* + * Define the rest of the sections + */ +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/aeroquad32mini/ram.ld b/Libmaple/libmaple/support/ld/aeroquad32mini/ram.ld index b74585b1..0ba02522 100644 --- a/Libmaple/libmaple/support/ld/aeroquad32mini/ram.ld +++ b/Libmaple/libmaple/support/ld/aeroquad32mini/ram.ld @@ -1,27 +1,27 @@ -/* - * Maple Mini (STM32F103CBT6, medium density) linker script for RAM builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", ram); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", ram); - -/* - * Define the rest of the sections - */ -INCLUDE common.inc +/* + * Maple Mini (STM32F103CBT6, medium density) linker script for RAM builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +/* + * Define the rest of the sections + */ +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/common.inc b/Libmaple/libmaple/support/ld/common.inc index 88463746..b53c4f6a 100644 --- a/Libmaple/libmaple/support/ld/common.inc +++ b/Libmaple/libmaple/support/ld/common.inc @@ -1,231 +1,231 @@ -/* - * Linker script for libmaple. - * - * Original author "lanchon" from ST forums, with modifications by LeafLabs. - */ - -OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") -ENTRY(_start) -SEARCH_DIR(.) - -/* - * Link against libgcc, libc, and libm - */ -GROUP(libgcc.a libc.a libm.a) - -/* These force the linker to search for particular symbols from - * the start of the link process and thus ensure the user's - * overrides are picked up - */ -INCLUDE names.inc - -/* STM32 vector table. See stm32_vector_table.S */ -EXTERN(__cs3_stm32_vector_table) - -/* libcs3 C start function. See cs3.h */ -EXTERN(__cs3_start_c) - -/* main entry point */ -EXTERN(main) - -/* Initial stack pointer value. */ -EXTERN(__cs3_stack) -PROVIDE(__cs3_stack = __cs3_region_start_ram + LENGTH(ram)); - -/* Reset vector and chip reset entry point. See start.S */ -EXTERN(_start) -PROVIDE(__cs3_reset = _start); - -/* Heap boundaries, for libmaple */ -EXTERN(_lm_heap_start); -EXTERN(_lm_heap_end); - -SECTIONS -{ - /* TODO pull out rodata and stick into separate sections */ - .text : - { - __text_start = .; - /* - * STM32 vector table. Leave this here. Yes, really. - */ - *(.stm32.interrupt_vector) - - /* - * Program code and vague linking - */ - *(.text .text.* .gnu.linkonce.t.*) - *(.plt) - *(.gnu.warning) - *(.glue_7t) *(.glue_7) *(.vfp11_veneer) - - *(.ARM.extab* .gnu.linkonce.armextab.*) - *(.gcc_except_table) - *(.eh_frame_hdr) - *(.eh_frame) - - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(0x4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - /* - * struct __cs3_region used during __cs3_start_c - */ - . = ALIGN(4); - __cs3_regions = .; - LONG (0) /* flags */ - LONG (__cs3_region_init_ram) /* initial contents */ - LONG (__cs3_region_start_ram) /* start address */ - LONG (__cs3_region_init_size_ram) /* size of initial data */ - LONG (__cs3_region_zero_size_ram) /* additional size to be zeroed */ - } > REGION_TEXT - - /* - * Read-only data - */ - .rodata : - { - *(.rodata .rodata.* .gnu.linkonce.r.*) - } > REGION_RODATA - - /* - * .ARM.exidx exception unwinding; mandated by ARM's C++ ABI - */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > REGION_RODATA - __exidx_end = .; - - /* - * End of text - */ - .text.align : - { - . = ALIGN(8); - _etext = .; - } > REGION_TEXT - - /* - * .USER_FLASH: We allow users to allocate into Flash here - */ - .USER_FLASH : - { - *(.USER_FLASH) - } > REGION_RODATA - - /* - * .data - */ - .data : - { - __cs3_region_start_ram = DEFINED(_FLASH_BUILD) ? . : __text_start; - - *(.got.plt) *(.got) - *(.data .data.* .gnu.linkonce.d.*) - - /* - * Heap: Linker scripts may choose a custom heap by overriding - * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in - * internal SRAM, beginning after .bss, and growing towards - * the stack. - * - * I'm shoving these here naively; there's probably a cleaner way - * to go about this. [mbolivar] - */ - _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : _end; - _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __cs3_stack; - . = ALIGN (8); - _edata = .; - } > REGION_DATA AT> REGION_TEXT - - /* - * .bss - */ - .bss : - { - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _end = .; - } > REGION_BSS AT> REGION_TEXT - - /* - * Constants needed for the pieces of CS3 we use during - * board startup; see libcs3_stm32_src/. - */ - __cs3_region_init_ram = (DEFINED(_FLASH_BUILD) ? - LOADADDR(.data) : - LOADADDR(.text)); - __cs3_region_init_size_ram = (DEFINED(_FLASH_BUILD) ? - _edata - ADDR(.data) : - _edata - ADDR(.text)); - __cs3_region_zero_size_ram = _end - _edata; - __cs3_region_num = 1; - - /* - * Debugging sections - */ - .stab 0 (NOLOAD) : { *(.stab) } - .stabstr 0 (NOLOAD) : { *(.stabstr) } - /* DWARF debug sections. - * Symbols in the DWARF debugging sections are relative to the beginning - * of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - - .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } - .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } - /DISCARD/ : { *(.note.GNU-stack) } -} +/* + * Linker script for libmaple. + * + * Original author "lanchon" from ST forums, with modifications by LeafLabs. + */ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +ENTRY(_start) +SEARCH_DIR(.) + +/* + * Link against libgcc, libc, and libm + */ +GROUP(libgcc.a libc.a libm.a) + +/* These force the linker to search for particular symbols from + * the start of the link process and thus ensure the user's + * overrides are picked up + */ +INCLUDE names.inc + +/* STM32 vector table. See stm32_vector_table.S */ +EXTERN(__cs3_stm32_vector_table) + +/* libcs3 C start function. See cs3.h */ +EXTERN(__cs3_start_c) + +/* main entry point */ +EXTERN(main) + +/* Initial stack pointer value. */ +EXTERN(__cs3_stack) +PROVIDE(__cs3_stack = __cs3_region_start_ram + LENGTH(ram)); + +/* Reset vector and chip reset entry point. See start.S */ +EXTERN(_start) +PROVIDE(__cs3_reset = _start); + +/* Heap boundaries, for libmaple */ +EXTERN(_lm_heap_start); +EXTERN(_lm_heap_end); + +SECTIONS +{ + /* TODO pull out rodata and stick into separate sections */ + .text : + { + __text_start = .; + /* + * STM32 vector table. Leave this here. Yes, really. + */ + *(.stm32.interrupt_vector) + + /* + * Program code and vague linking + */ + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(0x4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + /* + * struct __cs3_region used during __cs3_start_c + */ + . = ALIGN(4); + __cs3_regions = .; + LONG (0) /* flags */ + LONG (__cs3_region_init_ram) /* initial contents */ + LONG (__cs3_region_start_ram) /* start address */ + LONG (__cs3_region_init_size_ram) /* size of initial data */ + LONG (__cs3_region_zero_size_ram) /* additional size to be zeroed */ + } > REGION_TEXT + + /* + * Read-only data + */ + .rodata : + { + *(.rodata .rodata.* .gnu.linkonce.r.*) + } > REGION_RODATA + + /* + * .ARM.exidx exception unwinding; mandated by ARM's C++ ABI + */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > REGION_RODATA + __exidx_end = .; + + /* + * End of text + */ + .text.align : + { + . = ALIGN(8); + _etext = .; + } > REGION_TEXT + + /* + * .USER_FLASH: We allow users to allocate into Flash here + */ + .USER_FLASH : + { + *(.USER_FLASH) + } > REGION_RODATA + + /* + * .data + */ + .data : + { + __cs3_region_start_ram = DEFINED(_FLASH_BUILD) ? . : __text_start; + + *(.got.plt) *(.got) + *(.data .data.* .gnu.linkonce.d.*) + + /* + * Heap: Linker scripts may choose a custom heap by overriding + * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in + * internal SRAM, beginning after .bss, and growing towards + * the stack. + * + * I'm shoving these here naively; there's probably a cleaner way + * to go about this. [mbolivar] + */ + _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : _end; + _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __cs3_stack; + . = ALIGN (8); + _edata = .; + } > REGION_DATA AT> REGION_TEXT + + /* + * .bss + */ + .bss : + { + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _end = .; + } > REGION_BSS AT> REGION_TEXT + + /* + * Constants needed for the pieces of CS3 we use during + * board startup; see libcs3_stm32_src/. + */ + __cs3_region_init_ram = (DEFINED(_FLASH_BUILD) ? + LOADADDR(.data) : + LOADADDR(.text)); + __cs3_region_init_size_ram = (DEFINED(_FLASH_BUILD) ? + _edata - ADDR(.data) : + _edata - ADDR(.text)); + __cs3_region_zero_size_ram = _end - _edata; + __cs3_region_num = 1; + + /* + * Debugging sections + */ + .stab 0 (NOLOAD) : { *(.stab) } + .stabstr 0 (NOLOAD) : { *(.stabstr) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/Libmaple/libmaple/support/ld/discovery_f4/flash.ld b/Libmaple/libmaple/support/ld/discovery_f4/flash.ld index f16d4e94..5583aa98 100644 --- a/Libmaple/libmaple/support/ld/discovery_f4/flash.ld +++ b/Libmaple/libmaple/support/ld/discovery_f4/flash.ld @@ -1,20 +1,20 @@ -/* - * Discovery F4 (STM32F407VGT6, high density) linker script for - * Flash builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 125K - rom (rx) : ORIGIN = 0x08010000, LENGTH = 960K /* ala42 */ -} - -GROUP(libcs4_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Discovery F4 (STM32F407VGT6, high density) linker script for + * Flash builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 125K + rom (rx) : ORIGIN = 0x08010000, LENGTH = 960K /* ala42 */ +} + +GROUP(libcs4_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/discovery_f4/jtag.ld b/Libmaple/libmaple/support/ld/discovery_f4/jtag.ld index 1a162d90..2fabdc93 100644 --- a/Libmaple/libmaple/support/ld/discovery_f4/jtag.ld +++ b/Libmaple/libmaple/support/ld/discovery_f4/jtag.ld @@ -1,20 +1,20 @@ -/* - * aeroquad32 (STM32F103VET6, high density) linker script for - * JTAG (bare metal, no bootloader) builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K -} - -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * aeroquad32 (STM32F103VET6, high density) linker script for + * JTAG (bare metal, no bootloader) builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/discovery_f4/ram.ld b/Libmaple/libmaple/support/ld/discovery_f4/ram.ld index d58188d3..0928b94d 100644 --- a/Libmaple/libmaple/support/ld/discovery_f4/ram.ld +++ b/Libmaple/libmaple/support/ld/discovery_f4/ram.ld @@ -1,20 +1,20 @@ -/* - * aeroquad32 (STM32F103VET6, high density) linker script for - * RAM builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K - /* rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K ala42 */ - rom (rx) : ORIGIN = 0x08010000, LENGTH = 0K /* ala42 */ -} - -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", ram); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", ram); - -INCLUDE common.inc +/* + * aeroquad32 (STM32F103VET6, high density) linker script for + * RAM builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + /* rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K ala42 */ + rom (rx) : ORIGIN = 0x08010000, LENGTH = 0K /* ala42 */ +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/freeflight/flash.ld b/Libmaple/libmaple/support/ld/freeflight/flash.ld index 54d854dd..4777a891 100644 --- a/Libmaple/libmaple/support/ld/freeflight/flash.ld +++ b/Libmaple/libmaple/support/ld/freeflight/flash.ld @@ -1,28 +1,28 @@ -/* - * Maple Mini (STM32F103CBT6, medium density) linker script for Flash builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 126K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -/* - * Define the rest of the sections - */ -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Maple Mini (STM32F103CBT6, medium density) linker script for Flash builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 126K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* + * Define the rest of the sections + */ +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/freeflight/jtag.ld b/Libmaple/libmaple/support/ld/freeflight/jtag.ld index b0f9c8fe..2f9cf319 100644 --- a/Libmaple/libmaple/support/ld/freeflight/jtag.ld +++ b/Libmaple/libmaple/support/ld/freeflight/jtag.ld @@ -1,29 +1,29 @@ -/* - * Maple Mini (STM32F103CBT6, medium density) linker script for JTAG - * (bare metal, no bootloader) builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -/* - * Define the rest of the sections - */ -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Maple Mini (STM32F103CBT6, medium density) linker script for JTAG + * (bare metal, no bootloader) builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* + * Define the rest of the sections + */ +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/freeflight/ram.ld b/Libmaple/libmaple/support/ld/freeflight/ram.ld index b74585b1..0ba02522 100644 --- a/Libmaple/libmaple/support/ld/freeflight/ram.ld +++ b/Libmaple/libmaple/support/ld/freeflight/ram.ld @@ -1,27 +1,27 @@ -/* - * Maple Mini (STM32F103CBT6, medium density) linker script for RAM builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", ram); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", ram); - -/* - * Define the rest of the sections - */ -INCLUDE common.inc +/* + * Maple Mini (STM32F103CBT6, medium density) linker script for RAM builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +/* + * Define the rest of the sections + */ +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/libcs3_stm32_src/Makefile b/Libmaple/libmaple/support/ld/libcs3_stm32_src/Makefile index e41cf6a8..e04ac390 100644 --- a/Libmaple/libmaple/support/ld/libcs3_stm32_src/Makefile +++ b/Libmaple/libmaple/support/ld/libcs3_stm32_src/Makefile @@ -1,36 +1,36 @@ -# setup environment - -TARGET_ARCH = -mcpu=cortex-m3 -mthumb - -CC = arm-none-eabi-gcc -CFLAGS = - -AS = $(CC) -x assembler-with-cpp -c $(TARGET_ARCH) -ASFLAGS = - -AR = arm-none-eabi-ar -ARFLAGS = cr - -LIB_OBJS = stm32_vector_table.o stm32_isrs.o start.o start_c.o - -help: - @echo "Targets:" - @echo "\t medium-density: Target medium density chips (e.g. Maple)" - @echo "\t high-density: Target high density chips (e.g. Maple-native)" - -.PHONY: help medium high - -medium-density: $(LIB_OBJS) - $(AR) $(ARFLAGS) libcs3_stm32_med_density.a $(LIB_OBJS) - rm -f $(LIB_OBJS) - -high-density: CFLAGS := -DSTM32_HIGH_DENSITY -high-density: ASFLAGS := -DSTM32_HIGH_DENSITY -high-density: $(LIB_OBJS) - $(AR) $(ARFLAGS) libcs3_stm32_high_density.a $(LIB_OBJS) - rm -f $(LIB_OBJS) - -# clean -.PHONY: clean -clean: - -rm -f $(LIB_OBJS) *.a +# setup environment + +TARGET_ARCH = -mcpu=cortex-m3 -mthumb + +CC = arm-none-eabi-gcc +CFLAGS = + +AS = $(CC) -x assembler-with-cpp -c $(TARGET_ARCH) +ASFLAGS = + +AR = arm-none-eabi-ar +ARFLAGS = cr + +LIB_OBJS = stm32_vector_table.o stm32_isrs.o start.o start_c.o + +help: + @echo "Targets:" + @echo "\t medium-density: Target medium density chips (e.g. Maple)" + @echo "\t high-density: Target high density chips (e.g. Maple-native)" + +.PHONY: help medium high + +medium-density: $(LIB_OBJS) + $(AR) $(ARFLAGS) libcs3_stm32_med_density.a $(LIB_OBJS) + rm -f $(LIB_OBJS) + +high-density: CFLAGS := -DSTM32_HIGH_DENSITY +high-density: ASFLAGS := -DSTM32_HIGH_DENSITY +high-density: $(LIB_OBJS) + $(AR) $(ARFLAGS) libcs3_stm32_high_density.a $(LIB_OBJS) + rm -f $(LIB_OBJS) + +# clean +.PHONY: clean +clean: + -rm -f $(LIB_OBJS) *.a diff --git a/Libmaple/libmaple/support/ld/libcs3_stm32_src/start.S b/Libmaple/libmaple/support/ld/libcs3_stm32_src/start.S index ae75747e..4d1d405e 100644 --- a/Libmaple/libmaple/support/ld/libcs3_stm32_src/start.S +++ b/Libmaple/libmaple/support/ld/libcs3_stm32_src/start.S @@ -1,27 +1,27 @@ -/* - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ - - .text - .code 16 - .thumb_func - - .globl _start - .type _start, %function -_start: - .fnstart - ldr r1,=__cs3_stack - mov sp,r1 - ldr r1,=__cs3_start_c - bx r1 - .pool - .cantunwind - .fnend +/* + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + + .text + .code 16 + .thumb_func + + .globl _start + .type _start, %function +_start: + .fnstart + ldr r1,=__cs3_stack + mov sp,r1 + ldr r1,=__cs3_start_c + bx r1 + .pool + .cantunwind + .fnend diff --git a/Libmaple/libmaple/support/ld/libcs3_stm32_src/start_c.c b/Libmaple/libmaple/support/ld/libcs3_stm32_src/start_c.c index dff9fa34..2ab0212b 100644 --- a/Libmaple/libmaple/support/ld/libcs3_stm32_src/start_c.c +++ b/Libmaple/libmaple/support/ld/libcs3_stm32_src/start_c.c @@ -1,58 +1,58 @@ -/* CS3 start_c routine. - * - * Copyright (c) 2006, 2007 CodeSourcery Inc - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ - -#include "cs3.h" - -extern void __libc_init_array (void); - -extern int main (int, char **, char **); - -extern void exit (int) __attribute__ ((noreturn, weak)); - -void __attribute ((noreturn)) -__cs3_start_c (void) -{ - unsigned regions = __cs3_region_num; - const struct __cs3_region *rptr = __cs3_regions; - int exit_code; - - /* Initialize memory */ - for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) - { - long long *src = (long long *)rptr->init; - long long *dst = (long long *)rptr->data; - unsigned limit = rptr->init_size; - unsigned count; - - if (src != dst) - for (count = 0; count != limit; count += sizeof (long long)) - *dst++ = *src++; - else - dst = (long long *)((char *)dst + limit); - limit = rptr->zero_size; - for (count = 0; count != limit; count += sizeof (long long)) - *dst++ = 0; - } - - /* Run initializers. */ - __libc_init_array (); - - exit_code = main (0, NULL, NULL); - if (exit) - exit (exit_code); - /* If exit is NULL, make sure we don't return. */ - for (;;) - continue; -} +/* CS3 start_c routine. + * + * Copyright (c) 2006, 2007 CodeSourcery Inc + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include "cs3.h" + +extern void __libc_init_array (void); + +extern int main (int, char **, char **); + +extern void exit (int) __attribute__ ((noreturn, weak)); + +void __attribute ((noreturn)) +__cs3_start_c (void) +{ + unsigned regions = __cs3_region_num; + const struct __cs3_region *rptr = __cs3_regions; + int exit_code; + + /* Initialize memory */ + for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) + { + long long *src = (long long *)rptr->init; + long long *dst = (long long *)rptr->data; + unsigned limit = rptr->init_size; + unsigned count; + + if (src != dst) + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = *src++; + else + dst = (long long *)((char *)dst + limit); + limit = rptr->zero_size; + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = 0; + } + + /* Run initializers. */ + __libc_init_array (); + + exit_code = main (0, NULL, NULL); + if (exit) + exit (exit_code); + /* If exit is NULL, make sure we don't return. */ + for (;;) + continue; +} diff --git a/Libmaple/libmaple/support/ld/libcs3_stm32_src/stm32_isrs.S b/Libmaple/libmaple/support/ld/libcs3_stm32_src/stm32_isrs.S index f95468c4..be102e7d 100644 --- a/Libmaple/libmaple/support/ld/libcs3_stm32_src/stm32_isrs.S +++ b/Libmaple/libmaple/support/ld/libcs3_stm32_src/stm32_isrs.S @@ -1,235 +1,235 @@ -/* STM32 ISR weak declarations */ - - .thumb - -/* Default handler for all non-overridden interrupts and exceptions */ - .globl __default_handler - .type __default_handler, %function - -__default_handler: - b . - - .weak __exc_nmi - .globl __exc_nmi - .set __exc_nmi, __default_handler - .weak __exc_hardfault - .globl __exc_hardfault - .set __exc_hardfault, __default_handler - .weak __exc_memmanage - .globl __exc_memmanage - .set __exc_memmanage, __default_handler - .weak __exc_busfault - .globl __exc_busfault - .set __exc_busfault, __default_handler - .weak __exc_usagefault - .globl __exc_usagefault - .set __exc_usagefault, __default_handler - .weak __stm32reservedexception7 - .globl __stm32reservedexception7 - .set __stm32reservedexception7, __default_handler - .weak __stm32reservedexception8 - .globl __stm32reservedexception8 - .set __stm32reservedexception8, __default_handler - .weak __stm32reservedexception9 - .globl __stm32reservedexception9 - .set __stm32reservedexception9, __default_handler - .weak __stm32reservedexception10 - .globl __stm32reservedexception10 - .set __stm32reservedexception10, __default_handler - .weak __exc_svc - .globl __exc_svc - .set __exc_svc, __default_handler - .weak __exc_debug_monitor - .globl __exc_debug_monitor - .set __exc_debug_monitor, __default_handler - .weak __stm32reservedexception13 - .globl __stm32reservedexception13 - .set __stm32reservedexception13, __default_handler - .weak __exc_pendsv - .globl __exc_pendsv - .set __exc_pendsv, __default_handler - .weak __exc_systick - .globl __exc_systick - .set __exc_systick, __default_handler - .weak __irq_wwdg - .globl __irq_wwdg - .set __irq_wwdg, __default_handler - .weak __irq_pvd - .globl __irq_pvd - .set __irq_pvd, __default_handler - .weak __irq_tamper - .globl __irq_tamper - .set __irq_tamper, __default_handler - .weak __irq_rtc - .globl __irq_rtc - .set __irq_rtc, __default_handler - .weak __irq_flash - .globl __irq_flash - .set __irq_flash, __default_handler - .weak __irq_rcc - .globl __irq_rcc - .set __irq_rcc, __default_handler - .weak __irq_exti0 - .globl __irq_exti0 - .set __irq_exti0, __default_handler - .weak __irq_exti1 - .globl __irq_exti1 - .set __irq_exti1, __default_handler - .weak __irq_exti2 - .globl __irq_exti2 - .set __irq_exti2, __default_handler - .weak __irq_exti3 - .globl __irq_exti3 - .set __irq_exti3, __default_handler - .weak __irq_exti4 - .globl __irq_exti4 - .set __irq_exti4, __default_handler - .weak __irq_dma1_channel1 - .globl __irq_dma1_channel1 - .set __irq_dma1_channel1, __default_handler - .weak __irq_dma1_channel2 - .globl __irq_dma1_channel2 - .set __irq_dma1_channel2, __default_handler - .weak __irq_dma1_channel3 - .globl __irq_dma1_channel3 - .set __irq_dma1_channel3, __default_handler - .weak __irq_dma1_channel4 - .globl __irq_dma1_channel4 - .set __irq_dma1_channel4, __default_handler - .weak __irq_dma1_channel5 - .globl __irq_dma1_channel5 - .set __irq_dma1_channel5, __default_handler - .weak __irq_dma1_channel6 - .globl __irq_dma1_channel6 - .set __irq_dma1_channel6, __default_handler - .weak __irq_dma1_channel7 - .globl __irq_dma1_channel7 - .set __irq_dma1_channel7, __default_handler - .weak __irq_adc - .globl __irq_adc - .set __irq_adc, __default_handler - .weak __irq_usb_hp_can_tx - .globl __irq_usb_hp_can_tx - .set __irq_usb_hp_can_tx, __default_handler - .weak __irq_usb_lp_can_rx0 - .globl __irq_usb_lp_can_rx0 - .set __irq_usb_lp_can_rx0, __default_handler - .weak __irq_can_rx1 - .globl __irq_can_rx1 - .set __irq_can_rx1, __default_handler - .weak __irq_can_sce - .globl __irq_can_sce - .set __irq_can_sce, __default_handler - .weak __irq_exti9_5 - .globl __irq_exti9_5 - .set __irq_exti9_5, __default_handler - .weak __irq_tim1_brk - .globl __irq_tim1_brk - .set __irq_tim1_brk, __default_handler - .weak __irq_tim1_up - .globl __irq_tim1_up - .set __irq_tim1_up, __default_handler - .weak __irq_tim1_trg_com - .globl __irq_tim1_trg_com - .set __irq_tim1_trg_com, __default_handler - .weak __irq_tim1_cc - .globl __irq_tim1_cc - .set __irq_tim1_cc, __default_handler - .weak __irq_tim2 - .globl __irq_tim2 - .set __irq_tim2, __default_handler - .weak __irq_tim3 - .globl __irq_tim3 - .set __irq_tim3, __default_handler - .weak __irq_tim4 - .globl __irq_tim4 - .set __irq_tim4, __default_handler - .weak __irq_i2c1_ev - .globl __irq_i2c1_ev - .set __irq_i2c1_ev, __default_handler - .weak __irq_i2c1_er - .globl __irq_i2c1_er - .set __irq_i2c1_er, __default_handler - .weak __irq_i2c2_ev - .globl __irq_i2c2_ev - .set __irq_i2c2_ev, __default_handler - .weak __irq_i2c2_er - .globl __irq_i2c2_er - .set __irq_i2c2_er, __default_handler - .weak __irq_spi1 - .globl __irq_spi1 - .set __irq_spi1, __default_handler - .weak __irq_spi2 - .globl __irq_spi2 - .set __irq_spi2, __default_handler - .weak __irq_usart1 - .globl __irq_usart1 - .set __irq_usart1, __default_handler - .weak __irq_usart2 - .globl __irq_usart2 - .set __irq_usart2, __default_handler - .weak __irq_usart3 - .globl __irq_usart3 - .set __irq_usart3, __default_handler - .weak __irq_exti15_10 - .globl __irq_exti15_10 - .set __irq_exti15_10, __default_handler - .weak __irq_rtcalarm - .globl __irq_rtcalarm - .set __irq_rtcalarm, __default_handler - .weak __irq_usbwakeup - .globl __irq_usbwakeup - .set __irq_usbwakeup, __default_handler -#if defined (STM32_HIGH_DENSITY) - .weak __irq_tim8_brk - .globl __irq_tim8_brk - .set __irq_tim8_brk, __default_handler - .weak __irq_tim8_up - .globl __irq_tim8_up - .set __irq_tim8_up, __default_handler - .weak __irq_tim8_trg_com - .globl __irq_tim8_trg_com - .set __irq_tim8_trg_com, __default_handler - .weak __irq_tim8_cc - .globl __irq_tim8_cc - .set __irq_tim8_cc, __default_handler - .weak __irq_adc3 - .globl __irq_adc3 - .set __irq_adc3, __default_handler - .weak __irq_fsmc - .globl __irq_fsmc - .set __irq_fsmc, __default_handler - .weak __irq_sdio - .globl __irq_sdio - .set __irq_sdio, __default_handler - .weak __irq_tim5 - .globl __irq_tim5 - .set __irq_tim5, __default_handler - .weak __irq_spi3 - .globl __irq_spi3 - .set __irq_spi3, __default_handler - .weak __irq_uart4 - .globl __irq_uart4 - .set __irq_uart4, __default_handler - .weak __irq_uart5 - .globl __irq_uart5 - .set __irq_uart5, __default_handler - .weak __irq_tim6 - .globl __irq_tim6 - .set __irq_tim6, __default_handler - .weak __irq_tim7 - .globl __irq_tim7 - .set __irq_tim7, __default_handler - .weak __irq_dma2_channel1 - .globl __irq_dma2_channel1 - .set __irq_dma2_channel1, __default_handler - .weak __irq_dma2_channel2 - .globl __irq_dma2_channel2 - .set __irq_dma2_channel2, __default_handler - .weak __irq_dma2_channel3 - .globl __irq_dma2_channel3 - .set __irq_dma2_channel3, __default_handler - .weak __irq_dma2_channel4_5 - .globl __irq_dma2_channel4_5 - .set __irq_dma2_channel4_5, __default_handler -#endif /* STM32_HIGH_DENSITY */ +/* STM32 ISR weak declarations */ + + .thumb + +/* Default handler for all non-overridden interrupts and exceptions */ + .globl __default_handler + .type __default_handler, %function + +__default_handler: + b . + + .weak __exc_nmi + .globl __exc_nmi + .set __exc_nmi, __default_handler + .weak __exc_hardfault + .globl __exc_hardfault + .set __exc_hardfault, __default_handler + .weak __exc_memmanage + .globl __exc_memmanage + .set __exc_memmanage, __default_handler + .weak __exc_busfault + .globl __exc_busfault + .set __exc_busfault, __default_handler + .weak __exc_usagefault + .globl __exc_usagefault + .set __exc_usagefault, __default_handler + .weak __stm32reservedexception7 + .globl __stm32reservedexception7 + .set __stm32reservedexception7, __default_handler + .weak __stm32reservedexception8 + .globl __stm32reservedexception8 + .set __stm32reservedexception8, __default_handler + .weak __stm32reservedexception9 + .globl __stm32reservedexception9 + .set __stm32reservedexception9, __default_handler + .weak __stm32reservedexception10 + .globl __stm32reservedexception10 + .set __stm32reservedexception10, __default_handler + .weak __exc_svc + .globl __exc_svc + .set __exc_svc, __default_handler + .weak __exc_debug_monitor + .globl __exc_debug_monitor + .set __exc_debug_monitor, __default_handler + .weak __stm32reservedexception13 + .globl __stm32reservedexception13 + .set __stm32reservedexception13, __default_handler + .weak __exc_pendsv + .globl __exc_pendsv + .set __exc_pendsv, __default_handler + .weak __exc_systick + .globl __exc_systick + .set __exc_systick, __default_handler + .weak __irq_wwdg + .globl __irq_wwdg + .set __irq_wwdg, __default_handler + .weak __irq_pvd + .globl __irq_pvd + .set __irq_pvd, __default_handler + .weak __irq_tamper + .globl __irq_tamper + .set __irq_tamper, __default_handler + .weak __irq_rtc + .globl __irq_rtc + .set __irq_rtc, __default_handler + .weak __irq_flash + .globl __irq_flash + .set __irq_flash, __default_handler + .weak __irq_rcc + .globl __irq_rcc + .set __irq_rcc, __default_handler + .weak __irq_exti0 + .globl __irq_exti0 + .set __irq_exti0, __default_handler + .weak __irq_exti1 + .globl __irq_exti1 + .set __irq_exti1, __default_handler + .weak __irq_exti2 + .globl __irq_exti2 + .set __irq_exti2, __default_handler + .weak __irq_exti3 + .globl __irq_exti3 + .set __irq_exti3, __default_handler + .weak __irq_exti4 + .globl __irq_exti4 + .set __irq_exti4, __default_handler + .weak __irq_dma1_channel1 + .globl __irq_dma1_channel1 + .set __irq_dma1_channel1, __default_handler + .weak __irq_dma1_channel2 + .globl __irq_dma1_channel2 + .set __irq_dma1_channel2, __default_handler + .weak __irq_dma1_channel3 + .globl __irq_dma1_channel3 + .set __irq_dma1_channel3, __default_handler + .weak __irq_dma1_channel4 + .globl __irq_dma1_channel4 + .set __irq_dma1_channel4, __default_handler + .weak __irq_dma1_channel5 + .globl __irq_dma1_channel5 + .set __irq_dma1_channel5, __default_handler + .weak __irq_dma1_channel6 + .globl __irq_dma1_channel6 + .set __irq_dma1_channel6, __default_handler + .weak __irq_dma1_channel7 + .globl __irq_dma1_channel7 + .set __irq_dma1_channel7, __default_handler + .weak __irq_adc + .globl __irq_adc + .set __irq_adc, __default_handler + .weak __irq_usb_hp_can_tx + .globl __irq_usb_hp_can_tx + .set __irq_usb_hp_can_tx, __default_handler + .weak __irq_usb_lp_can_rx0 + .globl __irq_usb_lp_can_rx0 + .set __irq_usb_lp_can_rx0, __default_handler + .weak __irq_can_rx1 + .globl __irq_can_rx1 + .set __irq_can_rx1, __default_handler + .weak __irq_can_sce + .globl __irq_can_sce + .set __irq_can_sce, __default_handler + .weak __irq_exti9_5 + .globl __irq_exti9_5 + .set __irq_exti9_5, __default_handler + .weak __irq_tim1_brk + .globl __irq_tim1_brk + .set __irq_tim1_brk, __default_handler + .weak __irq_tim1_up + .globl __irq_tim1_up + .set __irq_tim1_up, __default_handler + .weak __irq_tim1_trg_com + .globl __irq_tim1_trg_com + .set __irq_tim1_trg_com, __default_handler + .weak __irq_tim1_cc + .globl __irq_tim1_cc + .set __irq_tim1_cc, __default_handler + .weak __irq_tim2 + .globl __irq_tim2 + .set __irq_tim2, __default_handler + .weak __irq_tim3 + .globl __irq_tim3 + .set __irq_tim3, __default_handler + .weak __irq_tim4 + .globl __irq_tim4 + .set __irq_tim4, __default_handler + .weak __irq_i2c1_ev + .globl __irq_i2c1_ev + .set __irq_i2c1_ev, __default_handler + .weak __irq_i2c1_er + .globl __irq_i2c1_er + .set __irq_i2c1_er, __default_handler + .weak __irq_i2c2_ev + .globl __irq_i2c2_ev + .set __irq_i2c2_ev, __default_handler + .weak __irq_i2c2_er + .globl __irq_i2c2_er + .set __irq_i2c2_er, __default_handler + .weak __irq_spi1 + .globl __irq_spi1 + .set __irq_spi1, __default_handler + .weak __irq_spi2 + .globl __irq_spi2 + .set __irq_spi2, __default_handler + .weak __irq_usart1 + .globl __irq_usart1 + .set __irq_usart1, __default_handler + .weak __irq_usart2 + .globl __irq_usart2 + .set __irq_usart2, __default_handler + .weak __irq_usart3 + .globl __irq_usart3 + .set __irq_usart3, __default_handler + .weak __irq_exti15_10 + .globl __irq_exti15_10 + .set __irq_exti15_10, __default_handler + .weak __irq_rtcalarm + .globl __irq_rtcalarm + .set __irq_rtcalarm, __default_handler + .weak __irq_usbwakeup + .globl __irq_usbwakeup + .set __irq_usbwakeup, __default_handler +#if defined (STM32_HIGH_DENSITY) + .weak __irq_tim8_brk + .globl __irq_tim8_brk + .set __irq_tim8_brk, __default_handler + .weak __irq_tim8_up + .globl __irq_tim8_up + .set __irq_tim8_up, __default_handler + .weak __irq_tim8_trg_com + .globl __irq_tim8_trg_com + .set __irq_tim8_trg_com, __default_handler + .weak __irq_tim8_cc + .globl __irq_tim8_cc + .set __irq_tim8_cc, __default_handler + .weak __irq_adc3 + .globl __irq_adc3 + .set __irq_adc3, __default_handler + .weak __irq_fsmc + .globl __irq_fsmc + .set __irq_fsmc, __default_handler + .weak __irq_sdio + .globl __irq_sdio + .set __irq_sdio, __default_handler + .weak __irq_tim5 + .globl __irq_tim5 + .set __irq_tim5, __default_handler + .weak __irq_spi3 + .globl __irq_spi3 + .set __irq_spi3, __default_handler + .weak __irq_uart4 + .globl __irq_uart4 + .set __irq_uart4, __default_handler + .weak __irq_uart5 + .globl __irq_uart5 + .set __irq_uart5, __default_handler + .weak __irq_tim6 + .globl __irq_tim6 + .set __irq_tim6, __default_handler + .weak __irq_tim7 + .globl __irq_tim7 + .set __irq_tim7, __default_handler + .weak __irq_dma2_channel1 + .globl __irq_dma2_channel1 + .set __irq_dma2_channel1, __default_handler + .weak __irq_dma2_channel2 + .globl __irq_dma2_channel2 + .set __irq_dma2_channel2, __default_handler + .weak __irq_dma2_channel3 + .globl __irq_dma2_channel3 + .set __irq_dma2_channel3, __default_handler + .weak __irq_dma2_channel4_5 + .globl __irq_dma2_channel4_5 + .set __irq_dma2_channel4_5, __default_handler +#endif /* STM32_HIGH_DENSITY */ diff --git a/Libmaple/libmaple/support/ld/libcs3_stm32_src/stm32_vector_table.S b/Libmaple/libmaple/support/ld/libcs3_stm32_src/stm32_vector_table.S index 3055d394..7067d950 100644 --- a/Libmaple/libmaple/support/ld/libcs3_stm32_src/stm32_vector_table.S +++ b/Libmaple/libmaple/support/ld/libcs3_stm32_src/stm32_vector_table.S @@ -1,90 +1,90 @@ -/* STM32 vector table */ - - .section ".stm32.interrupt_vector" - - .globl __cs3_stm32_vector_table - .type __cs3_stm32_vector_table, %object - -__cs3_stm32_vector_table: -/* CM3 core interrupts */ - .long __cs3_stack - .long __cs3_reset - .long __exc_nmi - .long __exc_hardfault - .long __exc_memmanage - .long __exc_busfault - .long __exc_usagefault - .long __stm32reservedexception7 - .long __stm32reservedexception8 - .long __stm32reservedexception9 - .long __stm32reservedexception10 - .long __exc_svc - .long __exc_debug_monitor - .long __stm32reservedexception13 - .long __exc_pendsv - .long __exc_systick -/* Peripheral interrupts */ - .long __irq_wwdg - .long __irq_pvd - .long __irq_tamper - .long __irq_rtc - .long __irq_flash - .long __irq_rcc - .long __irq_exti0 - .long __irq_exti1 - .long __irq_exti2 - .long __irq_exti3 - .long __irq_exti4 - .long __irq_dma1_channel1 - .long __irq_dma1_channel2 - .long __irq_dma1_channel3 - .long __irq_dma1_channel4 - .long __irq_dma1_channel5 - .long __irq_dma1_channel6 - .long __irq_dma1_channel7 - .long __irq_adc - .long __irq_usb_hp_can_tx - .long __irq_usb_lp_can_rx0 - .long __irq_can_rx1 - .long __irq_can_sce - .long __irq_exti9_5 - .long __irq_tim1_brk - .long __irq_tim1_up - .long __irq_tim1_trg_com - .long __irq_tim1_cc - .long __irq_tim2 - .long __irq_tim3 - .long __irq_tim4 - .long __irq_i2c1_ev - .long __irq_i2c1_er - .long __irq_i2c2_ev - .long __irq_i2c2_er - .long __irq_spi1 - .long __irq_spi2 - .long __irq_usart1 - .long __irq_usart2 - .long __irq_usart3 - .long __irq_exti15_10 - .long __irq_rtcalarm - .long __irq_usbwakeup -#if defined (STM32_HIGH_DENSITY) - .long __irq_tim8_brk - .long __irq_tim8_up - .long __irq_tim8_trg_com - .long __irq_tim8_cc - .long __irq_adc3 - .long __irq_fsmc - .long __irq_sdio - .long __irq_tim5 - .long __irq_spi3 - .long __irq_uart4 - .long __irq_uart5 - .long __irq_tim6 - .long __irq_tim7 - .long __irq_dma2_channel1 - .long __irq_dma2_channel2 - .long __irq_dma2_channel3 - .long __irq_dma2_channel4_5 -#endif /* STM32_HIGH_DENSITY */ - - .size __cs3_stm32_vector_table, . - __cs3_stm32_vector_table +/* STM32 vector table */ + + .section ".stm32.interrupt_vector" + + .globl __cs3_stm32_vector_table + .type __cs3_stm32_vector_table, %object + +__cs3_stm32_vector_table: +/* CM3 core interrupts */ + .long __cs3_stack + .long __cs3_reset + .long __exc_nmi + .long __exc_hardfault + .long __exc_memmanage + .long __exc_busfault + .long __exc_usagefault + .long __stm32reservedexception7 + .long __stm32reservedexception8 + .long __stm32reservedexception9 + .long __stm32reservedexception10 + .long __exc_svc + .long __exc_debug_monitor + .long __stm32reservedexception13 + .long __exc_pendsv + .long __exc_systick +/* Peripheral interrupts */ + .long __irq_wwdg + .long __irq_pvd + .long __irq_tamper + .long __irq_rtc + .long __irq_flash + .long __irq_rcc + .long __irq_exti0 + .long __irq_exti1 + .long __irq_exti2 + .long __irq_exti3 + .long __irq_exti4 + .long __irq_dma1_channel1 + .long __irq_dma1_channel2 + .long __irq_dma1_channel3 + .long __irq_dma1_channel4 + .long __irq_dma1_channel5 + .long __irq_dma1_channel6 + .long __irq_dma1_channel7 + .long __irq_adc + .long __irq_usb_hp_can_tx + .long __irq_usb_lp_can_rx0 + .long __irq_can_rx1 + .long __irq_can_sce + .long __irq_exti9_5 + .long __irq_tim1_brk + .long __irq_tim1_up + .long __irq_tim1_trg_com + .long __irq_tim1_cc + .long __irq_tim2 + .long __irq_tim3 + .long __irq_tim4 + .long __irq_i2c1_ev + .long __irq_i2c1_er + .long __irq_i2c2_ev + .long __irq_i2c2_er + .long __irq_spi1 + .long __irq_spi2 + .long __irq_usart1 + .long __irq_usart2 + .long __irq_usart3 + .long __irq_exti15_10 + .long __irq_rtcalarm + .long __irq_usbwakeup +#if defined (STM32_HIGH_DENSITY) + .long __irq_tim8_brk + .long __irq_tim8_up + .long __irq_tim8_trg_com + .long __irq_tim8_cc + .long __irq_adc3 + .long __irq_fsmc + .long __irq_sdio + .long __irq_tim5 + .long __irq_spi3 + .long __irq_uart4 + .long __irq_uart5 + .long __irq_tim6 + .long __irq_tim7 + .long __irq_dma2_channel1 + .long __irq_dma2_channel2 + .long __irq_dma2_channel3 + .long __irq_dma2_channel4_5 +#endif /* STM32_HIGH_DENSITY */ + + .size __cs3_stm32_vector_table, . - __cs3_stm32_vector_table diff --git a/Libmaple/libmaple/support/ld/libcs4_stm32_src/Makefile b/Libmaple/libmaple/support/ld/libcs4_stm32_src/Makefile index 9054a413..d3fd2a3a 100644 --- a/Libmaple/libmaple/support/ld/libcs4_stm32_src/Makefile +++ b/Libmaple/libmaple/support/ld/libcs4_stm32_src/Makefile @@ -1,36 +1,36 @@ -# setup environment - -TARGET_ARCH = -mcpu=cortex-m4 -mthumb - -CC = arm-none-eabi-gcc -CFLAGS = - -AS = $(CC) -x assembler-with-cpp -c $(TARGET_ARCH) -ASFLAGS = - -AR = arm-none-eabi-ar -ARFLAGS = cr - -LIB_OBJS = stm32_vector_table.o stm32_isrs.o start.o start_c.o - -help: - @echo "Targets:" - @echo "\t medium-density: Target medium density chips (e.g. Maple)" - @echo "\t high-density: Target high density chips (e.g. Maple-native)" - -.PHONY: help medium high - -medium-density: $(LIB_OBJS) - $(AR) $(ARFLAGS) libcs3_stm32_med_density.a $(LIB_OBJS) - rm -f $(LIB_OBJS) - -high-density: CFLAGS := -DSTM32_HIGH_DENSITY -high-density: ASFLAGS := -DSTM32_HIGH_DENSITY -high-density: $(LIB_OBJS) - $(AR) $(ARFLAGS) libcs4_stm32_high_density.a $(LIB_OBJS) - rm -f $(LIB_OBJS) - -# clean -.PHONY: clean -clean: - -rm -f $(LIB_OBJS) *.a +# setup environment + +TARGET_ARCH = -mcpu=cortex-m4 -mthumb + +CC = arm-none-eabi-gcc +CFLAGS = + +AS = $(CC) -x assembler-with-cpp -c $(TARGET_ARCH) +ASFLAGS = + +AR = arm-none-eabi-ar +ARFLAGS = cr + +LIB_OBJS = stm32_vector_table.o stm32_isrs.o start.o start_c.o + +help: + @echo "Targets:" + @echo "\t medium-density: Target medium density chips (e.g. Maple)" + @echo "\t high-density: Target high density chips (e.g. Maple-native)" + +.PHONY: help medium high + +medium-density: $(LIB_OBJS) + $(AR) $(ARFLAGS) libcs3_stm32_med_density.a $(LIB_OBJS) + rm -f $(LIB_OBJS) + +high-density: CFLAGS := -DSTM32_HIGH_DENSITY +high-density: ASFLAGS := -DSTM32_HIGH_DENSITY +high-density: $(LIB_OBJS) + $(AR) $(ARFLAGS) libcs4_stm32_high_density.a $(LIB_OBJS) + rm -f $(LIB_OBJS) + +# clean +.PHONY: clean +clean: + -rm -f $(LIB_OBJS) *.a diff --git a/Libmaple/libmaple/support/ld/libcs4_stm32_src/start.S b/Libmaple/libmaple/support/ld/libcs4_stm32_src/start.S index ed41dda6..00c2a100 100644 --- a/Libmaple/libmaple/support/ld/libcs4_stm32_src/start.S +++ b/Libmaple/libmaple/support/ld/libcs4_stm32_src/start.S @@ -1,38 +1,38 @@ -/* - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ - - .text - .code 16 - .thumb_func - - .globl _start - .type _start, %function -_start: - .fnstart - - - //;FPU settings - ldr r0, =0xe000ed88 //; enable cp10,cp11 - ldr r1,[r0] - ldr r2, =0xf00000 - orr r1,r1,r2 - str r1,[r0] - - - - ldr r1,=__cs3_stack - mov sp,r1 - ldr r1,=__cs3_start_c - bx r1 - .pool - .cantunwind - .fnend +/* + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + + .text + .code 16 + .thumb_func + + .globl _start + .type _start, %function +_start: + .fnstart + + + //;FPU settings + ldr r0, =0xe000ed88 //; enable cp10,cp11 + ldr r1,[r0] + ldr r2, =0xf00000 + orr r1,r1,r2 + str r1,[r0] + + + + ldr r1,=__cs3_stack + mov sp,r1 + ldr r1,=__cs3_start_c + bx r1 + .pool + .cantunwind + .fnend diff --git a/Libmaple/libmaple/support/ld/libcs4_stm32_src/start_c.c b/Libmaple/libmaple/support/ld/libcs4_stm32_src/start_c.c index dff9fa34..2ab0212b 100644 --- a/Libmaple/libmaple/support/ld/libcs4_stm32_src/start_c.c +++ b/Libmaple/libmaple/support/ld/libcs4_stm32_src/start_c.c @@ -1,58 +1,58 @@ -/* CS3 start_c routine. - * - * Copyright (c) 2006, 2007 CodeSourcery Inc - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ - -#include "cs3.h" - -extern void __libc_init_array (void); - -extern int main (int, char **, char **); - -extern void exit (int) __attribute__ ((noreturn, weak)); - -void __attribute ((noreturn)) -__cs3_start_c (void) -{ - unsigned regions = __cs3_region_num; - const struct __cs3_region *rptr = __cs3_regions; - int exit_code; - - /* Initialize memory */ - for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) - { - long long *src = (long long *)rptr->init; - long long *dst = (long long *)rptr->data; - unsigned limit = rptr->init_size; - unsigned count; - - if (src != dst) - for (count = 0; count != limit; count += sizeof (long long)) - *dst++ = *src++; - else - dst = (long long *)((char *)dst + limit); - limit = rptr->zero_size; - for (count = 0; count != limit; count += sizeof (long long)) - *dst++ = 0; - } - - /* Run initializers. */ - __libc_init_array (); - - exit_code = main (0, NULL, NULL); - if (exit) - exit (exit_code); - /* If exit is NULL, make sure we don't return. */ - for (;;) - continue; -} +/* CS3 start_c routine. + * + * Copyright (c) 2006, 2007 CodeSourcery Inc + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include "cs3.h" + +extern void __libc_init_array (void); + +extern int main (int, char **, char **); + +extern void exit (int) __attribute__ ((noreturn, weak)); + +void __attribute ((noreturn)) +__cs3_start_c (void) +{ + unsigned regions = __cs3_region_num; + const struct __cs3_region *rptr = __cs3_regions; + int exit_code; + + /* Initialize memory */ + for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) + { + long long *src = (long long *)rptr->init; + long long *dst = (long long *)rptr->data; + unsigned limit = rptr->init_size; + unsigned count; + + if (src != dst) + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = *src++; + else + dst = (long long *)((char *)dst + limit); + limit = rptr->zero_size; + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = 0; + } + + /* Run initializers. */ + __libc_init_array (); + + exit_code = main (0, NULL, NULL); + if (exit) + exit (exit_code); + /* If exit is NULL, make sure we don't return. */ + for (;;) + continue; +} diff --git a/Libmaple/libmaple/support/ld/libcs4_stm32_src/stm32_isrs.S b/Libmaple/libmaple/support/ld/libcs4_stm32_src/stm32_isrs.S index 647ad506..34e515c0 100644 --- a/Libmaple/libmaple/support/ld/libcs4_stm32_src/stm32_isrs.S +++ b/Libmaple/libmaple/support/ld/libcs4_stm32_src/stm32_isrs.S @@ -1,323 +1,323 @@ -/* STM32 ISR weak declarations */ - - .thumb - -/* Default handler for all non-overridden interrupts and exceptions */ - .globl __default_handler - .type __default_handler, %function - -__default_handler: - b . - - .weak __exc_nmi - .globl __exc_nmi - .set __exc_nmi, __default_handler - .weak __exc_hardfault - .globl __exc_hardfault - .set __exc_hardfault, __default_handler - .weak __exc_memmanage - .globl __exc_memmanage - .set __exc_memmanage, __default_handler - .weak __exc_busfault - .globl __exc_busfault - .set __exc_busfault, __default_handler - .weak __exc_usagefault - .globl __exc_usagefault - .set __exc_usagefault, __default_handler - .weak __stm32reservedexception7 - .globl __stm32reservedexception7 - .set __stm32reservedexception7, __default_handler - .weak __stm32reservedexception8 - .globl __stm32reservedexception8 - .set __stm32reservedexception8, __default_handler - .weak __stm32reservedexception9 - .globl __stm32reservedexception9 - .set __stm32reservedexception9, __default_handler - .weak __stm32reservedexception10 - .globl __stm32reservedexception10 - .set __stm32reservedexception10, __default_handler - .weak __exc_svc - .globl __exc_svc - .set __exc_svc, __default_handler - .weak __exc_debug_monitor - .globl __exc_debug_monitor - .set __exc_debug_monitor, __default_handler - .weak __stm32reservedexception13 - .globl __stm32reservedexception13 - .set __stm32reservedexception13, __default_handler - .weak __exc_pendsv - .globl __exc_pendsv - .set __exc_pendsv, __default_handler - .weak __exc_systick - .globl __exc_systick - .set __exc_systick, __default_handler - .weak __irq_wwdg - .globl __irq_wwdg - .set __irq_wwdg, __default_handler - .weak __irq_pvd - .globl __irq_pvd - .set __irq_pvd, __default_handler - .weak __irq_tamper - .globl __irq_tamper - .set __irq_tamper, __default_handler - .weak __irq_rtc - .globl __irq_rtc - .set __irq_rtc, __default_handler - .weak __irq_flash - .globl __irq_flash - .set __irq_flash, __default_handler - .weak __irq_rcc - .globl __irq_rcc - .set __irq_rcc, __default_handler - .weak __irq_exti0 - .globl __irq_exti0 - .set __irq_exti0, __default_handler - .weak __irq_exti1 - .globl __irq_exti1 - .set __irq_exti1, __default_handler - .weak __irq_exti2 - .globl __irq_exti2 - .set __irq_exti2, __default_handler - .weak __irq_exti3 - .globl __irq_exti3 - .set __irq_exti3, __default_handler - .weak __irq_exti4 - .globl __irq_exti4 - .set __irq_exti4, __default_handler - .weak __irq_dma1_channel1 - .globl __irq_dma1_channel1 - .set __irq_dma1_channel1, __default_handler - .weak __irq_dma1_channel2 - .globl __irq_dma1_channel2 - .set __irq_dma1_channel2, __default_handler - .weak __irq_dma1_channel3 - .globl __irq_dma1_channel3 - .set __irq_dma1_channel3, __default_handler - .weak __irq_dma1_channel4 - .globl __irq_dma1_channel4 - .set __irq_dma1_channel4, __default_handler - .weak __irq_dma1_channel5 - .globl __irq_dma1_channel5 - .set __irq_dma1_channel5, __default_handler - .weak __irq_dma1_channel6 - .globl __irq_dma1_channel6 - .set __irq_dma1_channel6, __default_handler - .weak __irq_dma1_channel7 - .globl __irq_dma1_channel7 - .set __irq_dma1_channel7, __default_handler - .weak __irq_adc - .globl __irq_adc - .set __irq_adc, __default_handler - .weak __irq_usb_hp_can_tx - .globl __irq_usb_hp_can_tx - .set __irq_usb_hp_can_tx, __default_handler - .weak __irq_usb_lp_can_rx0 - .globl __irq_usb_lp_can_rx0 - .set __irq_usb_lp_can_rx0, __default_handler - .weak __irq_can_rx1 - .globl __irq_can_rx1 - .set __irq_can_rx1, __default_handler - .weak __irq_can_sce - .globl __irq_can_sce - .set __irq_can_sce, __default_handler - .weak __irq_exti9_5 - .globl __irq_exti9_5 - .set __irq_exti9_5, __default_handler - .weak __irq_tim1_brk - .globl __irq_tim1_brk - .set __irq_tim1_brk, __default_handler - .weak __irq_tim1_up - .globl __irq_tim1_up - .set __irq_tim1_up, __default_handler - .weak __irq_tim1_trg_com - .globl __irq_tim1_trg_com - .set __irq_tim1_trg_com, __default_handler - .weak __irq_tim1_cc - .globl __irq_tim1_cc - .set __irq_tim1_cc, __default_handler - .weak __irq_tim2 - .globl __irq_tim2 - .set __irq_tim2, __default_handler - .weak __irq_tim3 - .globl __irq_tim3 - .set __irq_tim3, __default_handler - .weak __irq_tim4 - .globl __irq_tim4 - .set __irq_tim4, __default_handler - .weak __irq_i2c1_ev - .globl __irq_i2c1_ev - .set __irq_i2c1_ev, __default_handler - .weak __irq_i2c1_er - .globl __irq_i2c1_er - .set __irq_i2c1_er, __default_handler - .weak __irq_i2c2_ev - .globl __irq_i2c2_ev - .set __irq_i2c2_ev, __default_handler - .weak __irq_i2c2_er - .globl __irq_i2c2_er - .set __irq_i2c2_er, __default_handler - .weak __irq_spi1 - .globl __irq_spi1 - .set __irq_spi1, __default_handler - .weak __irq_spi2 - .globl __irq_spi2 - .set __irq_spi2, __default_handler - .weak __irq_usart1 - .globl __irq_usart1 - .set __irq_usart1, __default_handler - .weak __irq_usart2 - .globl __irq_usart2 - .set __irq_usart2, __default_handler - .weak __irq_usart3 - .globl __irq_usart3 - .set __irq_usart3, __default_handler - .weak __irq_exti15_10 - .globl __irq_exti15_10 - .set __irq_exti15_10, __default_handler - .weak __irq_rtcalarm - .globl __irq_rtcalarm - .set __irq_rtcalarm, __default_handler - .weak __irq_usbwakeup - .globl __irq_usbwakeup - .set __irq_usbwakeup, __default_handler -#if defined (STM32_HIGH_DENSITY) - .weak __irq_tim8_brk - .globl __irq_tim8_brk - .set __irq_tim8_brk, __default_handler - .weak __irq_tim8_up - .globl __irq_tim8_up - .set __irq_tim8_up, __default_handler - .weak __irq_tim8_trg_com - .globl __irq_tim8_trg_com - .set __irq_tim8_trg_com, __default_handler - .weak __irq_tim8_cc - .globl __irq_tim8_cc - .set __irq_tim8_cc, __default_handler - .weak __irq_adc3 - .globl __irq_adc3 - .set __irq_adc3, __default_handler - .weak __irq_fsmc - .globl __irq_fsmc - .set __irq_fsmc, __default_handler - .weak __irq_sdio - .globl __irq_sdio - .set __irq_sdio, __default_handler - .weak __irq_tim5 - .globl __irq_tim5 - .set __irq_tim5, __default_handler - .weak __irq_spi3 - .globl __irq_spi3 - .set __irq_spi3, __default_handler - .weak __irq_uart4 - .globl __irq_uart4 - .set __irq_uart4, __default_handler - .weak __irq_uart5 - .globl __irq_uart5 - .set __irq_uart5, __default_handler - .weak __irq_tim6 - .globl __irq_tim6 - .set __irq_tim6, __default_handler - .weak __irq_tim7 - .globl __irq_tim7 - .set __irq_tim7, __default_handler - .weak __irq_dma2_channel1 - .globl __irq_dma2_channel1 - .set __irq_dma2_channel1, __default_handler - .weak __irq_dma2_channel2 - .globl __irq_dma2_channel2 - .set __irq_dma2_channel2, __default_handler - .weak __irq_dma2_channel3 - .globl __irq_dma2_channel3 - .set __irq_dma2_channel3, __default_handler - .weak __irq_dma2_channel4_5 - .globl __irq_dma2_channel4_5 - .set __irq_dma2_channel4_5, __default_handler -#endif /* STM32_HIGH_DENSITY */ - - .weak __irq_DMA2_Stream4_IRQHandler - .globl __irq_DMA2_Stream4_IRQHandler - .set __irq_DMA2_Stream4_IRQHandler, __default_handler - - .weak __irq_ETH_IRQHandler - .globl __irq_ETH_IRQHandler - .set __irq_ETH_IRQHandler, __default_handler - - .weak __irq_ETH_WKUP_IRQHandler - .globl __irq_ETH_WKUP_IRQHandler - .set __irq_ETH_WKUP_IRQHandler, __default_handler - - .weak __irq_CAN2_TX_IRQHandler - .globl __irq_CAN2_TX_IRQHandler - .set __irq_CAN2_TX_IRQHandler, __default_handler - - .weak __irq_CAN2_RX0_IRQHandler - .globl __irq_CAN2_RX0_IRQHandler - .set __irq_CAN2_RX0_IRQHandler, __default_handler - - .weak __irq_CAN2_RX1_IRQHandler - .globl __irq_CAN2_RX1_IRQHandler - .set __irq_CAN2_RX1_IRQHandler, __default_handler - - .weak __irq_CAN2_SCE_IRQHandler - .globl __irq_CAN2_SCE_IRQHandler - .set __irq_CAN2_SCE_IRQHandler, __default_handler - - .weak __irq_OTG_FS_IRQHandler - .globl __irq_OTG_FS_IRQHandler - .set __irq_OTG_FS_IRQHandler, __default_handler - - .weak __irq_DMA2_Stream5_IRQHandler - .globl __irq_DMA2_Stream5_IRQHandler - .set __irq_DMA2_Stream5_IRQHandler, __default_handler - - .weak __irq_DMA2_Stream6_IRQHandler - .globl __irq_DMA2_Stream6_IRQHandler - .set __irq_DMA2_Stream6_IRQHandler, __default_handler - - .weak __irq_DMA2_Stream7_IRQHandler - .globl __irq_DMA2_Stream7_IRQHandler - .set __irq_DMA2_Stream7_IRQHandler, __default_handler - - .weak __irq_USART6_IRQHandler - .globl __irq_USART6_IRQHandler - .set __irq_USART6_IRQHandler, __default_handler - - .weak __irq_I2C3_EV_IRQHandler - .globl __irq_I2C3_EV_IRQHandler - .set __irq_I2C3_EV_IRQHandler, __default_handler - - .weak __irq_I2C3_ER_IRQHandler - .globl __irq_I2C3_ER_IRQHandler - .set __irq_I2C3_ER_IRQHandler, __default_handler - - .weak __irq_OTG_HS_EP1_OUT_IRQHandler - .globl __irq_OTG_HS_EP1_OUT_IRQHandler - .set __irq_OTG_HS_EP1_OUT_IRQHandler, __default_handler - - .weak __irq_OTG_HS_EP1_IN_IRQHandler - .globl __irq_OTG_HS_EP1_IN_IRQHandler - .set __irq_OTG_HS_EP1_IN_IRQHandler, __default_handler - - .weak __irq_OTG_HS_WKUP_IRQHandler - .globl __irq_OTG_HS_WKUP_IRQHandler - .set __irq_OTG_HS_WKUP_IRQHandler, __default_handler - - .weak __irq_OTG_HS_IRQHandler - .globl __irq_OTG_HS_IRQHandler - .set __irq_OTG_HS_IRQHandler, __default_handler - - .weak __irq_DCMI_IRQHandler - .globl __irq_DCMI_IRQHandler - .set __irq_DCMI_IRQHandler, __default_handler - - .weak __irq_CRYP_IRQHandler - .globl __irq_CRYP_IRQHandler - .set __irq_CRYP_IRQHandler, __default_handler - - .weak __irq_HASH_RNG_IRQHandler - .globl __irq_HASH_RNG_IRQHandler - .set __irq_HASH_RNG_IRQHandler, __default_handler - - .weak __irq_FPU_IRQHandler - .globl __irq_FPU_IRQHandler - .set __irq_FPU_IRQHandler, __default_handler +/* STM32 ISR weak declarations */ + + .thumb + +/* Default handler for all non-overridden interrupts and exceptions */ + .globl __default_handler + .type __default_handler, %function + +__default_handler: + b . + + .weak __exc_nmi + .globl __exc_nmi + .set __exc_nmi, __default_handler + .weak __exc_hardfault + .globl __exc_hardfault + .set __exc_hardfault, __default_handler + .weak __exc_memmanage + .globl __exc_memmanage + .set __exc_memmanage, __default_handler + .weak __exc_busfault + .globl __exc_busfault + .set __exc_busfault, __default_handler + .weak __exc_usagefault + .globl __exc_usagefault + .set __exc_usagefault, __default_handler + .weak __stm32reservedexception7 + .globl __stm32reservedexception7 + .set __stm32reservedexception7, __default_handler + .weak __stm32reservedexception8 + .globl __stm32reservedexception8 + .set __stm32reservedexception8, __default_handler + .weak __stm32reservedexception9 + .globl __stm32reservedexception9 + .set __stm32reservedexception9, __default_handler + .weak __stm32reservedexception10 + .globl __stm32reservedexception10 + .set __stm32reservedexception10, __default_handler + .weak __exc_svc + .globl __exc_svc + .set __exc_svc, __default_handler + .weak __exc_debug_monitor + .globl __exc_debug_monitor + .set __exc_debug_monitor, __default_handler + .weak __stm32reservedexception13 + .globl __stm32reservedexception13 + .set __stm32reservedexception13, __default_handler + .weak __exc_pendsv + .globl __exc_pendsv + .set __exc_pendsv, __default_handler + .weak __exc_systick + .globl __exc_systick + .set __exc_systick, __default_handler + .weak __irq_wwdg + .globl __irq_wwdg + .set __irq_wwdg, __default_handler + .weak __irq_pvd + .globl __irq_pvd + .set __irq_pvd, __default_handler + .weak __irq_tamper + .globl __irq_tamper + .set __irq_tamper, __default_handler + .weak __irq_rtc + .globl __irq_rtc + .set __irq_rtc, __default_handler + .weak __irq_flash + .globl __irq_flash + .set __irq_flash, __default_handler + .weak __irq_rcc + .globl __irq_rcc + .set __irq_rcc, __default_handler + .weak __irq_exti0 + .globl __irq_exti0 + .set __irq_exti0, __default_handler + .weak __irq_exti1 + .globl __irq_exti1 + .set __irq_exti1, __default_handler + .weak __irq_exti2 + .globl __irq_exti2 + .set __irq_exti2, __default_handler + .weak __irq_exti3 + .globl __irq_exti3 + .set __irq_exti3, __default_handler + .weak __irq_exti4 + .globl __irq_exti4 + .set __irq_exti4, __default_handler + .weak __irq_dma1_channel1 + .globl __irq_dma1_channel1 + .set __irq_dma1_channel1, __default_handler + .weak __irq_dma1_channel2 + .globl __irq_dma1_channel2 + .set __irq_dma1_channel2, __default_handler + .weak __irq_dma1_channel3 + .globl __irq_dma1_channel3 + .set __irq_dma1_channel3, __default_handler + .weak __irq_dma1_channel4 + .globl __irq_dma1_channel4 + .set __irq_dma1_channel4, __default_handler + .weak __irq_dma1_channel5 + .globl __irq_dma1_channel5 + .set __irq_dma1_channel5, __default_handler + .weak __irq_dma1_channel6 + .globl __irq_dma1_channel6 + .set __irq_dma1_channel6, __default_handler + .weak __irq_dma1_channel7 + .globl __irq_dma1_channel7 + .set __irq_dma1_channel7, __default_handler + .weak __irq_adc + .globl __irq_adc + .set __irq_adc, __default_handler + .weak __irq_usb_hp_can_tx + .globl __irq_usb_hp_can_tx + .set __irq_usb_hp_can_tx, __default_handler + .weak __irq_usb_lp_can_rx0 + .globl __irq_usb_lp_can_rx0 + .set __irq_usb_lp_can_rx0, __default_handler + .weak __irq_can_rx1 + .globl __irq_can_rx1 + .set __irq_can_rx1, __default_handler + .weak __irq_can_sce + .globl __irq_can_sce + .set __irq_can_sce, __default_handler + .weak __irq_exti9_5 + .globl __irq_exti9_5 + .set __irq_exti9_5, __default_handler + .weak __irq_tim1_brk + .globl __irq_tim1_brk + .set __irq_tim1_brk, __default_handler + .weak __irq_tim1_up + .globl __irq_tim1_up + .set __irq_tim1_up, __default_handler + .weak __irq_tim1_trg_com + .globl __irq_tim1_trg_com + .set __irq_tim1_trg_com, __default_handler + .weak __irq_tim1_cc + .globl __irq_tim1_cc + .set __irq_tim1_cc, __default_handler + .weak __irq_tim2 + .globl __irq_tim2 + .set __irq_tim2, __default_handler + .weak __irq_tim3 + .globl __irq_tim3 + .set __irq_tim3, __default_handler + .weak __irq_tim4 + .globl __irq_tim4 + .set __irq_tim4, __default_handler + .weak __irq_i2c1_ev + .globl __irq_i2c1_ev + .set __irq_i2c1_ev, __default_handler + .weak __irq_i2c1_er + .globl __irq_i2c1_er + .set __irq_i2c1_er, __default_handler + .weak __irq_i2c2_ev + .globl __irq_i2c2_ev + .set __irq_i2c2_ev, __default_handler + .weak __irq_i2c2_er + .globl __irq_i2c2_er + .set __irq_i2c2_er, __default_handler + .weak __irq_spi1 + .globl __irq_spi1 + .set __irq_spi1, __default_handler + .weak __irq_spi2 + .globl __irq_spi2 + .set __irq_spi2, __default_handler + .weak __irq_usart1 + .globl __irq_usart1 + .set __irq_usart1, __default_handler + .weak __irq_usart2 + .globl __irq_usart2 + .set __irq_usart2, __default_handler + .weak __irq_usart3 + .globl __irq_usart3 + .set __irq_usart3, __default_handler + .weak __irq_exti15_10 + .globl __irq_exti15_10 + .set __irq_exti15_10, __default_handler + .weak __irq_rtcalarm + .globl __irq_rtcalarm + .set __irq_rtcalarm, __default_handler + .weak __irq_usbwakeup + .globl __irq_usbwakeup + .set __irq_usbwakeup, __default_handler +#if defined (STM32_HIGH_DENSITY) + .weak __irq_tim8_brk + .globl __irq_tim8_brk + .set __irq_tim8_brk, __default_handler + .weak __irq_tim8_up + .globl __irq_tim8_up + .set __irq_tim8_up, __default_handler + .weak __irq_tim8_trg_com + .globl __irq_tim8_trg_com + .set __irq_tim8_trg_com, __default_handler + .weak __irq_tim8_cc + .globl __irq_tim8_cc + .set __irq_tim8_cc, __default_handler + .weak __irq_adc3 + .globl __irq_adc3 + .set __irq_adc3, __default_handler + .weak __irq_fsmc + .globl __irq_fsmc + .set __irq_fsmc, __default_handler + .weak __irq_sdio + .globl __irq_sdio + .set __irq_sdio, __default_handler + .weak __irq_tim5 + .globl __irq_tim5 + .set __irq_tim5, __default_handler + .weak __irq_spi3 + .globl __irq_spi3 + .set __irq_spi3, __default_handler + .weak __irq_uart4 + .globl __irq_uart4 + .set __irq_uart4, __default_handler + .weak __irq_uart5 + .globl __irq_uart5 + .set __irq_uart5, __default_handler + .weak __irq_tim6 + .globl __irq_tim6 + .set __irq_tim6, __default_handler + .weak __irq_tim7 + .globl __irq_tim7 + .set __irq_tim7, __default_handler + .weak __irq_dma2_channel1 + .globl __irq_dma2_channel1 + .set __irq_dma2_channel1, __default_handler + .weak __irq_dma2_channel2 + .globl __irq_dma2_channel2 + .set __irq_dma2_channel2, __default_handler + .weak __irq_dma2_channel3 + .globl __irq_dma2_channel3 + .set __irq_dma2_channel3, __default_handler + .weak __irq_dma2_channel4_5 + .globl __irq_dma2_channel4_5 + .set __irq_dma2_channel4_5, __default_handler +#endif /* STM32_HIGH_DENSITY */ + + .weak __irq_DMA2_Stream4_IRQHandler + .globl __irq_DMA2_Stream4_IRQHandler + .set __irq_DMA2_Stream4_IRQHandler, __default_handler + + .weak __irq_ETH_IRQHandler + .globl __irq_ETH_IRQHandler + .set __irq_ETH_IRQHandler, __default_handler + + .weak __irq_ETH_WKUP_IRQHandler + .globl __irq_ETH_WKUP_IRQHandler + .set __irq_ETH_WKUP_IRQHandler, __default_handler + + .weak __irq_CAN2_TX_IRQHandler + .globl __irq_CAN2_TX_IRQHandler + .set __irq_CAN2_TX_IRQHandler, __default_handler + + .weak __irq_CAN2_RX0_IRQHandler + .globl __irq_CAN2_RX0_IRQHandler + .set __irq_CAN2_RX0_IRQHandler, __default_handler + + .weak __irq_CAN2_RX1_IRQHandler + .globl __irq_CAN2_RX1_IRQHandler + .set __irq_CAN2_RX1_IRQHandler, __default_handler + + .weak __irq_CAN2_SCE_IRQHandler + .globl __irq_CAN2_SCE_IRQHandler + .set __irq_CAN2_SCE_IRQHandler, __default_handler + + .weak __irq_OTG_FS_IRQHandler + .globl __irq_OTG_FS_IRQHandler + .set __irq_OTG_FS_IRQHandler, __default_handler + + .weak __irq_DMA2_Stream5_IRQHandler + .globl __irq_DMA2_Stream5_IRQHandler + .set __irq_DMA2_Stream5_IRQHandler, __default_handler + + .weak __irq_DMA2_Stream6_IRQHandler + .globl __irq_DMA2_Stream6_IRQHandler + .set __irq_DMA2_Stream6_IRQHandler, __default_handler + + .weak __irq_DMA2_Stream7_IRQHandler + .globl __irq_DMA2_Stream7_IRQHandler + .set __irq_DMA2_Stream7_IRQHandler, __default_handler + + .weak __irq_USART6_IRQHandler + .globl __irq_USART6_IRQHandler + .set __irq_USART6_IRQHandler, __default_handler + + .weak __irq_I2C3_EV_IRQHandler + .globl __irq_I2C3_EV_IRQHandler + .set __irq_I2C3_EV_IRQHandler, __default_handler + + .weak __irq_I2C3_ER_IRQHandler + .globl __irq_I2C3_ER_IRQHandler + .set __irq_I2C3_ER_IRQHandler, __default_handler + + .weak __irq_OTG_HS_EP1_OUT_IRQHandler + .globl __irq_OTG_HS_EP1_OUT_IRQHandler + .set __irq_OTG_HS_EP1_OUT_IRQHandler, __default_handler + + .weak __irq_OTG_HS_EP1_IN_IRQHandler + .globl __irq_OTG_HS_EP1_IN_IRQHandler + .set __irq_OTG_HS_EP1_IN_IRQHandler, __default_handler + + .weak __irq_OTG_HS_WKUP_IRQHandler + .globl __irq_OTG_HS_WKUP_IRQHandler + .set __irq_OTG_HS_WKUP_IRQHandler, __default_handler + + .weak __irq_OTG_HS_IRQHandler + .globl __irq_OTG_HS_IRQHandler + .set __irq_OTG_HS_IRQHandler, __default_handler + + .weak __irq_DCMI_IRQHandler + .globl __irq_DCMI_IRQHandler + .set __irq_DCMI_IRQHandler, __default_handler + + .weak __irq_CRYP_IRQHandler + .globl __irq_CRYP_IRQHandler + .set __irq_CRYP_IRQHandler, __default_handler + + .weak __irq_HASH_RNG_IRQHandler + .globl __irq_HASH_RNG_IRQHandler + .set __irq_HASH_RNG_IRQHandler, __default_handler + + .weak __irq_FPU_IRQHandler + .globl __irq_FPU_IRQHandler + .set __irq_FPU_IRQHandler, __default_handler diff --git a/Libmaple/libmaple/support/ld/libcs4_stm32_src/stm32_vector_table.S b/Libmaple/libmaple/support/ld/libcs4_stm32_src/stm32_vector_table.S index e4427b7a..b0b3ac88 100644 --- a/Libmaple/libmaple/support/ld/libcs4_stm32_src/stm32_vector_table.S +++ b/Libmaple/libmaple/support/ld/libcs4_stm32_src/stm32_vector_table.S @@ -1,113 +1,113 @@ -/* STM32 vector table */ - - .section ".stm32.interrupt_vector" - - .globl __cs3_stm32_vector_table - .type __cs3_stm32_vector_table, %object - -__cs3_stm32_vector_table: -/* CM3 core interrupts */ - .long __cs3_stack - .long __cs3_reset - .long __exc_nmi - .long __exc_hardfault - .long __exc_memmanage - .long __exc_busfault - .long __exc_usagefault - .long __stm32reservedexception7 - .long __stm32reservedexception8 - .long __stm32reservedexception9 - .long __stm32reservedexception10 - .long __exc_svc - .long __exc_debug_monitor - .long __stm32reservedexception13 - .long __exc_pendsv - .long __exc_systick -/* Peripheral interrupts */ - .long __irq_wwdg - .long __irq_pvd - .long __irq_tamper - .long __irq_rtc - .long __irq_flash - .long __irq_rcc - .long __irq_exti0 - .long __irq_exti1 - .long __irq_exti2 - .long __irq_exti3 - .long __irq_exti4 - .long __irq_dma1_channel1 - .long __irq_dma1_channel2 - .long __irq_dma1_channel3 - .long __irq_dma1_channel4 - .long __irq_dma1_channel5 - .long __irq_dma1_channel6 - .long __irq_dma1_channel7 - .long __irq_adc - .long __irq_usb_hp_can_tx - .long __irq_usb_lp_can_rx0 - .long __irq_can_rx1 - .long __irq_can_sce - .long __irq_exti9_5 - .long __irq_tim1_brk - .long __irq_tim1_up - .long __irq_tim1_trg_com - .long __irq_tim1_cc - .long __irq_tim2 - .long __irq_tim3 - .long __irq_tim4 - .long __irq_i2c1_ev - .long __irq_i2c1_er - .long __irq_i2c2_ev - .long __irq_i2c2_er - .long __irq_spi1 - .long __irq_spi2 - .long __irq_usart1 - .long __irq_usart2 - .long __irq_usart3 - .long __irq_exti15_10 - .long __irq_rtcalarm - .long __irq_usbwakeup -#if defined (STM32_HIGH_DENSITY) - .long __irq_tim8_brk - .long __irq_tim8_up - .long __irq_tim8_trg_com - .long __irq_tim8_cc - .long __irq_adc3 - .long __irq_fsmc - .long __irq_sdio - .long __irq_tim5 - .long __irq_spi3 - .long __irq_uart4 - .long __irq_uart5 - .long __irq_tim6 - .long __irq_tim7 - .long __irq_dma2_channel1 - .long __irq_dma2_channel2 - .long __irq_dma2_channel3 - .long __irq_dma2_channel4_5 -#endif /* STM32_HIGH_DENSITY */ - - .long __irq_DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ - .long __irq_ETH_IRQHandler /* Ethernet */ - .long __irq_ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */ - .long __irq_CAN2_TX_IRQHandler /* CAN2 TX */ - .long __irq_CAN2_RX0_IRQHandler /* CAN2 RX0 */ - .long __irq_CAN2_RX1_IRQHandler /* CAN2 RX1 */ - .long __irq_CAN2_SCE_IRQHandler /* CAN2 SCE */ - .long __irq_OTG_FS_IRQHandler /* USB OTG FS */ - .long __irq_DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ - .long __irq_DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ - .long __irq_DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ - .long __irq_USART6_IRQHandler /* USART6 */ - .long __irq_I2C3_EV_IRQHandler /* I2C3 event */ - .long __irq_I2C3_ER_IRQHandler /* I2C3 error */ - .long __irq_OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ - .long __irq_OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ - .long __irq_OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ - .long __irq_OTG_HS_IRQHandler /* USB OTG HS */ - .long __irq_DCMI_IRQHandler /* DCMI */ - .long __irq_CRYP_IRQHandler /* CRYP crypto */ - .long __irq_HASH_RNG_IRQHandler /* Hash and Rng */ - .long __irq_FPU_IRQHandler /* FPU */ - - .size __cs3_stm32_vector_table, . - __cs3_stm32_vector_table +/* STM32 vector table */ + + .section ".stm32.interrupt_vector" + + .globl __cs3_stm32_vector_table + .type __cs3_stm32_vector_table, %object + +__cs3_stm32_vector_table: +/* CM3 core interrupts */ + .long __cs3_stack + .long __cs3_reset + .long __exc_nmi + .long __exc_hardfault + .long __exc_memmanage + .long __exc_busfault + .long __exc_usagefault + .long __stm32reservedexception7 + .long __stm32reservedexception8 + .long __stm32reservedexception9 + .long __stm32reservedexception10 + .long __exc_svc + .long __exc_debug_monitor + .long __stm32reservedexception13 + .long __exc_pendsv + .long __exc_systick +/* Peripheral interrupts */ + .long __irq_wwdg + .long __irq_pvd + .long __irq_tamper + .long __irq_rtc + .long __irq_flash + .long __irq_rcc + .long __irq_exti0 + .long __irq_exti1 + .long __irq_exti2 + .long __irq_exti3 + .long __irq_exti4 + .long __irq_dma1_channel1 + .long __irq_dma1_channel2 + .long __irq_dma1_channel3 + .long __irq_dma1_channel4 + .long __irq_dma1_channel5 + .long __irq_dma1_channel6 + .long __irq_dma1_channel7 + .long __irq_adc + .long __irq_usb_hp_can_tx + .long __irq_usb_lp_can_rx0 + .long __irq_can_rx1 + .long __irq_can_sce + .long __irq_exti9_5 + .long __irq_tim1_brk + .long __irq_tim1_up + .long __irq_tim1_trg_com + .long __irq_tim1_cc + .long __irq_tim2 + .long __irq_tim3 + .long __irq_tim4 + .long __irq_i2c1_ev + .long __irq_i2c1_er + .long __irq_i2c2_ev + .long __irq_i2c2_er + .long __irq_spi1 + .long __irq_spi2 + .long __irq_usart1 + .long __irq_usart2 + .long __irq_usart3 + .long __irq_exti15_10 + .long __irq_rtcalarm + .long __irq_usbwakeup +#if defined (STM32_HIGH_DENSITY) + .long __irq_tim8_brk + .long __irq_tim8_up + .long __irq_tim8_trg_com + .long __irq_tim8_cc + .long __irq_adc3 + .long __irq_fsmc + .long __irq_sdio + .long __irq_tim5 + .long __irq_spi3 + .long __irq_uart4 + .long __irq_uart5 + .long __irq_tim6 + .long __irq_tim7 + .long __irq_dma2_channel1 + .long __irq_dma2_channel2 + .long __irq_dma2_channel3 + .long __irq_dma2_channel4_5 +#endif /* STM32_HIGH_DENSITY */ + + .long __irq_DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ + .long __irq_ETH_IRQHandler /* Ethernet */ + .long __irq_ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */ + .long __irq_CAN2_TX_IRQHandler /* CAN2 TX */ + .long __irq_CAN2_RX0_IRQHandler /* CAN2 RX0 */ + .long __irq_CAN2_RX1_IRQHandler /* CAN2 RX1 */ + .long __irq_CAN2_SCE_IRQHandler /* CAN2 SCE */ + .long __irq_OTG_FS_IRQHandler /* USB OTG FS */ + .long __irq_DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ + .long __irq_DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ + .long __irq_DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ + .long __irq_USART6_IRQHandler /* USART6 */ + .long __irq_I2C3_EV_IRQHandler /* I2C3 event */ + .long __irq_I2C3_ER_IRQHandler /* I2C3 error */ + .long __irq_OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ + .long __irq_OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ + .long __irq_OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ + .long __irq_OTG_HS_IRQHandler /* USB OTG HS */ + .long __irq_DCMI_IRQHandler /* DCMI */ + .long __irq_CRYP_IRQHandler /* CRYP crypto */ + .long __irq_HASH_RNG_IRQHandler /* Hash and Rng */ + .long __irq_FPU_IRQHandler /* FPU */ + + .size __cs3_stm32_vector_table, . - __cs3_stm32_vector_table diff --git a/Libmaple/libmaple/support/ld/maple/flash.ld b/Libmaple/libmaple/support/ld/maple/flash.ld index 05e94fc9..8a179f7c 100644 --- a/Libmaple/libmaple/support/ld/maple/flash.ld +++ b/Libmaple/libmaple/support/ld/maple/flash.ld @@ -1,29 +1,29 @@ -/* - * Maple (STM32F103RBT6, medium density) linker script for Flash builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -/* - * Define the rest of the sections - */ -_FLASH_BUILD = 1; - -INCLUDE common.inc +/* + * Maple (STM32F103RBT6, medium density) linker script for Flash builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* + * Define the rest of the sections + */ +_FLASH_BUILD = 1; + +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/maple/jtag.ld b/Libmaple/libmaple/support/ld/maple/jtag.ld index 6494cc21..365068fe 100644 --- a/Libmaple/libmaple/support/ld/maple/jtag.ld +++ b/Libmaple/libmaple/support/ld/maple/jtag.ld @@ -1,29 +1,29 @@ -/* - * Maple (STM32F103RBT6, medium density) linker script for JTAG (bare - * metal, no bootloader) builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -/* - * Define the rest of the sections - */ -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Maple (STM32F103RBT6, medium density) linker script for JTAG (bare + * metal, no bootloader) builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* + * Define the rest of the sections + */ +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/maple/ram.ld b/Libmaple/libmaple/support/ld/maple/ram.ld index b4212242..6f237c3a 100644 --- a/Libmaple/libmaple/support/ld/maple/ram.ld +++ b/Libmaple/libmaple/support/ld/maple/ram.ld @@ -1,27 +1,27 @@ -/* - * Maple (STM32F103RBT6, medium density) linker script for RAM builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", ram); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", ram); - -/* - * Define the rest of the sections - */ -INCLUDE common.inc +/* + * Maple (STM32F103RBT6, medium density) linker script for RAM builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +/* + * Define the rest of the sections + */ +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/maple_RET6/flash.ld b/Libmaple/libmaple/support/ld/maple_RET6/flash.ld index 61b71635..4cf9c4b9 100644 --- a/Libmaple/libmaple/support/ld/maple_RET6/flash.ld +++ b/Libmaple/libmaple/support/ld/maple_RET6/flash.ld @@ -1,20 +1,20 @@ -/* - * Maple RET6 Edition (STM32F103RET6, high density) linker script for - * Flash builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K -} - -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Maple RET6 Edition (STM32F103RET6, high density) linker script for + * Flash builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/maple_RET6/jtag.ld b/Libmaple/libmaple/support/ld/maple_RET6/jtag.ld index 89c307a8..6055dfb7 100644 --- a/Libmaple/libmaple/support/ld/maple_RET6/jtag.ld +++ b/Libmaple/libmaple/support/ld/maple_RET6/jtag.ld @@ -1,20 +1,20 @@ -/* - * Maple RET6 Edition (STM32F103RET6, high density) linker script for - * JTAG (bare metal, no bootloader) builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K -} - -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Maple RET6 Edition (STM32F103RET6, high density) linker script for + * JTAG (bare metal, no bootloader) builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/maple_RET6/ram.ld b/Libmaple/libmaple/support/ld/maple_RET6/ram.ld index 2b6f9ad5..a4c273b2 100644 --- a/Libmaple/libmaple/support/ld/maple_RET6/ram.ld +++ b/Libmaple/libmaple/support/ld/maple_RET6/ram.ld @@ -1,19 +1,19 @@ -/* - * Maple RET6 Edition (STM32F103RET6, high density) linker script for - * RAM builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K -} - -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", ram); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", ram); - -INCLUDE common.inc +/* + * Maple RET6 Edition (STM32F103RET6, high density) linker script for + * RAM builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/maple_mini/flash.ld b/Libmaple/libmaple/support/ld/maple_mini/flash.ld index 587ced44..ab032076 100644 --- a/Libmaple/libmaple/support/ld/maple_mini/flash.ld +++ b/Libmaple/libmaple/support/ld/maple_mini/flash.ld @@ -1,28 +1,28 @@ -/* - * Maple Mini (STM32F103CBT6, medium density) linker script for Flash builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -/* - * Define the rest of the sections - */ -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Maple Mini (STM32F103CBT6, medium density) linker script for Flash builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* + * Define the rest of the sections + */ +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/maple_mini/jtag.ld b/Libmaple/libmaple/support/ld/maple_mini/jtag.ld index b0f9c8fe..2f9cf319 100644 --- a/Libmaple/libmaple/support/ld/maple_mini/jtag.ld +++ b/Libmaple/libmaple/support/ld/maple_mini/jtag.ld @@ -1,29 +1,29 @@ -/* - * Maple Mini (STM32F103CBT6, medium density) linker script for JTAG - * (bare metal, no bootloader) builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -/* - * Define the rest of the sections - */ -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Maple Mini (STM32F103CBT6, medium density) linker script for JTAG + * (bare metal, no bootloader) builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* + * Define the rest of the sections + */ +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/maple_mini/ram.ld b/Libmaple/libmaple/support/ld/maple_mini/ram.ld index b74585b1..0ba02522 100644 --- a/Libmaple/libmaple/support/ld/maple_mini/ram.ld +++ b/Libmaple/libmaple/support/ld/maple_mini/ram.ld @@ -1,27 +1,27 @@ -/* - * Maple Mini (STM32F103CBT6, medium density) linker script for RAM builds. - */ - -/* - * Define memory spaces. - */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K -} - -/* - * Use medium density device vector table - */ -GROUP(libcs3_stm32_med_density.a) - -REGION_ALIAS("REGION_TEXT", ram); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", ram); - -/* - * Define the rest of the sections - */ -INCLUDE common.inc +/* + * Maple Mini (STM32F103CBT6, medium density) linker script for RAM builds. + */ + +/* + * Define memory spaces. + */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K +} + +/* + * Use medium density device vector table + */ +GROUP(libcs3_stm32_med_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +/* + * Define the rest of the sections + */ +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/maple_native/flash.ld b/Libmaple/libmaple/support/ld/maple_native/flash.ld index 8be59a8c..b6e10f82 100644 --- a/Libmaple/libmaple/support/ld/maple_native/flash.ld +++ b/Libmaple/libmaple/support/ld/maple_native/flash.ld @@ -1,27 +1,27 @@ -/* - * Maple Native (STM32F103ZET6, high density) linker script for Flash builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K -} - -/* - * Use high density device vector table - */ -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -/* Specify heap boundary addresses on the external SRAM chip */ -_lm_heap_start = 0x60000000; -_lm_heap_end = 0x60100000; - -_FLASH_BUILD = 1; -INCLUDE common.inc - +/* + * Maple Native (STM32F103ZET6, high density) linker script for Flash builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K +} + +/* + * Use high density device vector table + */ +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Specify heap boundary addresses on the external SRAM chip */ +_lm_heap_start = 0x60000000; +_lm_heap_end = 0x60100000; + +_FLASH_BUILD = 1; +INCLUDE common.inc + diff --git a/Libmaple/libmaple/support/ld/maple_native/jtag.ld b/Libmaple/libmaple/support/ld/maple_native/jtag.ld index 9eac239e..9af2a11d 100644 --- a/Libmaple/libmaple/support/ld/maple_native/jtag.ld +++ b/Libmaple/libmaple/support/ld/maple_native/jtag.ld @@ -1,27 +1,27 @@ -/* - * Maple Native (STM32F103ZET6, high density) linker script for JTAG - * (bare metal, no bootloader) builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K -} - -/* - * Use high density device vector table - */ -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", rom); - -/* Specify heap boundary addresses on the external SRAM chip */ -_lm_heap_start = 0x60000000; -_lm_heap_end = 0x60100000; - -_FLASH_BUILD = 1; -INCLUDE common.inc +/* + * Maple Native (STM32F103ZET6, high density) linker script for JTAG + * (bare metal, no bootloader) builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +/* + * Use high density device vector table + */ +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", rom); + +/* Specify heap boundary addresses on the external SRAM chip */ +_lm_heap_start = 0x60000000; +_lm_heap_end = 0x60100000; + +_FLASH_BUILD = 1; +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/maple_native/ram.ld b/Libmaple/libmaple/support/ld/maple_native/ram.ld index cb0b740a..72643166 100644 --- a/Libmaple/libmaple/support/ld/maple_native/ram.ld +++ b/Libmaple/libmaple/support/ld/maple_native/ram.ld @@ -1,25 +1,25 @@ -/* - * Maple Native (STM32F103ZET6, high density) linker script for RAM builds. - */ - -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K - rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K -} - -/* - * Use high density device vector table - */ -GROUP(libcs3_stm32_high_density.a) - -REGION_ALIAS("REGION_TEXT", ram); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); -REGION_ALIAS("REGION_RODATA", ram); - -/* Specify heap boundary addresses on the external SRAM chip */ -_lm_heap_start = 0x60000000; -_lm_heap_end = 0x60100000; - -INCLUDE common.inc +/* + * Maple Native (STM32F103ZET6, high density) linker script for RAM builds. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K +} + +/* + * Use high density device vector table + */ +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("REGION_RODATA", ram); + +/* Specify heap boundary addresses on the external SRAM chip */ +_lm_heap_start = 0x60000000; +_lm_heap_end = 0x60100000; + +INCLUDE common.inc diff --git a/Libmaple/libmaple/support/ld/names.inc b/Libmaple/libmaple/support/ld/names.inc index dfea912b..6d7ff6e9 100644 --- a/Libmaple/libmaple/support/ld/names.inc +++ b/Libmaple/libmaple/support/ld/names.inc @@ -1,78 +1,78 @@ -EXTERN(__cs3_stack) -EXTERN(__cs3_reset) -EXTERN(__exc_nmi) -EXTERN(__exc_hardfault) -EXTERN(__exc_memmanage) -EXTERN(__exc_busfault) -EXTERN(__exc_usagefault) -EXTERN(__stm32reservedexception7) -EXTERN(__stm32reservedexception8) -EXTERN(__stm32reservedexception9) -EXTERN(__stm32reservedexception10) -EXTERN(__exc_svc) -EXTERN(__exc_debug_monitor) -EXTERN(__stm32reservedexception13) -EXTERN(__exc_pendsv) -EXTERN(__exc_systick) - -EXTERN(__irq_wwdg) -EXTERN(__irq_pvd) -EXTERN(__irq_tamper) -EXTERN(__irq_rtc) -EXTERN(__irq_flash) -EXTERN(__irq_rcc) -EXTERN(__irq_exti0) -EXTERN(__irq_exti1) -EXTERN(__irq_exti2) -EXTERN(__irq_exti3) -EXTERN(__irq_exti4) -EXTERN(__irq_dma1_channel1) -EXTERN(__irq_dma1_channel2) -EXTERN(__irq_dma1_channel3) -EXTERN(__irq_dma1_channel4) -EXTERN(__irq_dma1_channel5) -EXTERN(__irq_dma1_channel6) -EXTERN(__irq_dma1_channel7) -EXTERN(__irq_adc) -EXTERN(__irq_usb_hp_can_tx) -EXTERN(__irq_usb_lp_can_rx0) -EXTERN(__irq_can_rx1) -EXTERN(__irq_can_sce) -EXTERN(__irq_exti9_5) -EXTERN(__irq_tim1_brk) -EXTERN(__irq_tim1_up) -EXTERN(__irq_tim1_trg_com) -EXTERN(__irq_tim1_cc) -EXTERN(__irq_tim2) -EXTERN(__irq_tim3) -EXTERN(__irq_tim4) -EXTERN(__irq_i2c1_ev) -EXTERN(__irq_i2c1_er) -EXTERN(__irq_i2c2_ev) -EXTERN(__irq_i2c2_er) -EXTERN(__irq_spi1) -EXTERN(__irq_spi2) -EXTERN(__irq_usart1) -EXTERN(__irq_usart2) -EXTERN(__irq_usart3) -EXTERN(__irq_exti15_10) -EXTERN(__irq_rtcalarm) -EXTERN(__irq_usbwakeup) - -EXTERN(__irq_tim8_brk) -EXTERN(__irq_tim8_up) -EXTERN(__irq_tim8_trg_com) -EXTERN(__irq_tim8_cc) -EXTERN(__irq_adc3) -EXTERN(__irq_fsmc) -EXTERN(__irq_sdio) -EXTERN(__irq_tim5) -EXTERN(__irq_spi3) -EXTERN(__irq_uart4) -EXTERN(__irq_uart5) -EXTERN(__irq_tim6) -EXTERN(__irq_tim7) -EXTERN(__irq_dma2_channel1) -EXTERN(__irq_dma2_channel2) -EXTERN(__irq_dma2_channel3) -EXTERN(__irq_dma2_channel4_5) +EXTERN(__cs3_stack) +EXTERN(__cs3_reset) +EXTERN(__exc_nmi) +EXTERN(__exc_hardfault) +EXTERN(__exc_memmanage) +EXTERN(__exc_busfault) +EXTERN(__exc_usagefault) +EXTERN(__stm32reservedexception7) +EXTERN(__stm32reservedexception8) +EXTERN(__stm32reservedexception9) +EXTERN(__stm32reservedexception10) +EXTERN(__exc_svc) +EXTERN(__exc_debug_monitor) +EXTERN(__stm32reservedexception13) +EXTERN(__exc_pendsv) +EXTERN(__exc_systick) + +EXTERN(__irq_wwdg) +EXTERN(__irq_pvd) +EXTERN(__irq_tamper) +EXTERN(__irq_rtc) +EXTERN(__irq_flash) +EXTERN(__irq_rcc) +EXTERN(__irq_exti0) +EXTERN(__irq_exti1) +EXTERN(__irq_exti2) +EXTERN(__irq_exti3) +EXTERN(__irq_exti4) +EXTERN(__irq_dma1_channel1) +EXTERN(__irq_dma1_channel2) +EXTERN(__irq_dma1_channel3) +EXTERN(__irq_dma1_channel4) +EXTERN(__irq_dma1_channel5) +EXTERN(__irq_dma1_channel6) +EXTERN(__irq_dma1_channel7) +EXTERN(__irq_adc) +EXTERN(__irq_usb_hp_can_tx) +EXTERN(__irq_usb_lp_can_rx0) +EXTERN(__irq_can_rx1) +EXTERN(__irq_can_sce) +EXTERN(__irq_exti9_5) +EXTERN(__irq_tim1_brk) +EXTERN(__irq_tim1_up) +EXTERN(__irq_tim1_trg_com) +EXTERN(__irq_tim1_cc) +EXTERN(__irq_tim2) +EXTERN(__irq_tim3) +EXTERN(__irq_tim4) +EXTERN(__irq_i2c1_ev) +EXTERN(__irq_i2c1_er) +EXTERN(__irq_i2c2_ev) +EXTERN(__irq_i2c2_er) +EXTERN(__irq_spi1) +EXTERN(__irq_spi2) +EXTERN(__irq_usart1) +EXTERN(__irq_usart2) +EXTERN(__irq_usart3) +EXTERN(__irq_exti15_10) +EXTERN(__irq_rtcalarm) +EXTERN(__irq_usbwakeup) + +EXTERN(__irq_tim8_brk) +EXTERN(__irq_tim8_up) +EXTERN(__irq_tim8_trg_com) +EXTERN(__irq_tim8_cc) +EXTERN(__irq_adc3) +EXTERN(__irq_fsmc) +EXTERN(__irq_sdio) +EXTERN(__irq_tim5) +EXTERN(__irq_spi3) +EXTERN(__irq_uart4) +EXTERN(__irq_uart5) +EXTERN(__irq_tim6) +EXTERN(__irq_tim7) +EXTERN(__irq_dma2_channel1) +EXTERN(__irq_dma2_channel2) +EXTERN(__irq_dma2_channel3) +EXTERN(__irq_dma2_channel4_5) diff --git a/Libmaple/libmaple/support/make/build-rules.mk b/Libmaple/libmaple/support/make/build-rules.mk index c061a879..aff86904 100644 --- a/Libmaple/libmaple/support/make/build-rules.mk +++ b/Libmaple/libmaple/support/make/build-rules.mk @@ -1,51 +1,51 @@ -# Useful tools -CC := arm-none-eabi-gcc -CXX := arm-none-eabi-g++ -LD := arm-none-eabi-ld -v -AR := arm-none-eabi-ar -AS := arm-none-eabi-gcc -OBJCOPY := arm-none-eabi-objcopy -DISAS := arm-none-eabi-objdump -OBJDUMP := arm-none-eabi-objdump -SIZE := arm-none-eabi-size -DFU := dfu-util -OPENOCD_WRAPPER := support/scripts/openocd-wrapper.sh - -# Suppress annoying output unless V is set -ifndef V - SILENT_CC = @echo ' [CC] ' $(@:$(BUILD_PATH)/%.o=%.c); - SILENT_AS = @echo ' [AS] ' $(@:$(BUILD_PATH)/%.o=%.S); - SILENT_CXX = @echo ' [CXX] ' $(@:$(BUILD_PATH)/%.o=%.cpp); - SILENT_LD = @echo ' [LD] ' $(@F); - SILENT_AR = @echo ' [AR] ' - SILENT_OBJCOPY = @echo ' [OBJCOPY] ' $(@F); - SILENT_DISAS = @echo ' [DISAS] ' $(@:$(BUILD_PATH)/%.bin=%).disas; - SILENT_OBJDUMP = @echo ' [OBJDUMP] ' $(OBJDUMP); -endif - -BUILDDIRS := -TGT_BIN := - -CFLAGS = $(GLOBAL_CFLAGS) $(TGT_CFLAGS) -CXXFLAGS = $(GLOBAL_CXXFLAGS) $(TGT_CXXFLAGS) -ASFLAGS = $(GLOBAL_ASFLAGS) $(TGT_ASFLAGS) -CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) - -ifdef IDE_VS -VS_TRIM_ERRORS = 2>&1 | sed -e 's/\(\w\+\):\([0-9]\+\):/\1(\2):/' -else -VS_TRIM_ERRORS = -endif - -# General directory independent build rules, generate dependency information - #$(SILENT_CC) $(CC) $(CFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $< -$(BUILD_PATH)/%.o: %.c - $(SILENT_CC) $(CC) $(CFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $(abspath $<) $(VS_TRIM_ERRORS) - -#$(SILENT_CXX) $(CXX) $(CFLAGS) $(CXXFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $< -$(BUILD_PATH)/%.o: %.cpp - $(SILENT_CXX) $(CXX) $(CFLAGS) $(CXXFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $(abspath $<) $(VS_TRIM_ERRORS) - -#$(SILENT_AS) $(AS) $(ASFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $< -$(BUILD_PATH)/%.o: %.S - $(SILENT_AS) $(AS) $(ASFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $(abspath $<) $(VS_TRIM_ERRORS) +# Useful tools +CC := arm-none-eabi-gcc +CXX := arm-none-eabi-g++ +LD := arm-none-eabi-ld -v +AR := arm-none-eabi-ar +AS := arm-none-eabi-gcc +OBJCOPY := arm-none-eabi-objcopy +DISAS := arm-none-eabi-objdump +OBJDUMP := arm-none-eabi-objdump +SIZE := arm-none-eabi-size +DFU := dfu-util +OPENOCD_WRAPPER := support/scripts/openocd-wrapper.sh + +# Suppress annoying output unless V is set +ifndef V + SILENT_CC = @echo ' [CC] ' $(@:$(BUILD_PATH)/%.o=%.c); + SILENT_AS = @echo ' [AS] ' $(@:$(BUILD_PATH)/%.o=%.S); + SILENT_CXX = @echo ' [CXX] ' $(@:$(BUILD_PATH)/%.o=%.cpp); + SILENT_LD = @echo ' [LD] ' $(@F); + SILENT_AR = @echo ' [AR] ' + SILENT_OBJCOPY = @echo ' [OBJCOPY] ' $(@F); + SILENT_DISAS = @echo ' [DISAS] ' $(@:$(BUILD_PATH)/%.bin=%).disas; + SILENT_OBJDUMP = @echo ' [OBJDUMP] ' $(OBJDUMP); +endif + +BUILDDIRS := +TGT_BIN := + +CFLAGS = $(GLOBAL_CFLAGS) $(TGT_CFLAGS) +CXXFLAGS = $(GLOBAL_CXXFLAGS) $(TGT_CXXFLAGS) +ASFLAGS = $(GLOBAL_ASFLAGS) $(TGT_ASFLAGS) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) + +ifdef IDE_VS +VS_TRIM_ERRORS = 2>&1 | sed -e 's/\(\w\+\):\([0-9]\+\):/\1(\2):/' +else +VS_TRIM_ERRORS = +endif + +# General directory independent build rules, generate dependency information + #$(SILENT_CC) $(CC) $(CFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $< +$(BUILD_PATH)/%.o: %.c + $(SILENT_CC) $(CC) $(CFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $(abspath $<) $(VS_TRIM_ERRORS) + +#$(SILENT_CXX) $(CXX) $(CFLAGS) $(CXXFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $< +$(BUILD_PATH)/%.o: %.cpp + $(SILENT_CXX) $(CXX) $(CFLAGS) $(CXXFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $(abspath $<) $(VS_TRIM_ERRORS) + +#$(SILENT_AS) $(AS) $(ASFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $< +$(BUILD_PATH)/%.o: %.S + $(SILENT_AS) $(AS) $(ASFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $(abspath $<) $(VS_TRIM_ERRORS) diff --git a/Libmaple/libmaple/support/make/build-templates.mk b/Libmaple/libmaple/support/make/build-templates.mk index 7208f573..fcf83a1c 100644 --- a/Libmaple/libmaple/support/make/build-templates.mk +++ b/Libmaple/libmaple/support/make/build-templates.mk @@ -1,6 +1,6 @@ -define LIBMAPLE_MODULE_template -dir := $(1) -LIBMAPLE_INCLUDES += -I$$(dir) -include $$(dir)/rules.mk -endef - +define LIBMAPLE_MODULE_template +dir := $(1) +LIBMAPLE_INCLUDES += -I$$(dir) +include $$(dir)/rules.mk +endef + diff --git a/Libmaple/libmaple/support/make/target-config.mk b/Libmaple/libmaple/support/make/target-config.mk index 0ad177fa..a0058e92 100644 --- a/Libmaple/libmaple/support/make/target-config.mk +++ b/Libmaple/libmaple/support/make/target-config.mk @@ -1,112 +1,112 @@ -# Board-specific configuration values. Flash and SRAM sizes in bytes. - -ifeq ($(BOARD), maple) - MCU := STM32F103RB - PRODUCT_ID := 0003 - ERROR_LED_PORT := GPIOA - ERROR_LED_PIN := 5 - DENSITY := STM32_MEDIUM_DENSITY - FLASH_SIZE := 131072 - SRAM_SIZE := 20480 -endif - -ifeq ($(BOARD), maple_native) - MCU := STM32F103ZE - PRODUCT_ID := 0003 - ERROR_LED_PORT := GPIOC - ERROR_LED_PIN := 15 - DENSITY := STM32_HIGH_DENSITY - FLASH_SIZE := 524288 - SRAM_SIZE := 65536 -endif - -ifeq ($(BOARD), maple_mini) - MCU := STM32F103CB - PRODUCT_ID := 0003 - ERROR_LED_PORT := GPIOC - ERROR_LED_PIN := 1 - DENSITY := STM32_MEDIUM_DENSITY - FLASH_SIZE := 131072 - SRAM_SIZE := 20480 -endif - -ifeq ($(BOARD), maple_RET6) - MCU := STM32F103RE - PRODUCT_ID := 0003 - ERROR_LED_PORT := GPIOA - ERROR_LED_PIN := 5 - DENSITY := STM32_HIGH_DENSITY - FLASH_SIZE := 524288 - SRAM_SIZE := 65536 -endif - -ifeq ($(BOARD), aeroquad32f1) - MCU := STM32F103VE - PRODUCT_ID := 0003 - ERROR_LED_PORT := GPIOE - ERROR_LED_PIN := 5 - DENSITY := STM32_HIGH_DENSITY - FLASH_SIZE := 524288 - SRAM_SIZE := 65536 - MCU_FAMILY := STM32F1 -endif - -ifeq ($(BOARD), aeroquad32) - MCU := STM32F406VG - PRODUCT_ID := 0003 - ERROR_LED_PORT := GPIOE - ERROR_LED_PIN := 5 - DENSITY := STM32_HIGH_DENSITY - FLASH_SIZE := 524288 - SRAM_SIZE := 65536 - MCU_FAMILY := STM32F2 -endif - -ifeq ($(BOARD), aeroquad32mini) - MCU := STM32F103CB - PRODUCT_ID := 0003 - ERROR_LED_PORT := GPIOB - ERROR_LED_PIN := 1 - DENSITY := STM32_MEDIUM_DENSITY - FLASH_SIZE := 131072 - SRAM_SIZE := 20480 - MCU_FAMILY := STM32F1 -endif - -ifeq ($(BOARD), freeflight) - MCU := STM32F103CB - PRODUCT_ID := 0003 - ERROR_LED_PORT := GPIOB - ERROR_LED_PIN := 3 - DENSITY := STM32_MEDIUM_DENSITY - FLASH_SIZE := 131072 - SRAM_SIZE := 20480 - MCU_FAMILY := STM32F1 -endif - -ifeq ($(BOARD), discovery_f4) - MCU := STM32F406VG - PRODUCT_ID := 0003 - ERROR_LED_PORT := GPIOD - ERROR_LED_PIN := 14 - DENSITY := STM32_HIGH_DENSITY - FLASH_SIZE := 524288 - SRAM_SIZE := 65536 - MCU_FAMILY := STM32F2 -endif - - -# Memory target-specific configuration values - -ifeq ($(MEMORY_TARGET), ram) - LDSCRIPT := $(BOARD)/ram.ld - VECT_BASE_ADDR := VECT_TAB_RAM -endif -ifeq ($(MEMORY_TARGET), flash) - LDSCRIPT := $(BOARD)/flash.ld - VECT_BASE_ADDR := VECT_TAB_FLASH -endif -ifeq ($(MEMORY_TARGET), jtag) - LDSCRIPT := $(BOARD)/jtag.ld - VECT_BASE_ADDR := VECT_TAB_BASE -endif +# Board-specific configuration values. Flash and SRAM sizes in bytes. + +ifeq ($(BOARD), maple) + MCU := STM32F103RB + PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOA + ERROR_LED_PIN := 5 + DENSITY := STM32_MEDIUM_DENSITY + FLASH_SIZE := 131072 + SRAM_SIZE := 20480 +endif + +ifeq ($(BOARD), maple_native) + MCU := STM32F103ZE + PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOC + ERROR_LED_PIN := 15 + DENSITY := STM32_HIGH_DENSITY + FLASH_SIZE := 524288 + SRAM_SIZE := 65536 +endif + +ifeq ($(BOARD), maple_mini) + MCU := STM32F103CB + PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOC + ERROR_LED_PIN := 1 + DENSITY := STM32_MEDIUM_DENSITY + FLASH_SIZE := 131072 + SRAM_SIZE := 20480 +endif + +ifeq ($(BOARD), maple_RET6) + MCU := STM32F103RE + PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOA + ERROR_LED_PIN := 5 + DENSITY := STM32_HIGH_DENSITY + FLASH_SIZE := 524288 + SRAM_SIZE := 65536 +endif + +ifeq ($(BOARD), aeroquad32f1) + MCU := STM32F103VE + PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOE + ERROR_LED_PIN := 5 + DENSITY := STM32_HIGH_DENSITY + FLASH_SIZE := 524288 + SRAM_SIZE := 65536 + MCU_FAMILY := STM32F1 +endif + +ifeq ($(BOARD), aeroquad32) + MCU := STM32F406VG + PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOE + ERROR_LED_PIN := 5 + DENSITY := STM32_HIGH_DENSITY + FLASH_SIZE := 524288 + SRAM_SIZE := 65536 + MCU_FAMILY := STM32F2 +endif + +ifeq ($(BOARD), aeroquad32mini) + MCU := STM32F103CB + PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOB + ERROR_LED_PIN := 1 + DENSITY := STM32_MEDIUM_DENSITY + FLASH_SIZE := 131072 + SRAM_SIZE := 20480 + MCU_FAMILY := STM32F1 +endif + +ifeq ($(BOARD), freeflight) + MCU := STM32F103CB + PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOB + ERROR_LED_PIN := 3 + DENSITY := STM32_MEDIUM_DENSITY + FLASH_SIZE := 131072 + SRAM_SIZE := 20480 + MCU_FAMILY := STM32F1 +endif + +ifeq ($(BOARD), discovery_f4) + MCU := STM32F406VG + PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOD + ERROR_LED_PIN := 14 + DENSITY := STM32_HIGH_DENSITY + FLASH_SIZE := 524288 + SRAM_SIZE := 65536 + MCU_FAMILY := STM32F2 +endif + + +# Memory target-specific configuration values + +ifeq ($(MEMORY_TARGET), ram) + LDSCRIPT := $(BOARD)/ram.ld + VECT_BASE_ADDR := VECT_TAB_RAM +endif +ifeq ($(MEMORY_TARGET), flash) + LDSCRIPT := $(BOARD)/flash.ld + VECT_BASE_ADDR := VECT_TAB_FLASH +endif +ifeq ($(MEMORY_TARGET), jtag) + LDSCRIPT := $(BOARD)/jtag.ld + VECT_BASE_ADDR := VECT_TAB_BASE +endif diff --git a/Libmaple/libmaple/support/openocd/debug_0.3.cfg b/Libmaple/libmaple/support/openocd/debug_0.3.cfg index ba83da5a..87d33ae3 100644 --- a/Libmaple/libmaple/support/openocd/debug_0.3.cfg +++ b/Libmaple/libmaple/support/openocd/debug_0.3.cfg @@ -1,75 +1,75 @@ -# script for stm32 - -interface ft2232 -ft2232_device_desc "Olimex OpenOCD JTAG" -ft2232_layout olimex-jtag -ft2232_vid_pid 0x15ba 0x0003 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# jtag speed speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so ufse F_JTAG = 1MHz -jtag_khz 1000 - -jtag_nsrst_delay 100 -jtag_ntrst_delay 100 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst - -#jtag scan chain -if { [info exists CPUTAPID ] } { - set _CPUTAPID $CPUTAPID -} else { - # See STM Document RM0008 - # Section 30.6.3 - set _CPUTAPID 0x3ba00477 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID ] } { - # FIXME this never gets used to override defaults... - set _BSTAPID $BSTAPID -} else { - # See STM Document RM0008 - # Section 29.6.2 - # Low density devices, Rev A - set _BSTAPID1 0x06412041 - # Medium density devices, Rev A - set _BSTAPID2 0x06410041 - # Medium density devices, Rev B and Rev Z - set _BSTAPID3 0x16410041 - # High density devices, Rev A - set _BSTAPID4 0x06414041 - # Connectivity line devices, Rev A and Rev Z - set _BSTAPID5 0x06418041 -} -jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ - -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ - -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 - - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 - -flash bank stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME - -proc nopforever {} { - puts "Resetting the chip..." - reset run -} - -init -nopforever +# script for stm32 + +interface ft2232 +ft2232_device_desc "Olimex OpenOCD JTAG" +ft2232_layout olimex-jtag +ft2232_vid_pid 0x15ba 0x0003 + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +# jtag speed speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so ufse F_JTAG = 1MHz +jtag_khz 1000 + +jtag_nsrst_delay 100 +jtag_ntrst_delay 100 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config trst_and_srst + +#jtag scan chain +if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID +} else { + # See STM Document RM0008 + # Section 30.6.3 + set _CPUTAPID 0x3ba00477 +} + +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +if { [info exists BSTAPID ] } { + # FIXME this never gets used to override defaults... + set _BSTAPID $BSTAPID +} else { + # See STM Document RM0008 + # Section 29.6.2 + # Low density devices, Rev A + set _BSTAPID1 0x06412041 + # Medium density devices, Rev A + set _BSTAPID2 0x06410041 + # Medium density devices, Rev B and Rev Z + set _BSTAPID3 0x16410041 + # High density devices, Rev A + set _BSTAPID4 0x06414041 + # Connectivity line devices, Rev A and Rev Z + set _BSTAPID5 0x06418041 +} +jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ + -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ + -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 + + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME + +$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 + +flash bank stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME + +proc nopforever {} { + puts "Resetting the chip..." + reset run +} + +init +nopforever diff --git a/Libmaple/libmaple/support/openocd/debug_0.4.cfg b/Libmaple/libmaple/support/openocd/debug_0.4.cfg index 83577a26..7d6982af 100644 --- a/Libmaple/libmaple/support/openocd/debug_0.4.cfg +++ b/Libmaple/libmaple/support/openocd/debug_0.4.cfg @@ -1,75 +1,75 @@ -# script for stm32 - -interface ft2232 -ft2232_device_desc "Olimex OpenOCD JTAG" -ft2232_layout olimex-jtag -ft2232_vid_pid 0x15ba 0x0003 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# jtag speed speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so ufse F_JTAG = 1MHz -jtag_khz 1000 - -jtag_nsrst_delay 100 -jtag_ntrst_delay 100 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only - -#jtag scan chain -if { [info exists CPUTAPID ] } { - set _CPUTAPID $CPUTAPID -} else { - # See STM Document RM0008 - # Section 30.6.3 - set _CPUTAPID 0x3ba00477 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID ] } { - # FIXME this never gets used to override defaults... - set _BSTAPID $BSTAPID -} else { - # See STM Document RM0008 - # Section 29.6.2 - # Low density devices, Rev A - set _BSTAPID1 0x06412041 - # Medium density devices, Rev A - set _BSTAPID2 0x06410041 - # Medium density devices, Rev B and Rev Z - set _BSTAPID3 0x16410041 - # High density devices, Rev A - set _BSTAPID4 0x06414041 - # Connectivity line devices, Rev A and Rev Z - set _BSTAPID5 0x06418041 -} -jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ - -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ - -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 - - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 - -flash bank bank0 stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME - -proc nopforever {} { - puts "Resetting the chip... Halting for debugger." - reset halt -} - -init -nopforever +# script for stm32 + +interface ft2232 +ft2232_device_desc "Olimex OpenOCD JTAG" +ft2232_layout olimex-jtag +ft2232_vid_pid 0x15ba 0x0003 + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +# jtag speed speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so ufse F_JTAG = 1MHz +jtag_khz 1000 + +jtag_nsrst_delay 100 +jtag_ntrst_delay 100 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config srst_only + +#jtag scan chain +if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID +} else { + # See STM Document RM0008 + # Section 30.6.3 + set _CPUTAPID 0x3ba00477 +} + +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +if { [info exists BSTAPID ] } { + # FIXME this never gets used to override defaults... + set _BSTAPID $BSTAPID +} else { + # See STM Document RM0008 + # Section 29.6.2 + # Low density devices, Rev A + set _BSTAPID1 0x06412041 + # Medium density devices, Rev A + set _BSTAPID2 0x06410041 + # Medium density devices, Rev B and Rev Z + set _BSTAPID3 0x16410041 + # High density devices, Rev A + set _BSTAPID4 0x06414041 + # Connectivity line devices, Rev A and Rev Z + set _BSTAPID5 0x06418041 +} +jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ + -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ + -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 + + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME + +$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 + +flash bank bank0 stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME + +proc nopforever {} { + puts "Resetting the chip... Halting for debugger." + reset halt +} + +init +nopforever diff --git a/Libmaple/libmaple/support/openocd/flash_0.3.cfg b/Libmaple/libmaple/support/openocd/flash_0.3.cfg index 7420f7f1..41c6532a 100644 --- a/Libmaple/libmaple/support/openocd/flash_0.3.cfg +++ b/Libmaple/libmaple/support/openocd/flash_0.3.cfg @@ -1,89 +1,89 @@ -# script for stm32 - -interface ft2232 -ft2232_device_desc "Olimex OpenOCD JTAG" -ft2232_layout olimex-jtag -ft2232_vid_pid 0x15ba 0x0003 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# jtag speed speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so ufse F_JTAG = 1MHz -jtag_khz 1000 - -jtag_nsrst_delay 100 -jtag_ntrst_delay 100 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst - -#jtag scan chain -if { [info exists CPUTAPID ] } { - set _CPUTAPID $CPUTAPID -} else { - # See STM Document RM0008 - # Section 30.6.3 - set _CPUTAPID 0x3ba00477 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID ] } { - # FIXME this never gets used to override defaults... - set _BSTAPID $BSTAPID -} else { - # See STM Document RM0008 - # Section 29.6.2 - # Low density devices, Rev A - set _BSTAPID1 0x06412041 - # Medium density devices, Rev A - set _BSTAPID2 0x06410041 - # Medium density devices, Rev B and Rev Z - set _BSTAPID3 0x16410041 - # High density devices, Rev A - set _BSTAPID4 0x06414041 - # Connectivity line devices, Rev A and Rev Z - set _BSTAPID5 0x06418041 -} -jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ - -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ - -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 - - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 -# TODO: native -#$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0 - -flash bank stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME - -proc flash_chip {} { - echo "Halting..." - halt - echo "Erasing..." - flash erase_address 0x08000000 0x20000 - # TODO: native - #flash erase_address 0x08000000 0x80000 - echo "Flashing image..." - flash write_bank 0 build/maple.bin 0 - echo "Verifying image..." - verify_image build/maple.bin 0x08000000 bin - echo "Checksum verified, resetting chip" - reset run - echo "Daemon shutdown" - shutdown -} - -init -flash_chip +# script for stm32 + +interface ft2232 +ft2232_device_desc "Olimex OpenOCD JTAG" +ft2232_layout olimex-jtag +ft2232_vid_pid 0x15ba 0x0003 + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +# jtag speed speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so ufse F_JTAG = 1MHz +jtag_khz 1000 + +jtag_nsrst_delay 100 +jtag_ntrst_delay 100 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config trst_and_srst + +#jtag scan chain +if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID +} else { + # See STM Document RM0008 + # Section 30.6.3 + set _CPUTAPID 0x3ba00477 +} + +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +if { [info exists BSTAPID ] } { + # FIXME this never gets used to override defaults... + set _BSTAPID $BSTAPID +} else { + # See STM Document RM0008 + # Section 29.6.2 + # Low density devices, Rev A + set _BSTAPID1 0x06412041 + # Medium density devices, Rev A + set _BSTAPID2 0x06410041 + # Medium density devices, Rev B and Rev Z + set _BSTAPID3 0x16410041 + # High density devices, Rev A + set _BSTAPID4 0x06414041 + # Connectivity line devices, Rev A and Rev Z + set _BSTAPID5 0x06418041 +} +jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ + -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ + -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 + + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME + +$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 +# TODO: native +#$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0 + +flash bank stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME + +proc flash_chip {} { + echo "Halting..." + halt + echo "Erasing..." + flash erase_address 0x08000000 0x20000 + # TODO: native + #flash erase_address 0x08000000 0x80000 + echo "Flashing image..." + flash write_bank 0 build/maple.bin 0 + echo "Verifying image..." + verify_image build/maple.bin 0x08000000 bin + echo "Checksum verified, resetting chip" + reset run + echo "Daemon shutdown" + shutdown +} + +init +flash_chip diff --git a/Libmaple/libmaple/support/openocd/flash_0.4.cfg b/Libmaple/libmaple/support/openocd/flash_0.4.cfg index 79e9c0b6..32c06c6b 100644 --- a/Libmaple/libmaple/support/openocd/flash_0.4.cfg +++ b/Libmaple/libmaple/support/openocd/flash_0.4.cfg @@ -1,95 +1,95 @@ -# script for stm32 - -interface ft2232 -ft2232_device_desc "Olimex OpenOCD JTAG" -ft2232_layout olimex-jtag -ft2232_vid_pid 0x15ba 0x0003 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# jtag speed speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so ufse F_JTAG = 1MHz -jtag_khz 1000 - -jtag_nsrst_delay 100 -jtag_ntrst_delay 100 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only - -#jtag scan chain -if { [info exists CPUTAPID ] } { - set _CPUTAPID $CPUTAPID -} else { - # See STM Document RM0008 - # Section 30.6.3 - set _CPUTAPID 0x3ba00477 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID ] } { - # FIXME this never gets used to override defaults... - set _BSTAPID $BSTAPID -} else { - # See STM Document RM0008 - # Section 29.6.2 - # Low density devices, Rev A - set _BSTAPID1 0x06412041 - # Medium density devices, Rev A - set _BSTAPID2 0x06410041 - # Medium density devices, Rev B and Rev Z - set _BSTAPID3 0x16410041 - # High density devices, Rev A - set _BSTAPID4 0x06414041 - # Connectivity line devices, Rev A and Rev Z - set _BSTAPID5 0x06418041 -} -jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ - -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ - -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 - - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 -# TODO: native -#$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0 - -flash bank bank0 stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME - -proc flash_chip {} { - echo "Halting..." - reset halt - - echo "Unlocking flash..." - flash protect 0 0 last off - - echo "Erasing..." - flash erase_address 0x08000000 0x20000 - - echo "Flashing image..." - flash write_bank 0 build/maple.bin 0 - - echo "Verifying image..." - verify_image build/maple.bin 0x08000000 bin - - echo "Checksum verified, resetting chip" - reset run - - echo "Daemon shutdown" - shutdown -} - -init -flash_chip +# script for stm32 + +interface ft2232 +ft2232_device_desc "Olimex OpenOCD JTAG" +ft2232_layout olimex-jtag +ft2232_vid_pid 0x15ba 0x0003 + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +# jtag speed speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so ufse F_JTAG = 1MHz +jtag_khz 1000 + +jtag_nsrst_delay 100 +jtag_ntrst_delay 100 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config srst_only + +#jtag scan chain +if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID +} else { + # See STM Document RM0008 + # Section 30.6.3 + set _CPUTAPID 0x3ba00477 +} + +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +if { [info exists BSTAPID ] } { + # FIXME this never gets used to override defaults... + set _BSTAPID $BSTAPID +} else { + # See STM Document RM0008 + # Section 29.6.2 + # Low density devices, Rev A + set _BSTAPID1 0x06412041 + # Medium density devices, Rev A + set _BSTAPID2 0x06410041 + # Medium density devices, Rev B and Rev Z + set _BSTAPID3 0x16410041 + # High density devices, Rev A + set _BSTAPID4 0x06414041 + # Connectivity line devices, Rev A and Rev Z + set _BSTAPID5 0x06418041 +} +jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ + -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ + -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 + + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME + +$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 +# TODO: native +#$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0 + +flash bank bank0 stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME + +proc flash_chip {} { + echo "Halting..." + reset halt + + echo "Unlocking flash..." + flash protect 0 0 last off + + echo "Erasing..." + flash erase_address 0x08000000 0x20000 + + echo "Flashing image..." + flash write_bank 0 build/maple.bin 0 + + echo "Verifying image..." + verify_image build/maple.bin 0x08000000 bin + + echo "Checksum verified, resetting chip" + reset run + + echo "Daemon shutdown" + shutdown +} + +init +flash_chip diff --git a/Libmaple/libmaple/support/scripts/45-maple.rules b/Libmaple/libmaple/support/scripts/45-maple.rules index 9f902013..d1bda5fb 100644 --- a/Libmaple/libmaple/support/scripts/45-maple.rules +++ b/Libmaple/libmaple/support/scripts/45-maple.rules @@ -1,5 +1,5 @@ -ATTRS{idProduct}=="1001", ATTRS{idVendor}=="0110", MODE="664", GROUP="plugdev" -ATTRS{idProduct}=="1002", ATTRS{idVendor}=="0110", MODE="664", GROUP="plugdev" -ATTRS{idProduct}=="0003", ATTRS{idVendor}=="1eaf", MODE="664", GROUP="plugdev" SYMLINK+="maple" -ATTRS{idProduct}=="0004", ATTRS{idVendor}=="1eaf", MODE="664", GROUP="plugdev" SYMLINK+="maple" - +ATTRS{idProduct}=="1001", ATTRS{idVendor}=="0110", MODE="664", GROUP="plugdev" +ATTRS{idProduct}=="1002", ATTRS{idVendor}=="0110", MODE="664", GROUP="plugdev" +ATTRS{idProduct}=="0003", ATTRS{idVendor}=="1eaf", MODE="664", GROUP="plugdev" SYMLINK+="maple" +ATTRS{idProduct}=="0004", ATTRS{idVendor}=="1eaf", MODE="664", GROUP="plugdev" SYMLINK+="maple" + diff --git a/Libmaple/libmaple/wirish/HardwareTimer.cpp b/Libmaple/libmaple/wirish/HardwareTimer.cpp index 26b72870..08e73d5f 100644 --- a/Libmaple/libmaple/wirish/HardwareTimer.cpp +++ b/Libmaple/libmaple/wirish/HardwareTimer.cpp @@ -1,151 +1,151 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include "HardwareTimer.h" -#include "boards.h" // for CYCLES_PER_MICROSECOND -#include "wirish_math.h" - -// TODO [0.1.0] Remove deprecated pieces - -#ifdef STM32_MEDIUM_DENSITY -#define NR_TIMERS 4 -#elif defined(STM32_HIGH_DENSITY) -#define NR_TIMERS 8 -#else -#error "Unsupported density" -#endif - -#define MAX_RELOAD ((1 << 16) - 1) - -HardwareTimer::HardwareTimer(uint8 timerNum) { - if (timerNum > NR_TIMERS) { - ASSERT(0); - } - timer_dev *devs[] = { - TIMER1, - TIMER2, - TIMER3, - TIMER4, -#ifdef STM32_HIGH_DENSITY - TIMER5, - TIMER6, - TIMER7, - TIMER8, -#endif - }; - this->dev = devs[timerNum - 1]; -} - -void HardwareTimer::pause(void) { - timer_pause(this->dev); -} - -void HardwareTimer::resume(void) { - timer_resume(this->dev); -} - -uint32 HardwareTimer::getPrescaleFactor(void) { - return timer_get_prescaler(this->dev) + 1; -} - -uint32 HardwareTimer::getClockSpeed(void) { - return rcc_dev_timer_clk_speed(this->dev->clk_id); -} - -void HardwareTimer::setPrescaleFactor(uint32 factor) { - timer_set_prescaler(this->dev, (uint16)(factor - 1)); -} - -uint16 HardwareTimer::getOverflow() { - return timer_get_reload(this->dev); -} - -void HardwareTimer::setOverflow(uint16 val) { - timer_set_reload(this->dev, val); -} - -uint16 HardwareTimer::getCount(void) { - return timer_get_count(this->dev); -} - -void HardwareTimer::setCount(uint16 val) { - uint16 ovf = this->getOverflow(); - timer_set_count(this->dev, min(val, ovf)); -} - -uint16 HardwareTimer::setPeriod(uint32 microseconds) { - // Not the best way to handle this edge case? - if (!microseconds) { - this->setPrescaleFactor(1); - this->setOverflow(1); - return this->getOverflow(); - } - - uint32 period_cyc = microseconds * CYCLES_PER_MICROSECOND; - uint16 prescaler = (uint16)(period_cyc / MAX_RELOAD + 1); - uint16 overflow = (uint16)round(period_cyc / prescaler); - this->setPrescaleFactor(prescaler); - this->setOverflow(overflow); - return overflow; -} - -void HardwareTimer::setMode(int channel, timer_mode mode) { - timer_set_mode(this->dev, (uint8)channel, (timer_mode)mode); -} - -uint16 HardwareTimer::getCompare(int channel) { - return timer_get_compare(this->dev, (uint8)channel); -} - -void HardwareTimer::setCompare(int channel, uint16 val) { - uint16 ovf = this->getOverflow(); - timer_set_compare(this->dev, (uint8)channel, min(val, ovf)); -} - -void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) { - timer_attach_interrupt(this->dev, (uint8)channel, handler); -} - -void HardwareTimer::detachInterrupt(int channel) { - timer_detach_interrupt(this->dev, (uint8)channel); -} - -void HardwareTimer::refresh(void) { - timer_generate_update(this->dev); -} - -/* -- Deprecated predefined instances -------------------------------------- */ - -HardwareTimer Timer1(1); -HardwareTimer Timer2(2); -HardwareTimer Timer3(3); -HardwareTimer Timer4(4); -#ifdef STM32_HIGH_DENSITY -HardwareTimer Timer5(5); -HardwareTimer Timer6(6); -HardwareTimer Timer7(7); -HardwareTimer Timer8(8); -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Bryan Newbold. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +#include "HardwareTimer.h" +#include "boards.h" // for CYCLES_PER_MICROSECOND +#include "wirish_math.h" + +// TODO [0.1.0] Remove deprecated pieces + +#ifdef STM32_MEDIUM_DENSITY +#define NR_TIMERS 4 +#elif defined(STM32_HIGH_DENSITY) +#define NR_TIMERS 8 +#else +#error "Unsupported density" +#endif + +#define MAX_RELOAD ((1 << 16) - 1) + +HardwareTimer::HardwareTimer(uint8 timerNum) { + if (timerNum > NR_TIMERS) { + ASSERT(0); + } + timer_dev *devs[] = { + TIMER1, + TIMER2, + TIMER3, + TIMER4, +#ifdef STM32_HIGH_DENSITY + TIMER5, + TIMER6, + TIMER7, + TIMER8, +#endif + }; + this->dev = devs[timerNum - 1]; +} + +void HardwareTimer::pause(void) { + timer_pause(this->dev); +} + +void HardwareTimer::resume(void) { + timer_resume(this->dev); +} + +uint32 HardwareTimer::getPrescaleFactor(void) { + return timer_get_prescaler(this->dev) + 1; +} + +uint32 HardwareTimer::getClockSpeed(void) { + return rcc_dev_timer_clk_speed(this->dev->clk_id); +} + +void HardwareTimer::setPrescaleFactor(uint32 factor) { + timer_set_prescaler(this->dev, (uint16)(factor - 1)); +} + +uint16 HardwareTimer::getOverflow() { + return timer_get_reload(this->dev); +} + +void HardwareTimer::setOverflow(uint16 val) { + timer_set_reload(this->dev, val); +} + +uint16 HardwareTimer::getCount(void) { + return timer_get_count(this->dev); +} + +void HardwareTimer::setCount(uint16 val) { + uint16 ovf = this->getOverflow(); + timer_set_count(this->dev, min(val, ovf)); +} + +uint16 HardwareTimer::setPeriod(uint32 microseconds) { + // Not the best way to handle this edge case? + if (!microseconds) { + this->setPrescaleFactor(1); + this->setOverflow(1); + return this->getOverflow(); + } + + uint32 period_cyc = microseconds * CYCLES_PER_MICROSECOND; + uint16 prescaler = (uint16)(period_cyc / MAX_RELOAD + 1); + uint16 overflow = (uint16)round(period_cyc / prescaler); + this->setPrescaleFactor(prescaler); + this->setOverflow(overflow); + return overflow; +} + +void HardwareTimer::setMode(int channel, timer_mode mode) { + timer_set_mode(this->dev, (uint8)channel, (timer_mode)mode); +} + +uint16 HardwareTimer::getCompare(int channel) { + return timer_get_compare(this->dev, (uint8)channel); +} + +void HardwareTimer::setCompare(int channel, uint16 val) { + uint16 ovf = this->getOverflow(); + timer_set_compare(this->dev, (uint8)channel, min(val, ovf)); +} + +void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) { + timer_attach_interrupt(this->dev, (uint8)channel, handler); +} + +void HardwareTimer::detachInterrupt(int channel) { + timer_detach_interrupt(this->dev, (uint8)channel); +} + +void HardwareTimer::refresh(void) { + timer_generate_update(this->dev); +} + +/* -- Deprecated predefined instances -------------------------------------- */ + +HardwareTimer Timer1(1); +HardwareTimer Timer2(2); +HardwareTimer Timer3(3); +HardwareTimer Timer4(4); +#ifdef STM32_HIGH_DENSITY +HardwareTimer Timer5(5); +HardwareTimer Timer6(6); +HardwareTimer Timer7(7); +HardwareTimer Timer8(8); +#endif diff --git a/Libmaple/libmaple/wirish/HardwareTimer.h b/Libmaple/libmaple/wirish/HardwareTimer.h index 6d7a0eb9..89e35649 100644 --- a/Libmaple/libmaple/wirish/HardwareTimer.h +++ b/Libmaple/libmaple/wirish/HardwareTimer.h @@ -1,337 +1,337 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief Wirish timer class. - */ - -#ifndef _HARDWARETIMER_H_ -#define _HARDWARETIMER_H_ - -// TODO [0.1.0] Remove deprecated pieces, pick a better API - -#include "timer.h" - -/** Timer mode. */ -typedef timer_mode TimerMode; - -/** @brief Deprecated; use TIMER_OUTPUT_COMPARE instead. */ -#define TIMER_OUTPUTCOMPARE TIMER_OUTPUT_COMPARE - -/** - * @brief Interface to one of the 16-bit timer peripherals. - */ -class HardwareTimer { -private: - timer_dev *dev; - -public: - /** - * @brief Construct a new HardwareTimer instance. - * @param timerNum number of the timer to control. - */ - HardwareTimer(uint8 timerNum); - - /** - * @brief Stop the counter, without affecting its configuration. - * - * @see HardwareTimer::resume() - */ - void pause(void); - - /** - * @brief Resume a paused timer, without affecting its configuration. - * - * The timer will resume counting and firing interrupts as - * appropriate. - * - * Note that there is some function call overhead associated with - * using this method, so using it in concert with - * HardwareTimer::pause() is not a robust way to align multiple - * timers to the same count value. - * - * @see HardwareTimer::pause() - */ - void resume(void); - - /** - * @brief Get the timer's clock speed. - * @return Timer input clock speed in Hz/second - */ - uint32 getClockSpeed(void); - - /** - * @brief Get the timer's prescale factor. - * @return Timer prescaler, from 1 to 65,536. - * @see HardwareTimer::setPrescaleFactor() - */ - uint32 getPrescaleFactor(); - - /** - * @brief Set the timer's prescale factor. - * - * The new value won't take effect until the next time the counter - * overflows. You can force the counter to reset using - * HardwareTimer::refresh(). - * - * @param factor The new prescale value to set, from 1 to 65,536. - * @see HardwareTimer::refresh() - */ - void setPrescaleFactor(uint32 factor); - - /** - * @brief Get the timer overflow value. - * @see HardwareTimer::setOverflow() - */ - uint16 getOverflow(); - - /** - * @brief Set the timer overflow (or "reload") value. - * - * The new value won't take effect until the next time the counter - * overflows. You can force the counter to reset using - * HardwareTimer::refresh(). - * - * @param val The new overflow value to set - * @see HardwareTimer::refresh() - */ - void setOverflow(uint16 val); - - /** - * @brief Get the current timer count. - * - * @return The timer's current count value - */ - uint16 getCount(void); - - /** - * @brief Set the current timer count. - * - * @param val The new count value to set. If this value exceeds - * the timer's overflow value, it is truncated to the - * overflow value. - */ - void setCount(uint16 val); - - /** - * @brief Set the timer's period in microseconds. - * - * Configures the prescaler and overflow values to generate a timer - * reload with a period as close to the given number of - * microseconds as possible. - * - * @param microseconds The desired period of the timer. This must be - * greater than zero. - * @return The new overflow value. - */ - uint16 setPeriod(uint32 microseconds); - - /** - * @brief Configure a timer channel's mode. - * @param channel Timer channel, from 1 to 4 - * @param mode Mode to set - */ - void setMode(int channel, timer_mode mode); - - /** - * @brief Get the compare value for the given channel. - * @see HardwareTimer::setCompare() - */ - uint16 getCompare(int channel); - - /** - * @brief Set the compare value for the given channel. - * - * @param channel the channel whose compare to set, from 1 to 4. - * @param compare The compare value to set. If greater than this - * timer's overflow value, it will be truncated to - * the overflow value. - * - * @see timer_mode - * @see HardwareTimer::setMode() - * @see HardwareTimer::attachInterrupt() - */ - void setCompare(int channel, uint16 compare); - - /** - * @brief Attach an interrupt handler to the given channel. - * - * This interrupt handler will be called when the timer's counter - * reaches the given channel compare value. - * - * @param channel the channel to attach the ISR to, from 1 to 4. - * @param handler The ISR to attach to the given channel. - * @see voidFuncPtr - */ - void attachInterrupt(int channel, voidFuncPtr handler); - - /** - * @brief Remove the interrupt handler attached to the given - * channel, if any. - * - * The handler will no longer be called by this timer. - * - * @param channel the channel whose interrupt to detach, from 1 to 4. - * @see HardwareTimer::attachInterrupt() - */ - void detachInterrupt(int channel); - - /** - * @brief Reset the counter, and update the prescaler and overflow - * values. - * - * This will reset the counter to 0 in upcounting mode (the - * default). It will also update the timer's prescaler and - * overflow, if you have set them up to be changed using - * HardwareTimer::setPrescaleFactor() or - * HardwareTimer::setOverflow(). - * - * @see HardwareTimer::setPrescaleFactor() - * @see HardwareTimer::setOverflow() - */ - void refresh(void); - - /* -- Deprecated methods ----------------------------------------------- */ - - /** @brief Deprecated; use setMode(channel, mode) instead. */ - void setChannelMode(int channel, timer_mode mode) { - setMode(channel, mode); - } - - /** @brief Deprecated; use setMode(TIMER_CH1, mode) instead. */ - void setChannel1Mode(timer_mode mode) { setMode(TIMER_CH1, mode); } - - /** @brief Deprecated; use setMode(TIMER_CH2, mode) instead. */ - void setChannel2Mode(timer_mode mode) { setMode(TIMER_CH2, mode); } - - /** @brief Deprecated; use setMode(TIMER_CH3, mode) instead. */ - void setChannel3Mode(timer_mode mode) { setMode(TIMER_CH3, mode); } - - /** @brief Deprecated; use setMode(TIMER_CH4, mode) instead. */ - void setChannel4Mode(timer_mode mode) { setMode(TIMER_CH4, mode); } - - /** @brief Deprecated; use return getCompare(TIMER_CH1) instead. */ - uint16 getCompare1() { return getCompare(TIMER_CH1); } - - /** @brief Deprecated; use return getCompare(TIMER_CH2) instead. */ - uint16 getCompare2() { return getCompare(TIMER_CH2); } - - /** @brief Deprecated; use return getCompare(TIMER_CH3) instead. */ - uint16 getCompare3() { return getCompare(TIMER_CH3); } - - /** @brief Deprecated; use return getCompare(TIMER_CH4) instead. */ - uint16 getCompare4() { return getCompare(TIMER_CH4); } - - /** @brief Deprecated; use setCompare(TIMER_CH1, compare) instead. */ - void setCompare1(uint16 compare) { setCompare(TIMER_CH1, compare); } - - /** @brief Deprecated; use setCompare(TIMER_CH2, compare) instead. */ - void setCompare2(uint16 compare) { setCompare(TIMER_CH2, compare); } - - /** @brief Deprecated; use setCompare(TIMER_CH3, compare) instead. */ - void setCompare3(uint16 compare) { setCompare(TIMER_CH3, compare); } - - /** @brief Deprecated; use setCompare(TIMER_CH4, compare) instead. */ - void setCompare4(uint16 compare) { setCompare(TIMER_CH4, compare); } - - /** @brief Deprecated; use attachInterrupt(TIMER_CH1, handler) instead. */ - void attachCompare1Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH1, handler); - } - - /** @brief Deprecated; use attachInterrupt(TIMER_CH2, handler) instead. */ - void attachCompare2Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH2, handler); - } - - /** @brief Deprecated; use attachInterrupt(TIMER_CH3, handler) instead. */ - void attachCompare3Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH3, handler); - } - - /** @brief Deprecated; use attachInterrupt(TIMER_CH4, handler) instead. */ - void attachCompare4Interrupt(voidFuncPtr handler) { - attachInterrupt(TIMER_CH4, handler); - } - - /** @brief Deprecated; use detachInterrupt(TIMER_CH1) instead. */ - void detachCompare1Interrupt(void) { detachInterrupt(TIMER_CH1); } - - /** @brief Deprecated; use detachInterrupt(TIMER_CH2) instead. */ - void detachCompare2Interrupt(void) { detachInterrupt(TIMER_CH2); } - - /** @brief Deprecated; use detachInterrupt(TIMER_CH3) instead. */ - void detachCompare3Interrupt(void) { detachInterrupt(TIMER_CH3); } - - /** @brief Deprecated; use detachInterrupt(TIMER_CH4) instead. */ - void detachCompare4Interrupt(void) { detachInterrupt(TIMER_CH4); } - - /** @brief Deprecated; use refresh() instead. */ - void generateUpdate(void) { refresh(); } -}; - -/* -- The rest of this file is deprecated. --------------------------------- */ - -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer1; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer2; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer3; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer4; -#ifdef STM32_HIGH_DENSITY -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer5; -/** - * @brief Deprecated. - * - * Pre-instantiated timer. - */ -extern HardwareTimer Timer8; -#endif - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Bryan Newbold. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief Wirish timer class. + */ + +#ifndef _HARDWARETIMER_H_ +#define _HARDWARETIMER_H_ + +// TODO [0.1.0] Remove deprecated pieces, pick a better API + +#include "timer.h" + +/** Timer mode. */ +typedef timer_mode TimerMode; + +/** @brief Deprecated; use TIMER_OUTPUT_COMPARE instead. */ +#define TIMER_OUTPUTCOMPARE TIMER_OUTPUT_COMPARE + +/** + * @brief Interface to one of the 16-bit timer peripherals. + */ +class HardwareTimer { +private: + timer_dev *dev; + +public: + /** + * @brief Construct a new HardwareTimer instance. + * @param timerNum number of the timer to control. + */ + HardwareTimer(uint8 timerNum); + + /** + * @brief Stop the counter, without affecting its configuration. + * + * @see HardwareTimer::resume() + */ + void pause(void); + + /** + * @brief Resume a paused timer, without affecting its configuration. + * + * The timer will resume counting and firing interrupts as + * appropriate. + * + * Note that there is some function call overhead associated with + * using this method, so using it in concert with + * HardwareTimer::pause() is not a robust way to align multiple + * timers to the same count value. + * + * @see HardwareTimer::pause() + */ + void resume(void); + + /** + * @brief Get the timer's clock speed. + * @return Timer input clock speed in Hz/second + */ + uint32 getClockSpeed(void); + + /** + * @brief Get the timer's prescale factor. + * @return Timer prescaler, from 1 to 65,536. + * @see HardwareTimer::setPrescaleFactor() + */ + uint32 getPrescaleFactor(); + + /** + * @brief Set the timer's prescale factor. + * + * The new value won't take effect until the next time the counter + * overflows. You can force the counter to reset using + * HardwareTimer::refresh(). + * + * @param factor The new prescale value to set, from 1 to 65,536. + * @see HardwareTimer::refresh() + */ + void setPrescaleFactor(uint32 factor); + + /** + * @brief Get the timer overflow value. + * @see HardwareTimer::setOverflow() + */ + uint16 getOverflow(); + + /** + * @brief Set the timer overflow (or "reload") value. + * + * The new value won't take effect until the next time the counter + * overflows. You can force the counter to reset using + * HardwareTimer::refresh(). + * + * @param val The new overflow value to set + * @see HardwareTimer::refresh() + */ + void setOverflow(uint16 val); + + /** + * @brief Get the current timer count. + * + * @return The timer's current count value + */ + uint16 getCount(void); + + /** + * @brief Set the current timer count. + * + * @param val The new count value to set. If this value exceeds + * the timer's overflow value, it is truncated to the + * overflow value. + */ + void setCount(uint16 val); + + /** + * @brief Set the timer's period in microseconds. + * + * Configures the prescaler and overflow values to generate a timer + * reload with a period as close to the given number of + * microseconds as possible. + * + * @param microseconds The desired period of the timer. This must be + * greater than zero. + * @return The new overflow value. + */ + uint16 setPeriod(uint32 microseconds); + + /** + * @brief Configure a timer channel's mode. + * @param channel Timer channel, from 1 to 4 + * @param mode Mode to set + */ + void setMode(int channel, timer_mode mode); + + /** + * @brief Get the compare value for the given channel. + * @see HardwareTimer::setCompare() + */ + uint16 getCompare(int channel); + + /** + * @brief Set the compare value for the given channel. + * + * @param channel the channel whose compare to set, from 1 to 4. + * @param compare The compare value to set. If greater than this + * timer's overflow value, it will be truncated to + * the overflow value. + * + * @see timer_mode + * @see HardwareTimer::setMode() + * @see HardwareTimer::attachInterrupt() + */ + void setCompare(int channel, uint16 compare); + + /** + * @brief Attach an interrupt handler to the given channel. + * + * This interrupt handler will be called when the timer's counter + * reaches the given channel compare value. + * + * @param channel the channel to attach the ISR to, from 1 to 4. + * @param handler The ISR to attach to the given channel. + * @see voidFuncPtr + */ + void attachInterrupt(int channel, voidFuncPtr handler); + + /** + * @brief Remove the interrupt handler attached to the given + * channel, if any. + * + * The handler will no longer be called by this timer. + * + * @param channel the channel whose interrupt to detach, from 1 to 4. + * @see HardwareTimer::attachInterrupt() + */ + void detachInterrupt(int channel); + + /** + * @brief Reset the counter, and update the prescaler and overflow + * values. + * + * This will reset the counter to 0 in upcounting mode (the + * default). It will also update the timer's prescaler and + * overflow, if you have set them up to be changed using + * HardwareTimer::setPrescaleFactor() or + * HardwareTimer::setOverflow(). + * + * @see HardwareTimer::setPrescaleFactor() + * @see HardwareTimer::setOverflow() + */ + void refresh(void); + + /* -- Deprecated methods ----------------------------------------------- */ + + /** @brief Deprecated; use setMode(channel, mode) instead. */ + void setChannelMode(int channel, timer_mode mode) { + setMode(channel, mode); + } + + /** @brief Deprecated; use setMode(TIMER_CH1, mode) instead. */ + void setChannel1Mode(timer_mode mode) { setMode(TIMER_CH1, mode); } + + /** @brief Deprecated; use setMode(TIMER_CH2, mode) instead. */ + void setChannel2Mode(timer_mode mode) { setMode(TIMER_CH2, mode); } + + /** @brief Deprecated; use setMode(TIMER_CH3, mode) instead. */ + void setChannel3Mode(timer_mode mode) { setMode(TIMER_CH3, mode); } + + /** @brief Deprecated; use setMode(TIMER_CH4, mode) instead. */ + void setChannel4Mode(timer_mode mode) { setMode(TIMER_CH4, mode); } + + /** @brief Deprecated; use return getCompare(TIMER_CH1) instead. */ + uint16 getCompare1() { return getCompare(TIMER_CH1); } + + /** @brief Deprecated; use return getCompare(TIMER_CH2) instead. */ + uint16 getCompare2() { return getCompare(TIMER_CH2); } + + /** @brief Deprecated; use return getCompare(TIMER_CH3) instead. */ + uint16 getCompare3() { return getCompare(TIMER_CH3); } + + /** @brief Deprecated; use return getCompare(TIMER_CH4) instead. */ + uint16 getCompare4() { return getCompare(TIMER_CH4); } + + /** @brief Deprecated; use setCompare(TIMER_CH1, compare) instead. */ + void setCompare1(uint16 compare) { setCompare(TIMER_CH1, compare); } + + /** @brief Deprecated; use setCompare(TIMER_CH2, compare) instead. */ + void setCompare2(uint16 compare) { setCompare(TIMER_CH2, compare); } + + /** @brief Deprecated; use setCompare(TIMER_CH3, compare) instead. */ + void setCompare3(uint16 compare) { setCompare(TIMER_CH3, compare); } + + /** @brief Deprecated; use setCompare(TIMER_CH4, compare) instead. */ + void setCompare4(uint16 compare) { setCompare(TIMER_CH4, compare); } + + /** @brief Deprecated; use attachInterrupt(TIMER_CH1, handler) instead. */ + void attachCompare1Interrupt(voidFuncPtr handler) { + attachInterrupt(TIMER_CH1, handler); + } + + /** @brief Deprecated; use attachInterrupt(TIMER_CH2, handler) instead. */ + void attachCompare2Interrupt(voidFuncPtr handler) { + attachInterrupt(TIMER_CH2, handler); + } + + /** @brief Deprecated; use attachInterrupt(TIMER_CH3, handler) instead. */ + void attachCompare3Interrupt(voidFuncPtr handler) { + attachInterrupt(TIMER_CH3, handler); + } + + /** @brief Deprecated; use attachInterrupt(TIMER_CH4, handler) instead. */ + void attachCompare4Interrupt(voidFuncPtr handler) { + attachInterrupt(TIMER_CH4, handler); + } + + /** @brief Deprecated; use detachInterrupt(TIMER_CH1) instead. */ + void detachCompare1Interrupt(void) { detachInterrupt(TIMER_CH1); } + + /** @brief Deprecated; use detachInterrupt(TIMER_CH2) instead. */ + void detachCompare2Interrupt(void) { detachInterrupt(TIMER_CH2); } + + /** @brief Deprecated; use detachInterrupt(TIMER_CH3) instead. */ + void detachCompare3Interrupt(void) { detachInterrupt(TIMER_CH3); } + + /** @brief Deprecated; use detachInterrupt(TIMER_CH4) instead. */ + void detachCompare4Interrupt(void) { detachInterrupt(TIMER_CH4); } + + /** @brief Deprecated; use refresh() instead. */ + void generateUpdate(void) { refresh(); } +}; + +/* -- The rest of this file is deprecated. --------------------------------- */ + +/** + * @brief Deprecated. + * + * Pre-instantiated timer. + */ +extern HardwareTimer Timer1; +/** + * @brief Deprecated. + * + * Pre-instantiated timer. + */ +extern HardwareTimer Timer2; +/** + * @brief Deprecated. + * + * Pre-instantiated timer. + */ +extern HardwareTimer Timer3; +/** + * @brief Deprecated. + * + * Pre-instantiated timer. + */ +extern HardwareTimer Timer4; +#ifdef STM32_HIGH_DENSITY +/** + * @brief Deprecated. + * + * Pre-instantiated timer. + */ +extern HardwareTimer Timer5; +/** + * @brief Deprecated. + * + * Pre-instantiated timer. + */ +extern HardwareTimer Timer8; +#endif + +#endif diff --git a/Libmaple/libmaple/wirish/Print.cpp b/Libmaple/libmaple/wirish/Print.cpp index adaa5a53..58c7cc7b 100644 --- a/Libmaple/libmaple/wirish/Print.cpp +++ b/Libmaple/libmaple/wirish/Print.cpp @@ -1,252 +1,252 @@ -/* - * Print.cpp - Base class that provides print() and println() - * Copyright (c) 2008 David A. Mellis. All right reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - * Modified 23 November 2006 by David A. Mellis - * Modified 12 April 2011 by Marti Bolivar - */ - -#include "Print.h" - -#include - -#ifndef LLONG_MAX -/* - * Note: - * - * At time of writing (12 April 2011), the limits.h that came with the - * newlib we distributed didn't include LLONG_MAX. Because we're - * staying away from using templates (see /notes/coding_standard.rst, - * "Language Features and Compiler Extensions"), this value was - * copy-pasted from a println() of the value - * - * std::numeric_limits::max(). - */ -#define LLONG_MAX 9223372036854775807LL -#endif - -#include "wirish_math.h" - -/* - * Public methods - */ - -void Print::write(const char *str) { - while (*str) { - write(*str++); - } -} - -void Print::write(const void *buffer, uint32 size) { - uint8 *ch = (uint8*)buffer; - while (size--) { - write(*ch++); - } -} - -void Print::print(uint8 b, int base) { - print((uint64)b, base); -} - -void Print::print(char c) { - write(c); -} - -void Print::print(const char str[]) { - write(str); -} - -void Print::print(int n, int base) { - print((long long)n, base); -} - -void Print::print(unsigned int n, int base) { - print((unsigned long long)n, base); -} - -void Print::print(long n, int base) { - print((long long)n, base); -} - -void Print::print(unsigned long n, int base) { - print((unsigned long long)n, base); -} - -void Print::print(long long n, int base) { - if (base == BYTE) { - write((uint8)n); - return; - } - if (n < 0) { - print('-'); - n = -n; - } - printNumber(n, base); -} - -void Print::print(unsigned long long n, int base) { - if (base == BYTE) { - write((uint8)n); - } else { - printNumber(n, base); - } -} - -void Print::print(double n, int digits) { - printFloat(n, digits); -} - -void Print::println(void) { - print('\r'); - print('\n'); -} - -void Print::println(char c) { - print(c); - println(); -} - -void Print::println(const char c[]) { - print(c); - println(); -} - -void Print::println(uint8 b, int base) { - print(b, base); - println(); -} - -void Print::println(int n, int base) { - print(n, base); - println(); -} - -void Print::println(unsigned int n, int base) { - print(n, base); - println(); -} - -void Print::println(long n, int base) { - print((long long)n, base); - println(); -} - -void Print::println(unsigned long n, int base) { - print((unsigned long long)n, base); - println(); -} - -void Print::println(long long n, int base) { - print(n, base); - println(); -} - -void Print::println(unsigned long long n, int base) { - print(n, base); - println(); -} - -void Print::println(double n, int digits) { - print(n, digits); - println(); -} - -/* - * Private methods - */ - -void Print::printNumber(unsigned long long n, uint8 base) { - unsigned char buf[CHAR_BIT * sizeof(long long)]; - unsigned long i = 0; - - if (n == 0) { - print('0'); - return; - } - - while (n > 0) { - buf[i++] = n % base; - n /= base; - } - - for (; i > 0; i--) { - print((char)(buf[i - 1] < 10 ? - '0' + buf[i - 1] : - 'A' + buf[i - 1] - 10)); - } -} - -/* According to snprintf(), - * - * nextafter((double)numeric_limits::max(), 0.0) ~= 9.22337e+18 - * - * This slightly smaller value was picked semi-arbitrarily. */ -#define LARGE_DOUBLE_TRESHOLD (9.1e18) - -/* THIS FUNCTION SHOULDN'T BE USED IF YOU NEED ACCURATE RESULTS. - * - * This implementation is meant to be simple and not occupy too much - * code size. However, printing floating point values accurately is a - * subtle task, best left to a well-tested library function. - * - * See Steele and White 2003 for more details: - * - * http://kurtstephens.com/files/p372-steele.pdf - */ -void Print::printFloat(double number, uint8 digits) { - // Hackish fail-fast behavior for large-magnitude doubles - if (abs(number) >= LARGE_DOUBLE_TRESHOLD) { - if (number < 0.0) { - print('-'); - } - print(""); - return; - } - - // Handle negative numbers - if (number < 0.0) { - print('-'); - number = -number; - } - - // Simplistic rounding strategy so that e.g. print(1.999, 2) - // prints as "2.00" - double rounding = 0.5; - for (uint8 i = 0; i < digits; i++) { - rounding /= 10.0; - } - number += rounding; - - // Extract the integer part of the number and print it - long long int_part = (long long)number; - double remainder = number - int_part; - print(int_part); - - // Print the decimal point, but only if there are digits beyond - if (digits > 0) { - print("."); - } - - // Extract digits from the remainder one at a time - while (digits-- > 0) { - remainder *= 10.0; - int to_print = (int)remainder; - print(to_print); - remainder -= to_print; - } -} +/* + * Print.cpp - Base class that provides print() and println() + * Copyright (c) 2008 David A. Mellis. All right reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Modified 23 November 2006 by David A. Mellis + * Modified 12 April 2011 by Marti Bolivar + */ + +#include "Print.h" + +#include + +#ifndef LLONG_MAX +/* + * Note: + * + * At time of writing (12 April 2011), the limits.h that came with the + * newlib we distributed didn't include LLONG_MAX. Because we're + * staying away from using templates (see /notes/coding_standard.rst, + * "Language Features and Compiler Extensions"), this value was + * copy-pasted from a println() of the value + * + * std::numeric_limits::max(). + */ +#define LLONG_MAX 9223372036854775807LL +#endif + +#include "wirish_math.h" + +/* + * Public methods + */ + +void Print::write(const char *str) { + while (*str) { + write(*str++); + } +} + +void Print::write(const void *buffer, uint32 size) { + uint8 *ch = (uint8*)buffer; + while (size--) { + write(*ch++); + } +} + +void Print::print(uint8 b, int base) { + print((uint64)b, base); +} + +void Print::print(char c) { + write(c); +} + +void Print::print(const char str[]) { + write(str); +} + +void Print::print(int n, int base) { + print((long long)n, base); +} + +void Print::print(unsigned int n, int base) { + print((unsigned long long)n, base); +} + +void Print::print(long n, int base) { + print((long long)n, base); +} + +void Print::print(unsigned long n, int base) { + print((unsigned long long)n, base); +} + +void Print::print(long long n, int base) { + if (base == BYTE) { + write((uint8)n); + return; + } + if (n < 0) { + print('-'); + n = -n; + } + printNumber(n, base); +} + +void Print::print(unsigned long long n, int base) { + if (base == BYTE) { + write((uint8)n); + } else { + printNumber(n, base); + } +} + +void Print::print(double n, int digits) { + printFloat(n, digits); +} + +void Print::println(void) { + print('\r'); + print('\n'); +} + +void Print::println(char c) { + print(c); + println(); +} + +void Print::println(const char c[]) { + print(c); + println(); +} + +void Print::println(uint8 b, int base) { + print(b, base); + println(); +} + +void Print::println(int n, int base) { + print(n, base); + println(); +} + +void Print::println(unsigned int n, int base) { + print(n, base); + println(); +} + +void Print::println(long n, int base) { + print((long long)n, base); + println(); +} + +void Print::println(unsigned long n, int base) { + print((unsigned long long)n, base); + println(); +} + +void Print::println(long long n, int base) { + print(n, base); + println(); +} + +void Print::println(unsigned long long n, int base) { + print(n, base); + println(); +} + +void Print::println(double n, int digits) { + print(n, digits); + println(); +} + +/* + * Private methods + */ + +void Print::printNumber(unsigned long long n, uint8 base) { + unsigned char buf[CHAR_BIT * sizeof(long long)]; + unsigned long i = 0; + + if (n == 0) { + print('0'); + return; + } + + while (n > 0) { + buf[i++] = n % base; + n /= base; + } + + for (; i > 0; i--) { + print((char)(buf[i - 1] < 10 ? + '0' + buf[i - 1] : + 'A' + buf[i - 1] - 10)); + } +} + +/* According to snprintf(), + * + * nextafter((double)numeric_limits::max(), 0.0) ~= 9.22337e+18 + * + * This slightly smaller value was picked semi-arbitrarily. */ +#define LARGE_DOUBLE_TRESHOLD (9.1e18) + +/* THIS FUNCTION SHOULDN'T BE USED IF YOU NEED ACCURATE RESULTS. + * + * This implementation is meant to be simple and not occupy too much + * code size. However, printing floating point values accurately is a + * subtle task, best left to a well-tested library function. + * + * See Steele and White 2003 for more details: + * + * http://kurtstephens.com/files/p372-steele.pdf + */ +void Print::printFloat(double number, uint8 digits) { + // Hackish fail-fast behavior for large-magnitude doubles + if (abs(number) >= LARGE_DOUBLE_TRESHOLD) { + if (number < 0.0) { + print('-'); + } + print(""); + return; + } + + // Handle negative numbers + if (number < 0.0) { + print('-'); + number = -number; + } + + // Simplistic rounding strategy so that e.g. print(1.999, 2) + // prints as "2.00" + double rounding = 0.5; + for (uint8 i = 0; i < digits; i++) { + rounding /= 10.0; + } + number += rounding; + + // Extract the integer part of the number and print it + long long int_part = (long long)number; + double remainder = number - int_part; + print(int_part); + + // Print the decimal point, but only if there are digits beyond + if (digits > 0) { + print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) { + remainder *= 10.0; + int to_print = (int)remainder; + print(to_print); + remainder -= to_print; + } +} diff --git a/Libmaple/libmaple/wirish/Print.h b/Libmaple/libmaple/wirish/Print.h index fbe372ac..c0c63cb8 100644 --- a/Libmaple/libmaple/wirish/Print.h +++ b/Libmaple/libmaple/wirish/Print.h @@ -1,67 +1,67 @@ -/* - * Print.h - Base class that provides print() and println() - * Copyright (c) 2008 David A. Mellis. All right reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA. - * - * Modified 12 April 2011 by Marti Bolivar - */ - -#ifndef _PRINT_H_ -#define _PRINT_H_ - -#include "libmaple_types.h" - -enum { - BYTE = 0, - BIN = 2, - OCT = 8, - DEC = 10, - HEX = 16 -}; - -class Print { -public: - virtual void write(uint8 ch) = 0; - virtual void write(const char *str); - virtual void write(const void *buf, uint32 len); - void print(char); - void print(const char[]); - void print(uint8, int=DEC); - void print(int, int=DEC); - void print(unsigned int, int=DEC); - void print(long, int=DEC); - void print(unsigned long, int=DEC); - void print(long long, int=DEC); - void print(unsigned long long, int=DEC); - void print(double, int=2); - void println(void); - void println(char); - void println(const char[]); - void println(uint8, int=DEC); - void println(int, int=DEC); - void println(unsigned int, int=DEC); - void println(long, int=DEC); - void println(unsigned long, int=DEC); - void println(long long, int=DEC); - void println(unsigned long long, int=DEC); - void println(double, int=2); -private: - void printNumber(unsigned long long, uint8); - void printFloat(double, uint8); -}; - -#endif +/* + * Print.h - Base class that provides print() and println() + * Copyright (c) 2008 David A. Mellis. All right reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * Modified 12 April 2011 by Marti Bolivar + */ + +#ifndef _PRINT_H_ +#define _PRINT_H_ + +#include "libmaple_types.h" + +enum { + BYTE = 0, + BIN = 2, + OCT = 8, + DEC = 10, + HEX = 16 +}; + +class Print { +public: + virtual void write(uint8 ch) = 0; + virtual void write(const char *str); + virtual void write(const void *buf, uint32 len); + void print(char); + void print(const char[]); + void print(uint8, int=DEC); + void print(int, int=DEC); + void print(unsigned int, int=DEC); + void print(long, int=DEC); + void print(unsigned long, int=DEC); + void print(long long, int=DEC); + void print(unsigned long long, int=DEC); + void print(double, int=2); + void println(void); + void println(char); + void println(const char[]); + void println(uint8, int=DEC); + void println(int, int=DEC); + void println(unsigned int, int=DEC); + void println(long, int=DEC); + void println(unsigned long, int=DEC); + void println(long long, int=DEC); + void println(unsigned long long, int=DEC); + void println(double, int=2); +private: + void printNumber(unsigned long long, uint8); + void printFloat(double, uint8); +}; + +#endif diff --git a/Libmaple/libmaple/wirish/WProgram.h b/Libmaple/libmaple/wirish/WProgram.h index 2c454e8f..2949a0a5 100644 --- a/Libmaple/libmaple/wirish/WProgram.h +++ b/Libmaple/libmaple/wirish/WProgram.h @@ -1,30 +1,30 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include "wirish.h" - -void setup(); -void loop(); +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +#include "wirish.h" + +void setup(); +void loop(); diff --git a/Libmaple/libmaple/wirish/bit_constants.h b/Libmaple/libmaple/wirish/bit_constants.h index 1da9c214..8accc6b8 100644 --- a/Libmaple/libmaple/wirish/bit_constants.h +++ b/Libmaple/libmaple/wirish/bit_constants.h @@ -1,579 +1,579 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief BIT[n] and binary literal defines, for Arduino - * compatibility. - */ - -#ifndef _BIT_CONSTANTS_H_ -#define _BIT_CONSTANTS_H_ - -#define BIT0 (1 << 0) -#define BIT1 (1 << 1) -#define BIT2 (1 << 2) -#define BIT3 (1 << 3) -#define BIT4 (1 << 4) -#define BIT5 (1 << 5) -#define BIT6 (1 << 6) -#define BIT7 (1 << 7) -#define BIT8 (1 << 8) -#define BIT9 (1 << 9) -#define BIT10 (1 << 10) -#define BIT11 (1 << 11) -#define BIT12 (1 << 12) -#define BIT13 (1 << 13) -#define BIT14 (1 << 14) -#define BIT15 (1 << 15) -#define BIT16 (1 << 16) -#define BIT17 (1 << 17) -#define BIT18 (1 << 18) -#define BIT19 (1 << 19) -#define BIT20 (1 << 20) -#define BIT21 (1 << 21) -#define BIT22 (1 << 22) -#define BIT23 (1 << 23) -#define BIT24 (1 << 24) -#define BIT25 (1 << 25) -#define BIT26 (1 << 26) -#define BIT27 (1 << 27) -#define BIT28 (1 << 28) -#define BIT29 (1 << 29) -#define BIT30 (1 << 30) -#define BIT31 (1 << 31) - -#define B0 0 -#define B00 0 -#define B000 0 -#define B0000 0 -#define B00000 0 -#define B000000 0 -#define B0000000 0 -#define B00000000 0 -#define B1 1 -#define B01 1 -#define B001 1 -#define B0001 1 -#define B00001 1 -#define B000001 1 -#define B0000001 1 -#define B00000001 1 -#define B10 2 -#define B010 2 -#define B0010 2 -#define B00010 2 -#define B000010 2 -#define B0000010 2 -#define B00000010 2 -#define B11 3 -#define B011 3 -#define B0011 3 -#define B00011 3 -#define B000011 3 -#define B0000011 3 -#define B00000011 3 -#define B100 4 -#define B0100 4 -#define B00100 4 -#define B000100 4 -#define B0000100 4 -#define B00000100 4 -#define B101 5 -#define B0101 5 -#define B00101 5 -#define B000101 5 -#define B0000101 5 -#define B00000101 5 -#define B110 6 -#define B0110 6 -#define B00110 6 -#define B000110 6 -#define B0000110 6 -#define B00000110 6 -#define B111 7 -#define B0111 7 -#define B00111 7 -#define B000111 7 -#define B0000111 7 -#define B00000111 7 -#define B1000 8 -#define B01000 8 -#define B001000 8 -#define B0001000 8 -#define B00001000 8 -#define B1001 9 -#define B01001 9 -#define B001001 9 -#define B0001001 9 -#define B00001001 9 -#define B1010 10 -#define B01010 10 -#define B001010 10 -#define B0001010 10 -#define B00001010 10 -#define B1011 11 -#define B01011 11 -#define B001011 11 -#define B0001011 11 -#define B00001011 11 -#define B1100 12 -#define B01100 12 -#define B001100 12 -#define B0001100 12 -#define B00001100 12 -#define B1101 13 -#define B01101 13 -#define B001101 13 -#define B0001101 13 -#define B00001101 13 -#define B1110 14 -#define B01110 14 -#define B001110 14 -#define B0001110 14 -#define B00001110 14 -#define B1111 15 -#define B01111 15 -#define B001111 15 -#define B0001111 15 -#define B00001111 15 -#define B10000 16 -#define B010000 16 -#define B0010000 16 -#define B00010000 16 -#define B10001 17 -#define B010001 17 -#define B0010001 17 -#define B00010001 17 -#define B10010 18 -#define B010010 18 -#define B0010010 18 -#define B00010010 18 -#define B10011 19 -#define B010011 19 -#define B0010011 19 -#define B00010011 19 -#define B10100 20 -#define B010100 20 -#define B0010100 20 -#define B00010100 20 -#define B10101 21 -#define B010101 21 -#define B0010101 21 -#define B00010101 21 -#define B10110 22 -#define B010110 22 -#define B0010110 22 -#define B00010110 22 -#define B10111 23 -#define B010111 23 -#define B0010111 23 -#define B00010111 23 -#define B11000 24 -#define B011000 24 -#define B0011000 24 -#define B00011000 24 -#define B11001 25 -#define B011001 25 -#define B0011001 25 -#define B00011001 25 -#define B11010 26 -#define B011010 26 -#define B0011010 26 -#define B00011010 26 -#define B11011 27 -#define B011011 27 -#define B0011011 27 -#define B00011011 27 -#define B11100 28 -#define B011100 28 -#define B0011100 28 -#define B00011100 28 -#define B11101 29 -#define B011101 29 -#define B0011101 29 -#define B00011101 29 -#define B11110 30 -#define B011110 30 -#define B0011110 30 -#define B00011110 30 -#define B11111 31 -#define B011111 31 -#define B0011111 31 -#define B00011111 31 -#define B100000 32 -#define B0100000 32 -#define B00100000 32 -#define B100001 33 -#define B0100001 33 -#define B00100001 33 -#define B100010 34 -#define B0100010 34 -#define B00100010 34 -#define B100011 35 -#define B0100011 35 -#define B00100011 35 -#define B100100 36 -#define B0100100 36 -#define B00100100 36 -#define B100101 37 -#define B0100101 37 -#define B00100101 37 -#define B100110 38 -#define B0100110 38 -#define B00100110 38 -#define B100111 39 -#define B0100111 39 -#define B00100111 39 -#define B101000 40 -#define B0101000 40 -#define B00101000 40 -#define B101001 41 -#define B0101001 41 -#define B00101001 41 -#define B101010 42 -#define B0101010 42 -#define B00101010 42 -#define B101011 43 -#define B0101011 43 -#define B00101011 43 -#define B101100 44 -#define B0101100 44 -#define B00101100 44 -#define B101101 45 -#define B0101101 45 -#define B00101101 45 -#define B101110 46 -#define B0101110 46 -#define B00101110 46 -#define B101111 47 -#define B0101111 47 -#define B00101111 47 -#define B110000 48 -#define B0110000 48 -#define B00110000 48 -#define B110001 49 -#define B0110001 49 -#define B00110001 49 -#define B110010 50 -#define B0110010 50 -#define B00110010 50 -#define B110011 51 -#define B0110011 51 -#define B00110011 51 -#define B110100 52 -#define B0110100 52 -#define B00110100 52 -#define B110101 53 -#define B0110101 53 -#define B00110101 53 -#define B110110 54 -#define B0110110 54 -#define B00110110 54 -#define B110111 55 -#define B0110111 55 -#define B00110111 55 -#define B111000 56 -#define B0111000 56 -#define B00111000 56 -#define B111001 57 -#define B0111001 57 -#define B00111001 57 -#define B111010 58 -#define B0111010 58 -#define B00111010 58 -#define B111011 59 -#define B0111011 59 -#define B00111011 59 -#define B111100 60 -#define B0111100 60 -#define B00111100 60 -#define B111101 61 -#define B0111101 61 -#define B00111101 61 -#define B111110 62 -#define B0111110 62 -#define B00111110 62 -#define B111111 63 -#define B0111111 63 -#define B00111111 63 -#define B1000000 64 -#define B01000000 64 -#define B1000001 65 -#define B01000001 65 -#define B1000010 66 -#define B01000010 66 -#define B1000011 67 -#define B01000011 67 -#define B1000100 68 -#define B01000100 68 -#define B1000101 69 -#define B01000101 69 -#define B1000110 70 -#define B01000110 70 -#define B1000111 71 -#define B01000111 71 -#define B1001000 72 -#define B01001000 72 -#define B1001001 73 -#define B01001001 73 -#define B1001010 74 -#define B01001010 74 -#define B1001011 75 -#define B01001011 75 -#define B1001100 76 -#define B01001100 76 -#define B1001101 77 -#define B01001101 77 -#define B1001110 78 -#define B01001110 78 -#define B1001111 79 -#define B01001111 79 -#define B1010000 80 -#define B01010000 80 -#define B1010001 81 -#define B01010001 81 -#define B1010010 82 -#define B01010010 82 -#define B1010011 83 -#define B01010011 83 -#define B1010100 84 -#define B01010100 84 -#define B1010101 85 -#define B01010101 85 -#define B1010110 86 -#define B01010110 86 -#define B1010111 87 -#define B01010111 87 -#define B1011000 88 -#define B01011000 88 -#define B1011001 89 -#define B01011001 89 -#define B1011010 90 -#define B01011010 90 -#define B1011011 91 -#define B01011011 91 -#define B1011100 92 -#define B01011100 92 -#define B1011101 93 -#define B01011101 93 -#define B1011110 94 -#define B01011110 94 -#define B1011111 95 -#define B01011111 95 -#define B1100000 96 -#define B01100000 96 -#define B1100001 97 -#define B01100001 97 -#define B1100010 98 -#define B01100010 98 -#define B1100011 99 -#define B01100011 99 -#define B1100100 100 -#define B01100100 100 -#define B1100101 101 -#define B01100101 101 -#define B1100110 102 -#define B01100110 102 -#define B1100111 103 -#define B01100111 103 -#define B1101000 104 -#define B01101000 104 -#define B1101001 105 -#define B01101001 105 -#define B1101010 106 -#define B01101010 106 -#define B1101011 107 -#define B01101011 107 -#define B1101100 108 -#define B01101100 108 -#define B1101101 109 -#define B01101101 109 -#define B1101110 110 -#define B01101110 110 -#define B1101111 111 -#define B01101111 111 -#define B1110000 112 -#define B01110000 112 -#define B1110001 113 -#define B01110001 113 -#define B1110010 114 -#define B01110010 114 -#define B1110011 115 -#define B01110011 115 -#define B1110100 116 -#define B01110100 116 -#define B1110101 117 -#define B01110101 117 -#define B1110110 118 -#define B01110110 118 -#define B1110111 119 -#define B01110111 119 -#define B1111000 120 -#define B01111000 120 -#define B1111001 121 -#define B01111001 121 -#define B1111010 122 -#define B01111010 122 -#define B1111011 123 -#define B01111011 123 -#define B1111100 124 -#define B01111100 124 -#define B1111101 125 -#define B01111101 125 -#define B1111110 126 -#define B01111110 126 -#define B1111111 127 -#define B01111111 127 -#define B10000000 128 -#define B10000001 129 -#define B10000010 130 -#define B10000011 131 -#define B10000100 132 -#define B10000101 133 -#define B10000110 134 -#define B10000111 135 -#define B10001000 136 -#define B10001001 137 -#define B10001010 138 -#define B10001011 139 -#define B10001100 140 -#define B10001101 141 -#define B10001110 142 -#define B10001111 143 -#define B10010000 144 -#define B10010001 145 -#define B10010010 146 -#define B10010011 147 -#define B10010100 148 -#define B10010101 149 -#define B10010110 150 -#define B10010111 151 -#define B10011000 152 -#define B10011001 153 -#define B10011010 154 -#define B10011011 155 -#define B10011100 156 -#define B10011101 157 -#define B10011110 158 -#define B10011111 159 -#define B10100000 160 -#define B10100001 161 -#define B10100010 162 -#define B10100011 163 -#define B10100100 164 -#define B10100101 165 -#define B10100110 166 -#define B10100111 167 -#define B10101000 168 -#define B10101001 169 -#define B10101010 170 -#define B10101011 171 -#define B10101100 172 -#define B10101101 173 -#define B10101110 174 -#define B10101111 175 -#define B10110000 176 -#define B10110001 177 -#define B10110010 178 -#define B10110011 179 -#define B10110100 180 -#define B10110101 181 -#define B10110110 182 -#define B10110111 183 -#define B10111000 184 -#define B10111001 185 -#define B10111010 186 -#define B10111011 187 -#define B10111100 188 -#define B10111101 189 -#define B10111110 190 -#define B10111111 191 -#define B11000000 192 -#define B11000001 193 -#define B11000010 194 -#define B11000011 195 -#define B11000100 196 -#define B11000101 197 -#define B11000110 198 -#define B11000111 199 -#define B11001000 200 -#define B11001001 201 -#define B11001010 202 -#define B11001011 203 -#define B11001100 204 -#define B11001101 205 -#define B11001110 206 -#define B11001111 207 -#define B11010000 208 -#define B11010001 209 -#define B11010010 210 -#define B11010011 211 -#define B11010100 212 -#define B11010101 213 -#define B11010110 214 -#define B11010111 215 -#define B11011000 216 -#define B11011001 217 -#define B11011010 218 -#define B11011011 219 -#define B11011100 220 -#define B11011101 221 -#define B11011110 222 -#define B11011111 223 -#define B11100000 224 -#define B11100001 225 -#define B11100010 226 -#define B11100011 227 -#define B11100100 228 -#define B11100101 229 -#define B11100110 230 -#define B11100111 231 -#define B11101000 232 -#define B11101001 233 -#define B11101010 234 -#define B11101011 235 -#define B11101100 236 -#define B11101101 237 -#define B11101110 238 -#define B11101111 239 -#define B11110000 240 -#define B11110001 241 -#define B11110010 242 -#define B11110011 243 -#define B11110100 244 -#define B11110101 245 -#define B11110110 246 -#define B11110111 247 -#define B11111000 248 -#define B11111001 249 -#define B11111010 250 -#define B11111011 251 -#define B11111100 252 -#define B11111101 253 -#define B11111110 254 -#define B11111111 255 - -#endif /* _BIT_CONSTANTS_H_ */ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief BIT[n] and binary literal defines, for Arduino + * compatibility. + */ + +#ifndef _BIT_CONSTANTS_H_ +#define _BIT_CONSTANTS_H_ + +#define BIT0 (1 << 0) +#define BIT1 (1 << 1) +#define BIT2 (1 << 2) +#define BIT3 (1 << 3) +#define BIT4 (1 << 4) +#define BIT5 (1 << 5) +#define BIT6 (1 << 6) +#define BIT7 (1 << 7) +#define BIT8 (1 << 8) +#define BIT9 (1 << 9) +#define BIT10 (1 << 10) +#define BIT11 (1 << 11) +#define BIT12 (1 << 12) +#define BIT13 (1 << 13) +#define BIT14 (1 << 14) +#define BIT15 (1 << 15) +#define BIT16 (1 << 16) +#define BIT17 (1 << 17) +#define BIT18 (1 << 18) +#define BIT19 (1 << 19) +#define BIT20 (1 << 20) +#define BIT21 (1 << 21) +#define BIT22 (1 << 22) +#define BIT23 (1 << 23) +#define BIT24 (1 << 24) +#define BIT25 (1 << 25) +#define BIT26 (1 << 26) +#define BIT27 (1 << 27) +#define BIT28 (1 << 28) +#define BIT29 (1 << 29) +#define BIT30 (1 << 30) +#define BIT31 (1 << 31) + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#endif /* _BIT_CONSTANTS_H_ */ diff --git a/Libmaple/libmaple/wirish/bits.h b/Libmaple/libmaple/wirish/bits.h index b2c9d5c0..3e755b7f 100644 --- a/Libmaple/libmaple/wirish/bits.h +++ b/Libmaple/libmaple/wirish/bits.h @@ -1,30 +1,30 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* Note: Use of this header file is deprecated. Use bit_constants.h - instead. */ - -#include "bit_constants.h" +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/* Note: Use of this header file is deprecated. Use bit_constants.h + instead. */ + +#include "bit_constants.h" diff --git a/Libmaple/libmaple/wirish/boards.cpp b/Libmaple/libmaple/wirish/boards.cpp index 233c6380..ea46f2a3 100644 --- a/Libmaple/libmaple/wirish/boards.cpp +++ b/Libmaple/libmaple/wirish/boards.cpp @@ -1,180 +1,180 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief Generic board initialization routines. - * - * By default, we bring up all Maple boards to 72MHz, clocked off the - * PLL, driven by the 8MHz external crystal. AHB and APB2 are clocked - * at 72MHz. APB1 is clocked at 36MHz. - */ -#include "boards.h" - -#include "flash.h" -#include "rcc.h" -#include "nvic.h" -#include "systick.h" -#include "gpio.h" -#include "adc.h" -#include "timer.h" -#include "usb.h" -#ifdef STM32F2 -//#include "usbF4.h" -#endif - -static void setupFlash(void); -static void setupClocks(void); -static void setupNVIC(void); -static void setupADC(void); -static void setupTimers(void); - -void init(void) { - setupFlash(); - - setupClocks(); - setupNVIC(); - systick_init(SYSTICK_RELOAD_VAL); - gpio_init_all(); - -#ifdef STM32F2 - rcc_clk_enable(RCC_SYSCFG); -#else - afio_init(); -#endif - - boardInit(); - setupADC(); - setupTimers(); - - //setupUSB(); -} - -/* You could farm this out to the files in boards/ if e.g. it takes - * too long to test on Maple Native (all those FSMC pins...). */ -bool boardUsesPin(uint8 pin) { - for (int i = 0; i < BOARD_NR_USED_PINS; i++) { - if (pin == boardUsedPins[i]) { - return true; - } - } - return false; -} - -static void setupFlash(void) { -#ifndef STM32F2 - // for F2 and F4 CPUs this is done in SetupClock...(), e.g. in SetupClock168MHz() - flash_enable_prefetch(); - flash_set_latency(FLASH_WAIT_STATE_2); -#endif -} - -/* - * Clock setup. Note that some of this only takes effect if we're - * running bare metal and the bootloader hasn't done it for us - * already. - * - * If you change this function, you MUST change the file-level Doxygen - * comment above. - */ -static void setupClocks() { - rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9); - rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); - rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); - rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); -} - -static void setupNVIC() { -#ifdef VECT_TAB_FLASH - nvic_init(USER_ADDR_ROM, 0); -#elif defined VECT_TAB_RAM - nvic_init(USER_ADDR_RAM, 0); -#elif defined VECT_TAB_BASE - nvic_init((uint32)0x08000000, 0); -#else -#error "You must select a base address for the vector table." -#endif -} - -static void adcDefaultConfig(const adc_dev* dev); - -static void setupADC() { -#ifdef STM32F2 - setupADC_F2(); -#else - rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6); -#endif - adc_foreach(adcDefaultConfig); -} - -static void timerDefaultConfig(timer_dev*); - -static void setupTimers() { - timer_foreach(timerDefaultConfig); -} - -static void adcDefaultConfig(const adc_dev *dev) { - adc_init(dev); - - adc_set_extsel(dev, ADC_SWSTART); - adc_set_exttrig(dev, true); - - adc_enable(dev); - adc_calibrate(dev); - adc_set_sample_rate(dev, ADC_SMPR_55_5); -} - -static void timerDefaultConfig(timer_dev *dev) { - timer_adv_reg_map *regs = (dev->regs).adv; - const uint16 full_overflow = 0xFFFF; - const uint16 half_duty = 0x8FFF; - - timer_init(dev); - timer_pause(dev); - - regs->CR1 = TIMER_CR1_ARPE; - regs->PSC = 1; - regs->SR = 0; - regs->DIER = 0; - regs->EGR = TIMER_EGR_UG; - - switch (dev->type) { - case TIMER_ADVANCED: - regs->BDTR = TIMER_BDTR_MOE | TIMER_BDTR_LOCK_OFF; - // fall-through - case TIMER_GENERAL: - timer_set_reload(dev, full_overflow); - - for (int channel = 1; channel <= 4; channel++) { - timer_set_compare(dev, channel, half_duty); - timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE); - } - // fall-through - case TIMER_BASIC: - break; - } - - timer_resume(dev); -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief Generic board initialization routines. + * + * By default, we bring up all Maple boards to 72MHz, clocked off the + * PLL, driven by the 8MHz external crystal. AHB and APB2 are clocked + * at 72MHz. APB1 is clocked at 36MHz. + */ +#include "boards.h" + +#include "flash.h" +#include "rcc.h" +#include "nvic.h" +#include "systick.h" +#include "gpio.h" +#include "adc.h" +#include "timer.h" +#include "usb.h" +#ifdef STM32F2 +//#include "usbF4.h" +#endif + +static void setupFlash(void); +static void setupClocks(void); +static void setupNVIC(void); +static void setupADC(void); +static void setupTimers(void); + +void init(void) { + setupFlash(); + + setupClocks(); + setupNVIC(); + systick_init(SYSTICK_RELOAD_VAL); + gpio_init_all(); + +#ifdef STM32F2 + rcc_clk_enable(RCC_SYSCFG); +#else + afio_init(); +#endif + + boardInit(); + setupADC(); + setupTimers(); + + //setupUSB(); +} + +/* You could farm this out to the files in boards/ if e.g. it takes + * too long to test on Maple Native (all those FSMC pins...). */ +bool boardUsesPin(uint8 pin) { + for (int i = 0; i < BOARD_NR_USED_PINS; i++) { + if (pin == boardUsedPins[i]) { + return true; + } + } + return false; +} + +static void setupFlash(void) { +#ifndef STM32F2 + // for F2 and F4 CPUs this is done in SetupClock...(), e.g. in SetupClock168MHz() + flash_enable_prefetch(); + flash_set_latency(FLASH_WAIT_STATE_2); +#endif +} + +/* + * Clock setup. Note that some of this only takes effect if we're + * running bare metal and the bootloader hasn't done it for us + * already. + * + * If you change this function, you MUST change the file-level Doxygen + * comment above. + */ +static void setupClocks() { + rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9); + rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); + rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); + rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); +} + +static void setupNVIC() { +#ifdef VECT_TAB_FLASH + nvic_init(USER_ADDR_ROM, 0); +#elif defined VECT_TAB_RAM + nvic_init(USER_ADDR_RAM, 0); +#elif defined VECT_TAB_BASE + nvic_init((uint32)0x08000000, 0); +#else +#error "You must select a base address for the vector table." +#endif +} + +static void adcDefaultConfig(const adc_dev* dev); + +static void setupADC() { +#ifdef STM32F2 + setupADC_F2(); +#else + rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6); +#endif + adc_foreach(adcDefaultConfig); +} + +static void timerDefaultConfig(timer_dev*); + +static void setupTimers() { + timer_foreach(timerDefaultConfig); +} + +static void adcDefaultConfig(const adc_dev *dev) { + adc_init(dev); + + adc_set_extsel(dev, ADC_SWSTART); + adc_set_exttrig(dev, true); + + adc_enable(dev); + adc_calibrate(dev); + adc_set_sample_rate(dev, ADC_SMPR_55_5); +} + +static void timerDefaultConfig(timer_dev *dev) { + timer_adv_reg_map *regs = (dev->regs).adv; + const uint16 full_overflow = 0xFFFF; + const uint16 half_duty = 0x8FFF; + + timer_init(dev); + timer_pause(dev); + + regs->CR1 = TIMER_CR1_ARPE; + regs->PSC = 1; + regs->SR = 0; + regs->DIER = 0; + regs->EGR = TIMER_EGR_UG; + + switch (dev->type) { + case TIMER_ADVANCED: + regs->BDTR = TIMER_BDTR_MOE | TIMER_BDTR_LOCK_OFF; + // fall-through + case TIMER_GENERAL: + timer_set_reload(dev, full_overflow); + + for (int channel = 1; channel <= 4; channel++) { + timer_set_compare(dev, channel, half_duty); + timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE); + } + // fall-through + case TIMER_BASIC: + break; + } + + timer_resume(dev); +} diff --git a/Libmaple/libmaple/wirish/boards.h b/Libmaple/libmaple/wirish/boards.h index f8db85d4..00d07cdd 100644 --- a/Libmaple/libmaple/wirish/boards.h +++ b/Libmaple/libmaple/wirish/boards.h @@ -1,163 +1,163 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Bryan Newbold. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file boards.h - * @author Bryan Newbold , - * Marti Bolivar - * @brief Board-specific pin information. - * - * To add a new board type, add a new pair of files to - * /wirish/boards/, update the section below with a new "BOARD" type, - * and update /wirish/rules.mk to include your boards/your_board.cpp - * file in the top-level Makefile build. - */ - -#ifndef _BOARDS_H_ -#define _BOARDS_H_ - -#include "libmaple.h" -#include "gpio.h" -#include "timer.h" - -#include "wirish_types.h" - -/* Set of all possible pin names; not all boards have all these (note - * that we use the Dx convention since all of the Maple's pins are - * "digital" pins (e.g. can be used with digitalRead() and - * digitalWrite()), but not all of them are connected to ADCs. */ -enum { - D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, - D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31, - D32, D33, D34, D35, D36, D37, D38, D39, D40, D41, D42, D43, D44, D45, D46, - D47, D48, D49, D50, D51, D52, D53, D54, D55, D56, D57, D58, D59, D60, D61, - D62, D63, D64, D65, D66, D67, D68, D69, D70, D71, D72, D73, D74, D75, D76, - D77, D78, D79, D80, D81, D82, D83, D84, D85, D86, D87, D88, D89, D90, D91, - D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105, - D106, D107, D108, D109, D110, D111, }; - -/** - * @brief Maps each Maple pin to a corresponding stm32_pin_info. - * @see stm32_pin_info - */ -extern const stm32_pin_info PIN_MAP[]; - -/** - * @brief Pins capable of PWM output. - * - * Its length is BOARD_NR_PWM_PINS. - */ -extern const uint8 boardPWMPins[]; - -/** - * @brief Array of pins capable of analog input. - * - * Its length is BOARD_NR_ADC_PINS. - */ -extern const uint8 boardADCPins[]; - -/** - * @brief Pins which are connected to external hardware. - * - * For example, on Maple boards, it always at least includes - * BOARD_LED_PIN. Its length is BOARD_NR_USED_PINS. - */ -extern const uint8 boardUsedPins[]; - -/** - * @brief Generic board initialization function. - * - * This function is called before main(). It ensures that the clocks - * and peripherals are configured properly for use with wirish, then - * calls boardInit(). - * - * @see boardInit() - */ -void init(void); - -/** - * @brief Board-specific initialization function. - * - * This function is called from init() after all generic board - * initialization has been performed. Each board is required to - * define its own. - * - * @see init() - */ -extern void boardInit(void); - -/** - * @brief Test if a pin is used for a special purpose on your board. - * @param pin Pin to test - * @return true if the given pin is in boardUsedPins, and false otherwise. - * @see boardUsedPins - */ -bool boardUsesPin(uint8 pin); - -/* Include the appropriate private header from boards/: */ - -/* FIXME HACK put boards/ before these paths once IDE uses make. */ - -#ifdef BOARD_maple -#include "maple.h" -#elif defined(BOARD_maple_native) -#include "maple_native.h" -#elif defined(BOARD_maple_mini) -#include "maple_mini.h" -#elif defined(BOARD_maple_RET6) -/* - * **NOT** MAPLE REV6. This the **Maple RET6 EDITION**, which is a - * Maple with an STM32F103RET6 (...RET6) instead of an STM32F103RBT6 - * (...RBT6) on it. Maple Rev6 (as of March 2011) DOES NOT EXIST. - */ -#include "maple_RET6.h" -#elif defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1) -#include "aeroquad32.h" -#elif defined(BOARD_aeroquad32mini) -#include "aeroquad32mini.h" -#elif defined(BOARD_discovery_f4) -#include "discovery_f4.h" -#elif defined(BOARD_freeflight) -#include "freeflight.h" -#else -/* - * TODO turn this into a warning so people can: - * - * #include "my_board_config.h" - * #include "wirish.h" - * - * This will enable third-party board support without requiring that - * anybody hack around in libmaple itself. - */ -#error "Board type has not been selected correctly." -#endif - -/* Set derived definitions */ - -#define CLOCK_SPEED_MHZ CYCLES_PER_MICROSECOND -#define CLOCK_SPEED_HZ (CLOCK_SPEED_MHZ * 1000000UL) - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Bryan Newbold. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file boards.h + * @author Bryan Newbold , + * Marti Bolivar + * @brief Board-specific pin information. + * + * To add a new board type, add a new pair of files to + * /wirish/boards/, update the section below with a new "BOARD" type, + * and update /wirish/rules.mk to include your boards/your_board.cpp + * file in the top-level Makefile build. + */ + +#ifndef _BOARDS_H_ +#define _BOARDS_H_ + +#include "libmaple.h" +#include "gpio.h" +#include "timer.h" + +#include "wirish_types.h" + +/* Set of all possible pin names; not all boards have all these (note + * that we use the Dx convention since all of the Maple's pins are + * "digital" pins (e.g. can be used with digitalRead() and + * digitalWrite()), but not all of them are connected to ADCs. */ +enum { + D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, + D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31, + D32, D33, D34, D35, D36, D37, D38, D39, D40, D41, D42, D43, D44, D45, D46, + D47, D48, D49, D50, D51, D52, D53, D54, D55, D56, D57, D58, D59, D60, D61, + D62, D63, D64, D65, D66, D67, D68, D69, D70, D71, D72, D73, D74, D75, D76, + D77, D78, D79, D80, D81, D82, D83, D84, D85, D86, D87, D88, D89, D90, D91, + D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105, + D106, D107, D108, D109, D110, D111, }; + +/** + * @brief Maps each Maple pin to a corresponding stm32_pin_info. + * @see stm32_pin_info + */ +extern const stm32_pin_info PIN_MAP[]; + +/** + * @brief Pins capable of PWM output. + * + * Its length is BOARD_NR_PWM_PINS. + */ +extern const uint8 boardPWMPins[]; + +/** + * @brief Array of pins capable of analog input. + * + * Its length is BOARD_NR_ADC_PINS. + */ +extern const uint8 boardADCPins[]; + +/** + * @brief Pins which are connected to external hardware. + * + * For example, on Maple boards, it always at least includes + * BOARD_LED_PIN. Its length is BOARD_NR_USED_PINS. + */ +extern const uint8 boardUsedPins[]; + +/** + * @brief Generic board initialization function. + * + * This function is called before main(). It ensures that the clocks + * and peripherals are configured properly for use with wirish, then + * calls boardInit(). + * + * @see boardInit() + */ +void init(void); + +/** + * @brief Board-specific initialization function. + * + * This function is called from init() after all generic board + * initialization has been performed. Each board is required to + * define its own. + * + * @see init() + */ +extern void boardInit(void); + +/** + * @brief Test if a pin is used for a special purpose on your board. + * @param pin Pin to test + * @return true if the given pin is in boardUsedPins, and false otherwise. + * @see boardUsedPins + */ +bool boardUsesPin(uint8 pin); + +/* Include the appropriate private header from boards/: */ + +/* FIXME HACK put boards/ before these paths once IDE uses make. */ + +#ifdef BOARD_maple +#include "maple.h" +#elif defined(BOARD_maple_native) +#include "maple_native.h" +#elif defined(BOARD_maple_mini) +#include "maple_mini.h" +#elif defined(BOARD_maple_RET6) +/* + * **NOT** MAPLE REV6. This the **Maple RET6 EDITION**, which is a + * Maple with an STM32F103RET6 (...RET6) instead of an STM32F103RBT6 + * (...RBT6) on it. Maple Rev6 (as of March 2011) DOES NOT EXIST. + */ +#include "maple_RET6.h" +#elif defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1) +#include "aeroquad32.h" +#elif defined(BOARD_aeroquad32mini) +#include "aeroquad32mini.h" +#elif defined(BOARD_discovery_f4) +#include "discovery_f4.h" +#elif defined(BOARD_freeflight) +#include "freeflight.h" +#else +/* + * TODO turn this into a warning so people can: + * + * #include "my_board_config.h" + * #include "wirish.h" + * + * This will enable third-party board support without requiring that + * anybody hack around in libmaple itself. + */ +#error "Board type has not been selected correctly." +#endif + +/* Set derived definitions */ + +#define CLOCK_SPEED_MHZ CYCLES_PER_MICROSECOND +#define CLOCK_SPEED_HZ (CLOCK_SPEED_MHZ * 1000000UL) + +#endif diff --git a/Libmaple/libmaple/wirish/boards/aeroquad32.cpp b/Libmaple/libmaple/wirish/boards/aeroquad32.cpp index 298776ac..5689bf4d 100644 --- a/Libmaple/libmaple/wirish/boards/aeroquad32.cpp +++ b/Libmaple/libmaple/wirish/boards/aeroquad32.cpp @@ -1,236 +1,236 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file aeroquad32.cpp - * @author ala42 - * @brief aeroquad32 board file. - */ - -#if defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1) - -#include "aeroquad32.h" - -//#include "fsmc.h" -#include "gpio.h" -#include "rcc.h" -#include "timer.h" - -#include "wirish_types.h" - -//static void initSRAMChip(void); -void boardInit(void) { -#ifdef STM32F2 - // JTAG SW lines - // PA13 JTMS-SWDIO - // PA14 JTCK-SWCLK - // PA15 JTDI - // PB3 JTDO - // PB4 NJTRST - - // see DS8626 page 49 - - // remap TIMER2 to A15,B3 - gpio_set_af_mode(GPIOA, 15, 1); - gpio_set_af_mode(GPIOB, 3, 1); - - // remap TIMER4 to D12-15 - gpio_set_af_mode(GPIOD, 12, 2); - gpio_set_af_mode(GPIOD, 13, 2); - gpio_set_af_mode(GPIOD, 14, 2); - gpio_set_af_mode(GPIOD, 15, 2); - - // remap TIMER1 to PE9,11,13,14 - gpio_set_af_mode(GPIOE, 9, 1); - gpio_set_af_mode(GPIOE, 11, 1); - gpio_set_af_mode(GPIOE, 13, 1); - gpio_set_af_mode(GPIOE, 14, 1); - - // remap TIMER8 to PC6-9 - gpio_set_af_mode(GPIOC, 6, 3); - gpio_set_af_mode(GPIOC, 7, 3); - gpio_set_af_mode(GPIOC, 8, 3); - gpio_set_af_mode(GPIOC, 9, 3); - - // remap TIMER3 to PB4,5,0,1 - gpio_set_af_mode(GPIOB, 4, 2); - gpio_set_af_mode(GPIOB, 5, 2); - gpio_set_af_mode(GPIOB, 0, 2); - gpio_set_af_mode(GPIOB, 1, 2); - - // remap TIMER5 to PA0,1,2 (3) - gpio_set_af_mode(GPIOA, 0, 2); - gpio_set_af_mode(GPIOA, 1, 2); - gpio_set_af_mode(GPIOA, 2, 2); - -#else - __io uint32 *mapr = &AFIO_BASE->MAPR; - *mapr = ((*mapr) & ~(7 << 24) & AFIO_MAPR_SPI1_REMAP ) - | AFIO_MAPR_TIM1_REMAP | AFIO_MAPR_TIM4_REMAP - | AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 | AFIO_MAPR_TIM3_REMAP_PARTIAL //| BIT(8) | BIT(11) - | AFIO_MAPR_USART2_REMAP | AFIO_MAPR_USART3_REMAP - | AFIO_MAPR_SWJ_CFG_NO_JTAG_SW; -#endif -} - -#if defined(BOARD_aeroquad32) -void boardInitAla42_BOARD_aeroquad32(void) { -} -#endif - -#if defined(BOARD_aeroquad32f1) -void boardInitAla42_BOARD_aeroquad32f1(void) { -} -#endif - -#if 0 -typedef struct stm32_pin_info { - gpio_dev *gpio_device; /**< Maple pin's GPIO device */ - timer_dev *timer_device; /**< Pin's timer device, if any. */ - const adc_dev *adc_device; /**< ADC device, if any. */ - uint8 gpio_bit; /**< Pin's GPIO port bit. */ - uint8 timer_channel; /**< Timer channel, or 0 if none. */ - uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ -} stm32_pin_info; - -#endif - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - {GPIOA, TIMER5, ADC1, 0, 1, 0}, /* D00/PA0 */ - {GPIOA, TIMER5, ADC1, 1, 2, 1}, /* D01/PA1 */ - {GPIOA, TIMER5, ADC1, 2, 3, 2}, /* D02/PA2 */ - {GPIOA, TIMER5, ADC1, 3, 4, 3}, /* D03/PA3 */ - {GPIOA, NULL, ADC1, 4, 0, 4}, /* D04/PA4 */ - {GPIOA, NULL, ADC1, 5, 0, 5}, /* D05/PA5 */ - {GPIOA, NULL, ADC1, 6, 1, 6}, /* D06/PA6 */ // ala check TIMER3 - {GPIOA, NULL, ADC1, 7, 0, 7}, /* D07/PA7 */ - {GPIOA, NULL, NULL, 8, 0, ADCx}, /* D08/PA8 */ // remap out - {GPIOA, NULL, NULL, 9, 0, ADCx}, /* D09/PA9 */ // remap out - {GPIOA, NULL, NULL, 10, 0, ADCx}, /* D10/PA10 */ // remap out - {GPIOA, NULL, NULL, 11, 0, ADCx}, /* D11/PA11 */ // remap out - {GPIOA, NULL, NULL, 12, 0, ADCx}, /* D12/PA12 */ - {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D13/PA13 */ - {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D14/PA14 */ - {GPIOA, TIMER2, NULL, 15, 1, ADCx}, /* D15/PA15 */ // remap in - - {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D16/PB0 */ - {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D17/PB1 */ - {GPIOB, NULL, NULL, 2, 0, ADCx}, /* D18/PB2 */ - {GPIOB, TIMER2, NULL, 3, 2, ADCx}, /* D19/PB3 */ // remap in - {GPIOB, TIMER3, NULL, 4, 1, ADCx}, /* D20/PB4 */ // remap in - {GPIOB, TIMER3, NULL, 5, 2, ADCx}, /* D21/PB5 */ // remap in - {GPIOB, NULL, NULL, 6, 0, ADCx}, /* D22/PB6 */ // remap out - {GPIOB, NULL, NULL, 7, 0, ADCx}, /* D23/PB7 */ // remap out - {GPIOB, NULL, NULL, 8, 0, ADCx}, /* D24/PB8 */ // remap out - {GPIOB, NULL, NULL, 9, 0, ADCx}, /* D25/PB9 */ // remap out - {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D26/PB10 */ - {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D27/PB11 */ - {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D28/PB12 */ - {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D29/PB13 */ - {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D30/PB14 */ - {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D31/PB15 */ - - {GPIOC, NULL, ADC1, 0, 0, 10}, /* D32/PC0 */ - {GPIOC, NULL, ADC1, 1, 0, 11}, /* D33/PC1 */ - {GPIOC, NULL, ADC1, 2, 0, 12}, /* D34/PC2 */ - {GPIOC, NULL, ADC1, 3, 0, 13}, /* D35/PC3 */ - {GPIOC, NULL, ADC1, 4, 0, 14}, /* D36/PC4 */ - {GPIOC, NULL, ADC1, 5, 0, 15}, /* D37/PC5 */ - {GPIOC, TIMER8, NULL, 6, 1, ADCx}, /* D38/PC6 */ - {GPIOC, TIMER8, NULL, 7, 2, ADCx}, /* D39/PC7 */ - {GPIOC, TIMER8, NULL, 8, 3, ADCx}, /* D40/PC8 */ - {GPIOC, TIMER8, NULL, 9, 4, ADCx}, /* D41/PC9 */ - {GPIOC, NULL, NULL, 10, 0, ADCx}, /* D42/PC10 */ - {GPIOC, NULL, NULL, 11, 0, ADCx}, /* D43/PC11 */ - {GPIOC, NULL, NULL, 12, 0, ADCx}, /* D44/PC12 */ - {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D45/PC13 */ - {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D46/PC14 */ - {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D47/PC15 */ - - {GPIOD, NULL, NULL, 0, 0, ADCx}, /* D48/PD0 */ - {GPIOD, NULL, NULL, 1, 0, ADCx}, /* D49/PD1 */ - {GPIOD, NULL, NULL, 2, 0, ADCx}, /* D50/PD2 */ - {GPIOD, NULL, NULL, 3, 0, ADCx}, /* D51/PD3 */ - {GPIOD, NULL, NULL, 4, 0, ADCx}, /* D52/PD4 */ - {GPIOD, NULL, NULL, 5, 0, ADCx}, /* D53/PD5 */ - {GPIOD, NULL, NULL, 6, 0, ADCx}, /* D54/PD6 */ - {GPIOD, NULL, NULL, 7, 0, ADCx}, /* D55/PD7 */ - {GPIOD, NULL, NULL, 8, 0, ADCx}, /* D56/PD8 */ - {GPIOD, NULL, NULL, 9, 0, ADCx}, /* D57/PD9 */ - {GPIOD, NULL, NULL, 10, 0, ADCx}, /* D58/PD10 */ - {GPIOD, NULL, NULL, 11, 0, ADCx}, /* D59/PD11 */ - {GPIOD, TIMER4, NULL, 12, 1, ADCx}, /* D60/PD12 */ // remap in - {GPIOD, TIMER4, NULL, 13, 2, ADCx}, /* D61/PD13 */ // remap in - {GPIOD, TIMER4, NULL, 14, 3, ADCx}, /* D62/PD14 */ // remap in - {GPIOD, TIMER4, NULL, 15, 4, ADCx}, /* D63/PD15 */ // remap in - - {GPIOE, NULL, NULL, 0, 0, ADCx}, /* D64/PE0 */ - {GPIOE, NULL, NULL, 1, 0, ADCx}, /* D65/PE1 */ - {GPIOE, NULL, NULL, 2, 0, ADCx}, /* D66/PE2 */ - {GPIOE, NULL, NULL, 3, 0, ADCx}, /* D67/PE3 */ - {GPIOE, NULL, NULL, 4, 0, ADCx}, /* D68/PE4 */ - {GPIOE, NULL, NULL, 5, 0, ADCx}, /* D69/PE5 */ - {GPIOE, NULL, NULL, 6, 0, ADCx}, /* D70/PE6 */ - {GPIOE, NULL, NULL, 7, 0, ADCx}, /* D71/PE7 */ - {GPIOE, NULL, NULL, 8, 0, ADCx}, /* D72/PE8 */ - {GPIOE, TIMER1, NULL, 9, 1, ADCx}, /* D73/PE9 */ // remap in - {GPIOE, NULL, NULL, 10, 0, ADCx}, /* D74/PE10 */ - {GPIOE, TIMER1, NULL, 11, 2, ADCx}, /* D75/PE11 */ // remap in - {GPIOE, NULL, NULL, 12, 0, ADCx}, /* D76/PE12 */ - {GPIOE, TIMER1, NULL, 13, 3, ADCx}, /* D77/PE13 */ // remap in - {GPIOE, TIMER1, NULL, 14, 4, ADCx}, /* D78/PE14 */ // remap in - {GPIOE, NULL, NULL, 15, 0, ADCx} /* D79/PE15 */ -}; - -extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { - 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 -}; - -extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { - 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 32, 33, 34, 35, 36, 37 -}; - -extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { - BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, - BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN, - 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 78, 79, 81, - 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 -}; - -/* -static void initSRAMChip(void) { - fsmc_nor_psram_reg_map *regs = FSMC_NOR_PSRAM1_BASE; - - fsmc_sram_init_gpios(); - rcc_clk_enable(RCC_FSMC); - - regs->BCR = (FSMC_BCR_WREN | FSMC_BCR_MWID_16BITS | FSMC_BCR_MTYP_SRAM | - FSMC_BCR_MBKEN); - fsmc_nor_psram_set_addset(regs, 0); - fsmc_nor_psram_set_datast(regs, 3); -} -*/ -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file aeroquad32.cpp + * @author ala42 + * @brief aeroquad32 board file. + */ + +#if defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1) + +#include "aeroquad32.h" + +//#include "fsmc.h" +#include "gpio.h" +#include "rcc.h" +#include "timer.h" + +#include "wirish_types.h" + +//static void initSRAMChip(void); +void boardInit(void) { +#ifdef STM32F2 + // JTAG SW lines + // PA13 JTMS-SWDIO + // PA14 JTCK-SWCLK + // PA15 JTDI + // PB3 JTDO + // PB4 NJTRST + + // see DS8626 page 49 + + // remap TIMER2 to A15,B3 + gpio_set_af_mode(GPIOA, 15, 1); + gpio_set_af_mode(GPIOB, 3, 1); + + // remap TIMER4 to D12-15 + gpio_set_af_mode(GPIOD, 12, 2); + gpio_set_af_mode(GPIOD, 13, 2); + gpio_set_af_mode(GPIOD, 14, 2); + gpio_set_af_mode(GPIOD, 15, 2); + + // remap TIMER1 to PE9,11,13,14 + gpio_set_af_mode(GPIOE, 9, 1); + gpio_set_af_mode(GPIOE, 11, 1); + gpio_set_af_mode(GPIOE, 13, 1); + gpio_set_af_mode(GPIOE, 14, 1); + + // remap TIMER8 to PC6-9 + gpio_set_af_mode(GPIOC, 6, 3); + gpio_set_af_mode(GPIOC, 7, 3); + gpio_set_af_mode(GPIOC, 8, 3); + gpio_set_af_mode(GPIOC, 9, 3); + + // remap TIMER3 to PB4,5,0,1 + gpio_set_af_mode(GPIOB, 4, 2); + gpio_set_af_mode(GPIOB, 5, 2); + gpio_set_af_mode(GPIOB, 0, 2); + gpio_set_af_mode(GPIOB, 1, 2); + + // remap TIMER5 to PA0,1,2 (3) + gpio_set_af_mode(GPIOA, 0, 2); + gpio_set_af_mode(GPIOA, 1, 2); + gpio_set_af_mode(GPIOA, 2, 2); + +#else + __io uint32 *mapr = &AFIO_BASE->MAPR; + *mapr = ((*mapr) & ~(7 << 24) & AFIO_MAPR_SPI1_REMAP ) + | AFIO_MAPR_TIM1_REMAP | AFIO_MAPR_TIM4_REMAP + | AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 | AFIO_MAPR_TIM3_REMAP_PARTIAL //| BIT(8) | BIT(11) + | AFIO_MAPR_USART2_REMAP | AFIO_MAPR_USART3_REMAP + | AFIO_MAPR_SWJ_CFG_NO_JTAG_SW; +#endif +} + +#if defined(BOARD_aeroquad32) +void boardInitAla42_BOARD_aeroquad32(void) { +} +#endif + +#if defined(BOARD_aeroquad32f1) +void boardInitAla42_BOARD_aeroquad32f1(void) { +} +#endif + +#if 0 +typedef struct stm32_pin_info { + gpio_dev *gpio_device; /**< Maple pin's GPIO device */ + timer_dev *timer_device; /**< Pin's timer device, if any. */ + const adc_dev *adc_device; /**< ADC device, if any. */ + uint8 gpio_bit; /**< Pin's GPIO port bit. */ + uint8 timer_channel; /**< Timer channel, or 0 if none. */ + uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ +} stm32_pin_info; + +#endif + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + {GPIOA, TIMER5, ADC1, 0, 1, 0}, /* D00/PA0 */ + {GPIOA, TIMER5, ADC1, 1, 2, 1}, /* D01/PA1 */ + {GPIOA, TIMER5, ADC1, 2, 3, 2}, /* D02/PA2 */ + {GPIOA, TIMER5, ADC1, 3, 4, 3}, /* D03/PA3 */ + {GPIOA, NULL, ADC1, 4, 0, 4}, /* D04/PA4 */ + {GPIOA, NULL, ADC1, 5, 0, 5}, /* D05/PA5 */ + {GPIOA, NULL, ADC1, 6, 1, 6}, /* D06/PA6 */ // ala check TIMER3 + {GPIOA, NULL, ADC1, 7, 0, 7}, /* D07/PA7 */ + {GPIOA, NULL, NULL, 8, 0, ADCx}, /* D08/PA8 */ // remap out + {GPIOA, NULL, NULL, 9, 0, ADCx}, /* D09/PA9 */ // remap out + {GPIOA, NULL, NULL, 10, 0, ADCx}, /* D10/PA10 */ // remap out + {GPIOA, NULL, NULL, 11, 0, ADCx}, /* D11/PA11 */ // remap out + {GPIOA, NULL, NULL, 12, 0, ADCx}, /* D12/PA12 */ + {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D13/PA13 */ + {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D14/PA14 */ + {GPIOA, TIMER2, NULL, 15, 1, ADCx}, /* D15/PA15 */ // remap in + + {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D16/PB0 */ + {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D17/PB1 */ + {GPIOB, NULL, NULL, 2, 0, ADCx}, /* D18/PB2 */ + {GPIOB, TIMER2, NULL, 3, 2, ADCx}, /* D19/PB3 */ // remap in + {GPIOB, TIMER3, NULL, 4, 1, ADCx}, /* D20/PB4 */ // remap in + {GPIOB, TIMER3, NULL, 5, 2, ADCx}, /* D21/PB5 */ // remap in + {GPIOB, NULL, NULL, 6, 0, ADCx}, /* D22/PB6 */ // remap out + {GPIOB, NULL, NULL, 7, 0, ADCx}, /* D23/PB7 */ // remap out + {GPIOB, NULL, NULL, 8, 0, ADCx}, /* D24/PB8 */ // remap out + {GPIOB, NULL, NULL, 9, 0, ADCx}, /* D25/PB9 */ // remap out + {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D26/PB10 */ + {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D27/PB11 */ + {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D28/PB12 */ + {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D29/PB13 */ + {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D30/PB14 */ + {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D31/PB15 */ + + {GPIOC, NULL, ADC1, 0, 0, 10}, /* D32/PC0 */ + {GPIOC, NULL, ADC1, 1, 0, 11}, /* D33/PC1 */ + {GPIOC, NULL, ADC1, 2, 0, 12}, /* D34/PC2 */ + {GPIOC, NULL, ADC1, 3, 0, 13}, /* D35/PC3 */ + {GPIOC, NULL, ADC1, 4, 0, 14}, /* D36/PC4 */ + {GPIOC, NULL, ADC1, 5, 0, 15}, /* D37/PC5 */ + {GPIOC, TIMER8, NULL, 6, 1, ADCx}, /* D38/PC6 */ + {GPIOC, TIMER8, NULL, 7, 2, ADCx}, /* D39/PC7 */ + {GPIOC, TIMER8, NULL, 8, 3, ADCx}, /* D40/PC8 */ + {GPIOC, TIMER8, NULL, 9, 4, ADCx}, /* D41/PC9 */ + {GPIOC, NULL, NULL, 10, 0, ADCx}, /* D42/PC10 */ + {GPIOC, NULL, NULL, 11, 0, ADCx}, /* D43/PC11 */ + {GPIOC, NULL, NULL, 12, 0, ADCx}, /* D44/PC12 */ + {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D45/PC13 */ + {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D46/PC14 */ + {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D47/PC15 */ + + {GPIOD, NULL, NULL, 0, 0, ADCx}, /* D48/PD0 */ + {GPIOD, NULL, NULL, 1, 0, ADCx}, /* D49/PD1 */ + {GPIOD, NULL, NULL, 2, 0, ADCx}, /* D50/PD2 */ + {GPIOD, NULL, NULL, 3, 0, ADCx}, /* D51/PD3 */ + {GPIOD, NULL, NULL, 4, 0, ADCx}, /* D52/PD4 */ + {GPIOD, NULL, NULL, 5, 0, ADCx}, /* D53/PD5 */ + {GPIOD, NULL, NULL, 6, 0, ADCx}, /* D54/PD6 */ + {GPIOD, NULL, NULL, 7, 0, ADCx}, /* D55/PD7 */ + {GPIOD, NULL, NULL, 8, 0, ADCx}, /* D56/PD8 */ + {GPIOD, NULL, NULL, 9, 0, ADCx}, /* D57/PD9 */ + {GPIOD, NULL, NULL, 10, 0, ADCx}, /* D58/PD10 */ + {GPIOD, NULL, NULL, 11, 0, ADCx}, /* D59/PD11 */ + {GPIOD, TIMER4, NULL, 12, 1, ADCx}, /* D60/PD12 */ // remap in + {GPIOD, TIMER4, NULL, 13, 2, ADCx}, /* D61/PD13 */ // remap in + {GPIOD, TIMER4, NULL, 14, 3, ADCx}, /* D62/PD14 */ // remap in + {GPIOD, TIMER4, NULL, 15, 4, ADCx}, /* D63/PD15 */ // remap in + + {GPIOE, NULL, NULL, 0, 0, ADCx}, /* D64/PE0 */ + {GPIOE, NULL, NULL, 1, 0, ADCx}, /* D65/PE1 */ + {GPIOE, NULL, NULL, 2, 0, ADCx}, /* D66/PE2 */ + {GPIOE, NULL, NULL, 3, 0, ADCx}, /* D67/PE3 */ + {GPIOE, NULL, NULL, 4, 0, ADCx}, /* D68/PE4 */ + {GPIOE, NULL, NULL, 5, 0, ADCx}, /* D69/PE5 */ + {GPIOE, NULL, NULL, 6, 0, ADCx}, /* D70/PE6 */ + {GPIOE, NULL, NULL, 7, 0, ADCx}, /* D71/PE7 */ + {GPIOE, NULL, NULL, 8, 0, ADCx}, /* D72/PE8 */ + {GPIOE, TIMER1, NULL, 9, 1, ADCx}, /* D73/PE9 */ // remap in + {GPIOE, NULL, NULL, 10, 0, ADCx}, /* D74/PE10 */ + {GPIOE, TIMER1, NULL, 11, 2, ADCx}, /* D75/PE11 */ // remap in + {GPIOE, NULL, NULL, 12, 0, ADCx}, /* D76/PE12 */ + {GPIOE, TIMER1, NULL, 13, 3, ADCx}, /* D77/PE13 */ // remap in + {GPIOE, TIMER1, NULL, 14, 4, ADCx}, /* D78/PE14 */ // remap in + {GPIOE, NULL, NULL, 15, 0, ADCx} /* D79/PE15 */ +}; + +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 +}; + +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 32, 33, 34, 35, 36, 37 +}; + +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN, + 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 78, 79, 81, + 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 +}; + +/* +static void initSRAMChip(void) { + fsmc_nor_psram_reg_map *regs = FSMC_NOR_PSRAM1_BASE; + + fsmc_sram_init_gpios(); + rcc_clk_enable(RCC_FSMC); + + regs->BCR = (FSMC_BCR_WREN | FSMC_BCR_MWID_16BITS | FSMC_BCR_MTYP_SRAM | + FSMC_BCR_MBKEN); + fsmc_nor_psram_set_addset(regs, 0); + fsmc_nor_psram_set_datast(regs, 3); +} +*/ +#endif diff --git a/Libmaple/libmaple/wirish/boards/aeroquad32.h b/Libmaple/libmaple/wirish/boards/aeroquad32.h index 9b4ccbad..95cb6887 100644 --- a/Libmaple/libmaple/wirish/boards/aeroquad32.h +++ b/Libmaple/libmaple/wirish/boards/aeroquad32.h @@ -1,93 +1,93 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file aeroquad32.h - * @author Marti Bolivar - * @brief Private include file for Maple Native in boards.h - * - * See maple.h for more information on these definitions. - */ - -#ifndef _BOARD_AEROQUAD32_H_ -#define _BOARD_AEROQUAD32_H_ - -#define Port2Pin(port, bit) ((port-'A')*16+bit) - -#ifdef BOARD_aeroquad32f1 - #define CYCLES_PER_MICROSECOND 72 -#else - #define CYCLES_PER_MICROSECOND 168 -#endif -//#define CYCLES_PER_MICROSECOND (F_CPU/1000000) - -#define SYSTICK_RELOAD_VAL (CYCLES_PER_MICROSECOND*1000-1) - -#define BOARD_LED_PIN Port2Pin('E', 5) -#define BOARD_BUTTON_PIN Port2Pin('C', 0) - -#define BOARD_NR_USARTS 5 -#define BOARD_USART1_TX_PIN Port2Pin('A', 9) -#define BOARD_USART1_RX_PIN Port2Pin('A',10) -#define BOARD_USART2_TX_PIN Port2Pin('D', 5) -#define BOARD_USART2_RX_PIN Port2Pin('D', 6) -#define BOARD_USART3_TX_PIN Port2Pin('D', 8) -#define BOARD_USART3_RX_PIN Port2Pin('D', 9) -#define BOARD_UART4_TX_PIN Port2Pin('C',10) -#define BOARD_UART4_RX_PIN Port2Pin('C',11) -#define BOARD_UART5_TX_PIN Port2Pin('C',12) -#define BOARD_UART5_RX_PIN Port2Pin('D', 2) - -#define BOARD_NR_SPI 4 -#define BOARD_SPI1_NSS_PIN Port2Pin('A', 4) -#define BOARD_SPI1_MOSI_PIN Port2Pin('A', 7) -#define BOARD_SPI1_MISO_PIN Port2Pin('A', 6) -#define BOARD_SPI1_SCK_PIN Port2Pin('A', 5) -#define BOARD_SPI2_NSS_PIN Port2Pin('B',12) -#define BOARD_SPI2_MOSI_PIN Port2Pin('B',15) -#define BOARD_SPI2_MISO_PIN Port2Pin('B',14) -#define BOARD_SPI2_SCK_PIN Port2Pin('B',13) -#define BOARD_SPI3_NSS_PIN Port2Pin('A',15) -#define BOARD_SPI3_MOSI_PIN Port2Pin('B', 5) -#define BOARD_SPI3_MISO_PIN Port2Pin('B', 4) -#define BOARD_SPI3_SCK_PIN Port2Pin('B', 3) - -#define BOARD_SPI3B_NSS_PIN Port2Pin('B', 8) -#define BOARD_SPI3B_MOSI_PIN Port2Pin('C',12) -#define BOARD_SPI3B_MISO_PIN Port2Pin('C',11) -#define BOARD_SPI3B_SCK_PIN Port2Pin('C',10) - -#define BOARD_NR_GPIO_PINS 80 -#define BOARD_NR_PWM_PINS 22 -#define BOARD_NR_ADC_PINS 16 -#define BOARD_NR_USED_PINS 43 // ala42 not set yet -#define BOARD_JTMS_SWDIO_PIN Port2Pin('A',13) -#define BOARD_JTCK_SWCLK_PIN Port2Pin('A',14) -#define BOARD_JTDI_PIN Port2Pin('A',15) -#define BOARD_JTDO_PIN Port2Pin('B', 3) -#define BOARD_NJTRST_PIN Port2Pin('B', 4) - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file aeroquad32.h + * @author Marti Bolivar + * @brief Private include file for Maple Native in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARD_AEROQUAD32_H_ +#define _BOARD_AEROQUAD32_H_ + +#define Port2Pin(port, bit) ((port-'A')*16+bit) + +#ifdef BOARD_aeroquad32f1 + #define CYCLES_PER_MICROSECOND 72 +#else + #define CYCLES_PER_MICROSECOND 168 +#endif +//#define CYCLES_PER_MICROSECOND (F_CPU/1000000) + +#define SYSTICK_RELOAD_VAL (CYCLES_PER_MICROSECOND*1000-1) + +#define BOARD_LED_PIN Port2Pin('E', 5) +#define BOARD_BUTTON_PIN Port2Pin('C', 0) + +#define BOARD_NR_USARTS 5 +#define BOARD_USART1_TX_PIN Port2Pin('A', 9) +#define BOARD_USART1_RX_PIN Port2Pin('A',10) +#define BOARD_USART2_TX_PIN Port2Pin('D', 5) +#define BOARD_USART2_RX_PIN Port2Pin('D', 6) +#define BOARD_USART3_TX_PIN Port2Pin('D', 8) +#define BOARD_USART3_RX_PIN Port2Pin('D', 9) +#define BOARD_UART4_TX_PIN Port2Pin('C',10) +#define BOARD_UART4_RX_PIN Port2Pin('C',11) +#define BOARD_UART5_TX_PIN Port2Pin('C',12) +#define BOARD_UART5_RX_PIN Port2Pin('D', 2) + +#define BOARD_NR_SPI 4 +#define BOARD_SPI1_NSS_PIN Port2Pin('A', 4) +#define BOARD_SPI1_MOSI_PIN Port2Pin('A', 7) +#define BOARD_SPI1_MISO_PIN Port2Pin('A', 6) +#define BOARD_SPI1_SCK_PIN Port2Pin('A', 5) +#define BOARD_SPI2_NSS_PIN Port2Pin('B',12) +#define BOARD_SPI2_MOSI_PIN Port2Pin('B',15) +#define BOARD_SPI2_MISO_PIN Port2Pin('B',14) +#define BOARD_SPI2_SCK_PIN Port2Pin('B',13) +#define BOARD_SPI3_NSS_PIN Port2Pin('A',15) +#define BOARD_SPI3_MOSI_PIN Port2Pin('B', 5) +#define BOARD_SPI3_MISO_PIN Port2Pin('B', 4) +#define BOARD_SPI3_SCK_PIN Port2Pin('B', 3) + +#define BOARD_SPI3B_NSS_PIN Port2Pin('B', 8) +#define BOARD_SPI3B_MOSI_PIN Port2Pin('C',12) +#define BOARD_SPI3B_MISO_PIN Port2Pin('C',11) +#define BOARD_SPI3B_SCK_PIN Port2Pin('C',10) + +#define BOARD_NR_GPIO_PINS 80 +#define BOARD_NR_PWM_PINS 22 +#define BOARD_NR_ADC_PINS 16 +#define BOARD_NR_USED_PINS 43 // ala42 not set yet +#define BOARD_JTMS_SWDIO_PIN Port2Pin('A',13) +#define BOARD_JTCK_SWCLK_PIN Port2Pin('A',14) +#define BOARD_JTDI_PIN Port2Pin('A',15) +#define BOARD_JTDO_PIN Port2Pin('B', 3) +#define BOARD_NJTRST_PIN Port2Pin('B', 4) + +#endif diff --git a/Libmaple/libmaple/wirish/boards/aeroquad32mini.cpp b/Libmaple/libmaple/wirish/boards/aeroquad32mini.cpp index daae832f..67ac2c11 100644 --- a/Libmaple/libmaple/wirish/boards/aeroquad32mini.cpp +++ b/Libmaple/libmaple/wirish/boards/aeroquad32mini.cpp @@ -1,105 +1,105 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file aeroquad32mini.cpp - * @author ala42 - * @brief aeroquad32mini board file. - */ - -#ifdef BOARD_aeroquad32mini - -#include "aeroquad32mini.h" - -//#include "fsmc.h" -#include "gpio.h" -#include "rcc.h" -#include "timer.h" - -#include "wirish_types.h" - -//static void initSRAMChip(void); -void boardInit(void) { - __io uint32 *mapr = &AFIO_BASE->MAPR; - *mapr = ((*mapr) & ~(7 << 24) ) - | AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 - | AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW; -} - - -#if 0 -typedef struct stm32_pin_info { - gpio_dev *gpio_device; /**< Maple pin's GPIO device */ - timer_dev *timer_device; /**< Pin's timer device, if any. */ - const adc_dev *adc_device; /**< ADC device, if any. */ - uint8 gpio_bit; /**< Pin's GPIO port bit. */ - uint8 timer_channel; /**< Timer channel, or 0 if none. */ - uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ -} stm32_pin_info; - -#endif - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - {GPIOA, NULL, NULL, 9, 0, ADCx}, /* D00/PA9 */ - {GPIOA, NULL, NULL, 10, 0, ADCx}, /* D01/PA10 */ - - {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D02/PB7 */ - {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D03/PA7 */ - {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D04/PB6 */ - {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D05/PB8 */ - {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* D06/PB9 */ - {GPIOA, TIMER2, NULL, 15, 1, ADCx}, /* D07/PA15 */ // remap in - {GPIOB, TIMER2, NULL, 3, 2, ADCx}, /* D08/PB3 */ // remap in - - {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D09/PA6 */ // ala check TIMER3 - {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D10/PB0 */ - {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D11/PB1 */ - {GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D12/PA2 */ - {GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D13/PA3 */ - - {GPIOA, NULL, ADC1, 0, 0, 0}, /* D14/PA0 */ - {GPIOA, NULL, ADC1, 5, 0, 5}, /* D15/PA5 */ - - {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D16/PB11 */ - {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D17/PB10 */ - - {GPIOA, NULL, ADC1, 4, 0, ADCx}, /* D18/PA4 */ -}; - -extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 -}; - -extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { - 3, 9, 10, 11, 12, 13, 14, 15 -}; - -extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { - BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, - BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN -}; - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file aeroquad32mini.cpp + * @author ala42 + * @brief aeroquad32mini board file. + */ + +#ifdef BOARD_aeroquad32mini + +#include "aeroquad32mini.h" + +//#include "fsmc.h" +#include "gpio.h" +#include "rcc.h" +#include "timer.h" + +#include "wirish_types.h" + +//static void initSRAMChip(void); +void boardInit(void) { + __io uint32 *mapr = &AFIO_BASE->MAPR; + *mapr = ((*mapr) & ~(7 << 24) ) + | AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 + | AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW; +} + + +#if 0 +typedef struct stm32_pin_info { + gpio_dev *gpio_device; /**< Maple pin's GPIO device */ + timer_dev *timer_device; /**< Pin's timer device, if any. */ + const adc_dev *adc_device; /**< ADC device, if any. */ + uint8 gpio_bit; /**< Pin's GPIO port bit. */ + uint8 timer_channel; /**< Timer channel, or 0 if none. */ + uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ +} stm32_pin_info; + +#endif + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + {GPIOA, NULL, NULL, 9, 0, ADCx}, /* D00/PA9 */ + {GPIOA, NULL, NULL, 10, 0, ADCx}, /* D01/PA10 */ + + {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D02/PB7 */ + {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D03/PA7 */ + {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D04/PB6 */ + {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D05/PB8 */ + {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* D06/PB9 */ + {GPIOA, TIMER2, NULL, 15, 1, ADCx}, /* D07/PA15 */ // remap in + {GPIOB, TIMER2, NULL, 3, 2, ADCx}, /* D08/PB3 */ // remap in + + {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D09/PA6 */ // ala check TIMER3 + {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D10/PB0 */ + {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D11/PB1 */ + {GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D12/PA2 */ + {GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D13/PA3 */ + + {GPIOA, NULL, ADC1, 0, 0, 0}, /* D14/PA0 */ + {GPIOA, NULL, ADC1, 5, 0, 5}, /* D15/PA5 */ + + {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D16/PB11 */ + {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D17/PB10 */ + + {GPIOA, NULL, ADC1, 4, 0, ADCx}, /* D18/PA4 */ +}; + +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 +}; + +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + 3, 9, 10, 11, 12, 13, 14, 15 +}; + +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN +}; + +#endif diff --git a/Libmaple/libmaple/wirish/boards/aeroquad32mini.h b/Libmaple/libmaple/wirish/boards/aeroquad32mini.h index 51dafcee..1cc90505 100644 --- a/Libmaple/libmaple/wirish/boards/aeroquad32mini.h +++ b/Libmaple/libmaple/wirish/boards/aeroquad32mini.h @@ -1,78 +1,78 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file aeroquad32.h - * @author Marti Bolivar - * @brief Private include file for Maple Native in boards.h - * - * See maple.h for more information on these definitions. - */ - -#ifndef _BOARD_AEROQUAD32MINI_H_ -#define _BOARD_AEROQUAD32MINI_H_ - -#define Port2Pin(port, bit) ((port-'A')*16+bit) - -#define CYCLES_PER_MICROSECOND 72 -#define SYSTICK_RELOAD_VAL 71999 - -#define BOARD_LED_PIN Port2Pin('E', 5) -#define BOARD_BUTTON_PIN Port2Pin('C', 0) - -#define BOARD_NR_USARTS 5 -#define BOARD_USART1_TX_PIN Port2Pin('A', 9) -#define BOARD_USART1_RX_PIN Port2Pin('A',10) -#define BOARD_USART2_TX_PIN Port2Pin('D', 5) -#define BOARD_USART2_RX_PIN Port2Pin('D', 6) -#define BOARD_USART3_TX_PIN Port2Pin('D', 8) -#define BOARD_USART3_RX_PIN Port2Pin('D', 9) -#define BOARD_UART4_TX_PIN Port2Pin('C',10) -#define BOARD_UART4_RX_PIN Port2Pin('C',11) -#define BOARD_UART5_TX_PIN Port2Pin('C',12) -#define BOARD_UART5_RX_PIN Port2Pin('D', 2) - -#define BOARD_NR_SPI 2 -#define BOARD_SPI1_NSS_PIN 18 //Port2Pin('A', 4) -#define BOARD_SPI1_MOSI_PIN 3 //Port2Pin('A', 7) -#define BOARD_SPI1_MISO_PIN 9 //Port2Pin('A', 6) -#define BOARD_SPI1_SCK_PIN 17 //Port2Pin('A', 5) -#define BOARD_SPI2_NSS_PIN Port2Pin('B',12) -#define BOARD_SPI2_MOSI_PIN Port2Pin('B',15) -#define BOARD_SPI2_MISO_PIN Port2Pin('B',14) -#define BOARD_SPI2_SCK_PIN Port2Pin('B',13) - -#define BOARD_NR_GPIO_PINS 19 -#define BOARD_NR_PWM_PINS 12 -#define BOARD_NR_ADC_PINS 8 -#define BOARD_NR_USED_PINS 7 // ala42 not set yet -#define BOARD_JTMS_SWDIO_PIN Port2Pin('A',13) -#define BOARD_JTCK_SWCLK_PIN Port2Pin('A',14) -#define BOARD_JTDI_PIN Port2Pin('A',15) -#define BOARD_JTDO_PIN Port2Pin('B', 3) -#define BOARD_NJTRST_PIN Port2Pin('B', 4) - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file aeroquad32.h + * @author Marti Bolivar + * @brief Private include file for Maple Native in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARD_AEROQUAD32MINI_H_ +#define _BOARD_AEROQUAD32MINI_H_ + +#define Port2Pin(port, bit) ((port-'A')*16+bit) + +#define CYCLES_PER_MICROSECOND 72 +#define SYSTICK_RELOAD_VAL 71999 + +#define BOARD_LED_PIN Port2Pin('E', 5) +#define BOARD_BUTTON_PIN Port2Pin('C', 0) + +#define BOARD_NR_USARTS 5 +#define BOARD_USART1_TX_PIN Port2Pin('A', 9) +#define BOARD_USART1_RX_PIN Port2Pin('A',10) +#define BOARD_USART2_TX_PIN Port2Pin('D', 5) +#define BOARD_USART2_RX_PIN Port2Pin('D', 6) +#define BOARD_USART3_TX_PIN Port2Pin('D', 8) +#define BOARD_USART3_RX_PIN Port2Pin('D', 9) +#define BOARD_UART4_TX_PIN Port2Pin('C',10) +#define BOARD_UART4_RX_PIN Port2Pin('C',11) +#define BOARD_UART5_TX_PIN Port2Pin('C',12) +#define BOARD_UART5_RX_PIN Port2Pin('D', 2) + +#define BOARD_NR_SPI 2 +#define BOARD_SPI1_NSS_PIN 18 //Port2Pin('A', 4) +#define BOARD_SPI1_MOSI_PIN 3 //Port2Pin('A', 7) +#define BOARD_SPI1_MISO_PIN 9 //Port2Pin('A', 6) +#define BOARD_SPI1_SCK_PIN 17 //Port2Pin('A', 5) +#define BOARD_SPI2_NSS_PIN Port2Pin('B',12) +#define BOARD_SPI2_MOSI_PIN Port2Pin('B',15) +#define BOARD_SPI2_MISO_PIN Port2Pin('B',14) +#define BOARD_SPI2_SCK_PIN Port2Pin('B',13) + +#define BOARD_NR_GPIO_PINS 19 +#define BOARD_NR_PWM_PINS 12 +#define BOARD_NR_ADC_PINS 8 +#define BOARD_NR_USED_PINS 7 // ala42 not set yet +#define BOARD_JTMS_SWDIO_PIN Port2Pin('A',13) +#define BOARD_JTCK_SWCLK_PIN Port2Pin('A',14) +#define BOARD_JTDI_PIN Port2Pin('A',15) +#define BOARD_JTDO_PIN Port2Pin('B', 3) +#define BOARD_NJTRST_PIN Port2Pin('B', 4) + +#endif diff --git a/Libmaple/libmaple/wirish/boards/discovery_f4.cpp b/Libmaple/libmaple/wirish/boards/discovery_f4.cpp index 7fbbf1b3..c508fa37 100644 --- a/Libmaple/libmaple/wirish/boards/discovery_f4.cpp +++ b/Libmaple/libmaple/wirish/boards/discovery_f4.cpp @@ -1,198 +1,198 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file discovery_f4.cpp - * @author ala42 - * @brief discovery_f4 board file. - */ - -#ifdef BOARD_discovery_f4 - -#include "discovery_f4.h" - -//#include "fsmc.h" -#include "gpio.h" -#include "rcc.h" -#include "timer.h" - -#include "wirish_types.h" - -//static void initSRAMChip(void); -void boardInit(void) { - // remap TIMER8 to PC6-9 - gpio_set_af_mode(GPIOC, 6, 3); - gpio_set_af_mode(GPIOC, 7, 3); - gpio_set_af_mode(GPIOC, 8, 3); - gpio_set_af_mode(GPIOC, 9, 3); - - // remap TIMER1 to PE9,11,13,14 - gpio_set_af_mode(GPIOE, 9, 1); - gpio_set_af_mode(GPIOE, 11, 1); - gpio_set_af_mode(GPIOE, 13, 1); - gpio_set_af_mode(GPIOE, 14, 1); - - // remap TIMER3 to PB4,5,0,1 - gpio_set_af_mode(GPIOB, 4, 2); - gpio_set_af_mode(GPIOB, 5, 2); - gpio_set_af_mode(GPIOB, 0, 2); - gpio_set_af_mode(GPIOB, 1, 2); - - - //gpio_set_af_mode(GPIOA, 2, 7); - //gpio_set_af_mode(GPIOA, 3, 7); - return; -} - - -#if 0 -typedef struct stm32_pin_info { - gpio_dev *gpio_device; /**< Maple pin's GPIO device */ - timer_dev *timer_device; /**< Pin's timer device, if any. */ - const adc_dev *adc_device; /**< ADC device, if any. */ - uint8 gpio_bit; /**< Pin's GPIO port bit. */ - uint8 timer_channel; /**< Timer channel, or 0 if none. */ - uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ -} stm32_pin_info; - -#endif - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - {GPIOA, TIMER5, ADC1, 0, 1, 0}, /* D00/PA0 */ - {GPIOA, TIMER5, ADC1, 1, 2, 1}, /* D01/PA1 */ - {GPIOA, TIMER5, ADC1, 2, 3, 2}, /* D02/PA2 */ - {GPIOA, TIMER5, ADC1, 3, 4, 3}, /* D03/PA3 */ - {GPIOA, NULL, ADC1, 4, 0, 4}, /* D04/PA4 */ - {GPIOA, NULL, ADC1, 5, 0, 5}, /* D05/PA5 */ - {GPIOA, NULL, ADC1, 6, 1, 6}, /* D06/PA6 */ // ala check TIMER3 - {GPIOA, NULL, ADC1, 7, 0, 7}, /* D07/PA7 */ - {GPIOA, NULL, NULL, 8, 0, ADCx}, /* D08/PA8 */ // remap out - {GPIOA, NULL, NULL, 9, 0, ADCx}, /* D09/PA9 */ // remap out - {GPIOA, NULL, NULL, 10, 0, ADCx}, /* D10/PA10 */ // remap out - {GPIOA, NULL, NULL, 11, 0, ADCx}, /* D11/PA11 */ // remap out - {GPIOA, NULL, NULL, 12, 0, ADCx}, /* D12/PA12 */ - {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D13/PA13 */ - {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D14/PA14 */ - {GPIOA, TIMER2, NULL, 15, 1, ADCx}, /* D15/PA15 */ // remap in - - {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D16/PB0 */ - {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D17/PB1 */ - {GPIOB, NULL, NULL, 2, 0, ADCx}, /* D18/PB2 */ - {GPIOB, TIMER2, NULL, 3, 2, ADCx}, /* D19/PB3 */ // remap in - {GPIOB, TIMER3, NULL, 4, 1, ADCx}, /* D20/PB4 */ // remap in - {GPIOB, TIMER3, NULL, 5, 2, ADCx}, /* D21/PB5 */ // remap in - {GPIOB, NULL, NULL, 6, 0, ADCx}, /* D22/PB6 */ // remap out - {GPIOB, NULL, NULL, 7, 0, ADCx}, /* D23/PB7 */ // remap out - {GPIOB, NULL, NULL, 8, 0, ADCx}, /* D24/PB8 */ // remap out - {GPIOB, NULL, NULL, 9, 0, ADCx}, /* D25/PB9 */ // remap out - {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D26/PB10 */ - {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D27/PB11 */ - {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D28/PB12 */ - {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D29/PB13 */ - {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D30/PB14 */ - {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D31/PB15 */ - - {GPIOC, NULL, ADC1, 0, 0, 10}, /* D32/PC0 */ - {GPIOC, NULL, ADC1, 1, 0, 11}, /* D33/PC1 */ - {GPIOC, NULL, ADC1, 2, 0, 12}, /* D34/PC2 */ - {GPIOC, NULL, ADC1, 3, 0, 13}, /* D35/PC3 */ - {GPIOC, NULL, ADC1, 4, 0, 14}, /* D36/PC4 */ - {GPIOC, NULL, ADC1, 5, 0, 15}, /* D37/PC5 */ - {GPIOC, TIMER8, NULL, 6, 1, ADCx}, /* D38/PC6 */ - {GPIOC, TIMER8, NULL, 7, 2, ADCx}, /* D39/PC7 */ - {GPIOC, TIMER8, NULL, 8, 3, ADCx}, /* D40/PC8 */ - {GPIOC, TIMER8, NULL, 9, 4, ADCx}, /* D41/PC9 */ - {GPIOC, NULL, NULL, 10, 0, ADCx}, /* D42/PC10 */ - {GPIOC, NULL, NULL, 11, 0, ADCx}, /* D43/PC11 */ - {GPIOC, NULL, NULL, 12, 0, ADCx}, /* D44/PC12 */ - {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D45/PC13 */ - {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D46/PC14 */ - {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D47/PC15 */ - - {GPIOD, NULL, NULL, 0, 0, ADCx}, /* D48/PD0 */ - {GPIOD, NULL, NULL, 1, 0, ADCx}, /* D49/PD1 */ - {GPIOD, NULL, NULL, 2, 0, ADCx}, /* D50/PD2 */ - {GPIOD, NULL, NULL, 3, 0, ADCx}, /* D51/PD3 */ - {GPIOD, NULL, NULL, 4, 0, ADCx}, /* D52/PD4 */ - {GPIOD, NULL, NULL, 5, 0, ADCx}, /* D53/PD5 */ - {GPIOD, NULL, NULL, 6, 0, ADCx}, /* D54/PD6 */ - {GPIOD, NULL, NULL, 7, 0, ADCx}, /* D55/PD7 */ - {GPIOD, NULL, NULL, 8, 0, ADCx}, /* D56/PD8 */ - {GPIOD, NULL, NULL, 9, 0, ADCx}, /* D57/PD9 */ - {GPIOD, NULL, NULL, 10, 0, ADCx}, /* D58/PD10 */ - {GPIOD, NULL, NULL, 11, 0, ADCx}, /* D59/PD11 */ - {GPIOD, TIMER4, NULL, 12, 1, ADCx}, /* D60/PD12 */ // remap in - {GPIOD, TIMER4, NULL, 13, 2, ADCx}, /* D61/PD13 */ // remap in - {GPIOD, TIMER4, NULL, 14, 3, ADCx}, /* D62/PD14 */ // remap in - {GPIOD, TIMER4, NULL, 15, 4, ADCx}, /* D63/PD15 */ // remap in - - {GPIOE, NULL, NULL, 0, 0, ADCx}, /* D64/PE0 */ - {GPIOE, NULL, NULL, 1, 0, ADCx}, /* D65/PE1 */ - {GPIOE, NULL, NULL, 2, 0, ADCx}, /* D66/PE2 */ - {GPIOE, NULL, NULL, 3, 0, ADCx}, /* D67/PE3 */ - {GPIOE, NULL, NULL, 4, 0, ADCx}, /* D68/PE4 */ - {GPIOE, NULL, NULL, 5, 0, ADCx}, /* D69/PE5 */ - {GPIOE, NULL, NULL, 6, 0, ADCx}, /* D70/PE6 */ - {GPIOE, NULL, NULL, 7, 0, ADCx}, /* D71/PE7 */ - {GPIOE, NULL, NULL, 8, 0, ADCx}, /* D72/PE8 */ - {GPIOE, TIMER1, NULL, 9, 1, ADCx}, /* D73/PE9 */ // remap in - {GPIOE, NULL, NULL, 10, 0, ADCx}, /* D74/PE10 */ - {GPIOE, TIMER1, NULL, 11, 2, ADCx}, /* D75/PE11 */ // remap in - {GPIOE, NULL, NULL, 12, 0, ADCx}, /* D76/PE12 */ - {GPIOE, TIMER1, NULL, 13, 3, ADCx}, /* D77/PE13 */ // remap in - {GPIOE, TIMER1, NULL, 14, 4, ADCx}, /* D78/PE14 */ // remap in - {GPIOE, NULL, NULL, 15, 0, ADCx} /* D79/PE15 */ -}; - -extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { - 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 -}; - -extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { - 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 32, 33, 34, 35, 36, 37 -}; - -extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { - BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, - BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN, - 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 78, 79, 81, - 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 -}; - -/* -static void initSRAMChip(void) { - fsmc_nor_psram_reg_map *regs = FSMC_NOR_PSRAM1_BASE; - - fsmc_sram_init_gpios(); - rcc_clk_enable(RCC_FSMC); - - regs->BCR = (FSMC_BCR_WREN | FSMC_BCR_MWID_16BITS | FSMC_BCR_MTYP_SRAM | - FSMC_BCR_MBKEN); - fsmc_nor_psram_set_addset(regs, 0); - fsmc_nor_psram_set_datast(regs, 3); -} -*/ -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file discovery_f4.cpp + * @author ala42 + * @brief discovery_f4 board file. + */ + +#ifdef BOARD_discovery_f4 + +#include "discovery_f4.h" + +//#include "fsmc.h" +#include "gpio.h" +#include "rcc.h" +#include "timer.h" + +#include "wirish_types.h" + +//static void initSRAMChip(void); +void boardInit(void) { + // remap TIMER8 to PC6-9 + gpio_set_af_mode(GPIOC, 6, 3); + gpio_set_af_mode(GPIOC, 7, 3); + gpio_set_af_mode(GPIOC, 8, 3); + gpio_set_af_mode(GPIOC, 9, 3); + + // remap TIMER1 to PE9,11,13,14 + gpio_set_af_mode(GPIOE, 9, 1); + gpio_set_af_mode(GPIOE, 11, 1); + gpio_set_af_mode(GPIOE, 13, 1); + gpio_set_af_mode(GPIOE, 14, 1); + + // remap TIMER3 to PB4,5,0,1 + gpio_set_af_mode(GPIOB, 4, 2); + gpio_set_af_mode(GPIOB, 5, 2); + gpio_set_af_mode(GPIOB, 0, 2); + gpio_set_af_mode(GPIOB, 1, 2); + + + //gpio_set_af_mode(GPIOA, 2, 7); + //gpio_set_af_mode(GPIOA, 3, 7); + return; +} + + +#if 0 +typedef struct stm32_pin_info { + gpio_dev *gpio_device; /**< Maple pin's GPIO device */ + timer_dev *timer_device; /**< Pin's timer device, if any. */ + const adc_dev *adc_device; /**< ADC device, if any. */ + uint8 gpio_bit; /**< Pin's GPIO port bit. */ + uint8 timer_channel; /**< Timer channel, or 0 if none. */ + uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ +} stm32_pin_info; + +#endif + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + {GPIOA, TIMER5, ADC1, 0, 1, 0}, /* D00/PA0 */ + {GPIOA, TIMER5, ADC1, 1, 2, 1}, /* D01/PA1 */ + {GPIOA, TIMER5, ADC1, 2, 3, 2}, /* D02/PA2 */ + {GPIOA, TIMER5, ADC1, 3, 4, 3}, /* D03/PA3 */ + {GPIOA, NULL, ADC1, 4, 0, 4}, /* D04/PA4 */ + {GPIOA, NULL, ADC1, 5, 0, 5}, /* D05/PA5 */ + {GPIOA, NULL, ADC1, 6, 1, 6}, /* D06/PA6 */ // ala check TIMER3 + {GPIOA, NULL, ADC1, 7, 0, 7}, /* D07/PA7 */ + {GPIOA, NULL, NULL, 8, 0, ADCx}, /* D08/PA8 */ // remap out + {GPIOA, NULL, NULL, 9, 0, ADCx}, /* D09/PA9 */ // remap out + {GPIOA, NULL, NULL, 10, 0, ADCx}, /* D10/PA10 */ // remap out + {GPIOA, NULL, NULL, 11, 0, ADCx}, /* D11/PA11 */ // remap out + {GPIOA, NULL, NULL, 12, 0, ADCx}, /* D12/PA12 */ + {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D13/PA13 */ + {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D14/PA14 */ + {GPIOA, TIMER2, NULL, 15, 1, ADCx}, /* D15/PA15 */ // remap in + + {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D16/PB0 */ + {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D17/PB1 */ + {GPIOB, NULL, NULL, 2, 0, ADCx}, /* D18/PB2 */ + {GPIOB, TIMER2, NULL, 3, 2, ADCx}, /* D19/PB3 */ // remap in + {GPIOB, TIMER3, NULL, 4, 1, ADCx}, /* D20/PB4 */ // remap in + {GPIOB, TIMER3, NULL, 5, 2, ADCx}, /* D21/PB5 */ // remap in + {GPIOB, NULL, NULL, 6, 0, ADCx}, /* D22/PB6 */ // remap out + {GPIOB, NULL, NULL, 7, 0, ADCx}, /* D23/PB7 */ // remap out + {GPIOB, NULL, NULL, 8, 0, ADCx}, /* D24/PB8 */ // remap out + {GPIOB, NULL, NULL, 9, 0, ADCx}, /* D25/PB9 */ // remap out + {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D26/PB10 */ + {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D27/PB11 */ + {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D28/PB12 */ + {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D29/PB13 */ + {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D30/PB14 */ + {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D31/PB15 */ + + {GPIOC, NULL, ADC1, 0, 0, 10}, /* D32/PC0 */ + {GPIOC, NULL, ADC1, 1, 0, 11}, /* D33/PC1 */ + {GPIOC, NULL, ADC1, 2, 0, 12}, /* D34/PC2 */ + {GPIOC, NULL, ADC1, 3, 0, 13}, /* D35/PC3 */ + {GPIOC, NULL, ADC1, 4, 0, 14}, /* D36/PC4 */ + {GPIOC, NULL, ADC1, 5, 0, 15}, /* D37/PC5 */ + {GPIOC, TIMER8, NULL, 6, 1, ADCx}, /* D38/PC6 */ + {GPIOC, TIMER8, NULL, 7, 2, ADCx}, /* D39/PC7 */ + {GPIOC, TIMER8, NULL, 8, 3, ADCx}, /* D40/PC8 */ + {GPIOC, TIMER8, NULL, 9, 4, ADCx}, /* D41/PC9 */ + {GPIOC, NULL, NULL, 10, 0, ADCx}, /* D42/PC10 */ + {GPIOC, NULL, NULL, 11, 0, ADCx}, /* D43/PC11 */ + {GPIOC, NULL, NULL, 12, 0, ADCx}, /* D44/PC12 */ + {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D45/PC13 */ + {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D46/PC14 */ + {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D47/PC15 */ + + {GPIOD, NULL, NULL, 0, 0, ADCx}, /* D48/PD0 */ + {GPIOD, NULL, NULL, 1, 0, ADCx}, /* D49/PD1 */ + {GPIOD, NULL, NULL, 2, 0, ADCx}, /* D50/PD2 */ + {GPIOD, NULL, NULL, 3, 0, ADCx}, /* D51/PD3 */ + {GPIOD, NULL, NULL, 4, 0, ADCx}, /* D52/PD4 */ + {GPIOD, NULL, NULL, 5, 0, ADCx}, /* D53/PD5 */ + {GPIOD, NULL, NULL, 6, 0, ADCx}, /* D54/PD6 */ + {GPIOD, NULL, NULL, 7, 0, ADCx}, /* D55/PD7 */ + {GPIOD, NULL, NULL, 8, 0, ADCx}, /* D56/PD8 */ + {GPIOD, NULL, NULL, 9, 0, ADCx}, /* D57/PD9 */ + {GPIOD, NULL, NULL, 10, 0, ADCx}, /* D58/PD10 */ + {GPIOD, NULL, NULL, 11, 0, ADCx}, /* D59/PD11 */ + {GPIOD, TIMER4, NULL, 12, 1, ADCx}, /* D60/PD12 */ // remap in + {GPIOD, TIMER4, NULL, 13, 2, ADCx}, /* D61/PD13 */ // remap in + {GPIOD, TIMER4, NULL, 14, 3, ADCx}, /* D62/PD14 */ // remap in + {GPIOD, TIMER4, NULL, 15, 4, ADCx}, /* D63/PD15 */ // remap in + + {GPIOE, NULL, NULL, 0, 0, ADCx}, /* D64/PE0 */ + {GPIOE, NULL, NULL, 1, 0, ADCx}, /* D65/PE1 */ + {GPIOE, NULL, NULL, 2, 0, ADCx}, /* D66/PE2 */ + {GPIOE, NULL, NULL, 3, 0, ADCx}, /* D67/PE3 */ + {GPIOE, NULL, NULL, 4, 0, ADCx}, /* D68/PE4 */ + {GPIOE, NULL, NULL, 5, 0, ADCx}, /* D69/PE5 */ + {GPIOE, NULL, NULL, 6, 0, ADCx}, /* D70/PE6 */ + {GPIOE, NULL, NULL, 7, 0, ADCx}, /* D71/PE7 */ + {GPIOE, NULL, NULL, 8, 0, ADCx}, /* D72/PE8 */ + {GPIOE, TIMER1, NULL, 9, 1, ADCx}, /* D73/PE9 */ // remap in + {GPIOE, NULL, NULL, 10, 0, ADCx}, /* D74/PE10 */ + {GPIOE, TIMER1, NULL, 11, 2, ADCx}, /* D75/PE11 */ // remap in + {GPIOE, NULL, NULL, 12, 0, ADCx}, /* D76/PE12 */ + {GPIOE, TIMER1, NULL, 13, 3, ADCx}, /* D77/PE13 */ // remap in + {GPIOE, TIMER1, NULL, 14, 4, ADCx}, /* D78/PE14 */ // remap in + {GPIOE, NULL, NULL, 15, 0, ADCx} /* D79/PE15 */ +}; + +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + 0, 1, 2, 3, 15, 16, 17, 19, 20, 21, 38, 39, 49, 41, 60, 61, 62, 63, 73, 75, 77, 78 +}; + +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 32, 33, 34, 35, 36, 37 +}; + +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN, + 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 78, 79, 81, + 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 +}; + +/* +static void initSRAMChip(void) { + fsmc_nor_psram_reg_map *regs = FSMC_NOR_PSRAM1_BASE; + + fsmc_sram_init_gpios(); + rcc_clk_enable(RCC_FSMC); + + regs->BCR = (FSMC_BCR_WREN | FSMC_BCR_MWID_16BITS | FSMC_BCR_MTYP_SRAM | + FSMC_BCR_MBKEN); + fsmc_nor_psram_set_addset(regs, 0); + fsmc_nor_psram_set_datast(regs, 3); +} +*/ +#endif diff --git a/Libmaple/libmaple/wirish/boards/discovery_f4.h b/Libmaple/libmaple/wirish/boards/discovery_f4.h index bb1c092b..7c37e56d 100644 --- a/Libmaple/libmaple/wirish/boards/discovery_f4.h +++ b/Libmaple/libmaple/wirish/boards/discovery_f4.h @@ -1,94 +1,94 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file aeroquad32.h - * @author Marti Bolivar - * @brief Private include file for Maple Native in boards.h - * - * See maple.h for more information on these definitions. - */ - -#ifndef _BOARD_DISCOVERY_F4_H_ -#define _BOARD_DISCOVERY_F4_H_ - -#define Port2Pin(port, bit) ((port-'A')*16+bit) - -#define CYCLES_PER_MICROSECOND 168 - - -#undef STM32_PCLK1 -#undef STM32_PCLK2 -#define STM32_PCLK1 (CYCLES_PER_MICROSECOND*1000000/4) -#define STM32_PCLK2 (CYCLES_PER_MICROSECOND*1000000/2) - -#define SYSTICK_RELOAD_VAL (CYCLES_PER_MICROSECOND*1000-1) - -#define BOARD_LED_PIN Port2Pin('D', 12) -#define BOARD_BUTTON_PIN Port2Pin('A', 0) - -#define BOARD_NR_USARTS 5 -#define BOARD_USART1_TX_PIN Port2Pin('A', 9) -#define BOARD_USART1_RX_PIN Port2Pin('A',10) -#define BOARD_USART2_TX_PIN Port2Pin('A', 2) -#define BOARD_USART2_RX_PIN Port2Pin('A', 3) -#define BOARD_USART3_TX_PIN Port2Pin('D', 8) -#define BOARD_USART3_RX_PIN Port2Pin('D', 9) -#define BOARD_UART4_TX_PIN Port2Pin('C',10) -#define BOARD_UART4_RX_PIN Port2Pin('C',11) -#define BOARD_UART5_TX_PIN Port2Pin('C',12) -#define BOARD_UART5_RX_PIN Port2Pin('D', 2) - -#define BOARD_NR_SPI 3 -#define BOARD_SPI1_NSS_PIN Port2Pin('A', 4) -#define BOARD_SPI1_MOSI_PIN Port2Pin('A', 7) -#define BOARD_SPI1_MISO_PIN Port2Pin('A', 6) -#define BOARD_SPI1_SCK_PIN Port2Pin('A', 5) -#define BOARD_SPI2_NSS_PIN Port2Pin('B',12) -#define BOARD_SPI2_MOSI_PIN Port2Pin('B',15) -#define BOARD_SPI2_MISO_PIN Port2Pin('B',14) -#define BOARD_SPI2_SCK_PIN Port2Pin('B',13) -#define BOARD_SPI3_NSS_PIN Port2Pin('A',15) -#define BOARD_SPI3_MOSI_PIN Port2Pin('B', 5) -#define BOARD_SPI3_MISO_PIN Port2Pin('B', 4) -#define BOARD_SPI3_SCK_PIN Port2Pin('B', 3) - -#define BOARD_SPI3B_NSS_PIN Port2Pin('B', 8) -#define BOARD_SPI3B_MOSI_PIN Port2Pin('C',12) -#define BOARD_SPI3B_MISO_PIN Port2Pin('C',11) -#define BOARD_SPI3B_SCK_PIN Port2Pin('C',10) - -#define BOARD_NR_GPIO_PINS 80 -#define BOARD_NR_PWM_PINS 22 -#define BOARD_NR_ADC_PINS 16 -#define BOARD_NR_USED_PINS 43 // ala42 not set yet -#define BOARD_JTMS_SWDIO_PIN Port2Pin('A',13) -#define BOARD_JTCK_SWCLK_PIN Port2Pin('A',14) -#define BOARD_JTDI_PIN Port2Pin('A',15) -#define BOARD_JTDO_PIN Port2Pin('B', 3) -#define BOARD_NJTRST_PIN Port2Pin('B', 4) - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file aeroquad32.h + * @author Marti Bolivar + * @brief Private include file for Maple Native in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARD_DISCOVERY_F4_H_ +#define _BOARD_DISCOVERY_F4_H_ + +#define Port2Pin(port, bit) ((port-'A')*16+bit) + +#define CYCLES_PER_MICROSECOND 168 + + +#undef STM32_PCLK1 +#undef STM32_PCLK2 +#define STM32_PCLK1 (CYCLES_PER_MICROSECOND*1000000/4) +#define STM32_PCLK2 (CYCLES_PER_MICROSECOND*1000000/2) + +#define SYSTICK_RELOAD_VAL (CYCLES_PER_MICROSECOND*1000-1) + +#define BOARD_LED_PIN Port2Pin('D', 12) +#define BOARD_BUTTON_PIN Port2Pin('A', 0) + +#define BOARD_NR_USARTS 5 +#define BOARD_USART1_TX_PIN Port2Pin('A', 9) +#define BOARD_USART1_RX_PIN Port2Pin('A',10) +#define BOARD_USART2_TX_PIN Port2Pin('A', 2) +#define BOARD_USART2_RX_PIN Port2Pin('A', 3) +#define BOARD_USART3_TX_PIN Port2Pin('D', 8) +#define BOARD_USART3_RX_PIN Port2Pin('D', 9) +#define BOARD_UART4_TX_PIN Port2Pin('C',10) +#define BOARD_UART4_RX_PIN Port2Pin('C',11) +#define BOARD_UART5_TX_PIN Port2Pin('C',12) +#define BOARD_UART5_RX_PIN Port2Pin('D', 2) + +#define BOARD_NR_SPI 3 +#define BOARD_SPI1_NSS_PIN Port2Pin('A', 4) +#define BOARD_SPI1_MOSI_PIN Port2Pin('A', 7) +#define BOARD_SPI1_MISO_PIN Port2Pin('A', 6) +#define BOARD_SPI1_SCK_PIN Port2Pin('A', 5) +#define BOARD_SPI2_NSS_PIN Port2Pin('B',12) +#define BOARD_SPI2_MOSI_PIN Port2Pin('B',15) +#define BOARD_SPI2_MISO_PIN Port2Pin('B',14) +#define BOARD_SPI2_SCK_PIN Port2Pin('B',13) +#define BOARD_SPI3_NSS_PIN Port2Pin('A',15) +#define BOARD_SPI3_MOSI_PIN Port2Pin('B', 5) +#define BOARD_SPI3_MISO_PIN Port2Pin('B', 4) +#define BOARD_SPI3_SCK_PIN Port2Pin('B', 3) + +#define BOARD_SPI3B_NSS_PIN Port2Pin('B', 8) +#define BOARD_SPI3B_MOSI_PIN Port2Pin('C',12) +#define BOARD_SPI3B_MISO_PIN Port2Pin('C',11) +#define BOARD_SPI3B_SCK_PIN Port2Pin('C',10) + +#define BOARD_NR_GPIO_PINS 80 +#define BOARD_NR_PWM_PINS 22 +#define BOARD_NR_ADC_PINS 16 +#define BOARD_NR_USED_PINS 43 // ala42 not set yet +#define BOARD_JTMS_SWDIO_PIN Port2Pin('A',13) +#define BOARD_JTCK_SWCLK_PIN Port2Pin('A',14) +#define BOARD_JTDI_PIN Port2Pin('A',15) +#define BOARD_JTDO_PIN Port2Pin('B', 3) +#define BOARD_NJTRST_PIN Port2Pin('B', 4) + +#endif diff --git a/Libmaple/libmaple/wirish/boards/freeflight.cpp b/Libmaple/libmaple/wirish/boards/freeflight.cpp index fb2a3635..0b271d33 100644 --- a/Libmaple/libmaple/wirish/boards/freeflight.cpp +++ b/Libmaple/libmaple/wirish/boards/freeflight.cpp @@ -1,113 +1,113 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file aeroquad32mini.cpp - * @author ala42 - * @brief aeroquad32mini board file. - */ - -#ifdef BOARD_freeflight - -#include "freeflight.h" - -//#include "fsmc.h" -#include "gpio.h" -#include "rcc.h" -#include "timer.h" - -#include "wirish_types.h" - -//static void initSRAMChip(void); -void boardInit(void) { - __io uint32 *mapr = &AFIO_BASE->MAPR; - *mapr = ((*mapr) & ~(7 << 24) ) - | AFIO_MAPR_SWJ_CFG_NO_JTAG_SW; -} - - -#if 0 -typedef struct stm32_pin_info { - gpio_dev *gpio_device; /**< Maple pin's GPIO device */ - timer_dev *timer_device; /**< Pin's timer device, if any. */ - const adc_dev *adc_device; /**< ADC device, if any. */ - uint8 gpio_bit; /**< Pin's GPIO port bit. */ - uint8 timer_channel; /**< Timer channel, or 0 if none. */ - uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ -} stm32_pin_info; - -#endif - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - {GPIOA, TIMER2, ADC1, 0, 1, 0}, /* D00/PA0 */ - {GPIOA, TIMER2, ADC1, 1, 2, 1}, /* D01/PA1 */ - {GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D02/PA2 */ - {GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D03/PA3 */ - {GPIOA, NULL, ADC1, 4, 0, 4}, /* D04/PA4 */ - {GPIOA, NULL, ADC1, 5, 0, 5}, /* D05/PA5 */ - {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D06/PA6 */ // ala check TIMER3 - {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D07/PA7 */ - {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D08/PA8 */ // remap out - {GPIOA, NULL, NULL, 9, 0, ADCx}, /* D09/PA9 */ // remap out - {GPIOA, NULL, NULL, 10, 0, ADCx}, /* D10/PA10 */ // remap out - {GPIOA, TIMER1, NULL, 11, 4, ADCx}, /* D11/PA11 */ // remap out - {GPIOA, NULL, NULL, 12, 0, ADCx}, /* D12/PA12 */ - {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D13/PA13 */ - {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D14/PA14 */ - {GPIOA, NULL, NULL, 15, 0, ADCx}, /* D15/PA15 */ // remap in - - {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D16/PB0 */ - {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D17/PB1 */ - {GPIOB, NULL, NULL, 2, 0, ADCx}, /* D18/PB2 */ - {GPIOB, NULL, NULL, 3, 2, ADCx}, /* D19/PB3 */ // remap in - {GPIOB, NULL, NULL, 4, 1, ADCx}, /* D20/PB4 */ // remap in - {GPIOB, NULL, NULL, 5, 2, ADCx}, /* D21/PB5 */ // remap in - {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D22/PB6 */ // remap out - {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D23/PB7 */ // remap out - {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D24/PB8 */ // remap out - {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* D25/PB9 */ // remap out - {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D26/PB10 */ - {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D27/PB11 */ - {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D28/PB12 */ - {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D29/PB13 */ - {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D30/PB14 */ - {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D31/PB15 */ -}; - -extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { - 0, 1, 2, 3, 6, 7, 8, 11, 16,17, 22, 23, 24, 25 -}; - -extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 -}; - -extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { - BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, - BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN -}; - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file aeroquad32mini.cpp + * @author ala42 + * @brief aeroquad32mini board file. + */ + +#ifdef BOARD_freeflight + +#include "freeflight.h" + +//#include "fsmc.h" +#include "gpio.h" +#include "rcc.h" +#include "timer.h" + +#include "wirish_types.h" + +//static void initSRAMChip(void); +void boardInit(void) { + __io uint32 *mapr = &AFIO_BASE->MAPR; + *mapr = ((*mapr) & ~(7 << 24) ) + | AFIO_MAPR_SWJ_CFG_NO_JTAG_SW; +} + + +#if 0 +typedef struct stm32_pin_info { + gpio_dev *gpio_device; /**< Maple pin's GPIO device */ + timer_dev *timer_device; /**< Pin's timer device, if any. */ + const adc_dev *adc_device; /**< ADC device, if any. */ + uint8 gpio_bit; /**< Pin's GPIO port bit. */ + uint8 timer_channel; /**< Timer channel, or 0 if none. */ + uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ +} stm32_pin_info; + +#endif + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + {GPIOA, TIMER2, ADC1, 0, 1, 0}, /* D00/PA0 */ + {GPIOA, TIMER2, ADC1, 1, 2, 1}, /* D01/PA1 */ + {GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D02/PA2 */ + {GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D03/PA3 */ + {GPIOA, NULL, ADC1, 4, 0, 4}, /* D04/PA4 */ + {GPIOA, NULL, ADC1, 5, 0, 5}, /* D05/PA5 */ + {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D06/PA6 */ // ala check TIMER3 + {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D07/PA7 */ + {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D08/PA8 */ // remap out + {GPIOA, NULL, NULL, 9, 0, ADCx}, /* D09/PA9 */ // remap out + {GPIOA, NULL, NULL, 10, 0, ADCx}, /* D10/PA10 */ // remap out + {GPIOA, TIMER1, NULL, 11, 4, ADCx}, /* D11/PA11 */ // remap out + {GPIOA, NULL, NULL, 12, 0, ADCx}, /* D12/PA12 */ + {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D13/PA13 */ + {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D14/PA14 */ + {GPIOA, NULL, NULL, 15, 0, ADCx}, /* D15/PA15 */ // remap in + + {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D16/PB0 */ + {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D17/PB1 */ + {GPIOB, NULL, NULL, 2, 0, ADCx}, /* D18/PB2 */ + {GPIOB, NULL, NULL, 3, 2, ADCx}, /* D19/PB3 */ // remap in + {GPIOB, NULL, NULL, 4, 1, ADCx}, /* D20/PB4 */ // remap in + {GPIOB, NULL, NULL, 5, 2, ADCx}, /* D21/PB5 */ // remap in + {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D22/PB6 */ // remap out + {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D23/PB7 */ // remap out + {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D24/PB8 */ // remap out + {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* D25/PB9 */ // remap out + {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D26/PB10 */ + {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D27/PB11 */ + {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D28/PB12 */ + {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D29/PB13 */ + {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D30/PB14 */ + {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D31/PB15 */ +}; + +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + 0, 1, 2, 3, 6, 7, 8, 11, 16,17, 22, 23, 24, 25 +}; + +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 +}; + +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN +}; + +#endif diff --git a/Libmaple/libmaple/wirish/boards/freeflight.h b/Libmaple/libmaple/wirish/boards/freeflight.h index ad8c4908..9aee8b96 100644 --- a/Libmaple/libmaple/wirish/boards/freeflight.h +++ b/Libmaple/libmaple/wirish/boards/freeflight.h @@ -1,68 +1,68 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file aeroquad32.h - * @author Marti Bolivar - * @brief Private include file for Maple Native in boards.h - * - * See maple.h for more information on these definitions. - */ - -#ifndef _BOARD_FREEFLIGHT_H_ -#define _BOARD_FREEFLIGHT_H_ - -#define Port2Pin(port, bit) ((port-'A')*16+bit) - -#define CYCLES_PER_MICROSECOND 72 -#define SYSTICK_RELOAD_VAL 71999 - -#define BOARD_LED_PIN Port2Pin('B', 4) -#define BOARD_BUTTON_PIN Port2Pin('B', 3) - -#define BOARD_NR_USARTS 2 -#define BOARD_USART1_TX_PIN Port2Pin('A', 9) -#define BOARD_USART1_RX_PIN Port2Pin('A',10) -#define BOARD_USART2_TX_PIN Port2Pin('A', 2) -#define BOARD_USART2_RX_PIN Port2Pin('A', 3) - -#define BOARD_NR_SPI 1 -#define BOARD_SPI1_NSS_PIN Port2Pin('B',12) -#define BOARD_SPI1_MOSI_PIN Port2Pin('B',15) -#define BOARD_SPI1_MISO_PIN Port2Pin('B',14) -#define BOARD_SPI1_SCK_PIN Port2Pin('B',13) - -#define BOARD_NR_GPIO_PINS 32 -#define BOARD_NR_PWM_PINS 14 -#define BOARD_NR_ADC_PINS 10 -#define BOARD_NR_USED_PINS 7 // ala42 not set yet -#define BOARD_JTMS_SWDIO_PIN Port2Pin('A',13) -#define BOARD_JTCK_SWCLK_PIN Port2Pin('A',14) -#define BOARD_JTDI_PIN Port2Pin('A',15) -#define BOARD_JTDO_PIN Port2Pin('B', 3) -#define BOARD_NJTRST_PIN Port2Pin('B', 4) - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file aeroquad32.h + * @author Marti Bolivar + * @brief Private include file for Maple Native in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARD_FREEFLIGHT_H_ +#define _BOARD_FREEFLIGHT_H_ + +#define Port2Pin(port, bit) ((port-'A')*16+bit) + +#define CYCLES_PER_MICROSECOND 72 +#define SYSTICK_RELOAD_VAL 71999 + +#define BOARD_LED_PIN Port2Pin('B', 4) +#define BOARD_BUTTON_PIN Port2Pin('B', 3) + +#define BOARD_NR_USARTS 2 +#define BOARD_USART1_TX_PIN Port2Pin('A', 9) +#define BOARD_USART1_RX_PIN Port2Pin('A',10) +#define BOARD_USART2_TX_PIN Port2Pin('A', 2) +#define BOARD_USART2_RX_PIN Port2Pin('A', 3) + +#define BOARD_NR_SPI 1 +#define BOARD_SPI1_NSS_PIN Port2Pin('B',12) +#define BOARD_SPI1_MOSI_PIN Port2Pin('B',15) +#define BOARD_SPI1_MISO_PIN Port2Pin('B',14) +#define BOARD_SPI1_SCK_PIN Port2Pin('B',13) + +#define BOARD_NR_GPIO_PINS 32 +#define BOARD_NR_PWM_PINS 14 +#define BOARD_NR_ADC_PINS 10 +#define BOARD_NR_USED_PINS 7 // ala42 not set yet +#define BOARD_JTMS_SWDIO_PIN Port2Pin('A',13) +#define BOARD_JTCK_SWCLK_PIN Port2Pin('A',14) +#define BOARD_JTDI_PIN Port2Pin('A',15) +#define BOARD_JTDO_PIN Port2Pin('B', 3) +#define BOARD_NJTRST_PIN Port2Pin('B', 4) + +#endif diff --git a/Libmaple/libmaple/wirish/boards/maple.cpp b/Libmaple/libmaple/wirish/boards/maple.cpp index 87301418..43d43863 100644 --- a/Libmaple/libmaple/wirish/boards/maple.cpp +++ b/Libmaple/libmaple/wirish/boards/maple.cpp @@ -1,116 +1,116 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file maple.cpp - * @author Marti Bolivar - * @brief Maple PIN_MAP and boardInit(). - */ - -#ifdef BOARD_maple - -#include "maple.h" - -#include "gpio.h" -#include "timer.h" -#include "wirish_types.h" - -void boardInit(void) { -} - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - - /* Top header */ - - {GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D0/PA3 */ - {GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D1/PA2 */ - {GPIOA, TIMER2, ADC1, 0, 1, 0}, /* D2/PA0 */ - {GPIOA, TIMER2, ADC1, 1, 2, 1}, /* D3/PA1 */ - {GPIOB, NULL, NULL, 5, 0, ADCx}, /* D4/PB5 */ - {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D5/PB6 */ - {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D6/PA8 */ - {GPIOA, TIMER1, NULL, 9, 2, ADCx}, /* D7/PA9 */ - {GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* D8/PA10 */ - {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D9/PB7 */ - {GPIOA, NULL, ADC1, 4, 0, 4}, /* D10/PA4 */ - {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D11/PA7 */ - {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D12/PA6 */ - {GPIOA, NULL, ADC1, 5, 0, 5}, /* D13/PA5 (LED) */ - {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D14/PB8 */ - - /* Little header */ - - {GPIOC, NULL, ADC1, 0, 0, 10}, /* D15/PC0 */ - {GPIOC, NULL, ADC1, 1, 0, 11}, /* D16/PC1 */ - {GPIOC, NULL, ADC1, 2, 0, 12}, /* D17/PC2 */ - {GPIOC, NULL, ADC1, 3, 0, 13}, /* D18/PC3 */ - {GPIOC, NULL, ADC1, 4, 0, 14}, /* D19/PC4 */ - {GPIOC, NULL, ADC1, 5, 0, 15}, /* D20/PC5 */ - - /* External header */ - - {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D21/PC13 */ - {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D22/PC14 */ - {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D23/PC15 */ - {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* D24/PB9 */ - {GPIOD, NULL, NULL, 2, 0, ADCx}, /* D25/PD2 */ - {GPIOC, NULL, NULL, 10, 0, ADCx}, /* D26/PC10 */ - {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D27/PB0 */ - {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D28/PB1 */ - {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D29/PB10 */ - {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D30/PB11 */ - {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D31/PB12 */ - {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D32/PB13 */ - {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D33/PB14 */ - {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D34/PB15 */ - {GPIOC, NULL, NULL, 6, 0, ADCx}, /* D35/PC6 */ - {GPIOC, NULL, NULL, 7, 0, ADCx}, /* D36/PC7 */ - {GPIOC, NULL, NULL, 8, 0, ADCx}, /* D37/PC8 */ - {GPIOC, NULL, NULL, 9, 0, ADCx}, /* D38/PC9 (BUT) */ - - /* JTAG header */ - - {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D39/PA13 */ - {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D40/PA14 */ - {GPIOA, NULL, NULL, 15, 0, ADCx}, /* D41/PA15 */ - {GPIOB, NULL, NULL, 3, 0, ADCx}, /* D42/PB3 */ - {GPIOB, NULL, NULL, 4, 0, ADCx}, /* D43/PB4 */ -}; - -extern const uint8 boardPWMPins[] __FLASH__ = { - 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28 -}; - -extern const uint8 boardADCPins[] __FLASH__ = { - 0, 1, 2, 3, 10, 11, 12, 15, 16, 17, 18, 19, 20, 27, 28 -}; - -extern const uint8 boardUsedPins[] __FLASH__ = { - BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, - BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN -}; - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file maple.cpp + * @author Marti Bolivar + * @brief Maple PIN_MAP and boardInit(). + */ + +#ifdef BOARD_maple + +#include "maple.h" + +#include "gpio.h" +#include "timer.h" +#include "wirish_types.h" + +void boardInit(void) { +} + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + + /* Top header */ + + {GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D0/PA3 */ + {GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D1/PA2 */ + {GPIOA, TIMER2, ADC1, 0, 1, 0}, /* D2/PA0 */ + {GPIOA, TIMER2, ADC1, 1, 2, 1}, /* D3/PA1 */ + {GPIOB, NULL, NULL, 5, 0, ADCx}, /* D4/PB5 */ + {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D5/PB6 */ + {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D6/PA8 */ + {GPIOA, TIMER1, NULL, 9, 2, ADCx}, /* D7/PA9 */ + {GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* D8/PA10 */ + {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D9/PB7 */ + {GPIOA, NULL, ADC1, 4, 0, 4}, /* D10/PA4 */ + {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D11/PA7 */ + {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D12/PA6 */ + {GPIOA, NULL, ADC1, 5, 0, 5}, /* D13/PA5 (LED) */ + {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D14/PB8 */ + + /* Little header */ + + {GPIOC, NULL, ADC1, 0, 0, 10}, /* D15/PC0 */ + {GPIOC, NULL, ADC1, 1, 0, 11}, /* D16/PC1 */ + {GPIOC, NULL, ADC1, 2, 0, 12}, /* D17/PC2 */ + {GPIOC, NULL, ADC1, 3, 0, 13}, /* D18/PC3 */ + {GPIOC, NULL, ADC1, 4, 0, 14}, /* D19/PC4 */ + {GPIOC, NULL, ADC1, 5, 0, 15}, /* D20/PC5 */ + + /* External header */ + + {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D21/PC13 */ + {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D22/PC14 */ + {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D23/PC15 */ + {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* D24/PB9 */ + {GPIOD, NULL, NULL, 2, 0, ADCx}, /* D25/PD2 */ + {GPIOC, NULL, NULL, 10, 0, ADCx}, /* D26/PC10 */ + {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D27/PB0 */ + {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D28/PB1 */ + {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D29/PB10 */ + {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D30/PB11 */ + {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D31/PB12 */ + {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D32/PB13 */ + {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D33/PB14 */ + {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D34/PB15 */ + {GPIOC, NULL, NULL, 6, 0, ADCx}, /* D35/PC6 */ + {GPIOC, NULL, NULL, 7, 0, ADCx}, /* D36/PC7 */ + {GPIOC, NULL, NULL, 8, 0, ADCx}, /* D37/PC8 */ + {GPIOC, NULL, NULL, 9, 0, ADCx}, /* D38/PC9 (BUT) */ + + /* JTAG header */ + + {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D39/PA13 */ + {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D40/PA14 */ + {GPIOA, NULL, NULL, 15, 0, ADCx}, /* D41/PA15 */ + {GPIOB, NULL, NULL, 3, 0, ADCx}, /* D42/PB3 */ + {GPIOB, NULL, NULL, 4, 0, ADCx}, /* D43/PB4 */ +}; + +extern const uint8 boardPWMPins[] __FLASH__ = { + 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28 +}; + +extern const uint8 boardADCPins[] __FLASH__ = { + 0, 1, 2, 3, 10, 11, 12, 15, 16, 17, 18, 19, 20, 27, 28 +}; + +extern const uint8 boardUsedPins[] __FLASH__ = { + BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN +}; + +#endif diff --git a/Libmaple/libmaple/wirish/boards/maple.h b/Libmaple/libmaple/wirish/boards/maple.h index 5cdf55a8..e26de99e 100644 --- a/Libmaple/libmaple/wirish/boards/maple.h +++ b/Libmaple/libmaple/wirish/boards/maple.h @@ -1,87 +1,87 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file maple.h - * @author Marti Bolivar - * @brief Private include file for Maple in boards.h - */ - -#ifndef _BOARD_MAPLE_H_ -#define _BOARD_MAPLE_H_ - -#define CYCLES_PER_MICROSECOND 72 -#define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */ - -#define BOARD_BUTTON_PIN 38 -#define BOARD_LED_PIN 13 - -/* Number of USARTs/UARTs whose pins are broken out to headers */ -#define BOARD_NR_USARTS 3 - -/* Default USART pin numbers (not considering AFIO remap) */ -#define BOARD_USART1_TX_PIN 7 -#define BOARD_USART1_RX_PIN 8 -#define BOARD_USART2_TX_PIN 1 -#define BOARD_USART2_RX_PIN 0 -#define BOARD_USART3_TX_PIN 29 -#define BOARD_USART3_RX_PIN 30 - -/* Number of SPI ports */ -#define BOARD_NR_SPI 2 - -/* Default SPI pin numbers (not considering AFIO remap) */ -#define BOARD_SPI1_NSS_PIN 10 -#define BOARD_SPI1_MOSI_PIN 11 -#define BOARD_SPI1_MISO_PIN 12 -#define BOARD_SPI1_SCK_PIN 13 -#define BOARD_SPI2_NSS_PIN 31 -#define BOARD_SPI2_MOSI_PIN 34 -#define BOARD_SPI2_MISO_PIN 33 -#define BOARD_SPI2_SCK_PIN 32 - -/* Total number of GPIO pins that are broken out to headers and - * intended for general use. */ -#define BOARD_NR_GPIO_PINS 44 - -/* Number of pins capable of PWM output */ -#define BOARD_NR_PWM_PINS 15 - -/* Number of pins capable of ADC conversion */ -#define BOARD_NR_ADC_PINS 15 - -/* Number of pins already connected to external hardware. For Maple, - * these are just BOARD_LED_PIN and BOARD_BUTTON_PIN. */ -#define BOARD_NR_USED_PINS 7 - -/* Debug port pins */ -#define BOARD_JTMS_SWDIO_PIN 39 -#define BOARD_JTCK_SWCLK_PIN 40 -#define BOARD_JTDI_PIN 41 -#define BOARD_JTDO_PIN 42 -#define BOARD_NJTRST_PIN 43 - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file maple.h + * @author Marti Bolivar + * @brief Private include file for Maple in boards.h + */ + +#ifndef _BOARD_MAPLE_H_ +#define _BOARD_MAPLE_H_ + +#define CYCLES_PER_MICROSECOND 72 +#define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */ + +#define BOARD_BUTTON_PIN 38 +#define BOARD_LED_PIN 13 + +/* Number of USARTs/UARTs whose pins are broken out to headers */ +#define BOARD_NR_USARTS 3 + +/* Default USART pin numbers (not considering AFIO remap) */ +#define BOARD_USART1_TX_PIN 7 +#define BOARD_USART1_RX_PIN 8 +#define BOARD_USART2_TX_PIN 1 +#define BOARD_USART2_RX_PIN 0 +#define BOARD_USART3_TX_PIN 29 +#define BOARD_USART3_RX_PIN 30 + +/* Number of SPI ports */ +#define BOARD_NR_SPI 2 + +/* Default SPI pin numbers (not considering AFIO remap) */ +#define BOARD_SPI1_NSS_PIN 10 +#define BOARD_SPI1_MOSI_PIN 11 +#define BOARD_SPI1_MISO_PIN 12 +#define BOARD_SPI1_SCK_PIN 13 +#define BOARD_SPI2_NSS_PIN 31 +#define BOARD_SPI2_MOSI_PIN 34 +#define BOARD_SPI2_MISO_PIN 33 +#define BOARD_SPI2_SCK_PIN 32 + +/* Total number of GPIO pins that are broken out to headers and + * intended for general use. */ +#define BOARD_NR_GPIO_PINS 44 + +/* Number of pins capable of PWM output */ +#define BOARD_NR_PWM_PINS 15 + +/* Number of pins capable of ADC conversion */ +#define BOARD_NR_ADC_PINS 15 + +/* Number of pins already connected to external hardware. For Maple, + * these are just BOARD_LED_PIN and BOARD_BUTTON_PIN. */ +#define BOARD_NR_USED_PINS 7 + +/* Debug port pins */ +#define BOARD_JTMS_SWDIO_PIN 39 +#define BOARD_JTCK_SWCLK_PIN 40 +#define BOARD_JTDI_PIN 41 +#define BOARD_JTDO_PIN 42 +#define BOARD_NJTRST_PIN 43 + +#endif diff --git a/Libmaple/libmaple/wirish/boards/maple_RET6.cpp b/Libmaple/libmaple/wirish/boards/maple_RET6.cpp index 226a7200..cbd7e250 100644 --- a/Libmaple/libmaple/wirish/boards/maple_RET6.cpp +++ b/Libmaple/libmaple/wirish/boards/maple_RET6.cpp @@ -1,118 +1,118 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file maple_RET6.cpp - * @author Marti Bolivar - * @brief Maple RET6 Edition board file - */ - -#ifdef BOARD_maple_RET6 - -#include "maple_RET6.h" - -#include "gpio.h" -#include "timer.h" -#include "wirish_types.h" - -void boardInit(void) { -} - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - - /* Top header */ - - {GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D0/PA3 */ - {GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D1/PA2 */ - {GPIOA, TIMER2, ADC1, 0, 1, 0}, /* D2/PA0 */ - {GPIOA, TIMER2, ADC1, 1, 2, 1}, /* D3/PA1 */ - {GPIOB, NULL, NULL, 5, 0, ADCx}, /* D4/PB5 */ - {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D5/PB6 */ - {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D6/PA8 */ - {GPIOA, TIMER1, NULL, 9, 2, ADCx}, /* D7/PA9 */ - {GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* D8/PA10 */ - {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D9/PB7 */ - {GPIOA, NULL, ADC1, 4, 0, 4}, /* D10/PA4 */ - {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D11/PA7 */ - {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D12/PA6 */ - {GPIOA, NULL, ADC1, 5, 0, 5}, /* D13/PA5 (LED) */ - {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D14/PB8 */ - - /* Little header */ - - {GPIOC, NULL, ADC1, 0, 0, 10}, /* D15/PC0 */ - {GPIOC, NULL, ADC1, 1, 0, 11}, /* D16/PC1 */ - {GPIOC, NULL, ADC1, 2, 0, 12}, /* D17/PC2 */ - {GPIOC, NULL, ADC1, 3, 0, 13}, /* D18/PC3 */ - {GPIOC, NULL, ADC1, 4, 0, 14}, /* D19/PC4 */ - {GPIOC, NULL, ADC1, 5, 0, 15}, /* D20/PC5 */ - - /* External header */ - - {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D21/PC13 */ - {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D22/PC14 */ - {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D23/PC15 */ - {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* D24/PB9 */ - {GPIOD, NULL, NULL, 2, 0, ADCx}, /* D25/PD2 */ - {GPIOC, NULL, NULL, 10, 0, ADCx}, /* D26/PC10 */ - {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D27/PB0 */ - {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D28/PB1 */ - {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D29/PB10 */ - {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D30/PB11 */ - {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D31/PB12 */ - {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D32/PB13 */ - {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D33/PB14 */ - {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D34/PB15 */ - {GPIOC, TIMER8, NULL, 6, 1, ADCx}, /* D35/PC6 */ - {GPIOC, TIMER8, NULL, 7, 2, ADCx}, /* D36/PC7 */ - {GPIOC, TIMER8, NULL, 8, 3, ADCx}, /* D37/PC8 */ - {GPIOC, TIMER8, NULL, 9, 4, ADCx}, /* D38/PC9 (BUT) */ - - /* JTAG header */ - - {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D39/PA13 */ - {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D40/PA14 */ - {GPIOA, NULL, NULL, 15, 0, ADCx}, /* D41/PA15 */ - {GPIOB, NULL, NULL, 3, 0, ADCx}, /* D42/PB3 */ - {GPIOB, NULL, NULL, 4, 0, ADCx}, /* D43/PB4 */ -}; - -/* Note: Do NOT include pin 38 (TIM8_CH4), as that's BOARD_BUTTON_PIN - * and thus not broken out to a header. */ -extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { - 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28, 35, 36, 37 -}; - -extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { - 0, 1, 2, 3, 10, 11, 12, 15, 16, 17, 18, 19, 20, 27, 28 -}; - -extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { - BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, - BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN -}; - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file maple_RET6.cpp + * @author Marti Bolivar + * @brief Maple RET6 Edition board file + */ + +#ifdef BOARD_maple_RET6 + +#include "maple_RET6.h" + +#include "gpio.h" +#include "timer.h" +#include "wirish_types.h" + +void boardInit(void) { +} + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + + /* Top header */ + + {GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D0/PA3 */ + {GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D1/PA2 */ + {GPIOA, TIMER2, ADC1, 0, 1, 0}, /* D2/PA0 */ + {GPIOA, TIMER2, ADC1, 1, 2, 1}, /* D3/PA1 */ + {GPIOB, NULL, NULL, 5, 0, ADCx}, /* D4/PB5 */ + {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D5/PB6 */ + {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D6/PA8 */ + {GPIOA, TIMER1, NULL, 9, 2, ADCx}, /* D7/PA9 */ + {GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* D8/PA10 */ + {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D9/PB7 */ + {GPIOA, NULL, ADC1, 4, 0, 4}, /* D10/PA4 */ + {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D11/PA7 */ + {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D12/PA6 */ + {GPIOA, NULL, ADC1, 5, 0, 5}, /* D13/PA5 (LED) */ + {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D14/PB8 */ + + /* Little header */ + + {GPIOC, NULL, ADC1, 0, 0, 10}, /* D15/PC0 */ + {GPIOC, NULL, ADC1, 1, 0, 11}, /* D16/PC1 */ + {GPIOC, NULL, ADC1, 2, 0, 12}, /* D17/PC2 */ + {GPIOC, NULL, ADC1, 3, 0, 13}, /* D18/PC3 */ + {GPIOC, NULL, ADC1, 4, 0, 14}, /* D19/PC4 */ + {GPIOC, NULL, ADC1, 5, 0, 15}, /* D20/PC5 */ + + /* External header */ + + {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D21/PC13 */ + {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D22/PC14 */ + {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D23/PC15 */ + {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* D24/PB9 */ + {GPIOD, NULL, NULL, 2, 0, ADCx}, /* D25/PD2 */ + {GPIOC, NULL, NULL, 10, 0, ADCx}, /* D26/PC10 */ + {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D27/PB0 */ + {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D28/PB1 */ + {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D29/PB10 */ + {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D30/PB11 */ + {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D31/PB12 */ + {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D32/PB13 */ + {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D33/PB14 */ + {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D34/PB15 */ + {GPIOC, TIMER8, NULL, 6, 1, ADCx}, /* D35/PC6 */ + {GPIOC, TIMER8, NULL, 7, 2, ADCx}, /* D36/PC7 */ + {GPIOC, TIMER8, NULL, 8, 3, ADCx}, /* D37/PC8 */ + {GPIOC, TIMER8, NULL, 9, 4, ADCx}, /* D38/PC9 (BUT) */ + + /* JTAG header */ + + {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D39/PA13 */ + {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D40/PA14 */ + {GPIOA, NULL, NULL, 15, 0, ADCx}, /* D41/PA15 */ + {GPIOB, NULL, NULL, 3, 0, ADCx}, /* D42/PB3 */ + {GPIOB, NULL, NULL, 4, 0, ADCx}, /* D43/PB4 */ +}; + +/* Note: Do NOT include pin 38 (TIM8_CH4), as that's BOARD_BUTTON_PIN + * and thus not broken out to a header. */ +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28, 35, 36, 37 +}; + +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + 0, 1, 2, 3, 10, 11, 12, 15, 16, 17, 18, 19, 20, 27, 28 +}; + +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN +}; + +#endif diff --git a/Libmaple/libmaple/wirish/boards/maple_RET6.h b/Libmaple/libmaple/wirish/boards/maple_RET6.h index 57ef2fc7..352d565d 100644 --- a/Libmaple/libmaple/wirish/boards/maple_RET6.h +++ b/Libmaple/libmaple/wirish/boards/maple_RET6.h @@ -1,88 +1,88 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file maple_RET6.h - * @author Marti Bolivar - * @brief Private include file for Maple RET6 Edition in boards.h - * - * See maple.h for more information on these definitions. - */ - -#ifndef _BOARDS_MAPLE_RET6_H_ -#define _BOARDS_MAPLE_RET6_H_ - -/* A few of these values will seem strange given that it's a - * high-density board. */ - -#define CYCLES_PER_MICROSECOND 72 -#define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */ - -#define BOARD_BUTTON_PIN 38 -#define BOARD_LED_PIN 13 - -/* Note: UART4 and UART5 have pins which aren't broken out :( */ -#define BOARD_NR_USARTS 3 -#define BOARD_USART1_TX_PIN 7 -#define BOARD_USART1_RX_PIN 8 -#define BOARD_USART2_TX_PIN 1 -#define BOARD_USART2_RX_PIN 0 -#define BOARD_USART3_TX_PIN 29 -#define BOARD_USART3_RX_PIN 30 - -/* Note: - * - * SPI3 is unusable due to pin 43 (PB4) and NRST tie-together :(, but - * leave the definitions so as not to clutter things up. This is only - * OK since RET6 Ed. is specifically advertised as a beta board. */ -#define BOARD_NR_SPI 2 -#define BOARD_SPI1_NSS_PIN 10 -#define BOARD_SPI1_MOSI_PIN 11 -#define BOARD_SPI1_MISO_PIN 12 -#define BOARD_SPI1_SCK_PIN 13 -#define BOARD_SPI2_NSS_PIN 31 -#define BOARD_SPI2_MOSI_PIN 34 -#define BOARD_SPI2_MISO_PIN 33 -#define BOARD_SPI2_SCK_PIN 32 -#define BOARD_SPI3_NSS_PIN 41 -#define BOARD_SPI3_MOSI_PIN 4 -#define BOARD_SPI3_MISO_PIN 43 -#define BOARD_SPI3_SCK_PIN 42 - -#define BOARD_NR_GPIO_PINS 44 -/* Note: NOT 19. The missing one is D38 a.k.a. BOARD_BUTTON_PIN, which - * isn't broken out to a header and is thus unusable for PWM. */ -#define BOARD_NR_PWM_PINS 18 -#define BOARD_NR_ADC_PINS 15 -#define BOARD_NR_USED_PINS 7 - -#define BOARD_JTMS_SWDIO_PIN 39 -#define BOARD_JTCK_SWCLK_PIN 40 -#define BOARD_JTDI_PIN 41 -#define BOARD_JTDO_PIN 42 -#define BOARD_NJTRST_PIN 43 - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file maple_RET6.h + * @author Marti Bolivar + * @brief Private include file for Maple RET6 Edition in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARDS_MAPLE_RET6_H_ +#define _BOARDS_MAPLE_RET6_H_ + +/* A few of these values will seem strange given that it's a + * high-density board. */ + +#define CYCLES_PER_MICROSECOND 72 +#define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */ + +#define BOARD_BUTTON_PIN 38 +#define BOARD_LED_PIN 13 + +/* Note: UART4 and UART5 have pins which aren't broken out :( */ +#define BOARD_NR_USARTS 3 +#define BOARD_USART1_TX_PIN 7 +#define BOARD_USART1_RX_PIN 8 +#define BOARD_USART2_TX_PIN 1 +#define BOARD_USART2_RX_PIN 0 +#define BOARD_USART3_TX_PIN 29 +#define BOARD_USART3_RX_PIN 30 + +/* Note: + * + * SPI3 is unusable due to pin 43 (PB4) and NRST tie-together :(, but + * leave the definitions so as not to clutter things up. This is only + * OK since RET6 Ed. is specifically advertised as a beta board. */ +#define BOARD_NR_SPI 2 +#define BOARD_SPI1_NSS_PIN 10 +#define BOARD_SPI1_MOSI_PIN 11 +#define BOARD_SPI1_MISO_PIN 12 +#define BOARD_SPI1_SCK_PIN 13 +#define BOARD_SPI2_NSS_PIN 31 +#define BOARD_SPI2_MOSI_PIN 34 +#define BOARD_SPI2_MISO_PIN 33 +#define BOARD_SPI2_SCK_PIN 32 +#define BOARD_SPI3_NSS_PIN 41 +#define BOARD_SPI3_MOSI_PIN 4 +#define BOARD_SPI3_MISO_PIN 43 +#define BOARD_SPI3_SCK_PIN 42 + +#define BOARD_NR_GPIO_PINS 44 +/* Note: NOT 19. The missing one is D38 a.k.a. BOARD_BUTTON_PIN, which + * isn't broken out to a header and is thus unusable for PWM. */ +#define BOARD_NR_PWM_PINS 18 +#define BOARD_NR_ADC_PINS 15 +#define BOARD_NR_USED_PINS 7 + +#define BOARD_JTMS_SWDIO_PIN 39 +#define BOARD_JTCK_SWCLK_PIN 40 +#define BOARD_JTDI_PIN 41 +#define BOARD_JTDO_PIN 42 +#define BOARD_NJTRST_PIN 43 + +#endif diff --git a/Libmaple/libmaple/wirish/boards/maple_mini.cpp b/Libmaple/libmaple/wirish/boards/maple_mini.cpp index f909de38..f111a14f 100644 --- a/Libmaple/libmaple/wirish/boards/maple_mini.cpp +++ b/Libmaple/libmaple/wirish/boards/maple_mini.cpp @@ -1,106 +1,106 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file maple_mini.cpp - * @author Marti Bolivar - * @brief Maple Mini board file. - */ - -#ifdef BOARD_maple_mini - -#include "maple_mini.h" - -#include "gpio.h" -#include "timer.h" -#include "wirish_debug.h" -#include "wirish_types.h" - -/* Since we want the Serial Wire/JTAG pins as GPIOs, disable both SW - * and JTAG debug support */ -void boardInit(void) { - disableDebugPorts(); -} - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - - /* Top header */ - - {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D0/PB11 */ - {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D1/PB10 */ - {GPIOB, NULL, NULL, 2, 0, ADCx}, /* D2/PB2 */ - {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D3/PB0 */ - {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D4/PA7 */ - {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D5/PA6 */ - {GPIOA, NULL, ADC1, 5, 0, 5}, /* D6/PA5 */ - {GPIOA, NULL, ADC1, 4, 0, 4}, /* D7/PA4 */ - {GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D8/PA3 */ - {GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D9/PA2 */ - {GPIOA, TIMER2, ADC1, 1, 2, 1}, /* D10/PA1 */ - {GPIOA, TIMER2, ADC1, 0, 1, 0}, /* D11/PA0 */ - {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D12/PC15 */ - {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D13/PC14 */ - {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D14/PC13 */ - - /* Bottom header */ - - {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D15/PB7 */ - {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D16/PB6 */ - {GPIOB, NULL, NULL, 5, 0, ADCx}, /* D17/PB5 */ - {GPIOB, NULL, NULL, 4, 0, ADCx}, /* D18/PB4 */ - {GPIOB, NULL, NULL, 3, 0, ADCx}, /* D19/PB3 */ - {GPIOA, NULL, NULL, 15, 0, ADCx}, /* D20/PA15 */ - {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D21/PA14 */ - {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D22/PA13 */ - {GPIOA, NULL, NULL, 12, 0, ADCx}, /* D23/PA12 */ - {GPIOA, TIMER1, NULL, 11, 4, ADCx}, /* D24/PA11 */ - {GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* D25/PA10 */ - {GPIOA, TIMER1, NULL, 9, 2, ADCx}, /* D26/PA9 */ - {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D27/PA8 */ - {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D28/PB15 */ - {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D29/PB14 */ - {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D30/PB13 */ - {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D31/PB12 */ - {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D32/PB8 */ - {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D33/PB1 */ -}; - -extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { - 3, 4, 5, 8, 9, 10, 11, 15, 16, 25, 26, 27 -}; - -extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { - 3, 4, 5, 6, 7, 8, 9, 10, 11 -}; - -#define USB_DP 23 -#define USB_DM 24 - -extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { - BOARD_LED_PIN, BOARD_BUTTON_PIN, USB_DP, USB_DM -}; - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file maple_mini.cpp + * @author Marti Bolivar + * @brief Maple Mini board file. + */ + +#ifdef BOARD_maple_mini + +#include "maple_mini.h" + +#include "gpio.h" +#include "timer.h" +#include "wirish_debug.h" +#include "wirish_types.h" + +/* Since we want the Serial Wire/JTAG pins as GPIOs, disable both SW + * and JTAG debug support */ +void boardInit(void) { + disableDebugPorts(); +} + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + + /* Top header */ + + {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D0/PB11 */ + {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D1/PB10 */ + {GPIOB, NULL, NULL, 2, 0, ADCx}, /* D2/PB2 */ + {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D3/PB0 */ + {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D4/PA7 */ + {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D5/PA6 */ + {GPIOA, NULL, ADC1, 5, 0, 5}, /* D6/PA5 */ + {GPIOA, NULL, ADC1, 4, 0, 4}, /* D7/PA4 */ + {GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D8/PA3 */ + {GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D9/PA2 */ + {GPIOA, TIMER2, ADC1, 1, 2, 1}, /* D10/PA1 */ + {GPIOA, TIMER2, ADC1, 0, 1, 0}, /* D11/PA0 */ + {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D12/PC15 */ + {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D13/PC14 */ + {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D14/PC13 */ + + /* Bottom header */ + + {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D15/PB7 */ + {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D16/PB6 */ + {GPIOB, NULL, NULL, 5, 0, ADCx}, /* D17/PB5 */ + {GPIOB, NULL, NULL, 4, 0, ADCx}, /* D18/PB4 */ + {GPIOB, NULL, NULL, 3, 0, ADCx}, /* D19/PB3 */ + {GPIOA, NULL, NULL, 15, 0, ADCx}, /* D20/PA15 */ + {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D21/PA14 */ + {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D22/PA13 */ + {GPIOA, NULL, NULL, 12, 0, ADCx}, /* D23/PA12 */ + {GPIOA, TIMER1, NULL, 11, 4, ADCx}, /* D24/PA11 */ + {GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* D25/PA10 */ + {GPIOA, TIMER1, NULL, 9, 2, ADCx}, /* D26/PA9 */ + {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D27/PA8 */ + {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D28/PB15 */ + {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D29/PB14 */ + {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D30/PB13 */ + {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D31/PB12 */ + {GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D32/PB8 */ + {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D33/PB1 */ +}; + +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + 3, 4, 5, 8, 9, 10, 11, 15, 16, 25, 26, 27 +}; + +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + 3, 4, 5, 6, 7, 8, 9, 10, 11 +}; + +#define USB_DP 23 +#define USB_DM 24 + +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + BOARD_LED_PIN, BOARD_BUTTON_PIN, USB_DP, USB_DM +}; + +#endif diff --git a/Libmaple/libmaple/wirish/boards/maple_mini.h b/Libmaple/libmaple/wirish/boards/maple_mini.h index 92733f1f..7bf7016c 100644 --- a/Libmaple/libmaple/wirish/boards/maple_mini.h +++ b/Libmaple/libmaple/wirish/boards/maple_mini.h @@ -1,73 +1,73 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file maple_mini.h - * @author Marti Bolivar - * @brief Private include file for Maple Mini in boards.h - * - * See maple.h for more information on these definitions. - */ - -#ifndef _BOARD_MAPLE_MINI_H_ -#define _BOARD_MAPLE_MINI_H_ - -#define CYCLES_PER_MICROSECOND 72 -#define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */ - -#define BOARD_BUTTON_PIN 32 -#define BOARD_LED_PIN 33 - -#define BOARD_NR_USARTS 3 -#define BOARD_USART1_TX_PIN 26 -#define BOARD_USART1_RX_PIN 25 -#define BOARD_USART2_TX_PIN 9 -#define BOARD_USART2_RX_PIN 8 -#define BOARD_USART3_TX_PIN 1 -#define BOARD_USART3_RX_PIN 0 - -#define BOARD_NR_SPI 2 -#define BOARD_SPI1_NSS_PIN 7 -#define BOARD_SPI1_MOSI_PIN 4 -#define BOARD_SPI1_MISO_PIN 5 -#define BOARD_SPI1_SCK_PIN 6 -#define BOARD_SPI2_NSS_PIN 31 -#define BOARD_SPI2_MOSI_PIN 28 -#define BOARD_SPI2_MISO_PIN 29 -#define BOARD_SPI2_SCK_PIN 30 - -#define BOARD_NR_GPIO_PINS 34 -#define BOARD_NR_PWM_PINS 12 -#define BOARD_NR_ADC_PINS 9 -#define BOARD_NR_USED_PINS 4 - -#define BOARD_JTMS_SWDIO_PIN 22 -#define BOARD_JTCK_SWCLK_PIN 21 -#define BOARD_JTDI_PIN 20 -#define BOARD_JTDO_PIN 19 -#define BOARD_NJTRST_PIN 18 - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file maple_mini.h + * @author Marti Bolivar + * @brief Private include file for Maple Mini in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARD_MAPLE_MINI_H_ +#define _BOARD_MAPLE_MINI_H_ + +#define CYCLES_PER_MICROSECOND 72 +#define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */ + +#define BOARD_BUTTON_PIN 32 +#define BOARD_LED_PIN 33 + +#define BOARD_NR_USARTS 3 +#define BOARD_USART1_TX_PIN 26 +#define BOARD_USART1_RX_PIN 25 +#define BOARD_USART2_TX_PIN 9 +#define BOARD_USART2_RX_PIN 8 +#define BOARD_USART3_TX_PIN 1 +#define BOARD_USART3_RX_PIN 0 + +#define BOARD_NR_SPI 2 +#define BOARD_SPI1_NSS_PIN 7 +#define BOARD_SPI1_MOSI_PIN 4 +#define BOARD_SPI1_MISO_PIN 5 +#define BOARD_SPI1_SCK_PIN 6 +#define BOARD_SPI2_NSS_PIN 31 +#define BOARD_SPI2_MOSI_PIN 28 +#define BOARD_SPI2_MISO_PIN 29 +#define BOARD_SPI2_SCK_PIN 30 + +#define BOARD_NR_GPIO_PINS 34 +#define BOARD_NR_PWM_PINS 12 +#define BOARD_NR_ADC_PINS 9 +#define BOARD_NR_USED_PINS 4 + +#define BOARD_JTMS_SWDIO_PIN 22 +#define BOARD_JTCK_SWCLK_PIN 21 +#define BOARD_JTDI_PIN 20 +#define BOARD_JTDO_PIN 19 +#define BOARD_NJTRST_PIN 18 + +#endif diff --git a/Libmaple/libmaple/wirish/boards/maple_native.cpp b/Libmaple/libmaple/wirish/boards/maple_native.cpp index 9cffde82..821be77c 100644 --- a/Libmaple/libmaple/wirish/boards/maple_native.cpp +++ b/Libmaple/libmaple/wirish/boards/maple_native.cpp @@ -1,201 +1,201 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file maple_native.cpp - * @author Marti Bolivar - * @brief Maple Native board file. - */ - -#ifdef BOARD_maple_native - -#include "maple_native.h" - -#include "fsmc.h" -#include "gpio.h" -#include "rcc.h" -#include "timer.h" - -#include "wirish_types.h" - -static void initSRAMChip(void); - -void boardInit(void) { - initSRAMChip(); -} - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { - - /* Top header */ - - {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D0/PB10 */ - {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D1/PB11 */ - {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D2/PB12 */ - {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D3/PB13 */ - {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D4/PB14 */ - {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D5/PB15 */ - {GPIOG, NULL, NULL, 15, 0, ADCx}, /* D6/PG15 (BUT) */ - {GPIOC, NULL, ADC1, 0, 0, 10}, /* D7/PC0 */ - {GPIOC, NULL, ADC1, 1, 0, 11}, /* D8/PC1 */ - {GPIOC, NULL, ADC1, 2, 0, 12}, /* D9/PC2 */ - {GPIOC, NULL, ADC1, 3, 0, 13}, /* D10/PC3 */ - {GPIOC, NULL, ADC1, 4, 0, 14}, /* D11/PC4 */ - {GPIOC, NULL, ADC1, 5, 0, 15}, /* D12/PC5 */ - {GPIOC, TIMER8, NULL, 6, 1, ADCx}, /* D13/PC6 */ - {GPIOC, TIMER8, NULL, 7, 2, ADCx}, /* D14/PC7 */ - {GPIOC, TIMER8, NULL, 8, 3, ADCx}, /* D15/PC8 */ - {GPIOC, TIMER8, NULL, 9, 4, ADCx}, /* D16/PC9 */ - {GPIOC, NULL, NULL, 10, 0, ADCx}, /* D17/PC10 */ - {GPIOC, NULL, NULL, 11, 0, ADCx}, /* D18/PC11 */ - {GPIOC, NULL, NULL, 12, 0, ADCx}, /* D19/PC12 */ - {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D20/PC13 */ - {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D21/PC14 */ - {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D22/PC15 (LED) */ - {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D23/PA8 */ - {GPIOA, TIMER1, NULL, 9, 2, ADCx}, /* D24/PA9 */ - {GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* D25/PA10 */ - {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* D26/PB9 */ - - /* Bottom header */ - /* Note: D{48, 49, 50, 51} are also TIMER2_CH{1, 2, 3, 4}, respectively. */ - /* TODO remap timer 2 in boardInit(); make the appropriate changes here */ - - {GPIOD, NULL, NULL, 2, 0, ADCx}, /* D27/PD2 */ - {GPIOD, NULL, NULL, 3, 0, ADCx}, /* D28/PD3 */ - {GPIOD, NULL, NULL, 6, 0, ADCx}, /* D29/PD6 */ - {GPIOG, NULL, NULL, 11, 0, ADCx}, /* D30/PG11 */ - {GPIOG, NULL, NULL, 12, 0, ADCx}, /* D31/PG12 */ - {GPIOG, NULL, NULL, 13, 0, ADCx}, /* D32/PG13 */ - {GPIOG, NULL, NULL, 14, 0, ADCx}, /* D33/PG14 */ - {GPIOG, NULL, NULL, 8, 0, ADCx}, /* D34/PG8 */ - {GPIOG, NULL, NULL, 7, 0, ADCx}, /* D35/PG7 */ - {GPIOG, NULL, NULL, 6, 0, ADCx}, /* D36/PG6 */ - {GPIOB, NULL, NULL, 5, 0, ADCx}, /* D37/PB5 */ - {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D38/PB6 */ - {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D39/PB7 */ - {GPIOF, NULL, NULL, 11, 0, ADCx}, /* D40/PF11 */ - {GPIOF, NULL, ADC3, 6, 0, 4}, /* D41/PF6 */ - {GPIOF, NULL, ADC3, 7, 0, 5}, /* D42/PF7 */ - {GPIOF, NULL, ADC3, 8, 0, 6}, /* D43/PF8 */ - {GPIOF, NULL, ADC3, 9, 0, 7}, /* D44/PF9 */ - {GPIOF, NULL, ADC3, 10, 0, 8}, /* D45/PF10 */ - {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D46/PB1 */ - {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D47/PB0 */ - {GPIOA, TIMER5, ADC1, 0, 1, 0}, /* D48/PA0 */ - {GPIOA, TIMER5, ADC1, 1, 2, 1}, /* D49/PA1 */ - {GPIOA, TIMER5, ADC1, 2, 3, 2}, /* D50/PA2 */ - {GPIOA, TIMER5, ADC1, 3, 4, 3}, /* D51/PA3 */ - {GPIOA, NULL, ADC1, 4, 0, 4}, /* D52/PA4 */ - {GPIOA, NULL, ADC1, 5, 0, 5}, /* D53/PA5 */ - {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D54/PA6 */ - {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D55/PA7 */ - - /* FSMC (triple) header */ - - {GPIOF, NULL, NULL, 0, 0, ADCx}, /* D56/PF0 */ - {GPIOD, NULL, NULL, 11, 0, ADCx}, /* D57/PD11 */ - {GPIOD, NULL, NULL, 14, 0, ADCx}, /* D58/PD14 */ - {GPIOF, NULL, NULL, 1, 0, ADCx}, /* D59/PF1 */ - {GPIOD, NULL, NULL, 12, 0, ADCx}, /* D60/PD12 */ - {GPIOD, NULL, NULL, 15, 0, ADCx}, /* D61/PD15 */ - {GPIOF, NULL, NULL, 2, 0, ADCx}, /* D62/PF2 */ - {GPIOD, NULL, NULL, 13, 0, ADCx}, /* D63/PD13 */ - {GPIOD, NULL, NULL, 0, 0, ADCx}, /* D64/PD0 */ - {GPIOF, NULL, NULL, 3, 0, ADCx}, /* D65/PF3 */ - {GPIOE, NULL, NULL, 3, 0, ADCx}, /* D66/PE3 */ - {GPIOD, NULL, NULL, 1, 0, ADCx}, /* D67/PD1 */ - {GPIOF, NULL, NULL, 4, 0, ADCx}, /* D68/PF4 */ - {GPIOE, NULL, NULL, 4, 0, ADCx}, /* D69/PE4 */ - {GPIOE, NULL, NULL, 7, 0, ADCx}, /* D70/PE7 */ - {GPIOF, NULL, NULL, 5, 0, ADCx}, /* D71/PF5 */ - {GPIOE, NULL, NULL, 5, 0, ADCx}, /* D72/PE5 */ - {GPIOE, NULL, NULL, 8, 0, ADCx}, /* D73/PE8 */ - {GPIOF, NULL, NULL, 12, 0, ADCx}, /* D74/PF12 */ - {GPIOE, NULL, NULL, 6, 0, ADCx}, /* D75/PE6 */ - {GPIOE, NULL, NULL, 9, 0, ADCx}, /* D76/PE9 */ - {GPIOF, NULL, NULL, 13, 0, ADCx}, /* D77/PF13 */ - {GPIOE, NULL, NULL, 10, 0, ADCx}, /* D78/PE10 */ - {GPIOF, NULL, NULL, 14, 0, ADCx}, /* D79/PF14 */ - {GPIOG, NULL, NULL, 9, 0, ADCx}, /* D80/PG9 */ - {GPIOE, NULL, NULL, 11, 0, ADCx}, /* D81/PE11 */ - {GPIOF, NULL, NULL, 15, 0, ADCx}, /* D82/PF15 */ - {GPIOG, NULL, NULL, 10, 0, ADCx}, /* D83/PG10 */ - {GPIOE, NULL, NULL, 12, 0, ADCx}, /* D84/PE12 */ - {GPIOG, NULL, NULL, 0, 0, ADCx}, /* D85/PG0 */ - {GPIOD, NULL, NULL, 5, 0, ADCx}, /* D86/PD5 */ - {GPIOE, NULL, NULL, 13, 0, ADCx}, /* D87/PE13 */ - {GPIOG, NULL, NULL, 1, 0, ADCx}, /* D88/PG1 */ - {GPIOD, NULL, NULL, 4, 0, ADCx}, /* D89/PD4 */ - {GPIOE, NULL, NULL, 14, 0, ADCx}, /* D90/PE14 */ - {GPIOG, NULL, NULL, 2, 0, ADCx}, /* D91/PG2 */ - {GPIOE, NULL, NULL, 1, 0, ADCx}, /* D92/PE1 */ - {GPIOE, NULL, NULL, 15, 0, ADCx}, /* D93/PE15 */ - {GPIOG, NULL, NULL, 3, 0, ADCx}, /* D94/PG3 */ - {GPIOE, NULL, NULL, 0, 0, ADCx}, /* D95/PE0 */ - {GPIOD, NULL, NULL, 8, 0, ADCx}, /* D96/PD8 */ - {GPIOG, NULL, NULL, 4, 0, ADCx}, /* D97/PG4 */ - {GPIOD, NULL, NULL, 9, 0, ADCx}, /* D98/PD9 */ - {GPIOG, NULL, NULL, 5, 0, ADCx}, /* D99/PG5 */ - {GPIOD, NULL, NULL, 10, 0, ADCx}, /* D100/PD10 */ - - /* JTAG header */ - - {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D101/PA13 */ - {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D102/PA14 */ - {GPIOA, NULL, NULL, 15, 0, ADCx}, /* D103/PA15 */ - {GPIOB, NULL, NULL, 3, 0, ADCx}, /* D104/PB3 */ - {GPIOB, NULL, NULL, 4, 0, ADCx} /* D105/PB4 */ -}; - -extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { - 13, 14, 15, 16, 23, 24, 25, 26, 38, 39, 46, 47, 48, 49, 50, 51, 54, 55 -}; - -extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { - 7, 8, 9, 10, 11, 12, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55 -}; - -extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { - BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, - BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN, - 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 78, 79, 81, - 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 -}; - -static void initSRAMChip(void) { - fsmc_nor_psram_reg_map *regs = FSMC_NOR_PSRAM1_BASE; - - fsmc_sram_init_gpios(); - rcc_clk_enable(RCC_FSMC); - - regs->BCR = (FSMC_BCR_WREN | FSMC_BCR_MWID_16BITS | FSMC_BCR_MTYP_SRAM | - FSMC_BCR_MBKEN); - fsmc_nor_psram_set_addset(regs, 0); - fsmc_nor_psram_set_datast(regs, 3); -} - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file maple_native.cpp + * @author Marti Bolivar + * @brief Maple Native board file. + */ + +#ifdef BOARD_maple_native + +#include "maple_native.h" + +#include "fsmc.h" +#include "gpio.h" +#include "rcc.h" +#include "timer.h" + +#include "wirish_types.h" + +static void initSRAMChip(void); + +void boardInit(void) { + initSRAMChip(); +} + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = { + + /* Top header */ + + {GPIOB, NULL, NULL, 10, 0, ADCx}, /* D0/PB10 */ + {GPIOB, NULL, NULL, 11, 0, ADCx}, /* D1/PB11 */ + {GPIOB, NULL, NULL, 12, 0, ADCx}, /* D2/PB12 */ + {GPIOB, NULL, NULL, 13, 0, ADCx}, /* D3/PB13 */ + {GPIOB, NULL, NULL, 14, 0, ADCx}, /* D4/PB14 */ + {GPIOB, NULL, NULL, 15, 0, ADCx}, /* D5/PB15 */ + {GPIOG, NULL, NULL, 15, 0, ADCx}, /* D6/PG15 (BUT) */ + {GPIOC, NULL, ADC1, 0, 0, 10}, /* D7/PC0 */ + {GPIOC, NULL, ADC1, 1, 0, 11}, /* D8/PC1 */ + {GPIOC, NULL, ADC1, 2, 0, 12}, /* D9/PC2 */ + {GPIOC, NULL, ADC1, 3, 0, 13}, /* D10/PC3 */ + {GPIOC, NULL, ADC1, 4, 0, 14}, /* D11/PC4 */ + {GPIOC, NULL, ADC1, 5, 0, 15}, /* D12/PC5 */ + {GPIOC, TIMER8, NULL, 6, 1, ADCx}, /* D13/PC6 */ + {GPIOC, TIMER8, NULL, 7, 2, ADCx}, /* D14/PC7 */ + {GPIOC, TIMER8, NULL, 8, 3, ADCx}, /* D15/PC8 */ + {GPIOC, TIMER8, NULL, 9, 4, ADCx}, /* D16/PC9 */ + {GPIOC, NULL, NULL, 10, 0, ADCx}, /* D17/PC10 */ + {GPIOC, NULL, NULL, 11, 0, ADCx}, /* D18/PC11 */ + {GPIOC, NULL, NULL, 12, 0, ADCx}, /* D19/PC12 */ + {GPIOC, NULL, NULL, 13, 0, ADCx}, /* D20/PC13 */ + {GPIOC, NULL, NULL, 14, 0, ADCx}, /* D21/PC14 */ + {GPIOC, NULL, NULL, 15, 0, ADCx}, /* D22/PC15 (LED) */ + {GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D23/PA8 */ + {GPIOA, TIMER1, NULL, 9, 2, ADCx}, /* D24/PA9 */ + {GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* D25/PA10 */ + {GPIOB, TIMER4, NULL, 9, 4, ADCx}, /* D26/PB9 */ + + /* Bottom header */ + /* Note: D{48, 49, 50, 51} are also TIMER2_CH{1, 2, 3, 4}, respectively. */ + /* TODO remap timer 2 in boardInit(); make the appropriate changes here */ + + {GPIOD, NULL, NULL, 2, 0, ADCx}, /* D27/PD2 */ + {GPIOD, NULL, NULL, 3, 0, ADCx}, /* D28/PD3 */ + {GPIOD, NULL, NULL, 6, 0, ADCx}, /* D29/PD6 */ + {GPIOG, NULL, NULL, 11, 0, ADCx}, /* D30/PG11 */ + {GPIOG, NULL, NULL, 12, 0, ADCx}, /* D31/PG12 */ + {GPIOG, NULL, NULL, 13, 0, ADCx}, /* D32/PG13 */ + {GPIOG, NULL, NULL, 14, 0, ADCx}, /* D33/PG14 */ + {GPIOG, NULL, NULL, 8, 0, ADCx}, /* D34/PG8 */ + {GPIOG, NULL, NULL, 7, 0, ADCx}, /* D35/PG7 */ + {GPIOG, NULL, NULL, 6, 0, ADCx}, /* D36/PG6 */ + {GPIOB, NULL, NULL, 5, 0, ADCx}, /* D37/PB5 */ + {GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D38/PB6 */ + {GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D39/PB7 */ + {GPIOF, NULL, NULL, 11, 0, ADCx}, /* D40/PF11 */ + {GPIOF, NULL, ADC3, 6, 0, 4}, /* D41/PF6 */ + {GPIOF, NULL, ADC3, 7, 0, 5}, /* D42/PF7 */ + {GPIOF, NULL, ADC3, 8, 0, 6}, /* D43/PF8 */ + {GPIOF, NULL, ADC3, 9, 0, 7}, /* D44/PF9 */ + {GPIOF, NULL, ADC3, 10, 0, 8}, /* D45/PF10 */ + {GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D46/PB1 */ + {GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D47/PB0 */ + {GPIOA, TIMER5, ADC1, 0, 1, 0}, /* D48/PA0 */ + {GPIOA, TIMER5, ADC1, 1, 2, 1}, /* D49/PA1 */ + {GPIOA, TIMER5, ADC1, 2, 3, 2}, /* D50/PA2 */ + {GPIOA, TIMER5, ADC1, 3, 4, 3}, /* D51/PA3 */ + {GPIOA, NULL, ADC1, 4, 0, 4}, /* D52/PA4 */ + {GPIOA, NULL, ADC1, 5, 0, 5}, /* D53/PA5 */ + {GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D54/PA6 */ + {GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D55/PA7 */ + + /* FSMC (triple) header */ + + {GPIOF, NULL, NULL, 0, 0, ADCx}, /* D56/PF0 */ + {GPIOD, NULL, NULL, 11, 0, ADCx}, /* D57/PD11 */ + {GPIOD, NULL, NULL, 14, 0, ADCx}, /* D58/PD14 */ + {GPIOF, NULL, NULL, 1, 0, ADCx}, /* D59/PF1 */ + {GPIOD, NULL, NULL, 12, 0, ADCx}, /* D60/PD12 */ + {GPIOD, NULL, NULL, 15, 0, ADCx}, /* D61/PD15 */ + {GPIOF, NULL, NULL, 2, 0, ADCx}, /* D62/PF2 */ + {GPIOD, NULL, NULL, 13, 0, ADCx}, /* D63/PD13 */ + {GPIOD, NULL, NULL, 0, 0, ADCx}, /* D64/PD0 */ + {GPIOF, NULL, NULL, 3, 0, ADCx}, /* D65/PF3 */ + {GPIOE, NULL, NULL, 3, 0, ADCx}, /* D66/PE3 */ + {GPIOD, NULL, NULL, 1, 0, ADCx}, /* D67/PD1 */ + {GPIOF, NULL, NULL, 4, 0, ADCx}, /* D68/PF4 */ + {GPIOE, NULL, NULL, 4, 0, ADCx}, /* D69/PE4 */ + {GPIOE, NULL, NULL, 7, 0, ADCx}, /* D70/PE7 */ + {GPIOF, NULL, NULL, 5, 0, ADCx}, /* D71/PF5 */ + {GPIOE, NULL, NULL, 5, 0, ADCx}, /* D72/PE5 */ + {GPIOE, NULL, NULL, 8, 0, ADCx}, /* D73/PE8 */ + {GPIOF, NULL, NULL, 12, 0, ADCx}, /* D74/PF12 */ + {GPIOE, NULL, NULL, 6, 0, ADCx}, /* D75/PE6 */ + {GPIOE, NULL, NULL, 9, 0, ADCx}, /* D76/PE9 */ + {GPIOF, NULL, NULL, 13, 0, ADCx}, /* D77/PF13 */ + {GPIOE, NULL, NULL, 10, 0, ADCx}, /* D78/PE10 */ + {GPIOF, NULL, NULL, 14, 0, ADCx}, /* D79/PF14 */ + {GPIOG, NULL, NULL, 9, 0, ADCx}, /* D80/PG9 */ + {GPIOE, NULL, NULL, 11, 0, ADCx}, /* D81/PE11 */ + {GPIOF, NULL, NULL, 15, 0, ADCx}, /* D82/PF15 */ + {GPIOG, NULL, NULL, 10, 0, ADCx}, /* D83/PG10 */ + {GPIOE, NULL, NULL, 12, 0, ADCx}, /* D84/PE12 */ + {GPIOG, NULL, NULL, 0, 0, ADCx}, /* D85/PG0 */ + {GPIOD, NULL, NULL, 5, 0, ADCx}, /* D86/PD5 */ + {GPIOE, NULL, NULL, 13, 0, ADCx}, /* D87/PE13 */ + {GPIOG, NULL, NULL, 1, 0, ADCx}, /* D88/PG1 */ + {GPIOD, NULL, NULL, 4, 0, ADCx}, /* D89/PD4 */ + {GPIOE, NULL, NULL, 14, 0, ADCx}, /* D90/PE14 */ + {GPIOG, NULL, NULL, 2, 0, ADCx}, /* D91/PG2 */ + {GPIOE, NULL, NULL, 1, 0, ADCx}, /* D92/PE1 */ + {GPIOE, NULL, NULL, 15, 0, ADCx}, /* D93/PE15 */ + {GPIOG, NULL, NULL, 3, 0, ADCx}, /* D94/PG3 */ + {GPIOE, NULL, NULL, 0, 0, ADCx}, /* D95/PE0 */ + {GPIOD, NULL, NULL, 8, 0, ADCx}, /* D96/PD8 */ + {GPIOG, NULL, NULL, 4, 0, ADCx}, /* D97/PG4 */ + {GPIOD, NULL, NULL, 9, 0, ADCx}, /* D98/PD9 */ + {GPIOG, NULL, NULL, 5, 0, ADCx}, /* D99/PG5 */ + {GPIOD, NULL, NULL, 10, 0, ADCx}, /* D100/PD10 */ + + /* JTAG header */ + + {GPIOA, NULL, NULL, 13, 0, ADCx}, /* D101/PA13 */ + {GPIOA, NULL, NULL, 14, 0, ADCx}, /* D102/PA14 */ + {GPIOA, NULL, NULL, 15, 0, ADCx}, /* D103/PA15 */ + {GPIOB, NULL, NULL, 3, 0, ADCx}, /* D104/PB3 */ + {GPIOB, NULL, NULL, 4, 0, ADCx} /* D105/PB4 */ +}; + +extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = { + 13, 14, 15, 16, 23, 24, 25, 26, 38, 39, 46, 47, 48, 49, 50, 51, 54, 55 +}; + +extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = { + 7, 8, 9, 10, 11, 12, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55 +}; + +extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = { + BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN, + BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN, + 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 78, 79, 81, + 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 +}; + +static void initSRAMChip(void) { + fsmc_nor_psram_reg_map *regs = FSMC_NOR_PSRAM1_BASE; + + fsmc_sram_init_gpios(); + rcc_clk_enable(RCC_FSMC); + + regs->BCR = (FSMC_BCR_WREN | FSMC_BCR_MWID_16BITS | FSMC_BCR_MTYP_SRAM | + FSMC_BCR_MBKEN); + fsmc_nor_psram_set_addset(regs, 0); + fsmc_nor_psram_set_datast(regs, 3); +} + +#endif diff --git a/Libmaple/libmaple/wirish/boards/maple_native.h b/Libmaple/libmaple/wirish/boards/maple_native.h index 851d9754..f575bfbb 100644 --- a/Libmaple/libmaple/wirish/boards/maple_native.h +++ b/Libmaple/libmaple/wirish/boards/maple_native.h @@ -1,80 +1,80 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file maple_native.h - * @author Marti Bolivar - * @brief Private include file for Maple Native in boards.h - * - * See maple.h for more information on these definitions. - */ - -#ifndef _BOARD_MAPLE_NATIVE_H_ -#define _BOARD_MAPLE_NATIVE_H_ - -#define CYCLES_PER_MICROSECOND 72 -#define SYSTICK_RELOAD_VAL 71999 - -#define BOARD_LED_PIN 22 -#define BOARD_BUTTON_PIN 6 - -#define BOARD_NR_USARTS 5 -#define BOARD_USART1_TX_PIN 24 -#define BOARD_USART1_RX_PIN 25 -#define BOARD_USART2_TX_PIN 50 -#define BOARD_USART2_RX_PIN 51 -#define BOARD_USART3_TX_PIN 0 -#define BOARD_USART3_RX_PIN 1 -#define BOARD_UART4_TX_PIN 17 -#define BOARD_UART4_RX_PIN 18 -#define BOARD_UART5_TX_PIN 19 -#define BOARD_UART5_RX_PIN 27 - -#define BOARD_NR_SPI 3 -#define BOARD_SPI1_NSS_PIN 52 -#define BOARD_SPI1_MOSI_PIN 55 -#define BOARD_SPI1_MISO_PIN 54 -#define BOARD_SPI1_SCK_PIN 53 -#define BOARD_SPI2_NSS_PIN 2 -#define BOARD_SPI2_MOSI_PIN 5 -#define BOARD_SPI2_MISO_PIN 4 -#define BOARD_SPI2_SCK_PIN 3 -#define BOARD_SPI3_NSS_PIN 103 -#define BOARD_SPI3_MOSI_PIN 37 -#define BOARD_SPI3_MISO_PIN 105 -#define BOARD_SPI3_SCK_PIN 104 - -#define BOARD_NR_GPIO_PINS 106 -#define BOARD_NR_PWM_PINS 18 -#define BOARD_NR_ADC_PINS 21 -#define BOARD_NR_USED_PINS 43 -#define BOARD_JTMS_SWDIO_PIN 101 -#define BOARD_JTCK_SWCLK_PIN 102 -#define BOARD_JTDI_PIN 103 -#define BOARD_JTDO_PIN 104 -#define BOARD_NJTRST_PIN 105 - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file maple_native.h + * @author Marti Bolivar + * @brief Private include file for Maple Native in boards.h + * + * See maple.h for more information on these definitions. + */ + +#ifndef _BOARD_MAPLE_NATIVE_H_ +#define _BOARD_MAPLE_NATIVE_H_ + +#define CYCLES_PER_MICROSECOND 72 +#define SYSTICK_RELOAD_VAL 71999 + +#define BOARD_LED_PIN 22 +#define BOARD_BUTTON_PIN 6 + +#define BOARD_NR_USARTS 5 +#define BOARD_USART1_TX_PIN 24 +#define BOARD_USART1_RX_PIN 25 +#define BOARD_USART2_TX_PIN 50 +#define BOARD_USART2_RX_PIN 51 +#define BOARD_USART3_TX_PIN 0 +#define BOARD_USART3_RX_PIN 1 +#define BOARD_UART4_TX_PIN 17 +#define BOARD_UART4_RX_PIN 18 +#define BOARD_UART5_TX_PIN 19 +#define BOARD_UART5_RX_PIN 27 + +#define BOARD_NR_SPI 3 +#define BOARD_SPI1_NSS_PIN 52 +#define BOARD_SPI1_MOSI_PIN 55 +#define BOARD_SPI1_MISO_PIN 54 +#define BOARD_SPI1_SCK_PIN 53 +#define BOARD_SPI2_NSS_PIN 2 +#define BOARD_SPI2_MOSI_PIN 5 +#define BOARD_SPI2_MISO_PIN 4 +#define BOARD_SPI2_SCK_PIN 3 +#define BOARD_SPI3_NSS_PIN 103 +#define BOARD_SPI3_MOSI_PIN 37 +#define BOARD_SPI3_MISO_PIN 105 +#define BOARD_SPI3_SCK_PIN 104 + +#define BOARD_NR_GPIO_PINS 106 +#define BOARD_NR_PWM_PINS 18 +#define BOARD_NR_ADC_PINS 21 +#define BOARD_NR_USED_PINS 43 +#define BOARD_JTMS_SWDIO_PIN 101 +#define BOARD_JTCK_SWCLK_PIN 102 +#define BOARD_JTDI_PIN 103 +#define BOARD_JTDO_PIN 104 +#define BOARD_NJTRST_PIN 105 + +#endif diff --git a/Libmaple/libmaple/wirish/comm/HardwareSPI.cpp b/Libmaple/libmaple/wirish/comm/HardwareSPI.cpp index 38b85a2b..bd5425c7 100644 --- a/Libmaple/libmaple/wirish/comm/HardwareSPI.cpp +++ b/Libmaple/libmaple/wirish/comm/HardwareSPI.cpp @@ -1,427 +1,427 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @author Marti Bolivar - * @brief Wirish SPI implementation. - */ - -#include "HardwareSPI.h" - -#include "timer.h" -#include "util.h" -#include "rcc.h" - -#include "wirish.h" -#include "boards.h" - -struct spi_pins { - uint8 nss; - uint8 sck; - uint8 miso; - uint8 mosi; -}; - -static const spi_pins* dev_to_spi_pins(spi_dev *dev); - -static void enable_device(spi_dev *dev, - bool as_master, - SPIFrequency frequency, - spi_cfg_flag endianness, - spi_mode mode); - -static const spi_pins board_spi_pins[] __FLASH__ = { - {BOARD_SPI1_NSS_PIN, - BOARD_SPI1_SCK_PIN, - BOARD_SPI1_MISO_PIN, - BOARD_SPI1_MOSI_PIN}, -#ifdef BOARD_SPI2_NSS_PIN - {BOARD_SPI2_NSS_PIN, - BOARD_SPI2_SCK_PIN, - BOARD_SPI2_MISO_PIN, - BOARD_SPI2_MOSI_PIN}, -#endif -#ifdef STM32_HIGH_DENSITY - {BOARD_SPI3_NSS_PIN, - BOARD_SPI3_SCK_PIN, - BOARD_SPI3_MISO_PIN, - BOARD_SPI3_MOSI_PIN}, -#endif -#ifdef STM32F2 - {BOARD_SPI3B_NSS_PIN, - BOARD_SPI3B_SCK_PIN, - BOARD_SPI3B_MISO_PIN, - BOARD_SPI3B_MOSI_PIN}, -#endif -}; - - -/* - * Constructor - */ - -HardwareSPI::HardwareSPI(uint32 spi_num) { - switch (spi_num) { - case 1: - this->spi_d = SPI1; - break; - case 2: - this->spi_d = SPI2; - break; -#ifdef STM32_HIGH_DENSITY - case 3: - this->spi_d = SPI3; - break; -#endif -#ifdef STM32F2 - case 4: - this->spi_d = SPI4; - break; -#endif - default: - ASSERT(0); - } -} - -/* - * Set up/tear down - */ - -void HardwareSPI::begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode) { - if (mode >= 4) { - ASSERT(0); - return; - } - spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB; - spi_mode m = (spi_mode)mode; - enable_device(this->spi_d, true, frequency, end, m); -} - -void HardwareSPI::begin(void) { - this->begin(SPI_1_125MHZ, MSBFIRST, 0); -} - -void HardwareSPI::beginSlave(uint32 bitOrder, uint32 mode) { - if (mode >= 4) { - ASSERT(0); - return; - } - spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB; - spi_mode m = (spi_mode)mode; - enable_device(this->spi_d, false, (SPIFrequency)0, end, m); -} - -void HardwareSPI::beginSlave(void) { - this->beginSlave(MSBFIRST, 0); -} - -void HardwareSPI::end(void) { - if (!spi_is_enabled(this->spi_d)) { - return; - } - - // Follows RM0008's sequence for disabling a SPI in master/slave - // full duplex mode. - while (spi_is_rx_nonempty(this->spi_d)) { - // FIXME [0.1.0] remove this once you have an interrupt based driver - volatile uint16 rx __attribute__((unused)) = spi_rx_reg(this->spi_d); - } - while (!spi_is_tx_empty(this->spi_d)) - ; - while (spi_is_busy(this->spi_d)) - ; - spi_peripheral_disable(this->spi_d); -} - -/* - * I/O - */ - -uint8 HardwareSPI::read(void) { - uint8 buf[1]; - this->read(buf, 1); - return buf[0]; -} - -void HardwareSPI::read(uint8 *buf, uint32 len) { - uint32 rxed = 0; - while (rxed < len) { - while (!spi_is_rx_nonempty(this->spi_d)) - ; - buf[rxed++] = (uint8)spi_rx_reg(this->spi_d); - } -} - -#if 0 -void HardwareSPI::readMaster(uint8 *buf, uint32 len) { - uint32 rxed = 0; - while (rxed < len) { - spi_tx_reg(this->spi_d, 0xff); - while (!spi_is_rx_nonempty(this->spi_d)) - ; - buf[rxed++] = (uint8)spi_rx_reg(this->spi_d); - buf[rxed++] = this->spi_d->regs->DR; - } -} -#endif -void HardwareSPI::readMaster(uint8 *buf, uint32 len) { - spi_reg_map *r = this->spi_d->regs; - uint32 rxed = 0; - while (rxed < len) { - r->DR = 0xff; - while (!(r->SR & SPI_SR_RXNE)) - ; - buf[rxed++] = r->DR; - } -} - - -void HardwareSPI::waitReady() { - while (!spi_is_rx_nonempty(this->spi_d)) - ; -} - -void HardwareSPI::write(uint8 byte) { - this->write(&byte, 1); -} - -void HardwareSPI::write(const uint8 *data, uint32 length) { - uint32 txed = 0; - while (txed < length) { - txed += spi_tx(this->spi_d, data + txed, length - txed); - } -} - -uint8 HardwareSPI::transfer(uint8 byte) { - this->write(byte); - return this->read(); -} - -/* - * Pin accessors - */ - -uint8 HardwareSPI::misoPin(void) { - return dev_to_spi_pins(this->spi_d)->miso; -} - -uint8 HardwareSPI::mosiPin(void) { - return dev_to_spi_pins(this->spi_d)->mosi; -} - -uint8 HardwareSPI::sckPin(void) { - return dev_to_spi_pins(this->spi_d)->sck; -} - -uint8 HardwareSPI::nssPin(void) { - return dev_to_spi_pins(this->spi_d)->nss; -} - -/* - * Deprecated functions - */ - -uint8 HardwareSPI::send(uint8 data) { - uint8 buf[] = {data}; - return this->send(buf, 1); -} - -#if 1 -uint8 HardwareSPI::send(const uint8 *buf, uint32 len) { - uint32 txed = 0; - uint8 ret = 0; - while (txed < len) { - this->write(buf[txed++]); - ret = this->read(); - } - return ret; -} -#else -// this does not work for an unknown reason -uint8 HardwareSPI::send(const uint8 *buf, uint32 len) { - volatile uint32 *dr = &(this->spi_d->regs->DR); - volatile uint32 *sr = &(this->spi_d->regs->SR); - uint32 txed = 0; - uint32 rx=0; - while (txed < len) { - //while (!(*sr & SPI_SR_TXE)) - // ; - //*dr = buf[txed++]; - this->write(buf[txed++]); - - while (!(*sr & SPI_SR_RXNE)) - ; - rx = *dr; - //rx = this->read(); - } - - return rx; -} -#endif - -uint8 HardwareSPI::recv(void) { - return this->read(); -} - -/* - * Auxiliary functions - */ - -static void configure_gpios(spi_dev *dev, bool as_master); -static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq); - -static const spi_pins* dev_to_spi_pins(spi_dev *dev) { - switch (dev->clk_id) { - case RCC_SPI1: return board_spi_pins; - case RCC_SPI2: return board_spi_pins + 1; -#ifdef STM32_HIGH_DENSITY - case RCC_SPI3: return board_spi_pins + 2; -#endif -#ifdef STM32F2 - case RCC_SPI4: return board_spi_pins + 3; -#endif - default: return NULL; - } -} - -/* Enables the device in master or slave full duplex mode. If you - * change this code, you must ensure that appropriate changes are made - * to HardwareSPI::end(). */ -static void enable_device(spi_dev *dev, - bool as_master, - SPIFrequency freq, - spi_cfg_flag endianness, - spi_mode mode) { - spi_baud_rate baud = determine_baud_rate(dev, freq); - uint32 cfg_flags = (endianness | SPI_DFF_8_BIT | SPI_SW_SLAVE | - (as_master ? SPI_SOFT_SS : 0)); - - spi_init(dev); - configure_gpios(dev, as_master); - if (as_master) { - spi_master_enable(dev, baud, mode, cfg_flags); - } else { - spi_slave_enable(dev, mode, cfg_flags); - } -} - -static void disable_pwm(const stm32_pin_info *i) { - if (i->timer_device) { - timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED); - } -} - -static void configure_gpios(spi_dev *dev, bool as_master) { - const spi_pins *pins = dev_to_spi_pins(dev); - - if (!pins) { - return; - } - - const stm32_pin_info *nssi = (pins->nss >= 0) ? &PIN_MAP[pins->nss] : NULL; - const stm32_pin_info *scki = &PIN_MAP[pins->sck]; - const stm32_pin_info *misoi = &PIN_MAP[pins->miso]; - const stm32_pin_info *mosii = &PIN_MAP[pins->mosi]; - - if(nssi) { - disable_pwm(nssi); - } - disable_pwm(scki); - disable_pwm(misoi); - disable_pwm(mosii); - -#ifdef STM32F2 - if(dev->clk_id <= RCC_SPI2) { - if(nssi) { - if(!as_master) { - gpio_set_af_mode(nssi->gpio_device, scki->gpio_bit, 5); - } - } - gpio_set_af_mode(scki->gpio_device, scki->gpio_bit, 5); - gpio_set_af_mode(misoi->gpio_device, misoi->gpio_bit, 5); - gpio_set_af_mode(mosii->gpio_device, mosii->gpio_bit, 5); - //gpio_set_af_mode(GPIOC, 10, 6); - //gpio_set_af_mode(GPIOC, 11, 6); - //gpio_set_af_mode(GPIOC, 12, 6); - } else { - if(nssi) { - if(!as_master) { - gpio_set_af_mode(nssi->gpio_device, scki->gpio_bit, 6); - } - } - gpio_set_af_mode(scki->gpio_device, scki->gpio_bit, 6); - gpio_set_af_mode(misoi->gpio_device, misoi->gpio_bit, 6); - gpio_set_af_mode(mosii->gpio_device, mosii->gpio_bit, 6); - //gpio_set_af_mode(GPIOC, 10, 6); - //gpio_set_af_mode(GPIOC, 11, 6); - //gpio_set_af_mode(GPIOC, 12, 6); - } -#endif - - if(nssi) { - spi_gpio_cfg(as_master, - nssi->gpio_device, - nssi->gpio_bit, - scki->gpio_device, - scki->gpio_bit, - misoi->gpio_bit, - mosii->gpio_bit); - } else { - spi_gpio_cfg(as_master, - NULL, - -1, - scki->gpio_device, - scki->gpio_bit, - misoi->gpio_bit, - mosii->gpio_bit); - } -} - -static const spi_baud_rate baud_rates[MAX_SPI_FREQS] __FLASH__ = { - SPI_BAUD_PCLK_DIV_2, - SPI_BAUD_PCLK_DIV_4, - SPI_BAUD_PCLK_DIV_8, - SPI_BAUD_PCLK_DIV_16, - SPI_BAUD_PCLK_DIV_32, - SPI_BAUD_PCLK_DIV_64, - SPI_BAUD_PCLK_DIV_128, - SPI_BAUD_PCLK_DIV_256, -}; - -/* - * Note: This assumes you're on a LeafLabs-style board - * (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz). - */ -static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq) { - if (rcc_dev_clk(dev->clk_id) == RCC_APB2 && freq == SPI_140_625KHZ) { - /* APB2 peripherals are too fast for 140.625 KHz */ - ASSERT(0); - return (spi_baud_rate)~0; - } - return (rcc_dev_clk(dev->clk_id) == RCC_APB2 ? - baud_rates[freq + 1] : - baud_rates[freq]); -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @author Marti Bolivar + * @brief Wirish SPI implementation. + */ + +#include "HardwareSPI.h" + +#include "timer.h" +#include "util.h" +#include "rcc.h" + +#include "wirish.h" +#include "boards.h" + +struct spi_pins { + uint8 nss; + uint8 sck; + uint8 miso; + uint8 mosi; +}; + +static const spi_pins* dev_to_spi_pins(spi_dev *dev); + +static void enable_device(spi_dev *dev, + bool as_master, + SPIFrequency frequency, + spi_cfg_flag endianness, + spi_mode mode); + +static const spi_pins board_spi_pins[] __FLASH__ = { + {BOARD_SPI1_NSS_PIN, + BOARD_SPI1_SCK_PIN, + BOARD_SPI1_MISO_PIN, + BOARD_SPI1_MOSI_PIN}, +#ifdef BOARD_SPI2_NSS_PIN + {BOARD_SPI2_NSS_PIN, + BOARD_SPI2_SCK_PIN, + BOARD_SPI2_MISO_PIN, + BOARD_SPI2_MOSI_PIN}, +#endif +#ifdef STM32_HIGH_DENSITY + {BOARD_SPI3_NSS_PIN, + BOARD_SPI3_SCK_PIN, + BOARD_SPI3_MISO_PIN, + BOARD_SPI3_MOSI_PIN}, +#endif +#ifdef STM32F2 + {BOARD_SPI3B_NSS_PIN, + BOARD_SPI3B_SCK_PIN, + BOARD_SPI3B_MISO_PIN, + BOARD_SPI3B_MOSI_PIN}, +#endif +}; + + +/* + * Constructor + */ + +HardwareSPI::HardwareSPI(uint32 spi_num) { + switch (spi_num) { + case 1: + this->spi_d = SPI1; + break; + case 2: + this->spi_d = SPI2; + break; +#ifdef STM32_HIGH_DENSITY + case 3: + this->spi_d = SPI3; + break; +#endif +#ifdef STM32F2 + case 4: + this->spi_d = SPI4; + break; +#endif + default: + ASSERT(0); + } +} + +/* + * Set up/tear down + */ + +void HardwareSPI::begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode) { + if (mode >= 4) { + ASSERT(0); + return; + } + spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB; + spi_mode m = (spi_mode)mode; + enable_device(this->spi_d, true, frequency, end, m); +} + +void HardwareSPI::begin(void) { + this->begin(SPI_1_125MHZ, MSBFIRST, 0); +} + +void HardwareSPI::beginSlave(uint32 bitOrder, uint32 mode) { + if (mode >= 4) { + ASSERT(0); + return; + } + spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB; + spi_mode m = (spi_mode)mode; + enable_device(this->spi_d, false, (SPIFrequency)0, end, m); +} + +void HardwareSPI::beginSlave(void) { + this->beginSlave(MSBFIRST, 0); +} + +void HardwareSPI::end(void) { + if (!spi_is_enabled(this->spi_d)) { + return; + } + + // Follows RM0008's sequence for disabling a SPI in master/slave + // full duplex mode. + while (spi_is_rx_nonempty(this->spi_d)) { + // FIXME [0.1.0] remove this once you have an interrupt based driver + volatile uint16 rx __attribute__((unused)) = spi_rx_reg(this->spi_d); + } + while (!spi_is_tx_empty(this->spi_d)) + ; + while (spi_is_busy(this->spi_d)) + ; + spi_peripheral_disable(this->spi_d); +} + +/* + * I/O + */ + +uint8 HardwareSPI::read(void) { + uint8 buf[1]; + this->read(buf, 1); + return buf[0]; +} + +void HardwareSPI::read(uint8 *buf, uint32 len) { + uint32 rxed = 0; + while (rxed < len) { + while (!spi_is_rx_nonempty(this->spi_d)) + ; + buf[rxed++] = (uint8)spi_rx_reg(this->spi_d); + } +} + +#if 0 +void HardwareSPI::readMaster(uint8 *buf, uint32 len) { + uint32 rxed = 0; + while (rxed < len) { + spi_tx_reg(this->spi_d, 0xff); + while (!spi_is_rx_nonempty(this->spi_d)) + ; + buf[rxed++] = (uint8)spi_rx_reg(this->spi_d); + buf[rxed++] = this->spi_d->regs->DR; + } +} +#endif +void HardwareSPI::readMaster(uint8 *buf, uint32 len) { + spi_reg_map *r = this->spi_d->regs; + uint32 rxed = 0; + while (rxed < len) { + r->DR = 0xff; + while (!(r->SR & SPI_SR_RXNE)) + ; + buf[rxed++] = r->DR; + } +} + + +void HardwareSPI::waitReady() { + while (!spi_is_rx_nonempty(this->spi_d)) + ; +} + +void HardwareSPI::write(uint8 byte) { + this->write(&byte, 1); +} + +void HardwareSPI::write(const uint8 *data, uint32 length) { + uint32 txed = 0; + while (txed < length) { + txed += spi_tx(this->spi_d, data + txed, length - txed); + } +} + +uint8 HardwareSPI::transfer(uint8 byte) { + this->write(byte); + return this->read(); +} + +/* + * Pin accessors + */ + +uint8 HardwareSPI::misoPin(void) { + return dev_to_spi_pins(this->spi_d)->miso; +} + +uint8 HardwareSPI::mosiPin(void) { + return dev_to_spi_pins(this->spi_d)->mosi; +} + +uint8 HardwareSPI::sckPin(void) { + return dev_to_spi_pins(this->spi_d)->sck; +} + +uint8 HardwareSPI::nssPin(void) { + return dev_to_spi_pins(this->spi_d)->nss; +} + +/* + * Deprecated functions + */ + +uint8 HardwareSPI::send(uint8 data) { + uint8 buf[] = {data}; + return this->send(buf, 1); +} + +#if 1 +uint8 HardwareSPI::send(const uint8 *buf, uint32 len) { + uint32 txed = 0; + uint8 ret = 0; + while (txed < len) { + this->write(buf[txed++]); + ret = this->read(); + } + return ret; +} +#else +// this does not work for an unknown reason +uint8 HardwareSPI::send(const uint8 *buf, uint32 len) { + volatile uint32 *dr = &(this->spi_d->regs->DR); + volatile uint32 *sr = &(this->spi_d->regs->SR); + uint32 txed = 0; + uint32 rx=0; + while (txed < len) { + //while (!(*sr & SPI_SR_TXE)) + // ; + //*dr = buf[txed++]; + this->write(buf[txed++]); + + while (!(*sr & SPI_SR_RXNE)) + ; + rx = *dr; + //rx = this->read(); + } + + return rx; +} +#endif + +uint8 HardwareSPI::recv(void) { + return this->read(); +} + +/* + * Auxiliary functions + */ + +static void configure_gpios(spi_dev *dev, bool as_master); +static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq); + +static const spi_pins* dev_to_spi_pins(spi_dev *dev) { + switch (dev->clk_id) { + case RCC_SPI1: return board_spi_pins; + case RCC_SPI2: return board_spi_pins + 1; +#ifdef STM32_HIGH_DENSITY + case RCC_SPI3: return board_spi_pins + 2; +#endif +#ifdef STM32F2 + case RCC_SPI4: return board_spi_pins + 3; +#endif + default: return NULL; + } +} + +/* Enables the device in master or slave full duplex mode. If you + * change this code, you must ensure that appropriate changes are made + * to HardwareSPI::end(). */ +static void enable_device(spi_dev *dev, + bool as_master, + SPIFrequency freq, + spi_cfg_flag endianness, + spi_mode mode) { + spi_baud_rate baud = determine_baud_rate(dev, freq); + uint32 cfg_flags = (endianness | SPI_DFF_8_BIT | SPI_SW_SLAVE | + (as_master ? SPI_SOFT_SS : 0)); + + spi_init(dev); + configure_gpios(dev, as_master); + if (as_master) { + spi_master_enable(dev, baud, mode, cfg_flags); + } else { + spi_slave_enable(dev, mode, cfg_flags); + } +} + +static void disable_pwm(const stm32_pin_info *i) { + if (i->timer_device) { + timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED); + } +} + +static void configure_gpios(spi_dev *dev, bool as_master) { + const spi_pins *pins = dev_to_spi_pins(dev); + + if (!pins) { + return; + } + + const stm32_pin_info *nssi = (pins->nss >= 0) ? &PIN_MAP[pins->nss] : NULL; + const stm32_pin_info *scki = &PIN_MAP[pins->sck]; + const stm32_pin_info *misoi = &PIN_MAP[pins->miso]; + const stm32_pin_info *mosii = &PIN_MAP[pins->mosi]; + + if(nssi) { + disable_pwm(nssi); + } + disable_pwm(scki); + disable_pwm(misoi); + disable_pwm(mosii); + +#ifdef STM32F2 + if(dev->clk_id <= RCC_SPI2) { + if(nssi) { + if(!as_master) { + gpio_set_af_mode(nssi->gpio_device, scki->gpio_bit, 5); + } + } + gpio_set_af_mode(scki->gpio_device, scki->gpio_bit, 5); + gpio_set_af_mode(misoi->gpio_device, misoi->gpio_bit, 5); + gpio_set_af_mode(mosii->gpio_device, mosii->gpio_bit, 5); + //gpio_set_af_mode(GPIOC, 10, 6); + //gpio_set_af_mode(GPIOC, 11, 6); + //gpio_set_af_mode(GPIOC, 12, 6); + } else { + if(nssi) { + if(!as_master) { + gpio_set_af_mode(nssi->gpio_device, scki->gpio_bit, 6); + } + } + gpio_set_af_mode(scki->gpio_device, scki->gpio_bit, 6); + gpio_set_af_mode(misoi->gpio_device, misoi->gpio_bit, 6); + gpio_set_af_mode(mosii->gpio_device, mosii->gpio_bit, 6); + //gpio_set_af_mode(GPIOC, 10, 6); + //gpio_set_af_mode(GPIOC, 11, 6); + //gpio_set_af_mode(GPIOC, 12, 6); + } +#endif + + if(nssi) { + spi_gpio_cfg(as_master, + nssi->gpio_device, + nssi->gpio_bit, + scki->gpio_device, + scki->gpio_bit, + misoi->gpio_bit, + mosii->gpio_bit); + } else { + spi_gpio_cfg(as_master, + NULL, + -1, + scki->gpio_device, + scki->gpio_bit, + misoi->gpio_bit, + mosii->gpio_bit); + } +} + +static const spi_baud_rate baud_rates[MAX_SPI_FREQS] __FLASH__ = { + SPI_BAUD_PCLK_DIV_2, + SPI_BAUD_PCLK_DIV_4, + SPI_BAUD_PCLK_DIV_8, + SPI_BAUD_PCLK_DIV_16, + SPI_BAUD_PCLK_DIV_32, + SPI_BAUD_PCLK_DIV_64, + SPI_BAUD_PCLK_DIV_128, + SPI_BAUD_PCLK_DIV_256, +}; + +/* + * Note: This assumes you're on a LeafLabs-style board + * (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz). + */ +static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq) { + if (rcc_dev_clk(dev->clk_id) == RCC_APB2 && freq == SPI_140_625KHZ) { + /* APB2 peripherals are too fast for 140.625 KHz */ + ASSERT(0); + return (spi_baud_rate)~0; + } + return (rcc_dev_clk(dev->clk_id) == RCC_APB2 ? + baud_rates[freq + 1] : + baud_rates[freq]); +} diff --git a/Libmaple/libmaple/wirish/comm/HardwareSPI.h b/Libmaple/libmaple/wirish/comm/HardwareSPI.h index c03821d7..c4f7806f 100644 --- a/Libmaple/libmaple/wirish/comm/HardwareSPI.h +++ b/Libmaple/libmaple/wirish/comm/HardwareSPI.h @@ -1,234 +1,234 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file HardwareSPI.h - * @brief High-level SPI interface - * - * This is a "bare essentials" polling driver for now. - */ - -/* TODO [0.1.0] Remove deprecated methods. */ - -#include "libmaple_types.h" -#include "spi.h" - -#include "boards.h" - -#ifndef _HARDWARESPI_H_ -#define _HARDWARESPI_H_ - -/** - * @brief Defines the possible SPI communication speeds. - */ -typedef enum SPIFrequency { - SPI_18MHZ = 0, /**< 18 MHz */ - SPI_9MHZ = 1, /**< 9 MHz */ - SPI_4_5MHZ = 2, /**< 4.5 MHz */ - SPI_2_25MHZ = 3, /**< 2.25 MHz */ - SPI_1_125MHZ = 4, /**< 1.125 MHz */ - SPI_562_500KHZ = 5, /**< 562.500 KHz */ - SPI_281_250KHZ = 6, /**< 281.250 KHz */ - SPI_140_625KHZ = 7, /**< 140.625 KHz */ -} SPIFrequency; - -#define MAX_SPI_FREQS 8 - -#if CYCLES_PER_MICROSECOND != 72 -/* TODO [0.2.0?] something smarter than this */ -//#warning "Unexpected clock speed; SPI frequency calculation will be incorrect" -#endif - -/** - * @brief Wirish SPI interface. - * - * This implementation uses software slave management, so the caller - * is responsible for controlling the slave select line. - */ -class HardwareSPI { -public: - /** - * @param spiPortNumber Number of the SPI port to manage. - */ - HardwareSPI(uint32 spiPortNumber); - - /* - * Set up/tear down - */ - - /** - * @brief Turn on a SPI port and set its GPIO pin modes for use as master. - * - * SPI port is enabled in full duplex mode, with software slave management. - * - * @param frequency Communication frequency - * @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST (big-endian) - * @param mode SPI mode to use, one of SPI_MODE_0, SPI_MODE_1, - * SPI_MODE_2, and SPI_MODE_3. - */ - void begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode); - - /** - * @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0). - */ - void begin(void); - - /** - * @brief Turn on a SPI port and set its GPIO pin modes for use as a slave. - * - * SPI port is enabled in full duplex mode, with software slave management. - * - * @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST(big-endian) - * @param mode SPI mode to use - */ - void beginSlave(uint32 bitOrder, uint32 mode); - - /** - * @brief Equivalent to beginSlave(MSBFIRST, 0). - */ - void beginSlave(void); - - /** - * @brief Disables the SPI port, but leaves its GPIO pin modes unchanged. - */ - void end(void); - - /* - * I/O - */ - - /** - * @brief Return the next unread byte. - * - * If there is no unread byte waiting, this function will block - * until one is received. - */ - uint8 read(void); - - /** - * @brief Read length bytes, storing them into buffer. - * @param buffer Buffer to store received bytes into. - * @param length Number of bytes to store in buffer. This - * function will block until the desired number of - * bytes have been read. - */ - void read(uint8 *buffer, uint32 length); - - /** - * @brief Read length bytes, storing them into buffer. - * @param buffer Buffer to store received bytes into. - * @param length Number of bytes to store in buffer. This - * function will block until the desired number of - * bytes have been read. - */ - void readMaster(uint8 *buffer, uint32 length); - - - void waitReady(); - /** - * @brief Transmit a byte. - * @param data Byte to transmit. - */ - void write(uint8 data); - - /** - * @brief Transmit multiple bytes. - * @param buffer Bytes to transmit. - * @param length Number of bytes in buffer to transmit. - */ - void write(const uint8 *buffer, uint32 length); - - /** - * @brief Transmit a byte, then return the next unread byte. - * - * This function transmits before receiving. - * - * @param data Byte to transmit. - * @return Next unread byte. - */ - uint8 transfer(uint8 data); - - /* - * Pin accessors - */ - - /** - * @brief Return the number of the MISO (master in, slave out) pin - */ - uint8 misoPin(void); - - /** - * @brief Return the number of the MOSI (master out, slave in) pin - */ - uint8 mosiPin(void); - - /** - * @brief Return the number of the SCK (serial clock) pin - */ - uint8 sckPin(void); - - /** - * @brief Return the number of the NSS (slave select) pin - */ - uint8 nssPin(void); - - /* -- The following methods are deprecated --------------------------- */ - - /** - * @brief Deprecated. - * - * Use HardwareSPI::transfer() instead. - * - * @see HardwareSPI::transfer() - */ - uint8 send(uint8 data); - - /** - * @brief Deprecated. - * - * Use HardwareSPI::write() in combination with - * HardwareSPI::read() (or HardwareSPI::transfer()) instead. - * - * @see HardwareSPI::write() - * @see HardwareSPI::read() - * @see HardwareSPI::transfer() - */ - uint8 send(const uint8 *data, uint32 length); - - /** - * @brief Deprecated. - * - * Use HardwareSPI::read() instead. - * - * @see HardwareSPI::read() - */ - uint8 recv(void); -private: - spi_dev *spi_d; -}; - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file HardwareSPI.h + * @brief High-level SPI interface + * + * This is a "bare essentials" polling driver for now. + */ + +/* TODO [0.1.0] Remove deprecated methods. */ + +#include "libmaple_types.h" +#include "spi.h" + +#include "boards.h" + +#ifndef _HARDWARESPI_H_ +#define _HARDWARESPI_H_ + +/** + * @brief Defines the possible SPI communication speeds. + */ +typedef enum SPIFrequency { + SPI_18MHZ = 0, /**< 18 MHz */ + SPI_9MHZ = 1, /**< 9 MHz */ + SPI_4_5MHZ = 2, /**< 4.5 MHz */ + SPI_2_25MHZ = 3, /**< 2.25 MHz */ + SPI_1_125MHZ = 4, /**< 1.125 MHz */ + SPI_562_500KHZ = 5, /**< 562.500 KHz */ + SPI_281_250KHZ = 6, /**< 281.250 KHz */ + SPI_140_625KHZ = 7, /**< 140.625 KHz */ +} SPIFrequency; + +#define MAX_SPI_FREQS 8 + +#if CYCLES_PER_MICROSECOND != 72 +/* TODO [0.2.0?] something smarter than this */ +//#warning "Unexpected clock speed; SPI frequency calculation will be incorrect" +#endif + +/** + * @brief Wirish SPI interface. + * + * This implementation uses software slave management, so the caller + * is responsible for controlling the slave select line. + */ +class HardwareSPI { +public: + /** + * @param spiPortNumber Number of the SPI port to manage. + */ + HardwareSPI(uint32 spiPortNumber); + + /* + * Set up/tear down + */ + + /** + * @brief Turn on a SPI port and set its GPIO pin modes for use as master. + * + * SPI port is enabled in full duplex mode, with software slave management. + * + * @param frequency Communication frequency + * @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST (big-endian) + * @param mode SPI mode to use, one of SPI_MODE_0, SPI_MODE_1, + * SPI_MODE_2, and SPI_MODE_3. + */ + void begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode); + + /** + * @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0). + */ + void begin(void); + + /** + * @brief Turn on a SPI port and set its GPIO pin modes for use as a slave. + * + * SPI port is enabled in full duplex mode, with software slave management. + * + * @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST(big-endian) + * @param mode SPI mode to use + */ + void beginSlave(uint32 bitOrder, uint32 mode); + + /** + * @brief Equivalent to beginSlave(MSBFIRST, 0). + */ + void beginSlave(void); + + /** + * @brief Disables the SPI port, but leaves its GPIO pin modes unchanged. + */ + void end(void); + + /* + * I/O + */ + + /** + * @brief Return the next unread byte. + * + * If there is no unread byte waiting, this function will block + * until one is received. + */ + uint8 read(void); + + /** + * @brief Read length bytes, storing them into buffer. + * @param buffer Buffer to store received bytes into. + * @param length Number of bytes to store in buffer. This + * function will block until the desired number of + * bytes have been read. + */ + void read(uint8 *buffer, uint32 length); + + /** + * @brief Read length bytes, storing them into buffer. + * @param buffer Buffer to store received bytes into. + * @param length Number of bytes to store in buffer. This + * function will block until the desired number of + * bytes have been read. + */ + void readMaster(uint8 *buffer, uint32 length); + + + void waitReady(); + /** + * @brief Transmit a byte. + * @param data Byte to transmit. + */ + void write(uint8 data); + + /** + * @brief Transmit multiple bytes. + * @param buffer Bytes to transmit. + * @param length Number of bytes in buffer to transmit. + */ + void write(const uint8 *buffer, uint32 length); + + /** + * @brief Transmit a byte, then return the next unread byte. + * + * This function transmits before receiving. + * + * @param data Byte to transmit. + * @return Next unread byte. + */ + uint8 transfer(uint8 data); + + /* + * Pin accessors + */ + + /** + * @brief Return the number of the MISO (master in, slave out) pin + */ + uint8 misoPin(void); + + /** + * @brief Return the number of the MOSI (master out, slave in) pin + */ + uint8 mosiPin(void); + + /** + * @brief Return the number of the SCK (serial clock) pin + */ + uint8 sckPin(void); + + /** + * @brief Return the number of the NSS (slave select) pin + */ + uint8 nssPin(void); + + /* -- The following methods are deprecated --------------------------- */ + + /** + * @brief Deprecated. + * + * Use HardwareSPI::transfer() instead. + * + * @see HardwareSPI::transfer() + */ + uint8 send(uint8 data); + + /** + * @brief Deprecated. + * + * Use HardwareSPI::write() in combination with + * HardwareSPI::read() (or HardwareSPI::transfer()) instead. + * + * @see HardwareSPI::write() + * @see HardwareSPI::read() + * @see HardwareSPI::transfer() + */ + uint8 send(const uint8 *data, uint32 length); + + /** + * @brief Deprecated. + * + * Use HardwareSPI::read() instead. + * + * @see HardwareSPI::read() + */ + uint8 recv(void); +private: + spi_dev *spi_d; +}; + +#endif + diff --git a/Libmaple/libmaple/wirish/comm/HardwareSerial.cpp b/Libmaple/libmaple/wirish/comm/HardwareSerial.cpp index a49bf47a..516fa1b6 100644 --- a/Libmaple/libmaple/wirish/comm/HardwareSerial.cpp +++ b/Libmaple/libmaple/wirish/comm/HardwareSerial.cpp @@ -1,149 +1,149 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file HardwareSerial.cpp - * @brief Wirish serial port implementation. - */ - -#include "libmaple.h" -#include "gpio.h" -#include "timer.h" - -#include "HardwareSerial.h" -#include "boards.h" - -#define TX1 BOARD_USART1_TX_PIN -#define RX1 BOARD_USART1_RX_PIN - -#ifdef BOARD_USART2_TX_PIN - #define TX2 BOARD_USART2_TX_PIN - #define RX2 BOARD_USART2_RX_PIN -#endif - -#ifdef BOARD_USART3_TX_PIN - #define TX3 BOARD_USART3_TX_PIN - #define RX3 BOARD_USART3_RX_PIN -#endif - -#if defined STM32_HIGH_DENSITY && !defined(BOARD_maple_RET6) -#define TX4 BOARD_UART4_TX_PIN -#define RX4 BOARD_UART4_RX_PIN -#define TX5 BOARD_UART5_TX_PIN -#define RX5 BOARD_UART5_RX_PIN -#endif - -HardwareSerial Serial1(USART1, TX1, RX1); - -#ifdef TX2 -HardwareSerial Serial2(USART2, TX2, RX2); -#endif - -#ifdef TX3 -HardwareSerial Serial3(USART3, TX3, RX3); -#endif - -#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) -HardwareSerial Serial4(UART4, TX4, RX4); -HardwareSerial Serial5(UART5, TX5, RX5); -#endif - -HardwareSerial::HardwareSerial(usart_dev *usart_device, - uint8 tx_pin, - uint8 rx_pin) { - this->usart_device = usart_device; - this->tx_pin = tx_pin; - this->rx_pin = rx_pin; -} - -/* - * Set up/tear down - */ - -void HardwareSerial::begin(uint32 baud) { - ASSERT(baud <= usart_device->max_baud); - - if (baud > usart_device->max_baud) { - return; - } - - const stm32_pin_info *txi = &PIN_MAP[tx_pin]; - const stm32_pin_info *rxi = &PIN_MAP[rx_pin]; -#ifdef STM32F2 - // int af = 7<<8; - gpio_set_af_mode(txi->gpio_device, txi->gpio_bit, 7); - gpio_set_af_mode(rxi->gpio_device, rxi->gpio_bit, 7); - gpio_set_mode(txi->gpio_device, txi->gpio_bit, (gpio_pin_mode)(GPIO_AF_OUTPUT_PP | GPIO_PUPD_INPUT_PU | 0x700)); - gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, (gpio_pin_mode)(GPIO_MODE_AF | GPIO_PUPD_INPUT_PU | 0x700)); - //gpio_set_mode(txi->gpio_device, txi->gpio_bit, (gpio_pin_mode)(GPIO_PUPD_INPUT_PU)); - //gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, (gpio_pin_mode)(GPIO_PUPD_INPUT_PU)); -#else - gpio_set_mode(txi->gpio_device, txi->gpio_bit, GPIO_AF_OUTPUT_PP); - gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, GPIO_INPUT_FLOATING); -#endif -#if 0 - if (txi->timer_device != NULL) { - /* Turn off any PWM if there's a conflict on this GPIO bit. */ - timer_set_mode(txi->timer_device, txi->timer_channel, TIMER_DISABLED); - } -#endif - - usart_init(usart_device); - usart_set_baud_rate(usart_device, baud); - usart_enable(usart_device); -} - -void HardwareSerial::end(void) { - usart_disable(usart_device); -} - -/* - * I/O - */ - -int HardwareSerial::read(void) { - if(usart_data_available(usart_device) > 0) { - return usart_getc(usart_device); - } else { - return -1; - } -} - -uint32 HardwareSerial::available(void) { - return usart_data_available(usart_device); -} - -uint32 HardwareSerial::pending(void) { - return usart_data_pending(usart_device); -} - -void HardwareSerial::write(unsigned char ch) { - usart_putc(usart_device, ch); -} - -void HardwareSerial::flush(void) { - usart_reset_rx(usart_device); -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file HardwareSerial.cpp + * @brief Wirish serial port implementation. + */ + +#include "libmaple.h" +#include "gpio.h" +#include "timer.h" + +#include "HardwareSerial.h" +#include "boards.h" + +#define TX1 BOARD_USART1_TX_PIN +#define RX1 BOARD_USART1_RX_PIN + +#ifdef BOARD_USART2_TX_PIN + #define TX2 BOARD_USART2_TX_PIN + #define RX2 BOARD_USART2_RX_PIN +#endif + +#ifdef BOARD_USART3_TX_PIN + #define TX3 BOARD_USART3_TX_PIN + #define RX3 BOARD_USART3_RX_PIN +#endif + +#if defined STM32_HIGH_DENSITY && !defined(BOARD_maple_RET6) +#define TX4 BOARD_UART4_TX_PIN +#define RX4 BOARD_UART4_RX_PIN +#define TX5 BOARD_UART5_TX_PIN +#define RX5 BOARD_UART5_RX_PIN +#endif + +HardwareSerial Serial1(USART1, TX1, RX1); + +#ifdef TX2 +HardwareSerial Serial2(USART2, TX2, RX2); +#endif + +#ifdef TX3 +HardwareSerial Serial3(USART3, TX3, RX3); +#endif + +#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) +HardwareSerial Serial4(UART4, TX4, RX4); +HardwareSerial Serial5(UART5, TX5, RX5); +#endif + +HardwareSerial::HardwareSerial(usart_dev *usart_device, + uint8 tx_pin, + uint8 rx_pin) { + this->usart_device = usart_device; + this->tx_pin = tx_pin; + this->rx_pin = rx_pin; +} + +/* + * Set up/tear down + */ + +void HardwareSerial::begin(uint32 baud) { + ASSERT(baud <= usart_device->max_baud); + + if (baud > usart_device->max_baud) { + return; + } + + const stm32_pin_info *txi = &PIN_MAP[tx_pin]; + const stm32_pin_info *rxi = &PIN_MAP[rx_pin]; +#ifdef STM32F2 + // int af = 7<<8; + gpio_set_af_mode(txi->gpio_device, txi->gpio_bit, 7); + gpio_set_af_mode(rxi->gpio_device, rxi->gpio_bit, 7); + gpio_set_mode(txi->gpio_device, txi->gpio_bit, (gpio_pin_mode)(GPIO_AF_OUTPUT_PP | GPIO_PUPD_INPUT_PU | 0x700)); + gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, (gpio_pin_mode)(GPIO_MODE_AF | GPIO_PUPD_INPUT_PU | 0x700)); + //gpio_set_mode(txi->gpio_device, txi->gpio_bit, (gpio_pin_mode)(GPIO_PUPD_INPUT_PU)); + //gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, (gpio_pin_mode)(GPIO_PUPD_INPUT_PU)); +#else + gpio_set_mode(txi->gpio_device, txi->gpio_bit, GPIO_AF_OUTPUT_PP); + gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, GPIO_INPUT_FLOATING); +#endif +#if 0 + if (txi->timer_device != NULL) { + /* Turn off any PWM if there's a conflict on this GPIO bit. */ + timer_set_mode(txi->timer_device, txi->timer_channel, TIMER_DISABLED); + } +#endif + + usart_init(usart_device); + usart_set_baud_rate(usart_device, baud); + usart_enable(usart_device); +} + +void HardwareSerial::end(void) { + usart_disable(usart_device); +} + +/* + * I/O + */ + +int HardwareSerial::read(void) { + if(usart_data_available(usart_device) > 0) { + return usart_getc(usart_device); + } else { + return -1; + } +} + +uint32 HardwareSerial::available(void) { + return usart_data_available(usart_device); +} + +uint32 HardwareSerial::pending(void) { + return usart_data_pending(usart_device); +} + +void HardwareSerial::write(unsigned char ch) { + usart_putc(usart_device, ch); +} + +void HardwareSerial::flush(void) { + usart_reset_rx(usart_device); +} diff --git a/Libmaple/libmaple/wirish/comm/HardwareSerial.h b/Libmaple/libmaple/wirish/comm/HardwareSerial.h index c4ba1969..6441560c 100644 --- a/Libmaple/libmaple/wirish/comm/HardwareSerial.h +++ b/Libmaple/libmaple/wirish/comm/HardwareSerial.h @@ -1,85 +1,85 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file HardwareSerial.h - * @brief Wirish serial port interface. - */ - -#ifndef _HARDWARESERIAL_H_ -#define _HARDWARESERIAL_H_ - -#include "libmaple_types.h" -#include "usart.h" - -#include "Print.h" - -/* - * IMPORTANT: - * - * This class documented "by hand" (i.e., not using Doxygen) in the - * leaflabs-docs/ repository. - * - * If you alter the public HardwareSerial interface, you MUST update - * the documentation accordingly. - */ - -class HardwareSerial : public Print { -public: - HardwareSerial(usart_dev *usart_device, - uint8 tx_pin, - uint8 rx_pin); - - /* Set up/tear down */ - void begin(uint32 baud); - void end(void); - - /* I/O */ - uint32 available(void); - uint32 pending(void); - int read(void); - void flush(void); - virtual void write(unsigned char); - using Print::write; - - /* Pin accessors */ - int txPin(void) { return this->tx_pin; } - int rxPin(void) { return this->rx_pin; } -private: - usart_dev *usart_device; - uint8 tx_pin; - uint8 rx_pin; -}; - -extern HardwareSerial Serial1; -extern HardwareSerial Serial2; -extern HardwareSerial Serial3; -#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) -extern HardwareSerial Serial4; -extern HardwareSerial Serial5; -#endif -extern HardwareSerial &SerialDebug; -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file HardwareSerial.h + * @brief Wirish serial port interface. + */ + +#ifndef _HARDWARESERIAL_H_ +#define _HARDWARESERIAL_H_ + +#include "libmaple_types.h" +#include "usart.h" + +#include "Print.h" + +/* + * IMPORTANT: + * + * This class documented "by hand" (i.e., not using Doxygen) in the + * leaflabs-docs/ repository. + * + * If you alter the public HardwareSerial interface, you MUST update + * the documentation accordingly. + */ + +class HardwareSerial : public Print { +public: + HardwareSerial(usart_dev *usart_device, + uint8 tx_pin, + uint8 rx_pin); + + /* Set up/tear down */ + void begin(uint32 baud); + void end(void); + + /* I/O */ + uint32 available(void); + uint32 pending(void); + int read(void); + void flush(void); + virtual void write(unsigned char); + using Print::write; + + /* Pin accessors */ + int txPin(void) { return this->tx_pin; } + int rxPin(void) { return this->rx_pin; } +private: + usart_dev *usart_device; + uint8 tx_pin; + uint8 rx_pin; +}; + +extern HardwareSerial Serial1; +extern HardwareSerial Serial2; +extern HardwareSerial Serial3; +#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) +extern HardwareSerial Serial4; +extern HardwareSerial Serial5; +#endif +extern HardwareSerial &SerialDebug; +#endif diff --git a/Libmaple/libmaple/wirish/cxxabi-compat.cpp b/Libmaple/libmaple/wirish/cxxabi-compat.cpp index 2e07e0bb..516b112a 100644 --- a/Libmaple/libmaple/wirish/cxxabi-compat.cpp +++ b/Libmaple/libmaple/wirish/cxxabi-compat.cpp @@ -1,6 +1,6 @@ -/* We compile with nodefaultlibs, so we need to provide an error - * handler for an empty pure virtual function */ -extern "C" void __cxa_pure_virtual(void) { - while(1) - ; -} +/* We compile with nodefaultlibs, so we need to provide an error + * handler for an empty pure virtual function */ +extern "C" void __cxa_pure_virtual(void) { + while(1) + ; +} diff --git a/Libmaple/libmaple/wirish/ext_interrupts.cpp b/Libmaple/libmaple/wirish/ext_interrupts.cpp index 118a734c..f014f130 100644 --- a/Libmaple/libmaple/wirish/ext_interrupts.cpp +++ b/Libmaple/libmaple/wirish/ext_interrupts.cpp @@ -1,84 +1,84 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file ext_interrupts.c - * - * @brief Wiring-like interface for external interrupts - */ - -#include "boards.h" -#include "gpio.h" -#include "exti.h" -#include "ext_interrupts.h" - -static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode); - -/** - * @brief Attach an interrupt handler to a pin, triggering on the given mode. - * @param pin Pin to attach an interrupt handler onto. - * @param handler Function to call when the external interrupt is triggered. - * @param mode Trigger mode for the given interrupt. - * @see ExtIntTriggerMode - */ -void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) { - if (pin >= BOARD_NR_GPIO_PINS || !handler) { - return; - } - - exti_trigger_mode outMode = exti_out_mode(mode); - - exti_attach_interrupt((afio_exti_num)(PIN_MAP[pin].gpio_bit), - gpio_exti_port(PIN_MAP[pin].gpio_device), - handler, - outMode); -} - -/** - * @brief Disable any external interrupt attached to a pin. - * @param pin Pin number to detach any interrupt from. - */ -void detachInterrupt(uint8 pin) { - if (pin >= BOARD_NR_GPIO_PINS) { - return; - } - - exti_detach_interrupt((afio_exti_num)(PIN_MAP[pin].gpio_bit)); -} - -static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode) { - switch (mode) { - case RISING: - return EXTI_RISING; - case FALLING: - return EXTI_FALLING; - case CHANGE: - return EXTI_RISING_FALLING; - } - // Can't happen - ASSERT(0); - return (exti_trigger_mode)0; -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file ext_interrupts.c + * + * @brief Wiring-like interface for external interrupts + */ + +#include "boards.h" +#include "gpio.h" +#include "exti.h" +#include "ext_interrupts.h" + +static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode); + +/** + * @brief Attach an interrupt handler to a pin, triggering on the given mode. + * @param pin Pin to attach an interrupt handler onto. + * @param handler Function to call when the external interrupt is triggered. + * @param mode Trigger mode for the given interrupt. + * @see ExtIntTriggerMode + */ +void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) { + if (pin >= BOARD_NR_GPIO_PINS || !handler) { + return; + } + + exti_trigger_mode outMode = exti_out_mode(mode); + + exti_attach_interrupt((afio_exti_num)(PIN_MAP[pin].gpio_bit), + gpio_exti_port(PIN_MAP[pin].gpio_device), + handler, + outMode); +} + +/** + * @brief Disable any external interrupt attached to a pin. + * @param pin Pin number to detach any interrupt from. + */ +void detachInterrupt(uint8 pin) { + if (pin >= BOARD_NR_GPIO_PINS) { + return; + } + + exti_detach_interrupt((afio_exti_num)(PIN_MAP[pin].gpio_bit)); +} + +static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode) { + switch (mode) { + case RISING: + return EXTI_RISING; + case FALLING: + return EXTI_FALLING; + case CHANGE: + return EXTI_RISING_FALLING; + } + // Can't happen + ASSERT(0); + return (exti_trigger_mode)0; +} diff --git a/Libmaple/libmaple/wirish/ext_interrupts.h b/Libmaple/libmaple/wirish/ext_interrupts.h index 10aa1d63..b5c6f983 100644 --- a/Libmaple/libmaple/wirish/ext_interrupts.h +++ b/Libmaple/libmaple/wirish/ext_interrupts.h @@ -1,106 +1,106 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include "libmaple_types.h" -#include "nvic.h" - -/** - * @file ext_interrupts.h - * - * @brief Wiring-like external interrupt prototypes and types. - */ - -#ifndef _EXT_INTERRUPTS_H_ -#define _EXT_INTERRUPTS_H_ - -/** - * The kind of transition on an external pin which should trigger an - * interrupt. - */ -typedef enum ExtIntTriggerMode { - RISING, /**< To trigger an interrupt when the pin transitions LOW - to HIGH */ - FALLING, /**< To trigger an interrupt when the pin transitions - HIGH to LOW */ - CHANGE /**< To trigger an interrupt when the pin transitions from - LOW to HIGH or HIGH to LOW (i.e., when the pin - changes). */ -} ExtIntTriggerMode; - -/** - * @brief Registers an interrupt handler on a pin. - * - * The interrupt will be triggered on a given transition on the pin, - * as specified by the mode parameter. The handler runs in interrupt - * context. The new handler will replace whatever handler is - * currently registered for the pin, if any. - * - * @param pin Maple pin number - * @param handler Function to run upon external interrupt trigger. - * The handler should take no arguments, and have void return type. - * @param mode Type of transition to trigger on, e.g. falling, rising, etc. - * - * @sideeffect Registers a handler - * @see detachInterrupt() - */ -void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode); - -/** - * @brief Disable any registered external interrupt. - * @param pin Maple pin number - * @sideeffect unregisters external interrupt handler - * @see attachInterrupt() - */ -void detachInterrupt(uint8 pin); - -/** - * Re-enable interrupts. - * - * Call this after noInterrupts() to re-enable interrupt handling, - * after you have finished with a timing-critical section of code. - * - * @see noInterrupts() - */ -static inline void interrupts() { - nvic_globalirq_enable(); -} - -/** - * Disable interrupts. - * - * After calling this function, all user-programmable interrupts will - * be disabled. You can call this function before a timing-critical - * section of code, then call interrupts() to re-enable interrupt - * handling. - * - * @see interrupts() - */ -static inline void noInterrupts() { - nvic_globalirq_disable(); -} - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +#include "libmaple_types.h" +#include "nvic.h" + +/** + * @file ext_interrupts.h + * + * @brief Wiring-like external interrupt prototypes and types. + */ + +#ifndef _EXT_INTERRUPTS_H_ +#define _EXT_INTERRUPTS_H_ + +/** + * The kind of transition on an external pin which should trigger an + * interrupt. + */ +typedef enum ExtIntTriggerMode { + RISING, /**< To trigger an interrupt when the pin transitions LOW + to HIGH */ + FALLING, /**< To trigger an interrupt when the pin transitions + HIGH to LOW */ + CHANGE /**< To trigger an interrupt when the pin transitions from + LOW to HIGH or HIGH to LOW (i.e., when the pin + changes). */ +} ExtIntTriggerMode; + +/** + * @brief Registers an interrupt handler on a pin. + * + * The interrupt will be triggered on a given transition on the pin, + * as specified by the mode parameter. The handler runs in interrupt + * context. The new handler will replace whatever handler is + * currently registered for the pin, if any. + * + * @param pin Maple pin number + * @param handler Function to run upon external interrupt trigger. + * The handler should take no arguments, and have void return type. + * @param mode Type of transition to trigger on, e.g. falling, rising, etc. + * + * @sideeffect Registers a handler + * @see detachInterrupt() + */ +void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode); + +/** + * @brief Disable any registered external interrupt. + * @param pin Maple pin number + * @sideeffect unregisters external interrupt handler + * @see attachInterrupt() + */ +void detachInterrupt(uint8 pin); + +/** + * Re-enable interrupts. + * + * Call this after noInterrupts() to re-enable interrupt handling, + * after you have finished with a timing-critical section of code. + * + * @see noInterrupts() + */ +static inline void interrupts() { + nvic_globalirq_enable(); +} + +/** + * Disable interrupts. + * + * After calling this function, all user-programmable interrupts will + * be disabled. You can call this function before a timing-critical + * section of code, then call interrupts() to re-enable interrupt + * handling. + * + * @see interrupts() + */ +static inline void noInterrupts() { + nvic_globalirq_disable(); +} + +#endif + diff --git a/Libmaple/libmaple/wirish/io.h b/Libmaple/libmaple/wirish/io.h index 7a66f691..1cbe2d95 100644 --- a/Libmaple/libmaple/wirish/io.h +++ b/Libmaple/libmaple/wirish/io.h @@ -1,222 +1,222 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file io.h - * - * @brief Arduino-compatible digital pin I/O interface. - */ - -#ifndef _IO_H_ -#define _IO_H_ - -#include "gpio.h" -#include "adc.h" - -#include "wirish_time.h" - -/** - * Specifies a GPIO pin behavior. - * @see pinMode() - */ -typedef enum WiringPinMode { - OUTPUT, /**< Basic digital output: when the pin is HIGH, the - voltage is held at +3.3v (Vcc) and when it is LOW, it - is pulled down to ground. */ - - OUTPUT_OPEN_DRAIN, /**< In open drain mode, the pin indicates - "low" by accepting current flow to ground - and "high" by providing increased - impedance. An example use would be to - connect a pin to a bus line (which is pulled - up to a positive voltage by a separate - supply through a large resistor). When the - pin is high, not much current flows through - to ground and the line stays at positive - voltage; when the pin is low, the bus - "drains" to ground with a small amount of - current constantly flowing through the large - resistor from the external supply. In this - mode, no current is ever actually sourced - from the pin. */ - - INPUT, /**< Basic digital input. The pin voltage is sampled; when - it is closer to 3.3v (Vcc) the pin status is high, and - when it is closer to 0v (ground) it is low. If no - external circuit is pulling the pin voltage to high or - low, it will tend to randomly oscillate and be very - sensitive to noise (e.g., a breath of air across the pin - might cause the state to flip). */ - - INPUT_ANALOG, /**< This is a special mode for when the pin will be - used for analog (not digital) reads. Enables ADC - conversion to be performed on the voltage at the - pin. */ - - INPUT_PULLUP, /**< The state of the pin in this mode is reported - the same way as with INPUT, but the pin voltage - is gently "pulled up" towards +3.3v. This means - the state will be high unless an external device - is specifically pulling the pin down to ground, - in which case the "gentle" pull-up will not - affect the state of the input. */ - - INPUT_PULLDOWN, /**< The state of the pin in this mode is reported - the same way as with INPUT, but the pin voltage - is gently "pulled down" towards 0v. This means - the state will be low unless an external device - is specifically pulling the pin up to 3.3v, in - which case the "gentle" pull-down will not - affect the state of the input. */ - - INPUT_FLOATING, /**< Synonym for INPUT. */ - - PWM, /**< This is a special mode for when the pin will be used for - PWM output (a special case of digital output). */ - - PWM_OPEN_DRAIN, /**< Like PWM, except that instead of alternating - cycles of LOW and HIGH, the voltage on the pin - consists of alternating cycles of LOW and - floating (disconnected). */ -} WiringPinMode; - -/** - * Configure behavior of a GPIO pin. - * - * @param pin Number of pin to configure. - * @param mode Mode corresponding to desired pin behavior. - * @see WiringPinMode - */ -void pinMode(uint8 pin, WiringPinMode mode); - -/** - * Writes a (digital) value to a pin. The pin must have its - * mode set to OUTPUT or OUTPUT_OPEN_DRAIN. - * - * @param pin Pin to write to. - * @param value Either LOW (write a 0) or HIGH (write a 1). - * @see pinMode() - */ -void digitalWrite(uint8 pin, uint8 value); - -/** - * Read a digital value from a pin. The pin must have its mode set to - * one of INPUT, INPUT_PULLUP, and INPUT_PULLDOWN. - * - * @param pin Pin to read from. - * @return LOW or HIGH. - * @see pinMode() - */ -uint32 digitalRead(uint8 pin); - -/** - * Read an analog value from pin. This function blocks during ADC - * conversion, and has 12 bits of resolution. The pin must have its - * mode set to INPUT_ANALOG. - * - * @param pin Pin to read from. - * @return Converted voltage, in the range 0--4095, (i.e. a 12-bit ADC - * conversion). - * @see pinMode() - */ -uint16 analogRead(uint8 pin); - -/** - * Toggles the digital value at the given pin. - * - * The pin must have its mode set to OUTPUT. - * - * @param pin the pin to toggle. If the pin is HIGH, set it LOW. If - * it is LOW, set it HIGH. - * - * @see pinMode() - */ -void togglePin(uint8 pin); - -/** - * Toggle the LED. - * - * If the LED is on, turn it off. If it is off, turn it on. - * - * The LED must its mode set to OUTPUT. This can be accomplished - * portably over all LeafLabs boards by calling pinMode(BOARD_LED_PIN, - * OUTPUT) before calling this function. - * - * @see pinMode() - */ -static inline void toggleLED() { - togglePin(BOARD_LED_PIN); -} - -/** - * If the button is currently pressed, waits until the button is no - * longer being pressed, and returns true. Otherwise, returns false. - * - * The button pin must have its mode set to INPUT. This can be - * accomplished portably over all LeafLabs boards by calling - * pinMode(BOARD_BUTTON_PIN, INPUT). - * - * @see pinMode() - */ -uint8 isButtonPressed(); - -/** - * Wait until the button is pressed and released, timing out if no - * press occurs. - * - * The button pin must have its mode set to INPUT. This can be - * accomplished portably over all LeafLabs boards by calling - * pinMode(BOARD_BUTTON_PIN, INPUT). - * - * @param timeout_millis Number of milliseconds to wait until the - * button is pressed. If timeout_millis is left out (or 0), wait - * forever. - * - * @return true, if the button was pressed; false, if the timeout was - * reached. - * - * @see pinMode() - */ -uint8 waitForButtonPress(uint32 timeout_millis=0); - -/** - * Shift out a byte of data, one bit at a time. - * - * This function starts at either the most significant or least - * significant bit in a byte value, and shifts out each byte in order - * onto a data pin. After each bit is written to the data pin, a - * separate clock pin is pulsed to indicate that the new bit is - * available. - * - * @param dataPin Pin to shift data out on - * @param clockPin Pin to pulse after each bit is shifted out - * @param bitOrder Either MSBFIRST (big-endian) or LSBFIRST (little-endian). - * @param value Value to shift out - */ -void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 value); - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file io.h + * + * @brief Arduino-compatible digital pin I/O interface. + */ + +#ifndef _IO_H_ +#define _IO_H_ + +#include "gpio.h" +#include "adc.h" + +#include "wirish_time.h" + +/** + * Specifies a GPIO pin behavior. + * @see pinMode() + */ +typedef enum WiringPinMode { + OUTPUT, /**< Basic digital output: when the pin is HIGH, the + voltage is held at +3.3v (Vcc) and when it is LOW, it + is pulled down to ground. */ + + OUTPUT_OPEN_DRAIN, /**< In open drain mode, the pin indicates + "low" by accepting current flow to ground + and "high" by providing increased + impedance. An example use would be to + connect a pin to a bus line (which is pulled + up to a positive voltage by a separate + supply through a large resistor). When the + pin is high, not much current flows through + to ground and the line stays at positive + voltage; when the pin is low, the bus + "drains" to ground with a small amount of + current constantly flowing through the large + resistor from the external supply. In this + mode, no current is ever actually sourced + from the pin. */ + + INPUT, /**< Basic digital input. The pin voltage is sampled; when + it is closer to 3.3v (Vcc) the pin status is high, and + when it is closer to 0v (ground) it is low. If no + external circuit is pulling the pin voltage to high or + low, it will tend to randomly oscillate and be very + sensitive to noise (e.g., a breath of air across the pin + might cause the state to flip). */ + + INPUT_ANALOG, /**< This is a special mode for when the pin will be + used for analog (not digital) reads. Enables ADC + conversion to be performed on the voltage at the + pin. */ + + INPUT_PULLUP, /**< The state of the pin in this mode is reported + the same way as with INPUT, but the pin voltage + is gently "pulled up" towards +3.3v. This means + the state will be high unless an external device + is specifically pulling the pin down to ground, + in which case the "gentle" pull-up will not + affect the state of the input. */ + + INPUT_PULLDOWN, /**< The state of the pin in this mode is reported + the same way as with INPUT, but the pin voltage + is gently "pulled down" towards 0v. This means + the state will be low unless an external device + is specifically pulling the pin up to 3.3v, in + which case the "gentle" pull-down will not + affect the state of the input. */ + + INPUT_FLOATING, /**< Synonym for INPUT. */ + + PWM, /**< This is a special mode for when the pin will be used for + PWM output (a special case of digital output). */ + + PWM_OPEN_DRAIN, /**< Like PWM, except that instead of alternating + cycles of LOW and HIGH, the voltage on the pin + consists of alternating cycles of LOW and + floating (disconnected). */ +} WiringPinMode; + +/** + * Configure behavior of a GPIO pin. + * + * @param pin Number of pin to configure. + * @param mode Mode corresponding to desired pin behavior. + * @see WiringPinMode + */ +void pinMode(uint8 pin, WiringPinMode mode); + +/** + * Writes a (digital) value to a pin. The pin must have its + * mode set to OUTPUT or OUTPUT_OPEN_DRAIN. + * + * @param pin Pin to write to. + * @param value Either LOW (write a 0) or HIGH (write a 1). + * @see pinMode() + */ +void digitalWrite(uint8 pin, uint8 value); + +/** + * Read a digital value from a pin. The pin must have its mode set to + * one of INPUT, INPUT_PULLUP, and INPUT_PULLDOWN. + * + * @param pin Pin to read from. + * @return LOW or HIGH. + * @see pinMode() + */ +uint32 digitalRead(uint8 pin); + +/** + * Read an analog value from pin. This function blocks during ADC + * conversion, and has 12 bits of resolution. The pin must have its + * mode set to INPUT_ANALOG. + * + * @param pin Pin to read from. + * @return Converted voltage, in the range 0--4095, (i.e. a 12-bit ADC + * conversion). + * @see pinMode() + */ +uint16 analogRead(uint8 pin); + +/** + * Toggles the digital value at the given pin. + * + * The pin must have its mode set to OUTPUT. + * + * @param pin the pin to toggle. If the pin is HIGH, set it LOW. If + * it is LOW, set it HIGH. + * + * @see pinMode() + */ +void togglePin(uint8 pin); + +/** + * Toggle the LED. + * + * If the LED is on, turn it off. If it is off, turn it on. + * + * The LED must its mode set to OUTPUT. This can be accomplished + * portably over all LeafLabs boards by calling pinMode(BOARD_LED_PIN, + * OUTPUT) before calling this function. + * + * @see pinMode() + */ +static inline void toggleLED() { + togglePin(BOARD_LED_PIN); +} + +/** + * If the button is currently pressed, waits until the button is no + * longer being pressed, and returns true. Otherwise, returns false. + * + * The button pin must have its mode set to INPUT. This can be + * accomplished portably over all LeafLabs boards by calling + * pinMode(BOARD_BUTTON_PIN, INPUT). + * + * @see pinMode() + */ +uint8 isButtonPressed(); + +/** + * Wait until the button is pressed and released, timing out if no + * press occurs. + * + * The button pin must have its mode set to INPUT. This can be + * accomplished portably over all LeafLabs boards by calling + * pinMode(BOARD_BUTTON_PIN, INPUT). + * + * @param timeout_millis Number of milliseconds to wait until the + * button is pressed. If timeout_millis is left out (or 0), wait + * forever. + * + * @return true, if the button was pressed; false, if the timeout was + * reached. + * + * @see pinMode() + */ +uint8 waitForButtonPress(uint32 timeout_millis=0); + +/** + * Shift out a byte of data, one bit at a time. + * + * This function starts at either the most significant or least + * significant bit in a byte value, and shifts out each byte in order + * onto a data pin. After each bit is written to the data pin, a + * separate clock pin is pulsed to indicate that the new bit is + * available. + * + * @param dataPin Pin to shift data out on + * @param clockPin Pin to pulse after each bit is shifted out + * @param bitOrder Either MSBFIRST (big-endian) or LSBFIRST (little-endian). + * @param value Value to shift out + */ +void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 value); + +#endif + diff --git a/Libmaple/libmaple/wirish/main.cxx b/Libmaple/libmaple/wirish/main.cxx index 6b7b3825..9c0b9cc0 100644 --- a/Libmaple/libmaple/wirish/main.cxx +++ b/Libmaple/libmaple/wirish/main.cxx @@ -1,40 +1,40 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated objects that need libmaple may fail. - __attribute__(( constructor )) void premain() { - init(); -} - -int main(void) { - setup(); - - while (1) { - loop(); - } - return 0; -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. + __attribute__(( constructor )) void premain() { + init(); +} + +int main(void) { + setup(); + + while (1) { + loop(); + } + return 0; +} diff --git a/Libmaple/libmaple/wirish/pwm.cpp b/Libmaple/libmaple/wirish/pwm.cpp index b30ff5b4..1806348c 100644 --- a/Libmaple/libmaple/wirish/pwm.cpp +++ b/Libmaple/libmaple/wirish/pwm.cpp @@ -1,44 +1,44 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief Arduino-style PWM implementation. - */ - -#include "libmaple_types.h" -#include "timer.h" - -#include "boards.h" -#include "pwm.h" - -void pwmWrite(uint8 pin, uint16 duty_cycle) { - timer_dev *dev = PIN_MAP[pin].timer_device; - if (pin >= BOARD_NR_GPIO_PINS || dev == NULL || dev->type == TIMER_BASIC) { - return; - } - - timer_set_compare(dev, PIN_MAP[pin].timer_channel, duty_cycle); -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief Arduino-style PWM implementation. + */ + +#include "libmaple_types.h" +#include "timer.h" + +#include "boards.h" +#include "pwm.h" + +void pwmWrite(uint8 pin, uint16 duty_cycle) { + timer_dev *dev = PIN_MAP[pin].timer_device; + if (pin >= BOARD_NR_GPIO_PINS || dev == NULL || dev->type == TIMER_BASIC) { + return; + } + + timer_set_compare(dev, PIN_MAP[pin].timer_channel, duty_cycle); +} diff --git a/Libmaple/libmaple/wirish/pwm.h b/Libmaple/libmaple/wirish/pwm.h index f05e9e4e..6c53626d 100644 --- a/Libmaple/libmaple/wirish/pwm.h +++ b/Libmaple/libmaple/wirish/pwm.h @@ -1,55 +1,55 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file pwm.h - * - * @brief Arduino-compatible PWM interface. - */ - -#ifndef _PWM_H_ -#define _PWM_H_ - -/** - * As a convenience, analogWrite is an alias of pwmWrite to ease - * porting Arduino code. However, period and duty will have to be - * recalibrated. - */ -#define analogWrite pwmWrite - -/** - * Set the PWM duty on the given pin. - * - * User code is expected to determine and honor the maximum value - * (based on the configured period). - * - * @param pin PWM output pin - * @param duty_cycle Duty cycle to set. - */ -void pwmWrite(uint8 pin, uint16 duty_cycle); - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file pwm.h + * + * @brief Arduino-compatible PWM interface. + */ + +#ifndef _PWM_H_ +#define _PWM_H_ + +/** + * As a convenience, analogWrite is an alias of pwmWrite to ease + * porting Arduino code. However, period and duty will have to be + * recalibrated. + */ +#define analogWrite pwmWrite + +/** + * Set the PWM duty on the given pin. + * + * User code is expected to determine and honor the maximum value + * (based on the configured period). + * + * @param pin PWM output pin + * @param duty_cycle Duty cycle to set. + */ +void pwmWrite(uint8 pin, uint16 duty_cycle); + +#endif + diff --git a/Libmaple/libmaple/wirish/rules.mk b/Libmaple/libmaple/wirish/rules.mk index c47fb9eb..aa3b5279 100644 --- a/Libmaple/libmaple/wirish/rules.mk +++ b/Libmaple/libmaple/wirish/rules.mk @@ -1,54 +1,54 @@ -# Standard things -sp := $(sp).x -dirstack_$(sp) := $(d) -d := $(dir) -BUILDDIRS += $(BUILD_PATH)/$(d) -BUILDDIRS += $(BUILD_PATH)/$(d)/comm -BUILDDIRS += $(BUILD_PATH)/$(d)/boards - -WIRISH_INCLUDES := -I$(d) -I$(d)/comm -I$(d)/boards - -# Local flags -CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) - -# Local rules and targets -cSRCS_$(d) := - -cppSRCS_$(d) := wirish_math.cpp \ - Print.cpp \ - boards.cpp \ - boards/maple.cpp \ - boards/maple_mini.cpp \ - boards/maple_native.cpp \ - boards/maple_RET6.cpp \ - boards/aeroquad32.cpp \ - boards/aeroquad32mini.cpp \ - boards/discovery_f4.cpp \ - boards/freeflight.cpp \ - comm/HardwareSerial.cpp \ - comm/HardwareSPI.cpp \ - HardwareTimer.cpp \ - usb_serial.cpp \ - cxxabi-compat.cpp \ - wirish_shift.cpp \ - wirish_analog.cpp \ - wirish_time.cpp \ - pwm.cpp \ - ext_interrupts.cpp \ - wirish_digital.cpp - -cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) -cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) - -OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ - $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) -DEPS_$(d) := $(OBJS_$(d):%.o=%.d) - -$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) - -TGT_BIN += $(OBJS_$(d)) - -# Standard things --include $(DEPS_$(d)) -d := $(dirstack_$(sp)) -sp := $(basename $(sp)) +# Standard things +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) +BUILDDIRS += $(BUILD_PATH)/$(d) +BUILDDIRS += $(BUILD_PATH)/$(d)/comm +BUILDDIRS += $(BUILD_PATH)/$(d)/boards + +WIRISH_INCLUDES := -I$(d) -I$(d)/comm -I$(d)/boards + +# Local flags +CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) + +# Local rules and targets +cSRCS_$(d) := + +cppSRCS_$(d) := wirish_math.cpp \ + Print.cpp \ + boards.cpp \ + boards/maple.cpp \ + boards/maple_mini.cpp \ + boards/maple_native.cpp \ + boards/maple_RET6.cpp \ + boards/aeroquad32.cpp \ + boards/aeroquad32mini.cpp \ + boards/discovery_f4.cpp \ + boards/freeflight.cpp \ + comm/HardwareSerial.cpp \ + comm/HardwareSPI.cpp \ + HardwareTimer.cpp \ + usb_serial.cpp \ + cxxabi-compat.cpp \ + wirish_shift.cpp \ + wirish_analog.cpp \ + wirish_time.cpp \ + pwm.cpp \ + ext_interrupts.cpp \ + wirish_digital.cpp + +cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) + +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ + $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) +DEPS_$(d) := $(OBJS_$(d):%.o=%.d) + +$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) + +TGT_BIN += $(OBJS_$(d)) + +# Standard things +-include $(DEPS_$(d)) +d := $(dirstack_$(sp)) +sp := $(basename $(sp)) diff --git a/Libmaple/libmaple/wirish/usb_serial.cpp b/Libmaple/libmaple/wirish/usb_serial.cpp index dc510084..873e49dd 100644 --- a/Libmaple/libmaple/wirish/usb_serial.cpp +++ b/Libmaple/libmaple/wirish/usb_serial.cpp @@ -1,128 +1,128 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief USB virtual serial terminal - */ - -#include - -#include "wirish.h" -#include "usb.h" - -#define USB_TIMEOUT 50 - -USBSerial::USBSerial(void) { -} - -void USBSerial::begin(void) { - setupUSB(); -} - -void USBSerial::begin(int) { - setupUSB(); -} - -void USBSerial::end(void) { - disableUSB(); -} - -void USBSerial::write(uint8 ch) { - const uint8 buf[] = {ch}; - this->write(buf, 1); -} - -void USBSerial::write(const char *str) { - this->write(str, strlen(str)); -} - -void USBSerial::write(const void *buf, uint32 len) { - if (!(usbIsConnected() && usbIsConfigured()) || !buf) { - return; - } - - uint32 txed = 0; - uint32 old_txed = 0; - uint32 start = millis(); - - while (txed < len && (millis() - start < USB_TIMEOUT)) { - txed += usbSendBytes((const uint8*)buf + txed, len - txed); - if (old_txed != txed) { - start = millis(); - } - old_txed = txed; - } -} - -uint32 USBSerial::available(void) { - return usbBytesAvailable(); -} - -uint32 USBSerial::read(void *buf, uint32 len) { - if (!buf) { - return 0; - } - - uint32 rxed = 0; - while (rxed < len) { - rxed += usbReceiveBytes((uint8*)buf + rxed, len - rxed); - } - - return rxed; -} - -/* Blocks forever until 1 byte is received */ -uint8 USBSerial::read(void) { - uint8 buf[1]; - this->read(buf, 1); - return buf[0]; -} - -uint8 USBSerial::pending(void) { - return usbGetPending(); -} - -uint8 USBSerial::isConnected(void) { - return usbIsConnected() && usbIsConfigured(); -} - -uint8 USBSerial::getDTR(void) { - return usbGetDTR(); -} - -uint8 USBSerial::getRTS(void) { - return usbGetRTS(); -} - -void USBSerial::enableBlockingTx(void) { - usbEnableBlockingTx(); -} - -void USBSerial::disableBlockingTx(void) { - usbEnableBlockingTx(); -} - -USBSerial SerialUSB; +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief USB virtual serial terminal + */ + +#include + +#include "wirish.h" +#include "usb.h" + +#define USB_TIMEOUT 50 + +USBSerial::USBSerial(void) { +} + +void USBSerial::begin(void) { + setupUSB(); +} + +void USBSerial::begin(int) { + setupUSB(); +} + +void USBSerial::end(void) { + disableUSB(); +} + +void USBSerial::write(uint8 ch) { + const uint8 buf[] = {ch}; + this->write(buf, 1); +} + +void USBSerial::write(const char *str) { + this->write(str, strlen(str)); +} + +void USBSerial::write(const void *buf, uint32 len) { + if (!(usbIsConnected() && usbIsConfigured()) || !buf) { + return; + } + + uint32 txed = 0; + uint32 old_txed = 0; + uint32 start = millis(); + + while (txed < len && (millis() - start < USB_TIMEOUT)) { + txed += usbSendBytes((const uint8*)buf + txed, len - txed); + if (old_txed != txed) { + start = millis(); + } + old_txed = txed; + } +} + +uint32 USBSerial::available(void) { + return usbBytesAvailable(); +} + +uint32 USBSerial::read(void *buf, uint32 len) { + if (!buf) { + return 0; + } + + uint32 rxed = 0; + while (rxed < len) { + rxed += usbReceiveBytes((uint8*)buf + rxed, len - rxed); + } + + return rxed; +} + +/* Blocks forever until 1 byte is received */ +uint8 USBSerial::read(void) { + uint8 buf[1]; + this->read(buf, 1); + return buf[0]; +} + +uint8 USBSerial::pending(void) { + return usbGetPending(); +} + +uint8 USBSerial::isConnected(void) { + return usbIsConnected() && usbIsConfigured(); +} + +uint8 USBSerial::getDTR(void) { + return usbGetDTR(); +} + +uint8 USBSerial::getRTS(void) { + return usbGetRTS(); +} + +void USBSerial::enableBlockingTx(void) { + usbEnableBlockingTx(); +} + +void USBSerial::disableBlockingTx(void) { + usbEnableBlockingTx(); +} + +USBSerial SerialUSB; diff --git a/Libmaple/libmaple/wirish/usb_serial.h b/Libmaple/libmaple/wirish/usb_serial.h index 42034a4b..ce333025 100644 --- a/Libmaple/libmaple/wirish/usb_serial.h +++ b/Libmaple/libmaple/wirish/usb_serial.h @@ -1,68 +1,68 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief Wirish virtual serial port - */ - -#ifndef _USB_SERIAL_H_ -#define _USB_SERIAL_H_ - -#include "Print.h" - -/** - * @brief Virtual serial terminal. - */ -class USBSerial : public Print { -public: - USBSerial(void); - - void begin(void); - void begin(int); - void end(void); - - uint32 available(void); - - uint32 read(void *buf, uint32 len); - uint8 read(void); - - void write(uint8); - void write(const char *str); - void write(const void*, uint32); - - uint8 getRTS(); - uint8 getDTR(); - uint8 isConnected(); - uint8 pending(); - - void enableBlockingTx(void); - void disableBlockingTx(void); -}; - -extern USBSerial SerialUSB; - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief Wirish virtual serial port + */ + +#ifndef _USB_SERIAL_H_ +#define _USB_SERIAL_H_ + +#include "Print.h" + +/** + * @brief Virtual serial terminal. + */ +class USBSerial : public Print { +public: + USBSerial(void); + + void begin(void); + void begin(int); + void end(void); + + uint32 available(void); + + uint32 read(void *buf, uint32 len); + uint8 read(void); + + void write(uint8); + void write(const char *str); + void write(const void*, uint32); + + uint8 getRTS(); + uint8 getDTR(); + uint8 isConnected(); + uint8 pending(); + + void enableBlockingTx(void); + void disableBlockingTx(void); +}; + +extern USBSerial SerialUSB; + +#endif + diff --git a/Libmaple/libmaple/wirish/wirish.h b/Libmaple/libmaple/wirish/wirish.h index ec7662be..6be84232 100644 --- a/Libmaple/libmaple/wirish/wirish.h +++ b/Libmaple/libmaple/wirish/wirish.h @@ -1,75 +1,75 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief Main include file for the Wirish core. - * - * Includes various Arduino wiring macros and bit defines - */ - -#ifndef _WIRISH_H_ -#define _WIRISH_H_ - -#include "libmaple.h" - -#include "wirish_types.h" -#include "boards.h" -#include "io.h" -#include "bits.h" -#include "pwm.h" -#include "ext_interrupts.h" -#include "wirish_debug.h" -#include "wirish_math.h" -#include "wirish_time.h" -#include "HardwareSPI.h" -#include "HardwareSerial.h" -#include "HardwareTimer.h" -#include "usb_serial.h" - -/* Arduino wiring macros and bit defines */ -#define HIGH 0x1 -#define LOW 0x0 - -#define true 0x1 -#define false 0x0 - -#define LSBFIRST 0 -#define MSBFIRST 1 - -#define lowByte(w) ((w) & 0xFF) -#define highByte(w) (((w) >> 8) & 0xFF) -#define bitRead(value, bit) (((value) >> (bit)) & 0x01) -#define bitSet(value, bit) ((value) |= (1UL << (bit))) -#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) -#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : \ - bitClear(value, bit)) -#define bit(b) (1UL << (b)) - -typedef uint8 boolean; -typedef uint8 byte; - -#endif - +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief Main include file for the Wirish core. + * + * Includes various Arduino wiring macros and bit defines + */ + +#ifndef _WIRISH_H_ +#define _WIRISH_H_ + +#include "libmaple.h" + +#include "wirish_types.h" +#include "boards.h" +#include "io.h" +#include "bits.h" +#include "pwm.h" +#include "ext_interrupts.h" +#include "wirish_debug.h" +#include "wirish_math.h" +#include "wirish_time.h" +#include "HardwareSPI.h" +#include "HardwareSerial.h" +#include "HardwareTimer.h" +#include "usb_serial.h" + +/* Arduino wiring macros and bit defines */ +#define HIGH 0x1 +#define LOW 0x0 + +#define true 0x1 +#define false 0x0 + +#define LSBFIRST 0 +#define MSBFIRST 1 + +#define lowByte(w) ((w) & 0xFF) +#define highByte(w) (((w) >> 8) & 0xFF) +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : \ + bitClear(value, bit)) +#define bit(b) (1UL << (b)) + +typedef uint8 boolean; +typedef uint8 byte; + +#endif + diff --git a/Libmaple/libmaple/wirish/wirish_analog.cpp b/Libmaple/libmaple/wirish/wirish_analog.cpp index e068a8cc..63b5eb2d 100644 --- a/Libmaple/libmaple/wirish/wirish_analog.cpp +++ b/Libmaple/libmaple/wirish/wirish_analog.cpp @@ -1,44 +1,44 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief Arduino-compatible ADC implementation. - */ - -#include "libmaple.h" -#include "wirish.h" -#include "io.h" - -/* Assumes that the ADC has been initialized and that the pin is set - * to INPUT_ANALOG */ -uint16 analogRead(uint8 pin) { - const adc_dev *dev = PIN_MAP[pin].adc_device; - if (dev == NULL) { - return 0; - } - - return adc_read(dev, PIN_MAP[pin].adc_channel); -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief Arduino-compatible ADC implementation. + */ + +#include "libmaple.h" +#include "wirish.h" +#include "io.h" + +/* Assumes that the ADC has been initialized and that the pin is set + * to INPUT_ANALOG */ +uint16 analogRead(uint8 pin) { + const adc_dev *dev = PIN_MAP[pin].adc_device; + if (dev == NULL) { + return 0; + } + + return adc_read(dev, PIN_MAP[pin].adc_channel); +} diff --git a/Libmaple/libmaple/wirish/wirish_debug.h b/Libmaple/libmaple/wirish/wirish_debug.h index f2b6e771..d4c0bab4 100644 --- a/Libmaple/libmaple/wirish/wirish_debug.h +++ b/Libmaple/libmaple/wirish/wirish_debug.h @@ -1,54 +1,54 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish_debug.h - * @brief High level debug port configuration - */ - -/** - * @brief Disable the JTAG and Serial Wire (SW) debug ports. - * - * You can call this function in order to use the JTAG and SW debug - * pins as ordinary GPIOs. - * - * @see enableDebugPorts() - */ -static inline void disableDebugPorts(void) { - afio_cfg_debug_ports(AFIO_DEBUG_NONE); -} - -/** - * @brief Enable the JTAG and Serial Wire (SW) debug ports. - * - * After you call this function, the JTAG and SW debug pins will no - * longer be usable as GPIOs. - * - * @see disableDebugPorts() - */ -static inline void enableDebugPorts(void) { - afio_cfg_debug_ports(AFIO_DEBUG_FULL_SWJ); -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file wirish_debug.h + * @brief High level debug port configuration + */ + +/** + * @brief Disable the JTAG and Serial Wire (SW) debug ports. + * + * You can call this function in order to use the JTAG and SW debug + * pins as ordinary GPIOs. + * + * @see enableDebugPorts() + */ +static inline void disableDebugPorts(void) { + afio_cfg_debug_ports(AFIO_DEBUG_NONE); +} + +/** + * @brief Enable the JTAG and Serial Wire (SW) debug ports. + * + * After you call this function, the JTAG and SW debug pins will no + * longer be usable as GPIOs. + * + * @see disableDebugPorts() + */ +static inline void enableDebugPorts(void) { + afio_cfg_debug_ports(AFIO_DEBUG_FULL_SWJ); +} diff --git a/Libmaple/libmaple/wirish/wirish_digital.cpp b/Libmaple/libmaple/wirish/wirish_digital.cpp index 26eaff6a..a8b3ad81 100644 --- a/Libmaple/libmaple/wirish/wirish_digital.cpp +++ b/Libmaple/libmaple/wirish/wirish_digital.cpp @@ -1,141 +1,141 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/* - * Arduino-compatible digital I/O implementation. - */ - -#include "wirish.h" -#include "io.h" - -void pinMode(uint8 pin, WiringPinMode mode) { - gpio_pin_mode outputMode; - boolean pwm = false; - - if (pin >= BOARD_NR_GPIO_PINS) { - return; - } - - switch(mode) { - case OUTPUT: - outputMode = GPIO_OUTPUT_PP; - break; - case OUTPUT_OPEN_DRAIN: - outputMode = GPIO_OUTPUT_OD; - break; - case INPUT: - case INPUT_FLOATING: - outputMode = GPIO_INPUT_FLOATING; - break; - case INPUT_ANALOG: - outputMode = GPIO_INPUT_ANALOG; - break; - case INPUT_PULLUP: - outputMode = GPIO_INPUT_PU; - break; - case INPUT_PULLDOWN: - outputMode = GPIO_INPUT_PD; - break; - case PWM: - outputMode = GPIO_AF_OUTPUT_PP; - pwm = true; - break; - case PWM_OPEN_DRAIN: - outputMode = GPIO_AF_OUTPUT_OD; - pwm = true; - break; - default: - ASSERT(0); - return; - } - - gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, outputMode); - - if (PIN_MAP[pin].timer_device != NULL) { - /* Enable/disable timer channels if we're switching into or - * out of PWM. */ - timer_set_mode(PIN_MAP[pin].timer_device, - PIN_MAP[pin].timer_channel, - pwm ? TIMER_PWM : TIMER_DISABLED); - } -} - - -uint32 digitalRead(uint8 pin) { - if (pin >= BOARD_NR_GPIO_PINS) { - return 0; - } - - return gpio_read_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit) ? - HIGH : LOW; -} - -void digitalWrite(uint8 pin, uint8 val) { - if (pin >= BOARD_NR_GPIO_PINS) { - return; - } - - gpio_write_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, val); -} - -void togglePin(uint8 pin) { - if (pin >= BOARD_NR_GPIO_PINS) { - return; - } - - gpio_toggle_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit); -} - -#define BUTTON_DEBOUNCE_DELAY 1 - -uint8 isButtonPressed() { - if (digitalRead(BOARD_BUTTON_PIN)) { - delay(BUTTON_DEBOUNCE_DELAY); - while (digitalRead(BOARD_BUTTON_PIN)) - ; - return true; - } - return false; -} - -uint8 waitForButtonPress(uint32 timeout) { - uint32 start = millis(); - uint32 time; - if (timeout == 0) { - while (!isButtonPressed()) - ; - return true; - } - do { - time = millis(); - /* properly handle wrap-around */ - if ((start > time && time + (0xffffffffU - start) > timeout) || - time - start > timeout) { - return false; - } - } while (!isButtonPressed()); - return true; -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/* + * Arduino-compatible digital I/O implementation. + */ + +#include "wirish.h" +#include "io.h" + +void pinMode(uint8 pin, WiringPinMode mode) { + gpio_pin_mode outputMode; + boolean pwm = false; + + if (pin >= BOARD_NR_GPIO_PINS) { + return; + } + + switch(mode) { + case OUTPUT: + outputMode = GPIO_OUTPUT_PP; + break; + case OUTPUT_OPEN_DRAIN: + outputMode = GPIO_OUTPUT_OD; + break; + case INPUT: + case INPUT_FLOATING: + outputMode = GPIO_INPUT_FLOATING; + break; + case INPUT_ANALOG: + outputMode = GPIO_INPUT_ANALOG; + break; + case INPUT_PULLUP: + outputMode = GPIO_INPUT_PU; + break; + case INPUT_PULLDOWN: + outputMode = GPIO_INPUT_PD; + break; + case PWM: + outputMode = GPIO_AF_OUTPUT_PP; + pwm = true; + break; + case PWM_OPEN_DRAIN: + outputMode = GPIO_AF_OUTPUT_OD; + pwm = true; + break; + default: + ASSERT(0); + return; + } + + gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, outputMode); + + if (PIN_MAP[pin].timer_device != NULL) { + /* Enable/disable timer channels if we're switching into or + * out of PWM. */ + timer_set_mode(PIN_MAP[pin].timer_device, + PIN_MAP[pin].timer_channel, + pwm ? TIMER_PWM : TIMER_DISABLED); + } +} + + +uint32 digitalRead(uint8 pin) { + if (pin >= BOARD_NR_GPIO_PINS) { + return 0; + } + + return gpio_read_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit) ? + HIGH : LOW; +} + +void digitalWrite(uint8 pin, uint8 val) { + if (pin >= BOARD_NR_GPIO_PINS) { + return; + } + + gpio_write_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, val); +} + +void togglePin(uint8 pin) { + if (pin >= BOARD_NR_GPIO_PINS) { + return; + } + + gpio_toggle_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit); +} + +#define BUTTON_DEBOUNCE_DELAY 1 + +uint8 isButtonPressed() { + if (digitalRead(BOARD_BUTTON_PIN)) { + delay(BUTTON_DEBOUNCE_DELAY); + while (digitalRead(BOARD_BUTTON_PIN)) + ; + return true; + } + return false; +} + +uint8 waitForButtonPress(uint32 timeout) { + uint32 start = millis(); + uint32 time; + if (timeout == 0) { + while (!isButtonPressed()) + ; + return true; + } + do { + time = millis(); + /* properly handle wrap-around */ + if ((start > time && time + (0xffffffffU - start) > timeout) || + time - start > timeout) { + return false; + } + } while (!isButtonPressed()); + return true; +} diff --git a/Libmaple/libmaple/wirish/wirish_math.cpp b/Libmaple/libmaple/wirish/wirish_math.cpp index db68e02b..5aa65103 100644 --- a/Libmaple/libmaple/wirish/wirish_math.cpp +++ b/Libmaple/libmaple/wirish/wirish_math.cpp @@ -1,49 +1,49 @@ -/* - * Modified by LeafLabs, LLC. - * - * Part of the Wiring project - http://wiring.org.co Copyright (c) - * 2004-06 Hernando Barragan Modified 13 August 2006, David A. Mellis - * for Arduino - http://www.arduino.cc/ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include -#include "math.h" - -void randomSeed(unsigned int seed) { - if (seed != 0) { - srand(seed); - } -} - -long random(long howbig) { - if (howbig == 0) { - return 0; - } - - return rand() % howbig; -} - -long random(long howsmall, long howbig) { - if (howsmall >= howbig) { - return howsmall; - } - - long diff = howbig - howsmall; - return random(diff) + howsmall; -} - +/* + * Modified by LeafLabs, LLC. + * + * Part of the Wiring project - http://wiring.org.co Copyright (c) + * 2004-06 Hernando Barragan Modified 13 August 2006, David A. Mellis + * for Arduino - http://www.arduino.cc/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include +#include "math.h" + +void randomSeed(unsigned int seed) { + if (seed != 0) { + srand(seed); + } +} + +long random(long howbig) { + if (howbig == 0) { + return 0; + } + + return rand() % howbig; +} + +long random(long howsmall, long howbig) { + if (howsmall >= howbig) { + return howsmall; + } + + long diff = howbig - howsmall; + return random(diff) + howsmall; +} + diff --git a/Libmaple/libmaple/wirish/wirish_math.h b/Libmaple/libmaple/wirish/wirish_math.h index c9010065..a85b30ad 100644 --- a/Libmaple/libmaple/wirish/wirish_math.h +++ b/Libmaple/libmaple/wirish/wirish_math.h @@ -1,151 +1,151 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish_math.h - * @brief Includes ; provides Arduino-compatible math routines. - */ - -#ifndef _WIRING_MATH_H_ -#define _WIRING_MATH_H_ - -#include - -/** - * @brief Initialize the pseudo-random number generator. - * @param seed the number used to initialize the seed; cannot be zero. - */ -void randomSeed(unsigned int seed); - -/** - * @brief Generate a pseudo-random number with upper bound. - * @param max An upper bound on the returned value, exclusive. - * @return A pseudo-random number in the range [0,max). - * @see randomSeed() - */ -long random(long max); - -/** - * @brief Generate a pseudo-random number with lower and upper bounds. - * @param min Lower bound on the returned value, inclusive. - * @param max Upper bound on the returned value, exclusive. - * @return A pseudo-random number in the range [min, max). - * @see randomSeed() - */ -long random(long min, long max); - -/** - * @brief Remap a number from one range to another. - * - * That is, a value equal to fromStart gets mapped to toStart, a value - * of fromEnd to toEnd, and other values are mapped proportionately. - * - * Does not constrain value to lie within [fromStart, fromEnd]. - * - * If a "start" value is larger than its corresponding "end", the - * ranges are reversed, so map(n, 1, 10, 10, 1) would reverse the - * range [1,10]. - * - * Negative numbers may appear as any argument. - * - * @param value the value to map. - * @param fromStart the beginning of the value's current range. - * @param fromEnd the end of the value's current range. - * @param toStart the beginning of the value's mapped range. - * @param toEnd the end of the value's mapped range. - * @return the mapped value. - */ -static inline long map(long value, long fromStart, long fromEnd, - long toStart, long toEnd) { - return (value - fromStart) * (toEnd - toStart) / (fromEnd - fromStart) + - toStart; -} - -#define PI 3.1415926535897932384626433832795 -#define HALF_PI 1.5707963267948966192313216916398 -#define TWO_PI 6.283185307179586476925286766559 -#define DEG_TO_RAD 0.017453292519943295769236907684886 -#define RAD_TO_DEG 57.295779513082320876798154814105 - -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) -#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) -#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) -#define radians(deg) ((deg)*DEG_TO_RAD) -#define degrees(rad) ((rad)*RAD_TO_DEG) -#define sq(x) ((x)*(x)) - -/* undefine stdlib's abs if encountered */ -#ifdef abs -#undef abs -#endif -#define abs(x) (((x) > 0) ? (x) : -(x)) - -/* Following are duplicate declarations (with Doxygen comments) for - * some of the math.h functions; this is for the convenience of the - * Sphinx docs. - */ - -/** - * Compute the cosine of an angle, in radians. - * @param x The radian measure of the angle. - * @return The cosine of x. This value will be between -1 and 1. - */ -double cos(double x); - -/** - * Compute the sine of an angle, in radians. - * @param x The radian measure of the angle. - * @return The sine of x. This value will be between -1 and 1. - */ -double sin(double x); - -/** - * Compute the tangent of an angle, in radians. - * @param x The radian measure of the angle. - * @return The tangent of x. There are no limits on the return value - * of this function. - */ -double tan(double x); - -/** - * Compute the square root of a number. - * @param x The number whose square root to find. This value cannot - * be negative. - * @return The square root of x. The return value is never negative. - */ -double sqrt(double x); - -/** - * Compute an exponentiation. - * @param x the base. This value cannot be zero if y <= 0. This value - * cannot be negative if y is not an integral value. - * @param y the exponent. - * @return x raised to the power y. - */ -double pow(double x, double y); - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file wirish_math.h + * @brief Includes ; provides Arduino-compatible math routines. + */ + +#ifndef _WIRING_MATH_H_ +#define _WIRING_MATH_H_ + +#include + +/** + * @brief Initialize the pseudo-random number generator. + * @param seed the number used to initialize the seed; cannot be zero. + */ +void randomSeed(unsigned int seed); + +/** + * @brief Generate a pseudo-random number with upper bound. + * @param max An upper bound on the returned value, exclusive. + * @return A pseudo-random number in the range [0,max). + * @see randomSeed() + */ +long random(long max); + +/** + * @brief Generate a pseudo-random number with lower and upper bounds. + * @param min Lower bound on the returned value, inclusive. + * @param max Upper bound on the returned value, exclusive. + * @return A pseudo-random number in the range [min, max). + * @see randomSeed() + */ +long random(long min, long max); + +/** + * @brief Remap a number from one range to another. + * + * That is, a value equal to fromStart gets mapped to toStart, a value + * of fromEnd to toEnd, and other values are mapped proportionately. + * + * Does not constrain value to lie within [fromStart, fromEnd]. + * + * If a "start" value is larger than its corresponding "end", the + * ranges are reversed, so map(n, 1, 10, 10, 1) would reverse the + * range [1,10]. + * + * Negative numbers may appear as any argument. + * + * @param value the value to map. + * @param fromStart the beginning of the value's current range. + * @param fromEnd the end of the value's current range. + * @param toStart the beginning of the value's mapped range. + * @param toEnd the end of the value's mapped range. + * @return the mapped value. + */ +static inline long map(long value, long fromStart, long fromEnd, + long toStart, long toEnd) { + return (value - fromStart) * (toEnd - toStart) / (fromEnd - fromStart) + + toStart; +} + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +/* undefine stdlib's abs if encountered */ +#ifdef abs +#undef abs +#endif +#define abs(x) (((x) > 0) ? (x) : -(x)) + +/* Following are duplicate declarations (with Doxygen comments) for + * some of the math.h functions; this is for the convenience of the + * Sphinx docs. + */ + +/** + * Compute the cosine of an angle, in radians. + * @param x The radian measure of the angle. + * @return The cosine of x. This value will be between -1 and 1. + */ +double cos(double x); + +/** + * Compute the sine of an angle, in radians. + * @param x The radian measure of the angle. + * @return The sine of x. This value will be between -1 and 1. + */ +double sin(double x); + +/** + * Compute the tangent of an angle, in radians. + * @param x The radian measure of the angle. + * @return The tangent of x. There are no limits on the return value + * of this function. + */ +double tan(double x); + +/** + * Compute the square root of a number. + * @param x The number whose square root to find. This value cannot + * be negative. + * @return The square root of x. The return value is never negative. + */ +double sqrt(double x); + +/** + * Compute an exponentiation. + * @param x the base. This value cannot be zero if y <= 0. This value + * cannot be negative if y is not an integral value. + * @param y the exponent. + * @return x raised to the power y. + */ +double pow(double x, double y); + +#endif diff --git a/Libmaple/libmaple/wirish/wirish_shift.cpp b/Libmaple/libmaple/wirish/wirish_shift.cpp index 43247b56..f67364d1 100644 --- a/Libmaple/libmaple/wirish/wirish_shift.cpp +++ b/Libmaple/libmaple/wirish/wirish_shift.cpp @@ -1,40 +1,40 @@ -/* - * wiring_shift.c - shiftOut() function - * Part of Arduino - http://www.arduino.cc/ - * - * Copyright (c) 2005-2006 David A. Mellis - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - * - * $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ - */ - -#include "wirish.h" - -void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 val) { - int i; - - for (i = 0; i < 8; i++) { - if (bitOrder == LSBFIRST) { - digitalWrite(dataPin, !!(val & (1 << i))); - } else { - digitalWrite(dataPin, !!(val & (1 << (7 - i)))); - } - - digitalWrite(clockPin, HIGH); - digitalWrite(clockPin, LOW); - } -} +/* + * wiring_shift.c - shiftOut() function + * Part of Arduino - http://www.arduino.cc/ + * + * Copyright (c) 2005-2006 David A. Mellis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ + */ + +#include "wirish.h" + +void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 val) { + int i; + + for (i = 0; i < 8; i++) { + if (bitOrder == LSBFIRST) { + digitalWrite(dataPin, !!(val & (1 << i))); + } else { + digitalWrite(dataPin, !!(val & (1 << (7 - i)))); + } + + digitalWrite(clockPin, HIGH); + digitalWrite(clockPin, LOW); + } +} diff --git a/Libmaple/libmaple/wirish/wirish_time.cpp b/Libmaple/libmaple/wirish/wirish_time.cpp index e9083bd7..270da28a 100644 --- a/Libmaple/libmaple/wirish/wirish_time.cpp +++ b/Libmaple/libmaple/wirish/wirish_time.cpp @@ -1,45 +1,45 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @brief Delay implementation. - */ - -#include "libmaple.h" -#include "systick.h" -#include "wirish_time.h" -#include "delay.h" - -void delay(unsigned long ms) { - uint32 i; - for (i = 0; i < ms; i++) { - delayMicroseconds(1000); - } -} - -void delayMicroseconds(uint32 us) { - delay_us(us); -} +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @brief Delay implementation. + */ + +#include "libmaple.h" +#include "systick.h" +#include "wirish_time.h" +#include "delay.h" + +void delay(unsigned long ms) { + uint32 i; + for (i = 0; i < ms; i++) { + delayMicroseconds(1000); + } +} + +void delayMicroseconds(uint32 us) { + delay_us(us); +} diff --git a/Libmaple/libmaple/wirish/wirish_time.h b/Libmaple/libmaple/wirish/wirish_time.h index c1e723ee..20a2fbfc 100644 --- a/Libmaple/libmaple/wirish/wirish_time.h +++ b/Libmaple/libmaple/wirish/wirish_time.h @@ -1,105 +1,105 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish_time.h - * @brief Timing and delay functions. - */ - -#ifndef __WIRISH_TIME_H_ -#define __WIRISH_TIME_H_ - -#include "libmaple.h" -#include "nvic.h" -#include "systick.h" -#include "boards.h" - -#define US_PER_MS 1000 - -/** - * Returns time (in milliseconds) since the beginning of program - * execution. On overflow, restarts at 0. - * @see micros() - */ -static inline uint32 millis(void) { - return systick_uptime(); -} - -/** - * Returns time (in microseconds) since the beginning of program - * execution. On overflow, restarts at 0. - * @see millis() - */ -static inline uint32 micros(void) { - uint32 ms; - uint32 cycle_cnt; - uint32 res; - - do { - ms = millis(); - cycle_cnt = systick_get_count(); - asm volatile("nop"); //allow interrupt to fire - asm volatile("nop"); - } while (ms != millis()); - - if(systick_check_underflow()) { - ms++; - cycle_cnt = systick_get_count(); - } - - /* SYSTICK_RELOAD_VAL is 1 less than the number of cycles it - actually takes to complete a SysTick reload */ - res = (ms * US_PER_MS) + - (SYSTICK_RELOAD_VAL + 1 - cycle_cnt) / CYCLES_PER_MICROSECOND; - - return res; -} - -/** - * Delay for at least the given number of milliseconds. - * - * Interrupts, etc. may cause the actual number of milliseconds to - * exceed ms. However, this function will return no less than ms - * milliseconds from the time it is called. - * - * @param ms the number of milliseconds to delay. - * @see delayMicroseconds() - */ -void delay(unsigned long ms); - -/** - * Delay for at least the given number of microseconds. - * - * Interrupts, etc. may cause the actual number of microseconds to - * exceed us. However, this function will return no less than us - * microseconds from the time it is called. - * - * @param us the number of microseconds to delay. - * @see delay() - */ -void delayMicroseconds(uint32 us); - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file wirish_time.h + * @brief Timing and delay functions. + */ + +#ifndef __WIRISH_TIME_H_ +#define __WIRISH_TIME_H_ + +#include "libmaple.h" +#include "nvic.h" +#include "systick.h" +#include "boards.h" + +#define US_PER_MS 1000 + +/** + * Returns time (in milliseconds) since the beginning of program + * execution. On overflow, restarts at 0. + * @see micros() + */ +static inline uint32 millis(void) { + return systick_uptime(); +} + +/** + * Returns time (in microseconds) since the beginning of program + * execution. On overflow, restarts at 0. + * @see millis() + */ +static inline uint32 micros(void) { + uint32 ms; + uint32 cycle_cnt; + uint32 res; + + do { + ms = millis(); + cycle_cnt = systick_get_count(); + asm volatile("nop"); //allow interrupt to fire + asm volatile("nop"); + } while (ms != millis()); + + if(systick_check_underflow()) { + ms++; + cycle_cnt = systick_get_count(); + } + + /* SYSTICK_RELOAD_VAL is 1 less than the number of cycles it + actually takes to complete a SysTick reload */ + res = (ms * US_PER_MS) + + (SYSTICK_RELOAD_VAL + 1 - cycle_cnt) / CYCLES_PER_MICROSECOND; + + return res; +} + +/** + * Delay for at least the given number of milliseconds. + * + * Interrupts, etc. may cause the actual number of milliseconds to + * exceed ms. However, this function will return no less than ms + * milliseconds from the time it is called. + * + * @param ms the number of milliseconds to delay. + * @see delayMicroseconds() + */ +void delay(unsigned long ms); + +/** + * Delay for at least the given number of microseconds. + * + * Interrupts, etc. may cause the actual number of microseconds to + * exceed us. However, this function will return no less than us + * microseconds from the time it is called. + * + * @param us the number of microseconds to delay. + * @see delay() + */ +void delayMicroseconds(uint32 us); + +#endif diff --git a/Libmaple/libmaple/wirish/wirish_types.h b/Libmaple/libmaple/wirish/wirish_types.h index d0b33c5c..a3c260a7 100644 --- a/Libmaple/libmaple/wirish/wirish_types.h +++ b/Libmaple/libmaple/wirish/wirish_types.h @@ -1,66 +1,66 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2011 LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -/** - * @file wirish_types.h - * @author Marti Bolivar - * @brief Wirish library type definitions. - */ - -#include "libmaple_types.h" -#include "gpio.h" -#include "timer.h" -#include "adc.h" - -#ifndef _WIRISH_TYPES_H_ -#define _WIRISH_TYPES_H_ - -/** - * Invalid stm32_pin_info adc_channel value. - * @see stm32_pin_info - */ -#define ADCx 0xFF - -/** - * @brief Stores STM32-specific information related to a given Maple pin. - * @see PIN_MAP - */ -typedef struct stm32_pin_info { - gpio_dev *gpio_device; /**< Maple pin's GPIO device */ - timer_dev *timer_device; /**< Pin's timer device, if any. */ - const adc_dev *adc_device; /**< ADC device, if any. */ - uint8 gpio_bit; /**< Pin's GPIO port bit. */ - uint8 timer_channel; /**< Timer channel, or 0 if none. */ - uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ - uint8 filler; -} stm32_pin_info; - -/** - * Variable attribute, instructs the linker to place the marked - * variable in Flash instead of RAM. */ -#define __FLASH__ __attr_flash - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file wirish_types.h + * @author Marti Bolivar + * @brief Wirish library type definitions. + */ + +#include "libmaple_types.h" +#include "gpio.h" +#include "timer.h" +#include "adc.h" + +#ifndef _WIRISH_TYPES_H_ +#define _WIRISH_TYPES_H_ + +/** + * Invalid stm32_pin_info adc_channel value. + * @see stm32_pin_info + */ +#define ADCx 0xFF + +/** + * @brief Stores STM32-specific information related to a given Maple pin. + * @see PIN_MAP + */ +typedef struct stm32_pin_info { + gpio_dev *gpio_device; /**< Maple pin's GPIO device */ + timer_dev *timer_device; /**< Pin's timer device, if any. */ + const adc_dev *adc_device; /**< ADC device, if any. */ + uint8 gpio_bit; /**< Pin's GPIO port bit. */ + uint8 timer_channel; /**< Timer channel, or 0 if none. */ + uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */ + uint8 filler; +} stm32_pin_info; + +/** + * Variable attribute, instructs the linker to place the marked + * variable in Flash instead of RAM. */ +#define __FLASH__ __attr_flash + +#endif diff --git a/Libmaple/maple-bootloader/.gitignore b/Libmaple/maple-bootloader/.gitignore index 5a883b71..af85d0d0 100644 --- a/Libmaple/maple-bootloader/.gitignore +++ b/Libmaple/maple-bootloader/.gitignore @@ -1,5 +1,5 @@ -.dep -TAGS -tags -cscope.out -build +.dep +TAGS +tags +cscope.out +build diff --git a/Libmaple/maple-bootloader/Makefile b/Libmaple/maple-bootloader/Makefile index 0f32b306..7c0503d8 100644 --- a/Libmaple/maple-bootloader/Makefile +++ b/Libmaple/maple-bootloader/Makefile @@ -1,264 +1,264 @@ -# Makefile skeleton adapted from Peter Harrison's - www.micromouse.com - -# MCU name and submodel -MCU = cortex-m3 -SUBMDL = stm32f103 -#CPUCLASS = STM32F1 -CPUCLASS = STM32F2 - -#BOARD = aeroquad32mini -#MEMORY = flash128k_ram20k -BOARD = aeroquad32 -#BOARD = DiscoveryF4 -MEMORY = flash512k_ram64k - - - - -# toolchain (using code sourcery now) -TCHAIN = arm-none-eabi -THUMB = -mthumb -THUMB_IW = -mthumb-interwork - -# Target file name (without extension). -BUILDDIR = build -TARGET = $(BUILDDIR)/maple_boot - -ST_LIB = stm32_lib -ST_USB = usb_lib - -# Optimization level [0,1,2,3,s] -OPT = 0 -DEBUG = -g -#DEBUG = dwarf-2 - -INCDIRS = ./$(ST_LIB) ./$(ST_USB) - -CFLAGS = $(DEBUG) -CFLAGS += -O$(OPT) -CFLAGS += -ffunction-sections -fdata-sections -CFLAGS += -Wall -Wimplicit -CFLAGS += -Wcast-align -CFLAGS += -Wpointer-arith -Wswitch -CFLAGS += -Wredundant-decls -Wreturn-type -Wshadow -Wunused -CFLAGS += -Wa,-adhlns=$(BUILDDIR)/$(subst $(suffix $<),.lst,$<) -CFLAGS += $(patsubst %,-I%,$(INCDIRS)) -CFLAGS += -D$(CPUCLASS) -CFLAGS += -DBOARD_$(BOARD) -CFLAGS += -DFASTSTART -#CFLAGS += -DUSB_DISC_OD - -# Assembler Flags -ASFLAGS = -Wa,-adhlns=$(BUILDDIR)/$(<:.s=.lst)#,--g$(DEBUG) - -LDFLAGS = -nostartfiles -Wl,-Map=$(TARGET).map,--cref,--gc-sections -LDFLAGS += -lc -lgcc - -# Set the linker script -LDFLAGS +=-T$(ST_LIB)/c_only_md_$(MEMORY).ld - -# Define programs and commands. -SHELL = sh -CC = $(TCHAIN)-gcc -CPP = $(TCHAIN)-g++ -AR = $(TCHAIN)-ar -OBJCOPY = $(TCHAIN)-objcopy -OBJDUMP = $(TCHAIN)-objdump -SIZE = $(TCHAIN)-size -NM = $(TCHAIN)-nm -REMOVE = rm -f -REMOVEDIR = rm -r -COPY = cp - -# Define Messages -# English -MSG_ERRORS_NONE = Errors: none -MSG_BEGIN = "-------- begin --------" -MSG_ETAGS = Created TAGS File -MSG_END = -------- end -------- -MSG_SIZE_BEFORE = Size before: -MSG_SIZE_AFTER = Size after: -MSG_FLASH = Creating load file for Flash: -MSG_EXTENDED_LISTING = Creating Extended Listing: -MSG_SYMBOL_TABLE = Creating Symbol Table: -MSG_LINKING = Linking: -MSG_COMPILING = Compiling C: -MSG_ASSEMBLING = Assembling: -MSG_CLEANING = Cleaning project: - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d -ALL_CFLAGS = -mcpu=$(MCU) $(THUMB_IW) -I. $(CFLAGS) $(GENDEPFLAGS) -ALL_ASFLAGS = -mcpu=$(MCU) $(THUMB_IW) -I. -x assembler-with-cpp $(ASFLAGS) - -# --------------------------------------------- # -# file management -ASRC = $(ST_LIB)/c_only_startup.s $(ST_LIB)/cortexm3_macro.s - -STM32SRCS = - -_STM32USBSRCS = usb_regs.c \ -usb_int.c \ -usb_init.c \ -usb_core.c \ -usb_mem.c - -STM32USBSRCS = $(patsubst %, $(ST_USB)/%,$(_STM32USBSRCS)) - -SRCS = usb.c usb_callbacks.c usb_descriptor.c main.c hardware.c dfu.c - - -SRC = $(SRCS) $(STM32SRCS) $(STM32USBSRCS) - -# Define all object files. -_COBJ = $(SRC:.c=.o) -_AOBJ = $(ASRC:.s=.o) -COBJ = $(patsubst %, $(BUILDDIR)/%,$(_COBJ)) -AOBJ = $(patsubst %, $(BUILDDIR)/%,$(_AOBJ)) - -# Define all listing files. -_LST = $(ASRC:.s=.lst) -_LST += $(SRC:.c=.lst) -LST = $(patsubst %, $(BUILDDIR)/%,$(_LST)) - -# Display size of file. -HEXSIZE = $(SIZE) --target=binary $(TARGET).hex -ELFSIZE = $(SIZE) -A $(TARGET).elf - -# go! -all: begin gccversion build sizeafter finished end -build: elf bin lss sym - -bin: $(TARGET).bin -elf: $(TARGET).elf -lss: $(TARGET).lss -sym: $(TARGET).sym -dfu: $(TARGET).bin - sudo dfu-util -d 0110:1001 -a 0 -D $(TARGET).bin - -begin: - mkdir -p build/stm32_lib - mkdir -p build/usb_lib - @echo -- - @echo $(MSG_BEGIN) - @echo $(COBJ) - -finished: - @echo $(MSG_ERRORS_NONE) -tags: - etags `find . -name "*.c" -o -name "*.cpp" -o -name "*.h"` - @echo $(MSG_ETAGS) -end: - @echo $(MSG_END) - @echo -sizeafter: - if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi -gccversion: - @$(CC) --version - -program: - @echo "Flash-programming with OpenOCD" - cp $(TARGET).bin flash/tmpflash.bin - cd flash && openocd -f flash.cfg - -program_serial: - @echo "Flash-programming with stm32loader.py" - ./flash/stm32loader.py -p /dev/ttyUSB0 -evw build/maple_boot.bin - -debug: $(TARGET).bin - @echo "Flash-programming with OpenOCD - DEBUG" - cp $(TARGET).bin flash/tmpflash.bin - cd flash && openocd -f debug.cfg - -install: $(TARGET).bin - cp $(TARGET).bin build/main.bin - openocd -f flash/perry_flash.cfg - -run: $(TARGET).bin - openocd -f flash/run.cfg - -# Create final output file (.hex) from ELF output file. -%.hex: %.elf - @echo - @echo $(MSG_FLASH) $@ - $(OBJCOPY) -O binary $< $@ - -# Create final output file (.bin) from ELF output file. -%.bin: %.elf - @echo - @echo $(MSG_FLASH) $@ - $(OBJCOPY) -O binary $< $@ - - -# Create extended listing file from ELF output file. -# testing: option -C -%.lss: %.elf - @echo - @echo $(MSG_EXTENDED_LISTING) $@ - $(OBJDUMP) -h -S -D $< > $@ - - -# Create a symbol table from ELF output file. -%.sym: %.elf - @echo - @echo $(MSG_SYMBOL_TABLE) $@ - $(NM) -n $< > $@ - - -# Link: create ELF output file from object files. -.SECONDARY : $(TARGET).elf -.PRECIOUS : $(COBJ) $(AOBJ) - -%.elf: $(COBJ) $(AOBJ) - @echo - @echo $(MSG_LINKING) $@ - $(CC) $(THUMB) $(ALL_CFLAGS) $(AOBJ) $(COBJ) --output $@ $(LDFLAGS) - -# Compile: create object files from C source files. ARM/Thumb -$(COBJ) : $(BUILDDIR)/%.o : %.c - @echo - @echo $(MSG_COMPILING) $< - $(CC) -c $(THUMB) $(ALL_CFLAGS) $< -o $@ - -# Assemble: create object files from assembler source files. ARM/Thumb -$(AOBJ) : $(BUILDDIR)/%.o : %.s - @echo - @echo $(MSG_ASSEMBLING) $< - $(CC) -c $(THUMB) $(ALL_ASFLAGS) $< -o $@ - -clean: begin clean_list finished end - -clean_list : - @echo - @echo $(MSG_CLEANING) - $(REMOVE) $(TARGET).hex - $(REMOVE) $(TARGET).bin - $(REMOVE) $(TARGET).obj - $(REMOVE) $(TARGET).elf - $(REMOVE) $(TARGET).map - $(REMOVE) $(TARGET).obj - $(REMOVE) $(TARGET).a90 - $(REMOVE) $(TARGET).sym - $(REMOVE) $(TARGET).lnk - $(REMOVE) $(TARGET).lss - $(REMOVE) $(COBJ) - $(REMOVE) $(AOBJ) - $(REMOVE) $(LST) - $(REMOVE) flash/tmpflash.bin -# $(REMOVE) $(SRC:.c=.s) -# $(REMOVE) $(SRC:.c=.d) - $(REMOVE) .dep/* - -# Include the dependency files. --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - - -# Listing of phony targets. -.PHONY : all begin finish tags end sizeafter gccversion \ -build elf hex bin lss sym clean clean_list program cscope - -cscope: - rm -rf *.cscope - find . -iname "*.[hcs]" | grep -v examples | xargs cscope -R -b - +# Makefile skeleton adapted from Peter Harrison's - www.micromouse.com + +# MCU name and submodel +MCU = cortex-m3 +SUBMDL = stm32f103 +#CPUCLASS = STM32F1 +CPUCLASS = STM32F2 + +#BOARD = aeroquad32mini +#MEMORY = flash128k_ram20k +BOARD = aeroquad32 +#BOARD = DiscoveryF4 +MEMORY = flash512k_ram64k + + + + +# toolchain (using code sourcery now) +TCHAIN = arm-none-eabi +THUMB = -mthumb +THUMB_IW = -mthumb-interwork + +# Target file name (without extension). +BUILDDIR = build +TARGET = $(BUILDDIR)/maple_boot + +ST_LIB = stm32_lib +ST_USB = usb_lib + +# Optimization level [0,1,2,3,s] +OPT = 0 +DEBUG = -g +#DEBUG = dwarf-2 + +INCDIRS = ./$(ST_LIB) ./$(ST_USB) + +CFLAGS = $(DEBUG) +CFLAGS += -O$(OPT) +CFLAGS += -ffunction-sections -fdata-sections +CFLAGS += -Wall -Wimplicit +CFLAGS += -Wcast-align +CFLAGS += -Wpointer-arith -Wswitch +CFLAGS += -Wredundant-decls -Wreturn-type -Wshadow -Wunused +CFLAGS += -Wa,-adhlns=$(BUILDDIR)/$(subst $(suffix $<),.lst,$<) +CFLAGS += $(patsubst %,-I%,$(INCDIRS)) +CFLAGS += -D$(CPUCLASS) +CFLAGS += -DBOARD_$(BOARD) +CFLAGS += -DFASTSTART +#CFLAGS += -DUSB_DISC_OD + +# Assembler Flags +ASFLAGS = -Wa,-adhlns=$(BUILDDIR)/$(<:.s=.lst)#,--g$(DEBUG) + +LDFLAGS = -nostartfiles -Wl,-Map=$(TARGET).map,--cref,--gc-sections +LDFLAGS += -lc -lgcc + +# Set the linker script +LDFLAGS +=-T$(ST_LIB)/c_only_md_$(MEMORY).ld + +# Define programs and commands. +SHELL = sh +CC = $(TCHAIN)-gcc +CPP = $(TCHAIN)-g++ +AR = $(TCHAIN)-ar +OBJCOPY = $(TCHAIN)-objcopy +OBJDUMP = $(TCHAIN)-objdump +SIZE = $(TCHAIN)-size +NM = $(TCHAIN)-nm +REMOVE = rm -f +REMOVEDIR = rm -r +COPY = cp + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = "-------- begin --------" +MSG_ETAGS = Created TAGS File +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_FLASH = Creating load file for Flash: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d +ALL_CFLAGS = -mcpu=$(MCU) $(THUMB_IW) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mcpu=$(MCU) $(THUMB_IW) -I. -x assembler-with-cpp $(ASFLAGS) + +# --------------------------------------------- # +# file management +ASRC = $(ST_LIB)/c_only_startup.s $(ST_LIB)/cortexm3_macro.s + +STM32SRCS = + +_STM32USBSRCS = usb_regs.c \ +usb_int.c \ +usb_init.c \ +usb_core.c \ +usb_mem.c + +STM32USBSRCS = $(patsubst %, $(ST_USB)/%,$(_STM32USBSRCS)) + +SRCS = usb.c usb_callbacks.c usb_descriptor.c main.c hardware.c dfu.c + + +SRC = $(SRCS) $(STM32SRCS) $(STM32USBSRCS) + +# Define all object files. +_COBJ = $(SRC:.c=.o) +_AOBJ = $(ASRC:.s=.o) +COBJ = $(patsubst %, $(BUILDDIR)/%,$(_COBJ)) +AOBJ = $(patsubst %, $(BUILDDIR)/%,$(_AOBJ)) + +# Define all listing files. +_LST = $(ASRC:.s=.lst) +_LST += $(SRC:.c=.lst) +LST = $(patsubst %, $(BUILDDIR)/%,$(_LST)) + +# Display size of file. +HEXSIZE = $(SIZE) --target=binary $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + +# go! +all: begin gccversion build sizeafter finished end +build: elf bin lss sym + +bin: $(TARGET).bin +elf: $(TARGET).elf +lss: $(TARGET).lss +sym: $(TARGET).sym +dfu: $(TARGET).bin + sudo dfu-util -d 0110:1001 -a 0 -D $(TARGET).bin + +begin: + mkdir -p build/stm32_lib + mkdir -p build/usb_lib + @echo -- + @echo $(MSG_BEGIN) + @echo $(COBJ) + +finished: + @echo $(MSG_ERRORS_NONE) +tags: + etags `find . -name "*.c" -o -name "*.cpp" -o -name "*.h"` + @echo $(MSG_ETAGS) +end: + @echo $(MSG_END) + @echo +sizeafter: + if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi +gccversion: + @$(CC) --version + +program: + @echo "Flash-programming with OpenOCD" + cp $(TARGET).bin flash/tmpflash.bin + cd flash && openocd -f flash.cfg + +program_serial: + @echo "Flash-programming with stm32loader.py" + ./flash/stm32loader.py -p /dev/ttyUSB0 -evw build/maple_boot.bin + +debug: $(TARGET).bin + @echo "Flash-programming with OpenOCD - DEBUG" + cp $(TARGET).bin flash/tmpflash.bin + cd flash && openocd -f debug.cfg + +install: $(TARGET).bin + cp $(TARGET).bin build/main.bin + openocd -f flash/perry_flash.cfg + +run: $(TARGET).bin + openocd -f flash/run.cfg + +# Create final output file (.hex) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O binary $< $@ + +# Create final output file (.bin) from ELF output file. +%.bin: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O binary $< $@ + + +# Create extended listing file from ELF output file. +# testing: option -C +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -D $< > $@ + + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(COBJ) $(AOBJ) + +%.elf: $(COBJ) $(AOBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(THUMB) $(ALL_CFLAGS) $(AOBJ) $(COBJ) --output $@ $(LDFLAGS) + +# Compile: create object files from C source files. ARM/Thumb +$(COBJ) : $(BUILDDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(THUMB) $(ALL_CFLAGS) $< -o $@ + +# Assemble: create object files from assembler source files. ARM/Thumb +$(AOBJ) : $(BUILDDIR)/%.o : %.s + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(THUMB) $(ALL_ASFLAGS) $< -o $@ + +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).bin + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(COBJ) + $(REMOVE) $(AOBJ) + $(REMOVE) $(LST) + $(REMOVE) flash/tmpflash.bin +# $(REMOVE) $(SRC:.c=.s) +# $(REMOVE) $(SRC:.c=.d) + $(REMOVE) .dep/* + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + + +# Listing of phony targets. +.PHONY : all begin finish tags end sizeafter gccversion \ +build elf hex bin lss sym clean clean_list program cscope + +cscope: + rm -rf *.cscope + find . -iname "*.[hcs]" | grep -v examples | xargs cscope -R -b + diff --git a/Libmaple/maple-bootloader/README b/Libmaple/maple-bootloader/README index 0f3f4a7a..bb6d719b 100644 --- a/Libmaple/maple-bootloader/README +++ b/Libmaple/maple-bootloader/README @@ -1,38 +1,38 @@ - -FILES ------------------------------------------------------------------------- - -stm32lib/* - - all the (possibly consolidated) stm32 lib and usb example code - -usb.c - - USB-specific hardware setup. Interrupts, clocks, etc. handling USB when - not "Attached". some low-level callbacks (low power mode, init, reset, - resume, etc). - -usb_callbacks.c - - aka endpoints: handling data transfer when "Configured". calls out to - application specific callbacks (eg DFU or serial shit) - -usb_descriptor.c - - aka application descriptor; big static struct and callbacks for sending - the descriptor. - -main.c - - main loop and calling any hardware init stuff. timing hacks for EEPROM - writes not to block usb interrupts. logic to handle 2 second timeout then - jump to user code. - -hardware.c - - init routines to setup clocks, interrupts, also destructor functions. - does not include USB stuff. EEPROM read/write functions. - -dfu.c - - mostly the giant FSM case switch, also some USB endpoint callbacks - - -TODO -------------------------------------------------------------------------- - - * tap reset then quickly tap The Button leaves the board in dfu wait loop - forever instead of just 2 seconds - - * use sizeof() for usb application descriptor + +FILES ------------------------------------------------------------------------- + +stm32lib/* + - all the (possibly consolidated) stm32 lib and usb example code + +usb.c + - USB-specific hardware setup. Interrupts, clocks, etc. handling USB when + not "Attached". some low-level callbacks (low power mode, init, reset, + resume, etc). + +usb_callbacks.c + - aka endpoints: handling data transfer when "Configured". calls out to + application specific callbacks (eg DFU or serial shit) + +usb_descriptor.c + - aka application descriptor; big static struct and callbacks for sending + the descriptor. + +main.c + - main loop and calling any hardware init stuff. timing hacks for EEPROM + writes not to block usb interrupts. logic to handle 2 second timeout then + jump to user code. + +hardware.c + - init routines to setup clocks, interrupts, also destructor functions. + does not include USB stuff. EEPROM read/write functions. + +dfu.c + - mostly the giant FSM case switch, also some USB endpoint callbacks + + +TODO -------------------------------------------------------------------------- + + * tap reset then quickly tap The Button leaves the board in dfu wait loop + forever instead of just 2 seconds + + * use sizeof() for usb application descriptor diff --git a/Libmaple/maple-bootloader/common.h b/Libmaple/maple-bootloader/common.h index f6a13d72..ba322df0 100644 --- a/Libmaple/maple-bootloader/common.h +++ b/Libmaple/maple-bootloader/common.h @@ -1,44 +1,44 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -/** - * @file common.h - * - * @brief toplevel include for bootloader source files - * - * - */ - -#ifndef __COMMON_H -#define __COMMON_H - -#include "config.h" -#include "hardware.h" -#include "stm32f10x_type.h" -#include "cortexm3_macro.h" -#include "usb.h" - -typedef void (*FuncPtr)(void); - -#endif +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +/** + * @file common.h + * + * @brief toplevel include for bootloader source files + * + * + */ + +#ifndef __COMMON_H +#define __COMMON_H + +#include "config.h" +#include "hardware.h" +#include "stm32f10x_type.h" +#include "cortexm3_macro.h" +#include "usb.h" + +typedef void (*FuncPtr)(void); + +#endif diff --git a/Libmaple/maple-bootloader/config.h b/Libmaple/maple-bootloader/config.h index 650227c6..55194b41 100644 --- a/Libmaple/maple-bootloader/config.h +++ b/Libmaple/maple-bootloader/config.h @@ -1,177 +1,177 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -/** - * @file config.h - * - * @brief bootloader settings and macro defines - * - * - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -#include "common.h" - - -/* On the Native, LED is PC15, now take PE5 */ -#ifdef BOARD_maple_native -#define FLASH_PAGE_SIZE 0x800 /* 2KB pages for high density devices */ -// LED is PC15 -#define LED_BANK GPIOC -#define LED 15 -#define LED_BANK_CR GPIO_CRH(LED_BANK) -#define LED_CR_MASK 0x0FFFFFFF -#define LED_CR_OUTPUT 0x10000000 -#define RCC_APB2ENR_LED 0x00000010 /* enable PC */ - -/* On the Native, BUT is PG15, now PC0 */ -#define BUTTON_BANK GPIOG -#define BUTTON 15 -#define BUT_BANK_CR GPIO_CRH(BUTTON_BANK) -#define BUT_CR_MASK 0x0FFFFFFF -#define BUT_CR_INPUTMODE 0x40000000 // input floating -#define RCC_APB2ENR_BUT 0x00000100 /* enable PG */ -#define BUTTON_SETUP resetPin -#endif - - -#ifdef BOARD_aeroquad32 - #define FLASH_PAGE_SIZE 0x800 /* 2KB pages for high density devices */ - #define USER_CODE_FLASH ((u32)0x08010000) /* ala42 */ - - // LED is PE5 - #define LED_BANK GPIOE - #define LED 5 - #define LED_BANK_CR GPIO_CRL(LED_BANK) - #define LED_CR_MASK 0xFF0FFFFF - #define LED_CR_OUTPUT 0x00100000 - #define RCC_APB2ENR_LED 0x00000040 /* enable PE */ - #define RCC_AHB1ENR_LED 0x00000010 /* F2 enable PE */ - - /* BUT is PD15 */ - #define BUTTON_BANK GPIOD - #define BUTTON 15 // PD15 - #define BUT_BANK_CR GPIO_CRH(BUTTON_BANK) - #define BUT_CR_MASK 0x0FFFFFFF - //#define BUT_CR_INPUTMODE 0x00000004 // input floating - #define BUT_CR_INPUTMODE 0x80000000 // input pull up/down, output pin has to be set for pull up, cleared for pull down - #define RCC_APB2ENR_BUT 0x00000020 /* enable PD */ - #define RCC_AHB1ENR_BUT 0x00000008 /* F2 enable PE */ - #define BUTTON_SETUP resetPin - - #if 0 - /* BUT is PC0 */ - #define BUTTON_BANK GPIOC - #define BUTTON 0 // PC0 - #define BUT_BANK_CR GPIO_CRL(BUTTON_BANK) - #define BUT_CR_MASK 0xFFFFFFF0 - //#define BUT_CR_INPUTMODE 0x00000004 // input floating - #define BUT_CR_INPUTMODE 0x00000008 // input pullup, output pin has to be set - #define RCC_APB2ENR_BUT 0x00000010 /* enable PC */ - #define RCC_AHB1ENR_BUT 0x00000004 /* F2 enable PC */ - #define BUTTON_SETUP setPin - #endif -#endif - -#ifdef BOARD_DiscoveryF4 - #define FLASH_PAGE_SIZE 0x800 /* 2KB pages for high density devices */ - #define USER_CODE_FLASH ((u32)0x08010000) /* ala42 */ - - // LED is PD13 - #define LED_BANK GPIOD - #define LED 13 - #define LED_BANK_CR GPIO_CRH(LED_BANK) - #define LED_CR_MASK 0xFF0FFFFF - #define LED_CR_OUTPUT 0x00100000 - //#define RCC_APB2ENR_LED 0x00000020 /* enable PD */ - #define RCC_AHB1ENR_LED 0x00000008 /* F2 enable PD */ - - /* BUT is PA0 */ - #define BUTTON_BANK GPIOA - #define BUTTON 0 // PA0 - //#define BUT_BANK_CR GPIO_CRL(BUTTON_BANK) - //#define BUT_CR_MASK 0xFFFFFFF0 - //#define BUT_CR_INPUTMODE 0x00000004 // input floating - //#define BUT_CR_INPUTMODE 0x00000008 // input pull up/down, output pin has to be set for pull up, cleared for pull down - #define RCC_AHB1ENR_BUT 0x00000001 /* F2 enable PA */ - //#define BUTTON_SETUP resetPin -#endif - - - - -#ifdef BOARD_aeroquad32mini - #define FLASH_PAGE_SIZE 0x400 /* 1KB pages for medium density devices */ - #define USER_CODE_FLASH ((u32)0x08005000) /* ala42 */ - // LED is PA3 - #define LED_BANK GPIOA - #define LED 3 - #define LED_BANK_CR GPIO_CRL(LED_BANK) - #define LED_CR_MASK 0xFFFF0FFF - #define LED_CR_OUTPUT 0x00001000 - #define RCC_APB2ENR_LED 0x00000004 /* enable PA */ - - /* BUT is PA4 */ - #define BUTTON_BANK GPIOA - #define BUTTON 4 // PA4 - #define BUT_BANK_CR GPIO_CRL(BUTTON_BANK) - #define BUT_CR_MASK 0xFFF0FFFF - //#define BUT_CR_INPUTMODE 0x00000004 // input floating - #define BUT_CR_INPUTMODE 0x00080000 // input pull up/down, output pin has to be set for pull up, cleared for pull down - #define RCC_APB2ENR_BUT 0x00000004 /* enable PA */ - #define BUTTON_SETUP resetPin -#endif - - - -/* Speed controls for strobing the LED pin */ -#ifdef STM32F2 - #define BLINK_FAST (2*0x50000) - #define BLINK_SLOW (2*0x100000) -#else - #define BLINK_FAST 0x50000 - #define BLINK_SLOW 0x100000 -#endif - -#ifdef FASTSTART -#define BOOTLOADER_WAIT 0 -#define STARTUP_BLINKS 2 -#else -#define BOOTLOADER_WAIT 3 // ala42: was 6 -#define STARTUP_BLINKS 5 -#endif - -#define USER_CODE_RAM ((u32)0x20000C00) -#define BUILT_IN_BOOT_LOADER ((u32)0x1FFF0000) -#define START_BOOT_LOADER_MAGIC_ADDR ((u32*)(USER_CODE_RAM-4)) -#define START_BOOT_LOADER_MAGIC (0x4AFC6BB2) - -#define VEND_ID0 0xAF -#define VEND_ID1 0x1E -#define PROD_ID0 0x03 -#define PROD_ID1 0x00 - -#endif +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +/** + * @file config.h + * + * @brief bootloader settings and macro defines + * + * + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include "common.h" + + +/* On the Native, LED is PC15, now take PE5 */ +#ifdef BOARD_maple_native +#define FLASH_PAGE_SIZE 0x800 /* 2KB pages for high density devices */ +// LED is PC15 +#define LED_BANK GPIOC +#define LED 15 +#define LED_BANK_CR GPIO_CRH(LED_BANK) +#define LED_CR_MASK 0x0FFFFFFF +#define LED_CR_OUTPUT 0x10000000 +#define RCC_APB2ENR_LED 0x00000010 /* enable PC */ + +/* On the Native, BUT is PG15, now PC0 */ +#define BUTTON_BANK GPIOG +#define BUTTON 15 +#define BUT_BANK_CR GPIO_CRH(BUTTON_BANK) +#define BUT_CR_MASK 0x0FFFFFFF +#define BUT_CR_INPUTMODE 0x40000000 // input floating +#define RCC_APB2ENR_BUT 0x00000100 /* enable PG */ +#define BUTTON_SETUP resetPin +#endif + + +#ifdef BOARD_aeroquad32 + #define FLASH_PAGE_SIZE 0x800 /* 2KB pages for high density devices */ + #define USER_CODE_FLASH ((u32)0x08010000) /* ala42 */ + + // LED is PE5 + #define LED_BANK GPIOE + #define LED 5 + #define LED_BANK_CR GPIO_CRL(LED_BANK) + #define LED_CR_MASK 0xFF0FFFFF + #define LED_CR_OUTPUT 0x00100000 + #define RCC_APB2ENR_LED 0x00000040 /* enable PE */ + #define RCC_AHB1ENR_LED 0x00000010 /* F2 enable PE */ + + /* BUT is PD15 */ + #define BUTTON_BANK GPIOD + #define BUTTON 15 // PD15 + #define BUT_BANK_CR GPIO_CRH(BUTTON_BANK) + #define BUT_CR_MASK 0x0FFFFFFF + //#define BUT_CR_INPUTMODE 0x00000004 // input floating + #define BUT_CR_INPUTMODE 0x80000000 // input pull up/down, output pin has to be set for pull up, cleared for pull down + #define RCC_APB2ENR_BUT 0x00000020 /* enable PD */ + #define RCC_AHB1ENR_BUT 0x00000008 /* F2 enable PE */ + #define BUTTON_SETUP resetPin + + #if 0 + /* BUT is PC0 */ + #define BUTTON_BANK GPIOC + #define BUTTON 0 // PC0 + #define BUT_BANK_CR GPIO_CRL(BUTTON_BANK) + #define BUT_CR_MASK 0xFFFFFFF0 + //#define BUT_CR_INPUTMODE 0x00000004 // input floating + #define BUT_CR_INPUTMODE 0x00000008 // input pullup, output pin has to be set + #define RCC_APB2ENR_BUT 0x00000010 /* enable PC */ + #define RCC_AHB1ENR_BUT 0x00000004 /* F2 enable PC */ + #define BUTTON_SETUP setPin + #endif +#endif + +#ifdef BOARD_DiscoveryF4 + #define FLASH_PAGE_SIZE 0x800 /* 2KB pages for high density devices */ + #define USER_CODE_FLASH ((u32)0x08010000) /* ala42 */ + + // LED is PD13 + #define LED_BANK GPIOD + #define LED 13 + #define LED_BANK_CR GPIO_CRH(LED_BANK) + #define LED_CR_MASK 0xFF0FFFFF + #define LED_CR_OUTPUT 0x00100000 + //#define RCC_APB2ENR_LED 0x00000020 /* enable PD */ + #define RCC_AHB1ENR_LED 0x00000008 /* F2 enable PD */ + + /* BUT is PA0 */ + #define BUTTON_BANK GPIOA + #define BUTTON 0 // PA0 + //#define BUT_BANK_CR GPIO_CRL(BUTTON_BANK) + //#define BUT_CR_MASK 0xFFFFFFF0 + //#define BUT_CR_INPUTMODE 0x00000004 // input floating + //#define BUT_CR_INPUTMODE 0x00000008 // input pull up/down, output pin has to be set for pull up, cleared for pull down + #define RCC_AHB1ENR_BUT 0x00000001 /* F2 enable PA */ + //#define BUTTON_SETUP resetPin +#endif + + + + +#ifdef BOARD_aeroquad32mini + #define FLASH_PAGE_SIZE 0x400 /* 1KB pages for medium density devices */ + #define USER_CODE_FLASH ((u32)0x08005000) /* ala42 */ + // LED is PA3 + #define LED_BANK GPIOA + #define LED 3 + #define LED_BANK_CR GPIO_CRL(LED_BANK) + #define LED_CR_MASK 0xFFFF0FFF + #define LED_CR_OUTPUT 0x00001000 + #define RCC_APB2ENR_LED 0x00000004 /* enable PA */ + + /* BUT is PA4 */ + #define BUTTON_BANK GPIOA + #define BUTTON 4 // PA4 + #define BUT_BANK_CR GPIO_CRL(BUTTON_BANK) + #define BUT_CR_MASK 0xFFF0FFFF + //#define BUT_CR_INPUTMODE 0x00000004 // input floating + #define BUT_CR_INPUTMODE 0x00080000 // input pull up/down, output pin has to be set for pull up, cleared for pull down + #define RCC_APB2ENR_BUT 0x00000004 /* enable PA */ + #define BUTTON_SETUP resetPin +#endif + + + +/* Speed controls for strobing the LED pin */ +#ifdef STM32F2 + #define BLINK_FAST (2*0x50000) + #define BLINK_SLOW (2*0x100000) +#else + #define BLINK_FAST 0x50000 + #define BLINK_SLOW 0x100000 +#endif + +#ifdef FASTSTART +#define BOOTLOADER_WAIT 0 +#define STARTUP_BLINKS 2 +#else +#define BOOTLOADER_WAIT 3 // ala42: was 6 +#define STARTUP_BLINKS 5 +#endif + +#define USER_CODE_RAM ((u32)0x20000C00) +#define BUILT_IN_BOOT_LOADER ((u32)0x1FFF0000) +#define START_BOOT_LOADER_MAGIC_ADDR ((u32*)(USER_CODE_RAM-4)) +#define START_BOOT_LOADER_MAGIC (0x4AFC6BB2) + +#define VEND_ID0 0xAF +#define VEND_ID1 0x1E +#define PROD_ID0 0x03 +#define PROD_ID1 0x00 + +#endif diff --git a/Libmaple/maple-bootloader/config.h.old b/Libmaple/maple-bootloader/config.h.old index 20d599c4..52592522 100644 --- a/Libmaple/maple-bootloader/config.h.old +++ b/Libmaple/maple-bootloader/config.h.old @@ -1,71 +1,71 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -/** - * @file config.h - * - * @brief bootloader settings and macro defines - * - * - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -#include "common.h" - -#define FLASH_PAGE_SIZE 0x800 /* 2KB pages for high density devices */ - -/* On the Native, LED is PC15 */ -#define LED_BANK GPIOC -#define LED 15 -#define LED_BANK_CR GPIO_CRH(LED_BANK) -#define LED_CR_MASK 0x0FFFFFFF -#define LED_CR_OUTPUT 0x10000000 -#define RCC_APB2ENR_LED 0x00000010 /* enable PC */ - -/* Speed controls for strobing the LED pin */ -#define BLINK_FAST 0x50000 -#define BLINK_SLOW 0x100000 - -/* On the Native, BUT is PG15 */ -#define BUTTON_BANK GPIOG -#define BUTTON 15 -#define BUT_BANK_CR GPIO_CRH(BUTTON_BANK) -#define BUT_CR_MASK 0x0FFFFFFF -#define BUT_CR_OUTPUT 0x40000000 -#define RCC_APB2ENR_BUT 0x00000100 /* enable PG */ - -#define STARTUP_BLINKS 5 -#define BOOTLOADER_WAIT 6 - -#define USER_CODE_RAM ((u32)0x20000C00) -#define USER_CODE_FLASH ((u32)0x08005000) - -#define VEND_ID0 0xAF -#define VEND_ID1 0x1E -#define PROD_ID0 0x03 -#define PROD_ID1 0x00 - -#endif +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +/** + * @file config.h + * + * @brief bootloader settings and macro defines + * + * + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include "common.h" + +#define FLASH_PAGE_SIZE 0x800 /* 2KB pages for high density devices */ + +/* On the Native, LED is PC15 */ +#define LED_BANK GPIOC +#define LED 15 +#define LED_BANK_CR GPIO_CRH(LED_BANK) +#define LED_CR_MASK 0x0FFFFFFF +#define LED_CR_OUTPUT 0x10000000 +#define RCC_APB2ENR_LED 0x00000010 /* enable PC */ + +/* Speed controls for strobing the LED pin */ +#define BLINK_FAST 0x50000 +#define BLINK_SLOW 0x100000 + +/* On the Native, BUT is PG15 */ +#define BUTTON_BANK GPIOG +#define BUTTON 15 +#define BUT_BANK_CR GPIO_CRH(BUTTON_BANK) +#define BUT_CR_MASK 0x0FFFFFFF +#define BUT_CR_OUTPUT 0x40000000 +#define RCC_APB2ENR_BUT 0x00000100 /* enable PG */ + +#define STARTUP_BLINKS 5 +#define BOOTLOADER_WAIT 6 + +#define USER_CODE_RAM ((u32)0x20000C00) +#define USER_CODE_FLASH ((u32)0x08005000) + +#define VEND_ID0 0xAF +#define VEND_ID1 0x1E +#define PROD_ID0 0x03 +#define PROD_ID1 0x00 + +#endif diff --git a/Libmaple/maple-bootloader/dfu.c b/Libmaple/maple-bootloader/dfu.c index 51969576..815a65a1 100644 --- a/Libmaple/maple-bootloader/dfu.c +++ b/Libmaple/maple-bootloader/dfu.c @@ -1,372 +1,372 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -/** - * @file dfu.c - * - * @brief The principle dfu state machine as well as the data - * transfer callbacks accessed by the usb library - * - * - */ - -#include "dfu.h" -#include "usb.h" - -/* DFU globals */ -volatile u32 userAppAddr = USER_CODE_RAM; /* default RAM user code location */ -volatile DFUStatus dfuAppStatus; /* includes state */ -volatile bool userFlash = FALSE; -volatile bool dfuBusy = FALSE; - -volatile u8 recvBuffer[wTransferSize]; -volatile u32 userFirmwareLen = 0; -volatile u16 thisBlockLen = 0; - - -volatile PLOT code_copy_lock; - -/* todo: force dfu globals to be singleton to avoid re-inits? */ -void dfuInit(void) { - dfuAppStatus.bStatus = OK; - dfuAppStatus.bwPollTimeout0 = 0x00; - dfuAppStatus.bwPollTimeout1 = 0x00; - dfuAppStatus.bwPollTimeout2 = 0x00; - dfuAppStatus.bState = dfuIDLE; - dfuAppStatus.iString = 0x00; /* all strings must be 0x00 until we make them! */ - userFirmwareLen = 0; - thisBlockLen = 0;; - userAppAddr = USER_CODE_RAM; /* default RAM user code location */ - userFlash = FALSE; - code_copy_lock = WAIT; - dfuBusy=FALSE; -} - -bool dfuUpdateByRequest(void) { - /* were using the global pInformation struct from usb_lib here, - see comment in maple_dfu.h around DFUEvent struct */ - dfuBusy = TRUE; - - u8 startState = dfuAppStatus.bState; - dfuAppStatus.bStatus = OK; - /* often leaner to nest if's then embed a switch/case */ - if (startState == dfuIDLE) { - /* device running inside DFU mode */ - dfuBusy = TRUE; // signals the main loop to defer to the dfu write-loop - - if (pInformation->USBbRequest == DFU_DNLOAD) { - - if (pInformation->USBwLengths.w > 0) { - userFirmwareLen = 0; - dfuAppStatus.bState = dfuDNLOAD_SYNC; - - if (pInformation->Current_AlternateSetting == 1) { - userAppAddr = USER_CODE_FLASH; - userFlash = TRUE; - - /* make sure the flash is setup properly, unlock it */ - setupFLASH(); - flashUnlock(); - - } else { - userAppAddr = USER_CODE_RAM; - userFlash = FALSE; - } - } else { - dfuAppStatus.bState = dfuERROR; - dfuAppStatus.bStatus = errNOTDONE; - } - } else if (pInformation->USBbRequest == DFU_UPLOAD) { - dfuAppStatus.bState = dfuUPLOAD_IDLE; - } else if (pInformation->USBbRequest == DFU_ABORT) { - dfuAppStatus.bState = dfuIDLE; - dfuAppStatus.bStatus = OK; /* are we really ok? we were just aborted */ - } else if (pInformation->USBbRequest == DFU_GETSTATUS) { - dfuAppStatus.bState = dfuIDLE; - } else if (pInformation->USBbRequest == DFU_GETSTATE) { - dfuAppStatus.bState = dfuIDLE; - } else { - dfuAppStatus.bState = dfuERROR; - dfuAppStatus.bStatus = errSTALLEDPKT; - } - - } else if (startState == dfuDNLOAD_SYNC) { - /* device received block, waiting for DFU_GETSTATUS request */ - - if (pInformation->USBbRequest == DFU_GETSTATUS) { - /* todo, add routine to wait for last block write to finish */ - if (userFlash) { - if (code_copy_lock==WAIT) { - code_copy_lock=BEGINNING; - dfuAppStatus.bwPollTimeout0 = 0xFF; /* is this enough? */ - dfuAppStatus.bwPollTimeout1 = 0x01; /* is this enough? */ - dfuAppStatus.bState=dfuDNBUSY; - - } else if (code_copy_lock==BEGINNING) { - dfuAppStatus.bState=dfuDNLOAD_SYNC; - - } else if (code_copy_lock==MIDDLE) { - dfuAppStatus.bState=dfuDNLOAD_SYNC; - - } else if (code_copy_lock==END) { - dfuAppStatus.bwPollTimeout0 = 0x00; - code_copy_lock=WAIT; - dfuAppStatus.bState=dfuDNLOAD_IDLE; - } - - } else { - dfuAppStatus.bState = dfuDNLOAD_IDLE; - dfuCopyBufferToExec(); - } - - } else if (pInformation->USBbRequest == DFU_GETSTATE) { - dfuAppStatus.bState = dfuDNLOAD_SYNC; - } else { - dfuAppStatus.bState = dfuERROR; - dfuAppStatus.bStatus = errSTALLEDPKT; - } - - } else if (startState == dfuDNBUSY) { - /* if were actually done writing, goto sync, else stay busy */ - if (code_copy_lock == END) { - dfuAppStatus.bwPollTimeout0 = 0x00; - code_copy_lock=WAIT; - dfuAppStatus.bState = dfuDNLOAD_IDLE; - } else { - dfuAppStatus.bState= dfuDNBUSY; - } - - } else if (startState == dfuDNLOAD_IDLE) { - /* device is expecting dfu_dnload requests */ - if (pInformation->USBbRequest == DFU_DNLOAD) { - if (pInformation->USBwLengths.w > 0) { - dfuAppStatus.bState = dfuDNLOAD_SYNC; - } else { - /* todo, support "disagreement" if device expects more data than this */ - dfuAppStatus.bState = dfuMANIFEST_SYNC; - - /* relock the flash */ - flashLock(); - } - } else if (pInformation->USBbRequest == DFU_ABORT) { - dfuAppStatus.bState = dfuIDLE; - } else if (pInformation->USBbRequest == DFU_GETSTATUS) { - dfuAppStatus.bState = dfuIDLE; - } else if (pInformation->USBbRequest == DFU_GETSTATE) { - dfuAppStatus.bState = dfuIDLE; - } else { - dfuAppStatus.bState = dfuERROR; - dfuAppStatus.bStatus = errSTALLEDPKT; - } - - } else if (startState == dfuMANIFEST_SYNC) { - /* device has received last block, waiting DFU_GETSTATUS request */ - - if (pInformation->USBbRequest == DFU_GETSTATUS) { - dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET; - dfuAppStatus.bStatus = OK; - } else if (pInformation->USBbRequest == DFU_GETSTATE) { - dfuAppStatus.bState = dfuMANIFEST_SYNC; - } else { - dfuAppStatus.bState = dfuERROR; - dfuAppStatus.bStatus = errSTALLEDPKT; - } - - } else if (startState == dfuMANIFEST) { - /* device is in manifestation phase */ - - /* should never receive request while in manifest! */ - dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET; - dfuAppStatus.bStatus = OK; - - } else if (startState == dfuMANIFEST_WAIT_RESET) { - /* device has programmed new firmware but needs external - usb reset or power on reset to run the new code */ - - /* consider timing out and self-resetting */ - dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET; - - } else if (startState == dfuUPLOAD_IDLE) { - /* device expecting further dfu_upload requests */ - - if (pInformation->USBbRequest == DFU_UPLOAD) { - /* todo, add routine to wait for last block write to finish */ - dfuAppStatus.bState = dfuERROR; - dfuAppStatus.bStatus = errSTALLEDPKT; - } else if (pInformation->USBbRequest == DFU_ABORT) { - dfuAppStatus.bState = dfuIDLE; - } else if (pInformation->USBbRequest == DFU_GETSTATUS) { - dfuAppStatus.bState = dfuUPLOAD_IDLE; - } else if (pInformation->USBbRequest == DFU_GETSTATE) { - dfuAppStatus.bState = dfuUPLOAD_IDLE; - } else { - dfuAppStatus.bState = dfuERROR; - dfuAppStatus.bStatus = errSTALLEDPKT; - } - - - } else if (startState == dfuERROR) { - /* status is in error, awaiting DFU_CLRSTATUS request */ - - if (pInformation->USBbRequest == DFU_GETSTATUS) { - /* todo, add routine to wait for last block write to finish */ - dfuAppStatus.bState = dfuERROR; - } else if (pInformation->USBbRequest == DFU_GETSTATE) { - dfuAppStatus.bState = dfuERROR; - } else if (pInformation->USBbRequest == DFU_CLRSTATUS) { - /* todo handle any cleanup we need here */ - dfuAppStatus.bState = dfuIDLE; - dfuAppStatus.bStatus = OK; - } else { - dfuAppStatus.bState = dfuERROR; - dfuAppStatus.bStatus = errSTALLEDPKT; - } - - } else { - /* some kind of error... */ - dfuAppStatus.bState = dfuERROR; - dfuAppStatus.bStatus = errSTALLEDPKT; - } - - if (dfuAppStatus.bStatus == OK) { - return TRUE; - } else { - return FALSE; - } -} - -void dfuUpdateByReset(void) { - u8 startState = dfuAppStatus.bState; - userFirmwareLen = 0; - - if (startState == appDETACH) { - dfuAppStatus.bState = dfuIDLE; - dfuAppStatus.bStatus = OK; - - nvicDisableInterrupts(); - usbEnbISR(); - - } else if (startState == appIDLE || startState == dfuIDLE) { - /* do nothing...might be normal usb bus activity */ - } else { - /* we reset from the dfu, reset everything and startover, - which is the correct operation if this is an erroneous - event or properly following a MANIFEST */ - dfuAppStatus.bState = dfuIDLE; - dfuAppStatus.bStatus = OK; - - systemHardReset(); - } -} - -void dfuUpdateByTimeout(void) { -} - -vu8* dfuCopyState(u16 length) { - if (length == 0) { - pInformation->Ctrl_Info.Usb_wLength=1; - return NULL; - } else { - return &dfuAppStatus.bState; - } -} - -vu8* dfuCopyStatus(u16 length) { - if (length == 0) { - pInformation->Ctrl_Info.Usb_wLength = 6; - return NULL; - } else { - return (vu8*)&dfuAppStatus; - } -} - - -vu8* dfuCopyDNLOAD(u16 length) { - if (length==0) { - pInformation->Ctrl_Info.Usb_wLength = pInformation->USBwLengths.w - pInformation->Ctrl_Info.Usb_wOffset; - thisBlockLen = pInformation->USBwLengths.w; - return NULL; - } else { - return ((vu8*)recvBuffer + pInformation->Ctrl_Info.Usb_wOffset); - } -} - -vu8* dfuCopyUPLOAD(u16 length) { - /* not implemented here nor supported by dfu-util */ - return NULL; -} - -void dfuCopyBufferToExec() { - int i; - u32* userSpace; - - if (!userFlash) { - userSpace = (u32*)(USER_CODE_RAM+userFirmwareLen); - /* we dont need to handle when thisBlock len is not divisible by 4, - since the linker will align everything to 4B anyway */ - for (i=0;iUSBbRequest == DFU_DNLOAD) { + + if (pInformation->USBwLengths.w > 0) { + userFirmwareLen = 0; + dfuAppStatus.bState = dfuDNLOAD_SYNC; + + if (pInformation->Current_AlternateSetting == 1) { + userAppAddr = USER_CODE_FLASH; + userFlash = TRUE; + + /* make sure the flash is setup properly, unlock it */ + setupFLASH(); + flashUnlock(); + + } else { + userAppAddr = USER_CODE_RAM; + userFlash = FALSE; + } + } else { + dfuAppStatus.bState = dfuERROR; + dfuAppStatus.bStatus = errNOTDONE; + } + } else if (pInformation->USBbRequest == DFU_UPLOAD) { + dfuAppStatus.bState = dfuUPLOAD_IDLE; + } else if (pInformation->USBbRequest == DFU_ABORT) { + dfuAppStatus.bState = dfuIDLE; + dfuAppStatus.bStatus = OK; /* are we really ok? we were just aborted */ + } else if (pInformation->USBbRequest == DFU_GETSTATUS) { + dfuAppStatus.bState = dfuIDLE; + } else if (pInformation->USBbRequest == DFU_GETSTATE) { + dfuAppStatus.bState = dfuIDLE; + } else { + dfuAppStatus.bState = dfuERROR; + dfuAppStatus.bStatus = errSTALLEDPKT; + } + + } else if (startState == dfuDNLOAD_SYNC) { + /* device received block, waiting for DFU_GETSTATUS request */ + + if (pInformation->USBbRequest == DFU_GETSTATUS) { + /* todo, add routine to wait for last block write to finish */ + if (userFlash) { + if (code_copy_lock==WAIT) { + code_copy_lock=BEGINNING; + dfuAppStatus.bwPollTimeout0 = 0xFF; /* is this enough? */ + dfuAppStatus.bwPollTimeout1 = 0x01; /* is this enough? */ + dfuAppStatus.bState=dfuDNBUSY; + + } else if (code_copy_lock==BEGINNING) { + dfuAppStatus.bState=dfuDNLOAD_SYNC; + + } else if (code_copy_lock==MIDDLE) { + dfuAppStatus.bState=dfuDNLOAD_SYNC; + + } else if (code_copy_lock==END) { + dfuAppStatus.bwPollTimeout0 = 0x00; + code_copy_lock=WAIT; + dfuAppStatus.bState=dfuDNLOAD_IDLE; + } + + } else { + dfuAppStatus.bState = dfuDNLOAD_IDLE; + dfuCopyBufferToExec(); + } + + } else if (pInformation->USBbRequest == DFU_GETSTATE) { + dfuAppStatus.bState = dfuDNLOAD_SYNC; + } else { + dfuAppStatus.bState = dfuERROR; + dfuAppStatus.bStatus = errSTALLEDPKT; + } + + } else if (startState == dfuDNBUSY) { + /* if were actually done writing, goto sync, else stay busy */ + if (code_copy_lock == END) { + dfuAppStatus.bwPollTimeout0 = 0x00; + code_copy_lock=WAIT; + dfuAppStatus.bState = dfuDNLOAD_IDLE; + } else { + dfuAppStatus.bState= dfuDNBUSY; + } + + } else if (startState == dfuDNLOAD_IDLE) { + /* device is expecting dfu_dnload requests */ + if (pInformation->USBbRequest == DFU_DNLOAD) { + if (pInformation->USBwLengths.w > 0) { + dfuAppStatus.bState = dfuDNLOAD_SYNC; + } else { + /* todo, support "disagreement" if device expects more data than this */ + dfuAppStatus.bState = dfuMANIFEST_SYNC; + + /* relock the flash */ + flashLock(); + } + } else if (pInformation->USBbRequest == DFU_ABORT) { + dfuAppStatus.bState = dfuIDLE; + } else if (pInformation->USBbRequest == DFU_GETSTATUS) { + dfuAppStatus.bState = dfuIDLE; + } else if (pInformation->USBbRequest == DFU_GETSTATE) { + dfuAppStatus.bState = dfuIDLE; + } else { + dfuAppStatus.bState = dfuERROR; + dfuAppStatus.bStatus = errSTALLEDPKT; + } + + } else if (startState == dfuMANIFEST_SYNC) { + /* device has received last block, waiting DFU_GETSTATUS request */ + + if (pInformation->USBbRequest == DFU_GETSTATUS) { + dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET; + dfuAppStatus.bStatus = OK; + } else if (pInformation->USBbRequest == DFU_GETSTATE) { + dfuAppStatus.bState = dfuMANIFEST_SYNC; + } else { + dfuAppStatus.bState = dfuERROR; + dfuAppStatus.bStatus = errSTALLEDPKT; + } + + } else if (startState == dfuMANIFEST) { + /* device is in manifestation phase */ + + /* should never receive request while in manifest! */ + dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET; + dfuAppStatus.bStatus = OK; + + } else if (startState == dfuMANIFEST_WAIT_RESET) { + /* device has programmed new firmware but needs external + usb reset or power on reset to run the new code */ + + /* consider timing out and self-resetting */ + dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET; + + } else if (startState == dfuUPLOAD_IDLE) { + /* device expecting further dfu_upload requests */ + + if (pInformation->USBbRequest == DFU_UPLOAD) { + /* todo, add routine to wait for last block write to finish */ + dfuAppStatus.bState = dfuERROR; + dfuAppStatus.bStatus = errSTALLEDPKT; + } else if (pInformation->USBbRequest == DFU_ABORT) { + dfuAppStatus.bState = dfuIDLE; + } else if (pInformation->USBbRequest == DFU_GETSTATUS) { + dfuAppStatus.bState = dfuUPLOAD_IDLE; + } else if (pInformation->USBbRequest == DFU_GETSTATE) { + dfuAppStatus.bState = dfuUPLOAD_IDLE; + } else { + dfuAppStatus.bState = dfuERROR; + dfuAppStatus.bStatus = errSTALLEDPKT; + } + + + } else if (startState == dfuERROR) { + /* status is in error, awaiting DFU_CLRSTATUS request */ + + if (pInformation->USBbRequest == DFU_GETSTATUS) { + /* todo, add routine to wait for last block write to finish */ + dfuAppStatus.bState = dfuERROR; + } else if (pInformation->USBbRequest == DFU_GETSTATE) { + dfuAppStatus.bState = dfuERROR; + } else if (pInformation->USBbRequest == DFU_CLRSTATUS) { + /* todo handle any cleanup we need here */ + dfuAppStatus.bState = dfuIDLE; + dfuAppStatus.bStatus = OK; + } else { + dfuAppStatus.bState = dfuERROR; + dfuAppStatus.bStatus = errSTALLEDPKT; + } + + } else { + /* some kind of error... */ + dfuAppStatus.bState = dfuERROR; + dfuAppStatus.bStatus = errSTALLEDPKT; + } + + if (dfuAppStatus.bStatus == OK) { + return TRUE; + } else { + return FALSE; + } +} + +void dfuUpdateByReset(void) { + u8 startState = dfuAppStatus.bState; + userFirmwareLen = 0; + + if (startState == appDETACH) { + dfuAppStatus.bState = dfuIDLE; + dfuAppStatus.bStatus = OK; + + nvicDisableInterrupts(); + usbEnbISR(); + + } else if (startState == appIDLE || startState == dfuIDLE) { + /* do nothing...might be normal usb bus activity */ + } else { + /* we reset from the dfu, reset everything and startover, + which is the correct operation if this is an erroneous + event or properly following a MANIFEST */ + dfuAppStatus.bState = dfuIDLE; + dfuAppStatus.bStatus = OK; + + systemHardReset(); + } +} + +void dfuUpdateByTimeout(void) { +} + +vu8* dfuCopyState(u16 length) { + if (length == 0) { + pInformation->Ctrl_Info.Usb_wLength=1; + return NULL; + } else { + return &dfuAppStatus.bState; + } +} + +vu8* dfuCopyStatus(u16 length) { + if (length == 0) { + pInformation->Ctrl_Info.Usb_wLength = 6; + return NULL; + } else { + return (vu8*)&dfuAppStatus; + } +} + + +vu8* dfuCopyDNLOAD(u16 length) { + if (length==0) { + pInformation->Ctrl_Info.Usb_wLength = pInformation->USBwLengths.w - pInformation->Ctrl_Info.Usb_wOffset; + thisBlockLen = pInformation->USBwLengths.w; + return NULL; + } else { + return ((vu8*)recvBuffer + pInformation->Ctrl_Info.Usb_wOffset); + } +} + +vu8* dfuCopyUPLOAD(u16 length) { + /* not implemented here nor supported by dfu-util */ + return NULL; +} + +void dfuCopyBufferToExec() { + int i; + u32* userSpace; + + if (!userFlash) { + userSpace = (u32*)(USER_CODE_RAM+userFirmwareLen); + /* we dont need to handle when thisBlock len is not divisible by 4, + since the linker will align everything to 4B anyway */ + for (i=0;iIDR & (0x01 << pin)) { - return TRUE; - } else { - return FALSE; - } -} - -void strobePin(u32 bank, u8 pin, u8 count, u32 rate) { - resetPin(bank,pin); - - u32 c; - while (count-- >0) { - for (c=rate;c>0;c--) { - asm volatile ("nop"); - } - setPin(bank,pin); - for (c=rate;c>0;c--) { - asm volatile ("nop"); - } - resetPin(bank,pin); - } -} - -void systemReset(void) { -#ifdef STM32F2 - /* Reset the RCC clock configuration to the default reset state ------------*/ - /* Set HSION bit */ - pRCC->CR |= (u32)0x00000001; - - /* Reset CFGR register */ - pRCC->CFGR = 0x00000000; - - /* Reset HSEON, CSSON and PLLON bits */ - pRCC->CR &= (u32)0xFEF6FFFF; - - /* Reset PLLCFGR register */ - pRCC->PLLCFGR = 0x24003010; - - /* Reset HSEBYP bit */ - pRCC->CR &= (u32)0xFFFBFFFF; - - /* Disable all interrupts */ - pRCC->CIR = 0x00000000; - -#else - SET_REG(RCC_CR, GET_REG(RCC_CR) | 0x00000001); - SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xF8FF0000); - SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFEF6FFFF); - SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFFFBFFFF); - SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xFF80FFFF); - - SET_REG(RCC_CIR, 0x00000000); /* disable all RCC interrupts */ -#endif -} - -void setupCLK (void) { -#ifdef STM32F2 -/******************************************************************************/ -/* PLL (clocked by HSE) used as System clock source */ -/******************************************************************************/ - u32 StartUpCounter = 0, HSEStatus = 0; - - /* Enable HSE */ - pRCC->CR |= RCC_CR_HSEON; - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = pRCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((pRCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = 0x01; - } - else - { - HSEStatus = 0x00; - } - - if (HSEStatus == 0x01) - { - /* HCLK = SYSCLK / 1*/ - pRCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - pRCC->CFGR |= RCC_CFGR_PPRE2_DIV2; - - /* PCLK1 = HCLK / 4*/ - pRCC->CFGR |= RCC_CFGR_PPRE1_DIV4; - - /* Configure the main PLL */ - pRCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - pRCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((pRCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - ((FLASH_TypeDef*)FLASH)->ACR = FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS; - - /* Select the main PLL as system clock source */ - pRCC->CFGR &= ~RCC_CFGR_SW; - pRCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((pRCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -#else - /* enable HSE */ - SET_REG(RCC_CR,GET_REG(RCC_CR) | 0x00010001); - while ((GET_REG(RCC_CR) & 0x00020000) == 0); /* for it to come on */ - - /* enable flash prefetch buffer */ - SET_REG(FLASH_ACR, 0x00000012); - - /* Configure PLL */ - SET_REG(RCC_CFGR,GET_REG(RCC_CFGR) | 0x001D0400); /* pll=72Mhz,APB1=36Mhz,AHB=72Mhz */ - SET_REG(RCC_CR,GET_REG(RCC_CR) | 0x01000000); /* enable the pll */ - while ((GET_REG(RCC_CR) & 0x03000000) == 0); /* wait for it to come on */ - - /* Set SYSCLK as PLL */ - SET_REG(RCC_CFGR,GET_REG(RCC_CFGR) | 0x00000002); - while ((GET_REG(RCC_CFGR) & 0x00000008) == 0); /* wait for it to come on */ -#endif -} - -void setupLED (void) { - /* enable LED pin */ -#ifdef STM32F2 - pRCC->AHB1ENR |= RCC_AHB1ENR_LED; - GPIO_TypeDef *p = (GPIO_TypeDef *)LED_BANK; - /* set to output */ - p->MODER |= 1 << (2*LED); - /* Configure pins speed to 100 MHz */ - //p->OSPEEDR = 0xffffc00f; // 2 bit/port medium speed = %01 - /* Configure pins Output type to push-pull */ - //p->OTYPER = 0x00000000; - /* No pull-up, pull-down for PEx pins */ - //p->PUPDR = 0x00000000; - -#else - pRCC->APB2ENR |= RCC_APB2ENR_LED; - /* Setup LED pin as output open drain */ - SET_REG(LED_BANK_CR,(GET_REG(LED_BANK_CR) & LED_CR_MASK) | LED_CR_OUTPUT); - setPin(LED_BANK, LED); -#endif - -} - -void setupBUTTON (void) { - /* enable button pin */ -#ifdef STM32F2 - pRCC->AHB1ENR |= RCC_AHB1ENR_BUT; - GPIO_TypeDef *p = (GPIO_TypeDef *)BUTTON_BANK; - p->PUPDR |= 2 << (2*BUTTON); // pull down - //p->PUPDR |= 1 << (2*BUTTON); // pull up - p->MODER &= ~(3 << (2*BUTTON)); // input -#else - pRCC->APB2ENR |= RCC_APB2ENR_BUT; - /* Setup button pin as floating input */ - SET_REG(BUT_BANK_CR,(GET_REG(BUT_BANK_CR) & BUT_CR_MASK) | BUT_CR_INPUTMODE); - BUTTON_SETUP(BUTTON_BANK, BUTTON); -#endif - -} - -void setupFLASH() { - /* configure the HSI oscillator */ - if ((pRCC->CR & 0x01) == 0x00) { - u32 rwmVal = pRCC->CR; - rwmVal |= 0x01; - pRCC->CR = rwmVal; - } - - /* wait for it to come on */ - while ((pRCC->CR & 0x02) == 0x00) {} -} - -bool checkUserCode (u32 usrAddr) { - u32 sp = *(vu32*) usrAddr; - - if ((sp & 0xFFF87FFF) == 0x20000000) { - return (TRUE); - } else { - return (FALSE); - } -} - -void jumpToUser (u32 usrAddr) { - typedef void (*funcPtr)(void); - - u32 jumpAddr = *(vu32*) (usrAddr + 0x04); /* reset ptr in vector table */ - funcPtr usrMain = (funcPtr) jumpAddr; - - //__MSR_MSP(*(vu32*) usrAddr); /* set the users stack ptr */ - //usrMain(); /* go! */ - - - - /* tear down all the dfu related setup */ - // disable usb interrupts, clear them, turn off usb, set the disc pin - // todo pick exactly what we want to do here, now its just a conservative - -#ifdef STM32F2 - nvicDisableInterrupts(); -#else - flashLock(); - usbDsbISR(); - nvicDisableInterrupts(); - usbDsbBus(); -#endif - - systemReset(); // resets clocks and periphs, not core regs - - - __MSR_MSP(*(vu32*) usrAddr); /* set the users stack ptr */ - - setPin(LED_BANK,LED); - usrMain(); /* go! */ -} - -void nvicInit(NVIC_InitTypeDef* NVIC_InitStruct) { - u32 tmppriority = 0x00; - u32 tmpreg = 0x00; - u32 tmpmask = 0x00; - u32 tmppre = 0; - u32 tmpsub = 0x0F; - - SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE; - NVIC_TypeDef* rNVIC = (NVIC_TypeDef *) NVIC_BASE; - - - /* Compute the Corresponding IRQ Priority --------------------------------*/ - tmppriority = (0x700 - (rSCB->AIRCR & (u32)0x700))>> 0x08; - tmppre = (0x4 - tmppriority); - tmpsub = tmpsub >> tmppriority; - - tmppriority = (u32)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; - tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub; - - tmppriority = tmppriority << 0x04; - tmppriority = ((u32)tmppriority) << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08); - - tmpreg = rNVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)]; - tmpmask = (u32)0xFF << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08); - tmpreg &= ~tmpmask; - tmppriority &= tmpmask; - tmpreg |= tmppriority; - - rNVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)] = tmpreg; - - /* Enable the Selected IRQ Channels --------------------------------------*/ - rNVIC->ISER[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] = - (u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F); -} - -void nvicDisableInterrupts() { - NVIC_TypeDef* rNVIC = (NVIC_TypeDef *) NVIC_BASE; - rNVIC->ICER[0] = 0xFFFFFFFF; - rNVIC->ICER[1] = 0xFFFFFFFF; - rNVIC->ICPR[0] = 0xFFFFFFFF; - rNVIC->ICPR[1] = 0xFFFFFFFF; - - SET_REG(STK_CTRL,0x04); /* disable the systick, which operates separately from nvic */ -} - -void systemHardReset(void) { - SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE; - - /* Reset */ - rSCB->AIRCR = (u32)AIRCR_RESET_REQ; - - /* should never get here */ - while (1) { - asm volatile("nop"); - } -} - -bool flashErasePage(u32 pageAddr) { - u32 rwmVal = GET_REG(FLASH_CR); - rwmVal = FLASH_CR_PER; - SET_REG(FLASH_CR,rwmVal); - - while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {} - SET_REG(FLASH_AR,pageAddr); - SET_REG(FLASH_CR,FLASH_CR_START | FLASH_CR_PER); - while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {} - - /* todo: verify the page was erased */ - - rwmVal = 0x00; - SET_REG(FLASH_CR,rwmVal); - - return TRUE; -} - -bool flashErasePages(u32 pageAddr, u16 n) { - while (n-->0) { - if (!flashErasePage(pageAddr+FLASH_PAGE_SIZE*n)) { - return FALSE; - } - } - - return TRUE; -} - -bool flashWriteWord(u32 addr, u32 word) { - vu16 *flashAddr = (vu16*)addr; - vu32 lhWord = (vu32)word & 0x0000FFFF; - vu32 hhWord = ((vu32)word & 0xFFFF0000)>>16; - - u32 rwmVal = GET_REG(FLASH_CR); - SET_REG(FLASH_CR,FLASH_CR_PG); - - /* apparently we need not write to FLASH_AR and can - simply do a native write of a half word */ - while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {} - *(flashAddr+0x01) = (vu16)hhWord; - while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {} - *(flashAddr) = (vu16)lhWord; - while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {} - - rwmVal &= 0xFFFFFFFE; - SET_REG(FLASH_CR,rwmVal); - - /* verify the write */ - if (*(vu32*)addr != word) { - return FALSE; - } - - return TRUE; -} - -void flashLock() { - /* take down the HSI oscillator? it may be in use elsewhere */ - - /* ensure all FPEC functions disabled and lock the FPEC */ - SET_REG(FLASH_CR,0x00000080); -} - -void flashUnlock() { - /* unlock the flash */ - SET_REG(FLASH_KEYR,FLASH_KEY1); - SET_REG(FLASH_KEYR,FLASH_KEY2); -} - - - - +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +/** + * @file hardware.c + * + * @brief init routines to setup clocks, interrupts, also destructor functions. + * does not include USB stuff. EEPROM read/write functions. + * + */ + +#include "hardware.h" + +void setPin(u32 bank, u8 pin) { + u32 pinMask = 0x1 << (pin); + SET_REG(GPIO_BSRR(bank),pinMask); +} + +void resetPin(u32 bank, u8 pin) { + u32 pinMask = 0x1 << (16+pin); + SET_REG(GPIO_BSRR(bank),pinMask); +} + +bool readPin(GPIO_TypeDef * bank, u8 pin) { + // todo, implement read + //if(GET_REG(GPIO_IDR(bank)) & (0x01 << pin)) { + if(bank->IDR & (0x01 << pin)) { + return TRUE; + } else { + return FALSE; + } +} + +void strobePin(u32 bank, u8 pin, u8 count, u32 rate) { + resetPin(bank,pin); + + u32 c; + while (count-- >0) { + for (c=rate;c>0;c--) { + asm volatile ("nop"); + } + setPin(bank,pin); + for (c=rate;c>0;c--) { + asm volatile ("nop"); + } + resetPin(bank,pin); + } +} + +void systemReset(void) { +#ifdef STM32F2 + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + pRCC->CR |= (u32)0x00000001; + + /* Reset CFGR register */ + pRCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON and PLLON bits */ + pRCC->CR &= (u32)0xFEF6FFFF; + + /* Reset PLLCFGR register */ + pRCC->PLLCFGR = 0x24003010; + + /* Reset HSEBYP bit */ + pRCC->CR &= (u32)0xFFFBFFFF; + + /* Disable all interrupts */ + pRCC->CIR = 0x00000000; + +#else + SET_REG(RCC_CR, GET_REG(RCC_CR) | 0x00000001); + SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xF8FF0000); + SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFEF6FFFF); + SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFFFBFFFF); + SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xFF80FFFF); + + SET_REG(RCC_CIR, 0x00000000); /* disable all RCC interrupts */ +#endif +} + +void setupCLK (void) { +#ifdef STM32F2 +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ + u32 StartUpCounter = 0, HSEStatus = 0; + + /* Enable HSE */ + pRCC->CR |= RCC_CR_HSEON; + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = pRCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((pRCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = 0x01; + } + else + { + HSEStatus = 0x00; + } + + if (HSEStatus == 0x01) + { + /* HCLK = SYSCLK / 1*/ + pRCC->CFGR |= RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK / 2*/ + pRCC->CFGR |= RCC_CFGR_PPRE2_DIV2; + + /* PCLK1 = HCLK / 4*/ + pRCC->CFGR |= RCC_CFGR_PPRE1_DIV4; + + /* Configure the main PLL */ + pRCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + + /* Enable the main PLL */ + pRCC->CR |= RCC_CR_PLLON; + + /* Wait till the main PLL is ready */ + while((pRCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + ((FLASH_TypeDef*)FLASH)->ACR = FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS; + + /* Select the main PLL as system clock source */ + pRCC->CFGR &= ~RCC_CFGR_SW; + pRCC->CFGR |= RCC_CFGR_SW_PLL; + + /* Wait till the main PLL is used as system clock source */ + while ((pRCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +#else + /* enable HSE */ + SET_REG(RCC_CR,GET_REG(RCC_CR) | 0x00010001); + while ((GET_REG(RCC_CR) & 0x00020000) == 0); /* for it to come on */ + + /* enable flash prefetch buffer */ + SET_REG(FLASH_ACR, 0x00000012); + + /* Configure PLL */ + SET_REG(RCC_CFGR,GET_REG(RCC_CFGR) | 0x001D0400); /* pll=72Mhz,APB1=36Mhz,AHB=72Mhz */ + SET_REG(RCC_CR,GET_REG(RCC_CR) | 0x01000000); /* enable the pll */ + while ((GET_REG(RCC_CR) & 0x03000000) == 0); /* wait for it to come on */ + + /* Set SYSCLK as PLL */ + SET_REG(RCC_CFGR,GET_REG(RCC_CFGR) | 0x00000002); + while ((GET_REG(RCC_CFGR) & 0x00000008) == 0); /* wait for it to come on */ +#endif +} + +void setupLED (void) { + /* enable LED pin */ +#ifdef STM32F2 + pRCC->AHB1ENR |= RCC_AHB1ENR_LED; + GPIO_TypeDef *p = (GPIO_TypeDef *)LED_BANK; + /* set to output */ + p->MODER |= 1 << (2*LED); + /* Configure pins speed to 100 MHz */ + //p->OSPEEDR = 0xffffc00f; // 2 bit/port medium speed = %01 + /* Configure pins Output type to push-pull */ + //p->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + //p->PUPDR = 0x00000000; + +#else + pRCC->APB2ENR |= RCC_APB2ENR_LED; + /* Setup LED pin as output open drain */ + SET_REG(LED_BANK_CR,(GET_REG(LED_BANK_CR) & LED_CR_MASK) | LED_CR_OUTPUT); + setPin(LED_BANK, LED); +#endif + +} + +void setupBUTTON (void) { + /* enable button pin */ +#ifdef STM32F2 + pRCC->AHB1ENR |= RCC_AHB1ENR_BUT; + GPIO_TypeDef *p = (GPIO_TypeDef *)BUTTON_BANK; + p->PUPDR |= 2 << (2*BUTTON); // pull down + //p->PUPDR |= 1 << (2*BUTTON); // pull up + p->MODER &= ~(3 << (2*BUTTON)); // input +#else + pRCC->APB2ENR |= RCC_APB2ENR_BUT; + /* Setup button pin as floating input */ + SET_REG(BUT_BANK_CR,(GET_REG(BUT_BANK_CR) & BUT_CR_MASK) | BUT_CR_INPUTMODE); + BUTTON_SETUP(BUTTON_BANK, BUTTON); +#endif + +} + +void setupFLASH() { + /* configure the HSI oscillator */ + if ((pRCC->CR & 0x01) == 0x00) { + u32 rwmVal = pRCC->CR; + rwmVal |= 0x01; + pRCC->CR = rwmVal; + } + + /* wait for it to come on */ + while ((pRCC->CR & 0x02) == 0x00) {} +} + +bool checkUserCode (u32 usrAddr) { + u32 sp = *(vu32*) usrAddr; + + if ((sp & 0xFFF87FFF) == 0x20000000) { + return (TRUE); + } else { + return (FALSE); + } +} + +void jumpToUser (u32 usrAddr) { + typedef void (*funcPtr)(void); + + u32 jumpAddr = *(vu32*) (usrAddr + 0x04); /* reset ptr in vector table */ + funcPtr usrMain = (funcPtr) jumpAddr; + + //__MSR_MSP(*(vu32*) usrAddr); /* set the users stack ptr */ + //usrMain(); /* go! */ + + + + /* tear down all the dfu related setup */ + // disable usb interrupts, clear them, turn off usb, set the disc pin + // todo pick exactly what we want to do here, now its just a conservative + +#ifdef STM32F2 + nvicDisableInterrupts(); +#else + flashLock(); + usbDsbISR(); + nvicDisableInterrupts(); + usbDsbBus(); +#endif + + systemReset(); // resets clocks and periphs, not core regs + + + __MSR_MSP(*(vu32*) usrAddr); /* set the users stack ptr */ + + setPin(LED_BANK,LED); + usrMain(); /* go! */ +} + +void nvicInit(NVIC_InitTypeDef* NVIC_InitStruct) { + u32 tmppriority = 0x00; + u32 tmpreg = 0x00; + u32 tmpmask = 0x00; + u32 tmppre = 0; + u32 tmpsub = 0x0F; + + SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE; + NVIC_TypeDef* rNVIC = (NVIC_TypeDef *) NVIC_BASE; + + + /* Compute the Corresponding IRQ Priority --------------------------------*/ + tmppriority = (0x700 - (rSCB->AIRCR & (u32)0x700))>> 0x08; + tmppre = (0x4 - tmppriority); + tmpsub = tmpsub >> tmppriority; + + tmppriority = (u32)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; + tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub; + + tmppriority = tmppriority << 0x04; + tmppriority = ((u32)tmppriority) << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08); + + tmpreg = rNVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)]; + tmpmask = (u32)0xFF << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08); + tmpreg &= ~tmpmask; + tmppriority &= tmpmask; + tmpreg |= tmppriority; + + rNVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)] = tmpreg; + + /* Enable the Selected IRQ Channels --------------------------------------*/ + rNVIC->ISER[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] = + (u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F); +} + +void nvicDisableInterrupts() { + NVIC_TypeDef* rNVIC = (NVIC_TypeDef *) NVIC_BASE; + rNVIC->ICER[0] = 0xFFFFFFFF; + rNVIC->ICER[1] = 0xFFFFFFFF; + rNVIC->ICPR[0] = 0xFFFFFFFF; + rNVIC->ICPR[1] = 0xFFFFFFFF; + + SET_REG(STK_CTRL,0x04); /* disable the systick, which operates separately from nvic */ +} + +void systemHardReset(void) { + SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE; + + /* Reset */ + rSCB->AIRCR = (u32)AIRCR_RESET_REQ; + + /* should never get here */ + while (1) { + asm volatile("nop"); + } +} + +bool flashErasePage(u32 pageAddr) { + u32 rwmVal = GET_REG(FLASH_CR); + rwmVal = FLASH_CR_PER; + SET_REG(FLASH_CR,rwmVal); + + while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {} + SET_REG(FLASH_AR,pageAddr); + SET_REG(FLASH_CR,FLASH_CR_START | FLASH_CR_PER); + while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {} + + /* todo: verify the page was erased */ + + rwmVal = 0x00; + SET_REG(FLASH_CR,rwmVal); + + return TRUE; +} + +bool flashErasePages(u32 pageAddr, u16 n) { + while (n-->0) { + if (!flashErasePage(pageAddr+FLASH_PAGE_SIZE*n)) { + return FALSE; + } + } + + return TRUE; +} + +bool flashWriteWord(u32 addr, u32 word) { + vu16 *flashAddr = (vu16*)addr; + vu32 lhWord = (vu32)word & 0x0000FFFF; + vu32 hhWord = ((vu32)word & 0xFFFF0000)>>16; + + u32 rwmVal = GET_REG(FLASH_CR); + SET_REG(FLASH_CR,FLASH_CR_PG); + + /* apparently we need not write to FLASH_AR and can + simply do a native write of a half word */ + while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {} + *(flashAddr+0x01) = (vu16)hhWord; + while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {} + *(flashAddr) = (vu16)lhWord; + while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {} + + rwmVal &= 0xFFFFFFFE; + SET_REG(FLASH_CR,rwmVal); + + /* verify the write */ + if (*(vu32*)addr != word) { + return FALSE; + } + + return TRUE; +} + +void flashLock() { + /* take down the HSI oscillator? it may be in use elsewhere */ + + /* ensure all FPEC functions disabled and lock the FPEC */ + SET_REG(FLASH_CR,0x00000080); +} + +void flashUnlock() { + /* unlock the flash */ + SET_REG(FLASH_KEYR,FLASH_KEY1); + SET_REG(FLASH_KEYR,FLASH_KEY2); +} + + + + diff --git a/Libmaple/maple-bootloader/hardware.h b/Libmaple/maple-bootloader/hardware.h index 1185f91f..89359949 100644 --- a/Libmaple/maple-bootloader/hardware.h +++ b/Libmaple/maple-bootloader/hardware.h @@ -1,515 +1,515 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -#ifndef __HARDWARE_H -#define __HARDWARE_H - -#include "stm32f10x_type.h" -#include "cortexm3_macro.h" -#include "common.h" - -/* macro'd register and peripheral definitions */ -#ifdef STM32F2 -#define PERIPH_BASE ((u32)0x40000000) /*!< Peripheral base address in the alias region */ -#define APB1PERIPH_BASE PERIPH_BASE -#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) -#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) -#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) - -/*!< AHB1 peripherals */ -#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) -#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400) -#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) -#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00) -#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000) -#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400) -#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800) -#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00) -#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000) -#define CRC_BASE (AHB1PERIPH_BASE + 0x3000) -#define RCC_BASE (AHB1PERIPH_BASE + 0x3800) -#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) - - -#define RCC ((u32)RCC_BASE) -#define FLASH ((u32)FLASH_R_BASE) -#define GPIOA ((u32)GPIOA_BASE) -#define GPIOB ((u32)GPIOB_BASE) -#define GPIOC ((u32)GPIOC_BASE) -#define GPIOD ((u32)GPIOD_BASE) -#define GPIOE ((u32)GPIOE_BASE) -#define GPIOF ((u32)GPIOF_BASE) -#define GPIOG ((u32)GPIOG_BASE) -#else -#define RCC ((u32)0x40021000) -#define FLASH ((u32)0x40022000) -#define GPIOA ((u32)0x40010800) -#define GPIOB ((u32)0x40010C00) -#define GPIOC ((u32)0x40011000) -#define GPIOD ((u32)0x40011400) -#define GPIOE ((u32)0x40011800) -#define GPIOF ((u32)0x40011C00) -#define GPIOG ((u32)0x40012000) - -#define RCC_CR (RCC) -#define RCC_CFGR (RCC + 0x04) -#define RCC_CIR (RCC + 0x08) -#define RCC_AHBENR (RCC + 0x14) -#define RCC_APB2ENR (RCC + 0x18) -#define RCC_APB1ENR (RCC + 0x16) -#endif - -#define FLASH_ACR (FLASH + 0x00) -#define FLASH_KEYR (FLASH + 0x04) -#define FLASH_OPTKEYR (FLASH + 0x08) -#define FLASH_SR (FLASH + 0x0C) -#define FLASH_CR (FLASH + 0x10) -#define FLASH_AR (FLASH + 0x14) -#define FLASH_OBR (FLASH + 0x1C) -#define FLASH_WRPR (FLASH + 0x20) - -#define FLASH_KEY1 0x45670123 -#define FLASH_KEY2 0xCDEF89AB -#define FLASH_RDPRT 0x00A5 -#define FLASH_SR_BSY 0x01 -#define FLASH_CR_PER 0x02 -#define FLASH_CR_PG 0x01 -#define FLASH_CR_START 0x40 - -#define GPIO_CRL(port) port -#define GPIO_CRH(port) (port+0x04) -#define GPIO_IDR(port) (port+0x08) -#define GPIO_ODR(port) (port+0x0c) - -#ifdef STM32F2 -#define GPIO_BSRR(port) (port+0x18) -#else -#define GPIO_BSRR(port) (port+0x10) -#endif - -#define SCS_BASE ((u32)0xE000E000) -#define NVIC_BASE (SCS_BASE + 0x0100) -#define SCB_BASE (SCS_BASE + 0x0D00) - - -#define SCS 0xE000E000 -#define NVIC (SCS+0x100) -#define SCB (SCS+0xD00) -#define STK (SCS+0x10) - -#define SCB_VTOR (SCB+0x08) -#define STK_CTRL (STK+0x00) - -/* -#define TIM1_APB2_ENB ((u32)0x00000800) -#define TIM1 ((u32)0x40012C00) -#define TIM1_PSC (TIM1+0x28) -#define TIM1_ARR (TIM1+0x2C) -#define TIM1_RCR (TIM1+0x30) -#define TIM1_CR1 (TIM1+0x00) -#define TIM1_CR2 (TIM1+0x04) -#define TIM1_DIER (TIM1+0x0C) -#define TIM1_UP_IRQ_Channel ((u8)0x19) - -#define TIM2_IRQ ((u8)0x1C) -*/ - -#define USB_HP_IRQ ((u8)0x13) -#define USB_LP_IRQ ((u8)0x14) - - -/* AIRCR */ -#define AIRCR_RESET 0x05FA0000 -#define AIRCR_RESET_REQ (AIRCR_RESET | (u32)0x04); - -/* temporary copyage of example from kiel */ -#define __VAL(__TIMCLK, __PERIOD) ((__TIMCLK/1000000UL)*__PERIOD) -#define __PSC(__TIMCLK, __PERIOD) (((__VAL(__TIMCLK, __PERIOD)+49999UL)/50000UL) - 1) -#define __ARR(__TIMCLK, __PERIOD) ((__VAL(__TIMCLK, __PERIOD)/(__PSC(__TIMCLK, __PERIOD)+1)) - 1) - -#define SET_REG(addr,val) do { *(vu32*)(addr)=(val); } while(0) -#define GET_REG(addr) (*(vu32*)(addr)) - -/* todo: there must be some major misunderstanding in how we access regs. The direct access approach (GET_REG) - causes the usb init to fail upon trying to activate RCC_APB1 |= 0x00800000. However, using the struct approach - from ST, it works fine...temporarily switching to that approach */ -#ifdef STM32F2 -/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ -#define PLL_M 8 -#define PLL_N 240 - -/* SYSCLK = PLL_VCO / PLL_P */ -#define PLL_P 2 - -/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ -#define PLL_Q 5 - -#define uint16_t u16 -#define uint32_t u32 -#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ - -/******************************************************************************/ -/* */ -/* Reset and Clock Control */ -/* */ -/******************************************************************************/ -/******************** Bit definition for RCC_CR register ********************/ -#define RCC_CR_HSION ((uint32_t)0x00000001) -#define RCC_CR_HSIRDY ((uint32_t)0x00000002) - -#define RCC_CR_HSITRIM ((uint32_t)0x000000F8) -#define RCC_CR_HSITRIM_0 ((uint32_t)0x00000008)/*!RAM - -/* - * for some STRx devices, the beginning of the startup code is stored in the .flashtext section, - * which goes to FLASH - */ - .flashtext : - { - . = ALIGN(4); - KEEP (*(.flashtext)) /* Startup code */ - . = ALIGN(4); - } >RAM - - /* - * the program code is stored in the .text section, which goes to Flash - */ - .text : - { - . = ALIGN(4); - *(.text) /* remaining code */ - *(.text.*) /* remaining code */ - *(.rodata) /* read-only data (constants) */ - *(.rodata*) - *(.glue_7) - *(.glue_7t) - . = ALIGN(4); - _etext = .; - _sidata = _etext; /* Uused by the startup in order to initialize the .data secion */ - } >RAM - -/* - * This is the initialized data section. It is stored in RAM but the initial values - * are held in flash and copied to RAM by the startup code - */ - .data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */ - { - . = ALIGN(4); - _sdata = . ; /* Used by the startup in order to initialize the .data section */ - KEEP( *(.data) ) - KEEP( *(.data.*) ) - . = ALIGN(4); - _edata = . ; /* Used by the startup in order to initialize the .data section */ - } >RAM - - - -/* - * This is the uninitialized data section. Date here is stored in RAM and will be - * set to zero by the startup code. - */ - .bss : - { - . = ALIGN(4); - _sbss = .; /* Used by the startup in order to initialize the .bss section */ - *(.bss) - *(COMMON) - . = ALIGN(4); - _ebss = . ; /* Used by the startup in order to initialize the .bss section */ - } >RAM - -PROVIDE ( end = _ebss ); -PROVIDE ( _end = _ebss ); - -/* - * This is the user stack section - * This is just to check that there is enough RAM left for the User mode stack - * It should generate an error if it's full. - */ - ._usrstack : - { - . = ALIGN(4); - _susrstack = . ; - . = . + _Minimum_Stack_Size ; - . = ALIGN(4); - _eusrstack = . ; - } >RAM - -/* - * after that it's only debugging information. - */ - -/* remove the debugging information from the standard libraries */ -DISCARD : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - -/* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -/* - * DWARF debug sections. - * Symbols in the DWARF debugging sections are relative to the beginning - * of the section so we begin them at 0. - */ - -/* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } -/* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } -/* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } -/* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } -/* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} +/* +Default linker script for STM32F10x_128K_20K +Original Copyright RAISONANCE S.A.S. 2008 +Modified P Harrison May 2009 +*/ + +/* + * Default stack sizes. + * + * These are used by the startup in order to allocate stacks for the different modes. + * PROVIDE" allows to easily override these values from an object file or the commmand line. + */ + +__Stack_Size = 1024 ; +PROVIDE ( _Stack_Size = __Stack_Size ) ; +__Stack_Init = _estack - __Stack_Size ; +PROVIDE ( _Stack_Init = __Stack_Init ) ; + +/* + *There will be a link error if there is not this amount of RAM free at the end. + */ +_Minimum_Stack_Size = 0x100 ; + + +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000C00, LENGTH = 17K +} + +/* higher address of the user mode stack */ +_estack = 0x20005000; +_magicRate = 0x5000; +SECTIONS +{ +/* + * for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, + * which goes to FLASH + */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >RAM + +/* + * for some STRx devices, the beginning of the startup code is stored in the .flashtext section, + * which goes to FLASH + */ + .flashtext : + { + . = ALIGN(4); + KEEP (*(.flashtext)) /* Startup code */ + . = ALIGN(4); + } >RAM + + /* + * the program code is stored in the .text section, which goes to Flash + */ + .text : + { + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); + _etext = .; + _sidata = _etext; /* Uused by the startup in order to initialize the .data secion */ + } >RAM + +/* + * This is the initialized data section. It is stored in RAM but the initial values + * are held in flash and copied to RAM by the startup code + */ + .data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */ + { + . = ALIGN(4); + _sdata = . ; /* Used by the startup in order to initialize the .data section */ + KEEP( *(.data) ) + KEEP( *(.data.*) ) + . = ALIGN(4); + _edata = . ; /* Used by the startup in order to initialize the .data section */ + } >RAM + + + +/* + * This is the uninitialized data section. Date here is stored in RAM and will be + * set to zero by the startup code. + */ + .bss : + { + . = ALIGN(4); + _sbss = .; /* Used by the startup in order to initialize the .bss section */ + *(.bss) + *(COMMON) + . = ALIGN(4); + _ebss = . ; /* Used by the startup in order to initialize the .bss section */ + } >RAM + +PROVIDE ( end = _ebss ); +PROVIDE ( _end = _ebss ); + +/* + * This is the user stack section + * This is just to check that there is enough RAM left for the User mode stack + * It should generate an error if it's full. + */ + ._usrstack : + { + . = ALIGN(4); + _susrstack = . ; + . = . + _Minimum_Stack_Size ; + . = ALIGN(4); + _eusrstack = . ; + } >RAM + +/* + * after that it's only debugging information. + */ + +/* remove the debugging information from the standard libraries */ +DISCARD : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + +/* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +/* + * DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. + */ + +/* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } +/* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } +/* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } +/* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } +/* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/Libmaple/maple-bootloader/stm32_lib/c_only_md_flash128k_ram20k.ld b/Libmaple/maple-bootloader/stm32_lib/c_only_md_flash128k_ram20k.ld index 4e10c375..ff1b72b0 100644 --- a/Libmaple/maple-bootloader/stm32_lib/c_only_md_flash128k_ram20k.ld +++ b/Libmaple/maple-bootloader/stm32_lib/c_only_md_flash128k_ram20k.ld @@ -1,172 +1,172 @@ -/* -Default linker script for STM32F10x_128K_20K -Original Copyright RAISONANCE S.A.S. 2008 -Modified P Harrison May 2009 -*/ - -/* - * Default stack sizes. - * - * These are used by the startup in order to allocate stacks for the different modes. - * PROVIDE" allows to easily override these values from an object file or the commmand line. - */ - -__Stack_Size = 1024 ; -PROVIDE ( _Stack_Size = __Stack_Size ) ; -__Stack_Init = _estack - __Stack_Size ; -PROVIDE ( _Stack_Init = __Stack_Init ) ; - -/* - *There will be a link error if there is not this amount of RAM free at the end. - */ -_Minimum_Stack_Size = 0x100 ; - - -MEMORY -{ - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K -} - -/* higher address of the user mode stack */ -_estack = 0x20005000; - -SECTIONS -{ -/* - * for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, - * which goes to FLASH - */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH - -/* - * for some STRx devices, the beginning of the startup code is stored in the .flashtext section, - * which goes to FLASH - */ - .flashtext : - { - . = ALIGN(4); - KEEP (*(.flashtext)) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* - * the program code is stored in the .text section, which goes to Flash - */ - .text : - { - . = ALIGN(4); - *(.text) /* remaining code */ - *(.text.*) /* remaining code */ - *(.rodata) /* read-only data (constants) */ - *(.rodata*) - *(.glue_7) - *(.glue_7t) - . = ALIGN(4); - _etext = .; - _sidata = _etext; - } >FLASH - -/* - * This is the initialized data section. It is stored in RAM but the initial values - * are held in flash and copied to RAM by the startup code - */ - -/* we copy the important program globals vector in RAM as well, so that users can fool with it */ - .data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */ - { - . = ALIGN(4); - _sdata = . ; /* Used by the startup in order to initialize the .data section */ - KEEP( *(.data) ) - KEEP( *(.data.*) ) - . = ALIGN(4); - _edata = . ; /* Used by the startup in order to initialize the .data section */ - } >RAM - - - -/* - * This is the uninitialized data section. Date here is stored in RAM and will be - * set to zero by the startup code. - */ - .bss : - { - . = ALIGN(4); - _sbss = .; /* Used by the startup in order to initialize the .bss section */ - *(.bss) - *(COMMON) - . = ALIGN(4); - _ebss = . ; /* Used by the startup in order to initialize the .bss section */ - } >RAM - -PROVIDE ( end = _ebss ); -PROVIDE ( _end = _ebss ); - -/* - * This is the user stack section - * This is just to check that there is enough RAM left for the User mode stack - * It should generate an error if it's full. - */ - ._usrstack : - { - . = ALIGN(4); - _susrstack = . ; - . = . + _Minimum_Stack_Size ; - . = ALIGN(4); - _eusrstack = . ; - } >RAM - -/* - * after that it's only debugging information. - */ - -/* remove the debugging information from the standard libraries */ -DISCARD : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - -/* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -/* - * DWARF debug sections. - * Symbols in the DWARF debugging sections are relative to the beginning - * of the section so we begin them at 0. - */ - -/* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } -/* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } -/* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } -/* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } -/* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} +/* +Default linker script for STM32F10x_128K_20K +Original Copyright RAISONANCE S.A.S. 2008 +Modified P Harrison May 2009 +*/ + +/* + * Default stack sizes. + * + * These are used by the startup in order to allocate stacks for the different modes. + * PROVIDE" allows to easily override these values from an object file or the commmand line. + */ + +__Stack_Size = 1024 ; +PROVIDE ( _Stack_Size = __Stack_Size ) ; +__Stack_Init = _estack - __Stack_Size ; +PROVIDE ( _Stack_Init = __Stack_Init ) ; + +/* + *There will be a link error if there is not this amount of RAM free at the end. + */ +_Minimum_Stack_Size = 0x100 ; + + +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K +} + +/* higher address of the user mode stack */ +_estack = 0x20005000; + +SECTIONS +{ +/* + * for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, + * which goes to FLASH + */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + +/* + * for some STRx devices, the beginning of the startup code is stored in the .flashtext section, + * which goes to FLASH + */ + .flashtext : + { + . = ALIGN(4); + KEEP (*(.flashtext)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* + * the program code is stored in the .text section, which goes to Flash + */ + .text : + { + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); + _etext = .; + _sidata = _etext; + } >FLASH + +/* + * This is the initialized data section. It is stored in RAM but the initial values + * are held in flash and copied to RAM by the startup code + */ + +/* we copy the important program globals vector in RAM as well, so that users can fool with it */ + .data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */ + { + . = ALIGN(4); + _sdata = . ; /* Used by the startup in order to initialize the .data section */ + KEEP( *(.data) ) + KEEP( *(.data.*) ) + . = ALIGN(4); + _edata = . ; /* Used by the startup in order to initialize the .data section */ + } >RAM + + + +/* + * This is the uninitialized data section. Date here is stored in RAM and will be + * set to zero by the startup code. + */ + .bss : + { + . = ALIGN(4); + _sbss = .; /* Used by the startup in order to initialize the .bss section */ + *(.bss) + *(COMMON) + . = ALIGN(4); + _ebss = . ; /* Used by the startup in order to initialize the .bss section */ + } >RAM + +PROVIDE ( end = _ebss ); +PROVIDE ( _end = _ebss ); + +/* + * This is the user stack section + * This is just to check that there is enough RAM left for the User mode stack + * It should generate an error if it's full. + */ + ._usrstack : + { + . = ALIGN(4); + _susrstack = . ; + . = . + _Minimum_Stack_Size ; + . = ALIGN(4); + _eusrstack = . ; + } >RAM + +/* + * after that it's only debugging information. + */ + +/* remove the debugging information from the standard libraries */ +DISCARD : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + +/* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +/* + * DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. + */ + +/* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } +/* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } +/* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } +/* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } +/* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/Libmaple/maple-bootloader/stm32_lib/c_only_md_flash512k_ram64k.ld b/Libmaple/maple-bootloader/stm32_lib/c_only_md_flash512k_ram64k.ld index 6f04fb1c..23140a3b 100644 --- a/Libmaple/maple-bootloader/stm32_lib/c_only_md_flash512k_ram64k.ld +++ b/Libmaple/maple-bootloader/stm32_lib/c_only_md_flash512k_ram64k.ld @@ -1,172 +1,172 @@ -/* -Default linker script for STM32F10x_128K_20K -Original Copyright RAISONANCE S.A.S. 2008 -Modified P Harrison May 2009 -*/ - -/* - * Default stack sizes. - * - * These are used by the startup in order to allocate stacks for the different modes. - * PROVIDE" allows to easily override these values from an object file or the commmand line. - */ - -__Stack_Size = 1024 ; -PROVIDE ( _Stack_Size = __Stack_Size ) ; -__Stack_Init = _estack - __Stack_Size ; -PROVIDE ( _Stack_Init = __Stack_Init ) ; - -/* - *There will be a link error if there is not this amount of RAM free at the end. - */ -_Minimum_Stack_Size = 0x100 ; - - -MEMORY -{ - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K -} - -/* higher address of the user mode stack */ -_estack = 0x20010000; - -SECTIONS -{ -/* - * for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, - * which goes to FLASH - */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH - -/* - * for some STRx devices, the beginning of the startup code is stored in the .flashtext section, - * which goes to FLASH - */ - .flashtext : - { - . = ALIGN(4); - KEEP (*(.flashtext)) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* - * the program code is stored in the .text section, which goes to Flash - */ - .text : - { - . = ALIGN(4); - *(.text) /* remaining code */ - *(.text.*) /* remaining code */ - *(.rodata) /* read-only data (constants) */ - *(.rodata*) - *(.glue_7) - *(.glue_7t) - . = ALIGN(4); - _etext = .; - _sidata = _etext; - } >FLASH - -/* - * This is the initialized data section. It is stored in RAM but the initial values - * are held in flash and copied to RAM by the startup code - */ - -/* we copy the important program globals vector in RAM as well, so that users can fool with it */ - .data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */ - { - . = ALIGN(4); - _sdata = . ; /* Used by the startup in order to initialize the .data section */ - KEEP( *(.data) ) - KEEP( *(.data.*) ) - . = ALIGN(4); - _edata = . ; /* Used by the startup in order to initialize the .data section */ - } >RAM - - - -/* - * This is the uninitialized data section. Date here is stored in RAM and will be - * set to zero by the startup code. - */ - .bss : - { - . = ALIGN(4); - _sbss = .; /* Used by the startup in order to initialize the .bss section */ - *(.bss) - *(COMMON) - . = ALIGN(4); - _ebss = . ; /* Used by the startup in order to initialize the .bss section */ - } >RAM - -PROVIDE ( end = _ebss ); -PROVIDE ( _end = _ebss ); - -/* - * This is the user stack section - * This is just to check that there is enough RAM left for the User mode stack - * It should generate an error if it's full. - */ - ._usrstack : - { - . = ALIGN(4); - _susrstack = . ; - . = . + _Minimum_Stack_Size ; - . = ALIGN(4); - _eusrstack = . ; - } >RAM - -/* - * after that it's only debugging information. - */ - -/* remove the debugging information from the standard libraries */ -DISCARD : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - -/* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -/* - * DWARF debug sections. - * Symbols in the DWARF debugging sections are relative to the beginning - * of the section so we begin them at 0. - */ - -/* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } -/* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } -/* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } -/* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } -/* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} +/* +Default linker script for STM32F10x_128K_20K +Original Copyright RAISONANCE S.A.S. 2008 +Modified P Harrison May 2009 +*/ + +/* + * Default stack sizes. + * + * These are used by the startup in order to allocate stacks for the different modes. + * PROVIDE" allows to easily override these values from an object file or the commmand line. + */ + +__Stack_Size = 1024 ; +PROVIDE ( _Stack_Size = __Stack_Size ) ; +__Stack_Init = _estack - __Stack_Size ; +PROVIDE ( _Stack_Init = __Stack_Init ) ; + +/* + *There will be a link error if there is not this amount of RAM free at the end. + */ +_Minimum_Stack_Size = 0x100 ; + + +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +/* higher address of the user mode stack */ +_estack = 0x20010000; + +SECTIONS +{ +/* + * for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, + * which goes to FLASH + */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + +/* + * for some STRx devices, the beginning of the startup code is stored in the .flashtext section, + * which goes to FLASH + */ + .flashtext : + { + . = ALIGN(4); + KEEP (*(.flashtext)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* + * the program code is stored in the .text section, which goes to Flash + */ + .text : + { + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); + _etext = .; + _sidata = _etext; + } >FLASH + +/* + * This is the initialized data section. It is stored in RAM but the initial values + * are held in flash and copied to RAM by the startup code + */ + +/* we copy the important program globals vector in RAM as well, so that users can fool with it */ + .data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */ + { + . = ALIGN(4); + _sdata = . ; /* Used by the startup in order to initialize the .data section */ + KEEP( *(.data) ) + KEEP( *(.data.*) ) + . = ALIGN(4); + _edata = . ; /* Used by the startup in order to initialize the .data section */ + } >RAM + + + +/* + * This is the uninitialized data section. Date here is stored in RAM and will be + * set to zero by the startup code. + */ + .bss : + { + . = ALIGN(4); + _sbss = .; /* Used by the startup in order to initialize the .bss section */ + *(.bss) + *(COMMON) + . = ALIGN(4); + _ebss = . ; /* Used by the startup in order to initialize the .bss section */ + } >RAM + +PROVIDE ( end = _ebss ); +PROVIDE ( _end = _ebss ); + +/* + * This is the user stack section + * This is just to check that there is enough RAM left for the User mode stack + * It should generate an error if it's full. + */ + ._usrstack : + { + . = ALIGN(4); + _susrstack = . ; + . = . + _Minimum_Stack_Size ; + . = ALIGN(4); + _eusrstack = . ; + } >RAM + +/* + * after that it's only debugging information. + */ + +/* remove the debugging information from the standard libraries */ +DISCARD : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + +/* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +/* + * DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. + */ + +/* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } +/* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } +/* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } +/* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } +/* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/Libmaple/maple-bootloader/stm32_lib/c_only_startup.s b/Libmaple/maple-bootloader/stm32_lib/c_only_startup.s index 7e5d92de..73a0da47 100644 --- a/Libmaple/maple-bootloader/stm32_lib/c_only_startup.s +++ b/Libmaple/maple-bootloader/stm32_lib/c_only_startup.s @@ -1,367 +1,367 @@ -/** - ****************************************************************************** - * @file startup_stm32f10x_md.s - * @author MCD Application Team - * @version V3.1.0 - * @date 06/19/2009 - * @brief STM32F10x Medium Density Devices vector table for RIDE7 toolchain. - * This module performs: - * - Set the initial SP - * - Set the initial PC == Reset_Handler, - * - Set the vector table entries with the exceptions ISR address - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M3 processor is in Thread mode, - * priority is Privileged, and the Stack is set to Main. - ******************************************************************************* - * @copy - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2009 STMicroelectronics

- */ - - .syntax unified - .cpu cortex-m3 - .fpu softvfp - .thumb - -.global g_pfnVectors -.global SystemInit_ExtMemCtl_Dummy -.global Default_Handler - -/* start address for the initialization values of the .data section. -defined in linker script */ -.word _sidata -/* start address for the .data section. defined in linker script */ -.word _sdata -/* end address for the .data section. defined in linker script */ -.word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss - -.equ BootRAM, 0xF108F85F -/** - * @brief 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 main() routine is called. - * @param None - * @retval : None -*/ - - .section .text.Reset_Handler - .weak Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - -/* Copy the data segment initializers from flash to SRAM */ - movs r1, #0 - b LoopCopyDataInit - -CopyDataInit: - ldr r3, =_sidata - ldr r3, [r3, r1] - str r3, [r0, r1] - adds r1, r1, #4 - -LoopCopyDataInit: - ldr r0, =_sdata - ldr r3, =_edata - adds r2, r0, r1 - cmp r2, r3 - bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss -/* Call the application's entry point.*/ - bl main - bx lr -.size Reset_Handler, .-Reset_Handler - -/** - * @brief This is the code that gets called when the processor receives an - * unexpected interrupt. This simply enters an infinite loop, preserving - * the system state for examination by a debugger. - * - * @param None - * @retval : None -*/ - .section .text.Default_Handler,"ax",%progbits -Default_Handler: -Infinite_Loop: - b Infinite_Loop - .size Default_Handler, .-Default_Handler -/****************************************************************************** -* -* The minimal vector table for a Cortex M3. Note that the proper constructs -* must be placed on this to ensure that it ends up at physical address -* 0x0000.0000. -* -******************************************************************************/ - .section .isr_vector,"a",%progbits - .type g_pfnVectors, %object - .size g_pfnVectors, .-g_pfnVectors - - -g_pfnVectors: - .word _estack - .word Reset_Handler - .word NMI_Handler - .word HardFault_Handler - .word MemManage_Handler - .word BusFault_Handler - .word UsageFault_Handler - .word 0 - .word 0 - .word 0 - .word 0 - .word SVC_Handler - .word DebugMon_Handler - .word 0 - .word PendSV_Handler - .word SysTick_Handler - .word WWDG_IRQHandler - .word PVD_IRQHandler - .word TAMPER_IRQHandler - .word RTC_IRQHandler - .word FLASH_IRQHandler - .word RCC_IRQHandler - .word EXTI0_IRQHandler - .word EXTI1_IRQHandler - .word EXTI2_IRQHandler - .word EXTI3_IRQHandler - .word EXTI4_IRQHandler - .word DMA1_Channel1_IRQHandler - .word DMA1_Channel2_IRQHandler - .word DMA1_Channel3_IRQHandler - .word DMA1_Channel4_IRQHandler - .word DMA1_Channel5_IRQHandler - .word DMA1_Channel6_IRQHandler - .word DMA1_Channel7_IRQHandler - .word ADC1_2_IRQHandler - .word USB_HP_CAN1_TX_IRQHandler - .word USB_LP_CAN1_RX0_IRQHandler - .word CAN1_RX1_IRQHandler - .word CAN1_SCE_IRQHandler - .word EXTI9_5_IRQHandler - .word TIM1_BRK_IRQHandler - .word TIM1_UP_IRQHandler - .word TIM1_TRG_COM_IRQHandler - .word TIM1_CC_IRQHandler - .word TIM2_IRQHandler - .word TIM3_IRQHandler - .word TIM4_IRQHandler - .word I2C1_EV_IRQHandler - .word I2C1_ER_IRQHandler - .word I2C2_EV_IRQHandler - .word I2C2_ER_IRQHandler - .word SPI1_IRQHandler - .word SPI2_IRQHandler - .word USART1_IRQHandler - .word USART2_IRQHandler - .word USART3_IRQHandler - .word EXTI15_10_IRQHandler - .word RTCAlarm_IRQHandler - .word USBWakeUp_IRQHandler -/* - .word TIM8_BRK - .word TIM8_UP - .word TIM8_TRG_COM - .word TIM8_CC - .word ADC3 - .word FSMC - .word SDIO - .word TIM5 - .word SPI3 - .word UART4 - .word UART5 - .word TIM6 - .word TIM7 - .word DMA2_Channel1 - .word DMA2_Channel2 - .word DMA2_Channel3 - .word DMA2_Channel5 -*/ - .word BootRAM /* @0x108. This is for boot in RAM mode for - STM32F10x Medium Density devices. */ - -/******************************************************************************* -* -* Provide weak aliases for each Exception handler to the Default_Handler. -* As they are weak aliases, any function with the same name will override -* this definition. -* -*******************************************************************************/ - - .weak NMI_Handler - .thumb_set NMI_Handler,Default_Handler - - .weak HardFault_Handler - .thumb_set HardFault_Handler,Default_Handler - - .weak MemManage_Handler - .thumb_set MemManage_Handler,Default_Handler - - .weak BusFault_Handler - .thumb_set BusFault_Handler,Default_Handler - - .weak UsageFault_Handler - .thumb_set UsageFault_Handler,Default_Handler - - .weak SVC_Handler - .thumb_set SVC_Handler,Default_Handler - - .weak DebugMon_Handler - .thumb_set DebugMon_Handler,Default_Handler - - .weak PendSV_Handler - .thumb_set PendSV_Handler,Default_Handler - - .weak SysTick_Handler - .thumb_set SysTick_Handler,Default_Handler - - .weak WWDG_IRQHandler - .thumb_set WWDG_IRQHandler,Default_Handler - - .weak PVD_IRQHandler - .thumb_set PVD_IRQHandler,Default_Handler - - .weak TAMPER_IRQHandler - .thumb_set TAMPER_IRQHandler,Default_Handler - - .weak RTC_IRQHandler - .thumb_set RTC_IRQHandler,Default_Handler - - .weak FLASH_IRQHandler - .thumb_set FLASH_IRQHandler,Default_Handler - - .weak RCC_IRQHandler - .thumb_set RCC_IRQHandler,Default_Handler - - .weak EXTI0_IRQHandler - .thumb_set EXTI0_IRQHandler,Default_Handler - - .weak EXTI1_IRQHandler - .thumb_set EXTI1_IRQHandler,Default_Handler - - .weak EXTI2_IRQHandler - .thumb_set EXTI2_IRQHandler,Default_Handler - - .weak EXTI3_IRQHandler - .thumb_set EXTI3_IRQHandler,Default_Handler - - .weak EXTI4_IRQHandler - .thumb_set EXTI4_IRQHandler,Default_Handler - - .weak DMA1_Channel1_IRQHandler - .thumb_set DMA1_Channel1_IRQHandler,Default_Handler - - .weak DMA1_Channel2_IRQHandler - .thumb_set DMA1_Channel2_IRQHandler,Default_Handler - - .weak DMA1_Channel3_IRQHandler - .thumb_set DMA1_Channel3_IRQHandler,Default_Handler - - .weak DMA1_Channel4_IRQHandler - .thumb_set DMA1_Channel4_IRQHandler,Default_Handler - - .weak DMA1_Channel5_IRQHandler - .thumb_set DMA1_Channel5_IRQHandler,Default_Handler - - .weak DMA1_Channel6_IRQHandler - .thumb_set DMA1_Channel6_IRQHandler,Default_Handler - - .weak DMA1_Channel7_IRQHandler - .thumb_set DMA1_Channel7_IRQHandler,Default_Handler - - .weak ADC1_2_IRQHandler - .thumb_set ADC1_2_IRQHandler,Default_Handler - - .weak USB_HP_CAN1_TX_IRQHandler - .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler - - .weak USB_LP_CAN1_RX0_IRQHandler - .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler - - .weak CAN1_RX1_IRQHandler - .thumb_set CAN1_RX1_IRQHandler,Default_Handler - - .weak CAN1_SCE_IRQHandler - .thumb_set CAN1_SCE_IRQHandler,Default_Handler - - .weak EXTI9_5_IRQHandler - .thumb_set EXTI9_5_IRQHandler,Default_Handler - - .weak TIM1_BRK_IRQHandler - .thumb_set TIM1_BRK_IRQHandler,Default_Handler - - .weak TIM1_UP_IRQHandler - .thumb_set TIM1_UP_IRQHandler,Default_Handler - - .weak TIM1_TRG_COM_IRQHandler - .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler - - .weak TIM1_CC_IRQHandler - .thumb_set TIM1_CC_IRQHandler,Default_Handler - - .weak TIM2_IRQHandler - .thumb_set TIM2_IRQHandler,Default_Handler - - .weak TIM3_IRQHandler - .thumb_set TIM3_IRQHandler,Default_Handler - - .weak TIM4_IRQHandler - .thumb_set TIM4_IRQHandler,Default_Handler - - .weak I2C1_EV_IRQHandler - .thumb_set I2C1_EV_IRQHandler,Default_Handler - - .weak I2C1_ER_IRQHandler - .thumb_set I2C1_ER_IRQHandler,Default_Handler - - .weak I2C2_EV_IRQHandler - .thumb_set I2C2_EV_IRQHandler,Default_Handler - - .weak I2C2_ER_IRQHandler - .thumb_set I2C2_ER_IRQHandler,Default_Handler - - .weak SPI1_IRQHandler - .thumb_set SPI1_IRQHandler,Default_Handler - - .weak SPI2_IRQHandler - .thumb_set SPI2_IRQHandler,Default_Handler - - .weak USART1_IRQHandler - .thumb_set USART1_IRQHandler,Default_Handler - - .weak USART2_IRQHandler - .thumb_set USART2_IRQHandler,Default_Handler - - .weak USART3_IRQHandler - .thumb_set USART3_IRQHandler,Default_Handler - - .weak EXTI15_10_IRQHandler - .thumb_set EXTI15_10_IRQHandler,Default_Handler - - .weak RTCAlarm_IRQHandler - .thumb_set RTCAlarm_IRQHandler,Default_Handler - - .weak USBWakeUp_IRQHandler - .thumb_set USBWakeUp_IRQHandler,Default_Handler - +/** + ****************************************************************************** + * @file startup_stm32f10x_md.s + * @author MCD Application Team + * @version V3.1.0 + * @date 06/19/2009 + * @brief STM32F10x Medium Density Devices vector table for RIDE7 toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M3 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ******************************************************************************* + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2009 STMicroelectronics

+ */ + + .syntax unified + .cpu cortex-m3 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global SystemInit_ExtMemCtl_Dummy +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + +.equ BootRAM, 0xF108F85F +/** + * @brief 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 main() routine is called. + * @param None + * @retval : None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss +/* Call the application's entry point.*/ + bl main + bx lr +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_IRQHandler + .word TAMPER_IRQHandler + .word RTC_IRQHandler + .word FLASH_IRQHandler + .word RCC_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word DMA1_Channel5_IRQHandler + .word DMA1_Channel6_IRQHandler + .word DMA1_Channel7_IRQHandler + .word ADC1_2_IRQHandler + .word USB_HP_CAN1_TX_IRQHandler + .word USB_LP_CAN1_RX0_IRQHandler + .word CAN1_RX1_IRQHandler + .word CAN1_SCE_IRQHandler + .word EXTI9_5_IRQHandler + .word TIM1_BRK_IRQHandler + .word TIM1_UP_IRQHandler + .word TIM1_TRG_COM_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word TIM3_IRQHandler + .word TIM4_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C2_EV_IRQHandler + .word I2C2_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word USART1_IRQHandler + .word USART2_IRQHandler + .word USART3_IRQHandler + .word EXTI15_10_IRQHandler + .word RTCAlarm_IRQHandler + .word USBWakeUp_IRQHandler +/* + .word TIM8_BRK + .word TIM8_UP + .word TIM8_TRG_COM + .word TIM8_CC + .word ADC3 + .word FSMC + .word SDIO + .word TIM5 + .word SPI3 + .word UART4 + .word UART5 + .word TIM6 + .word TIM7 + .word DMA2_Channel1 + .word DMA2_Channel2 + .word DMA2_Channel3 + .word DMA2_Channel5 +*/ + .word BootRAM /* @0x108. This is for boot in RAM mode for + STM32F10x Medium Density devices. */ + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_IRQHandler + .thumb_set PVD_IRQHandler,Default_Handler + + .weak TAMPER_IRQHandler + .thumb_set TAMPER_IRQHandler,Default_Handler + + .weak RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel2_IRQHandler + .thumb_set DMA1_Channel2_IRQHandler,Default_Handler + + .weak DMA1_Channel3_IRQHandler + .thumb_set DMA1_Channel3_IRQHandler,Default_Handler + + .weak DMA1_Channel4_IRQHandler + .thumb_set DMA1_Channel4_IRQHandler,Default_Handler + + .weak DMA1_Channel5_IRQHandler + .thumb_set DMA1_Channel5_IRQHandler,Default_Handler + + .weak DMA1_Channel6_IRQHandler + .thumb_set DMA1_Channel6_IRQHandler,Default_Handler + + .weak DMA1_Channel7_IRQHandler + .thumb_set DMA1_Channel7_IRQHandler,Default_Handler + + .weak ADC1_2_IRQHandler + .thumb_set ADC1_2_IRQHandler,Default_Handler + + .weak USB_HP_CAN1_TX_IRQHandler + .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler + + .weak USB_LP_CAN1_RX0_IRQHandler + .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler + + .weak CAN1_RX1_IRQHandler + .thumb_set CAN1_RX1_IRQHandler,Default_Handler + + .weak CAN1_SCE_IRQHandler + .thumb_set CAN1_SCE_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_IRQHandler + .thumb_set TIM1_UP_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_IRQHandler + .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM4_IRQHandler + .thumb_set TIM4_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTCAlarm_IRQHandler + .thumb_set RTCAlarm_IRQHandler,Default_Handler + + .weak USBWakeUp_IRQHandler + .thumb_set USBWakeUp_IRQHandler,Default_Handler + diff --git a/Libmaple/maple-bootloader/stm32_lib/c_only_startup_user.s b/Libmaple/maple-bootloader/stm32_lib/c_only_startup_user.s index 3b2f82f0..67a72345 100644 --- a/Libmaple/maple-bootloader/stm32_lib/c_only_startup_user.s +++ b/Libmaple/maple-bootloader/stm32_lib/c_only_startup_user.s @@ -1,128 +1,128 @@ -/** - ****************************************************************************** - * @file startup_stm32f10x_md.s - * @author MCD Application Team - * @version V3.1.0 - * @date 06/19/2009 - * @brief STM32F10x Medium Density Devices vector table for RIDE7 toolchain. - * This module performs: - * - Set the initial SP - * - Set the initial PC == Reset_Handler, - * - Set the vector table entries with the exceptions ISR address - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M3 processor is in Thread mode, - * priority is Privileged, and the Stack is set to Main. - ******************************************************************************* - * @copy - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2009 STMicroelectronics

- */ - - .syntax unified - .cpu cortex-m3 - .fpu softvfp - .thumb - -.global g_pfnVectors -.global SystemInit_ExtMemCtl_Dummy -.global Default_Handler - -/* start address for the initialization values of the .data section. -defined in linker script */ -.word _sidata -/* start address for the .data section. defined in linker script */ -.word _sdata -/* end address for the .data section. defined in linker script */ -.word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss -.word _magicRate - -.equ BootRAM, 0xF108F85F -/** - * @brief 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 main() routine is called. - * @param None - * @retval : None -*/ - - .section .text.Reset_Handler - .weak Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - -/* Copy the data segment initializers from flash to SRAM */ - movs r1, #0 - b LoopCopyDataInit - -CopyDataInit: - ldr r3, =_sidata - ldr r3, [r3, r1] - str r3, [r0, r1] - adds r1, r1, #4 - -LoopCopyDataInit: - ldr r0, =_sdata - ldr r3, =_edata - adds r2, r0, r1 - cmp r2, r3 - bcc CopyDataInit - ldr r2, =_sbss - b LoopFillZerobss -/* Zero fill the bss segment. */ -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -LoopFillZerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss -/* Call the application's entry point.*/ - bl main - bx lr -.size Reset_Handler, .-Reset_Handler - -/** - * @brief This is the code that gets called when the processor receives an - * unexpected interrupt. This simply enters an infinite loop, preserving - * the system state for examination by a debugger. - * - * @param None - * @retval : None -*/ - .section .text.Default_Handler,"ax",%progbits -Default_Handler: -Infinite_Loop: - b Infinite_Loop - .size Default_Handler, .-Default_Handler -/****************************************************************************** -* -* The minimal vector table for a Cortex M3. Note that the proper constructs -* must be placed on this to ensure that it ends up at physical address -* 0x0000.0000. -* -******************************************************************************/ - .section .isr_vector,"a",%progbits - .type g_pfnVectors, %object - .size g_pfnVectors, .-g_pfnVectors - - -g_pfnVectors: - .word _estack - .word Reset_Handler - .word _magicRate - - +/** + ****************************************************************************** + * @file startup_stm32f10x_md.s + * @author MCD Application Team + * @version V3.1.0 + * @date 06/19/2009 + * @brief STM32F10x Medium Density Devices vector table for RIDE7 toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M3 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ******************************************************************************* + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2009 STMicroelectronics

+ */ + + .syntax unified + .cpu cortex-m3 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global SystemInit_ExtMemCtl_Dummy +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +.word _magicRate + +.equ BootRAM, 0xF108F85F +/** + * @brief 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 main() routine is called. + * @param None + * @retval : None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss +/* Call the application's entry point.*/ + bl main + bx lr +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word _magicRate + + diff --git a/Libmaple/maple-bootloader/stm32_lib/cortexm3_macro.h b/Libmaple/maple-bootloader/stm32_lib/cortexm3_macro.h index b26807f9..6adbc3bb 100644 --- a/Libmaple/maple-bootloader/stm32_lib/cortexm3_macro.h +++ b/Libmaple/maple-bootloader/stm32_lib/cortexm3_macro.h @@ -1,53 +1,53 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : cortexm3_macro.h -* Author : MCD Application Team -* Version : V2.0.3 -* Date : 09/22/2008 -* Description : Header file for cortexm3_macro.s. -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __CORTEXM3_MACRO_H -#define __CORTEXM3_MACRO_H - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_type.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -void __WFI(void); -void __WFE(void); -void __SEV(void); -void __ISB(void); -void __DSB(void); -void __DMB(void); -void __SVC(void); -u32 __MRS_CONTROL(void); -void __MSR_CONTROL(u32 Control); -u32 __MRS_PSP(void); -void __MSR_PSP(u32 TopOfProcessStack); -u32 __MRS_MSP(void); -void __MSR_MSP(u32 TopOfMainStack); -void __RESETPRIMASK(void); -void __SETPRIMASK(void); -u32 __READ_PRIMASK(void); -void __RESETFAULTMASK(void); -void __SETFAULTMASK(void); -u32 __READ_FAULTMASK(void); -void __BASEPRICONFIG(u32 NewPriority); -u32 __GetBASEPRI(void); -u16 __REV_HalfWord(u16 Data); -u32 __REV_Word(u32 Data); - -#endif /* __CORTEXM3_MACRO_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : cortexm3_macro.h +* Author : MCD Application Team +* Version : V2.0.3 +* Date : 09/22/2008 +* Description : Header file for cortexm3_macro.s. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CORTEXM3_MACRO_H +#define __CORTEXM3_MACRO_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_type.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +void __WFI(void); +void __WFE(void); +void __SEV(void); +void __ISB(void); +void __DSB(void); +void __DMB(void); +void __SVC(void); +u32 __MRS_CONTROL(void); +void __MSR_CONTROL(u32 Control); +u32 __MRS_PSP(void); +void __MSR_PSP(u32 TopOfProcessStack); +u32 __MRS_MSP(void); +void __MSR_MSP(u32 TopOfMainStack); +void __RESETPRIMASK(void); +void __SETPRIMASK(void); +u32 __READ_PRIMASK(void); +void __RESETFAULTMASK(void); +void __SETFAULTMASK(void); +u32 __READ_FAULTMASK(void); +void __BASEPRICONFIG(u32 NewPriority); +u32 __GetBASEPRI(void); +u16 __REV_HalfWord(u16 Data); +u32 __REV_Word(u32 Data); + +#endif /* __CORTEXM3_MACRO_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/stm32_lib/cortexm3_macro.s b/Libmaple/maple-bootloader/stm32_lib/cortexm3_macro.s index 345c3b7e..a6eb4bca 100644 --- a/Libmaple/maple-bootloader/stm32_lib/cortexm3_macro.s +++ b/Libmaple/maple-bootloader/stm32_lib/cortexm3_macro.s @@ -1,312 +1,312 @@ -# 1 "./stm32_lib/cortexm3_macro.S" -# 1 "" -# 1 "" -# 1 "./stm32_lib/cortexm3_macro.S" -# 16 "./stm32_lib/cortexm3_macro.S" - .cpu cortex-m3 -.fpu softvfp -.syntax unified -.thumb -.text - - - .globl __WFI - .globl __WFE - .globl __SEV - .globl __ISB - .globl __DSB - .globl __DMB - .globl __SVC - .globl __MRS_CONTROL - .globl __MSR_CONTROL - .globl __MRS_PSP - .globl __MSR_PSP - .globl __MRS_MSP - .globl __MSR_MSP - .globl __RESETPRIMASK - .globl __SETPRIMASK - .globl __READ_PRIMASK - .globl __RESETFAULTMASK - .globl __SETFAULTMASK - .globl __READ_FAULTMASK - .globl __BASEPRICONFIG - .globl __GetBASEPRI - .globl __REV_HalfWord - .globl __REV_Word - - - - - - - -.thumb_func -__WFI: - - WFI - BX r14 - - - - - - - -.thumb_func -__WFE: - - WFE - BX r14 - - - - - - - -.thumb_func -__SEV: - - SEV - BX r14 - - - - - - - -.thumb_func -__ISB: - - ISB - BX r14 - - - - - - - -.thumb_func -__DSB: - - DSB - BX r14 - - - - - - - -.thumb_func -__DMB: - - DMB - BX r14 - - - - - - - -.thumb_func -__SVC: - - SVC 0x01 - BX r14 - - - - - - - -.thumb_func -__MRS_CONTROL: - - MRS r0,control - BX r14 - - - - - - - -.thumb_func -__MSR_CONTROL: - - MSR control, r0 - ISB - BX r14 - - - - - - -.thumb_func -__MRS_PSP: - - MRS r0, psp - BX r14 - - - - - - - -.thumb_func -__MSR_PSP: - - MSR psp, r0 - BX r14 - - - - - - - -.thumb_func -__MRS_MSP: - - MRS r0, msp - BX r14 - - - - - - - -.thumb_func -__MSR_MSP: - - MSR msp, r0 - BX r14 - - - - - - - -.thumb_func -__RESETPRIMASK: - - CPSIE i - BX r14 - - - - - - - -.thumb_func -__SETPRIMASK: - - CPSID i - BX r14 - - - - - - - -.thumb_func -__READ_PRIMASK: - - MRS r0, PRIMASK - BX r14 - - - - - - - -.thumb_func -__RESETFAULTMASK: - - CPSIE f - BX r14 - - - - - - - -.thumb_func -__SETFAULTMASK: - - CPSID f - BX r14 - - - - - - - -.thumb_func -__READ_FAULTMASK: - - MRS r0, FAULTMASK - BX r14 - - - - - - - -.thumb_func -__BASEPRICONFIG: - - MSR basepri, r0 - BX r14 - - - - - - - -.thumb_func -__GetBASEPRI: - - MRS r0, basepri_max - BX r14 - - - - - - -.thumb_func -__REV_HalfWord: - - REV16 r0, r0 - BX r14 - - - - - - - -.thumb_func -__REV_Word: - - REV r0, r0 - BX r14 - -.end +# 1 "./stm32_lib/cortexm3_macro.S" +# 1 "" +# 1 "" +# 1 "./stm32_lib/cortexm3_macro.S" +# 16 "./stm32_lib/cortexm3_macro.S" + .cpu cortex-m3 +.fpu softvfp +.syntax unified +.thumb +.text + + + .globl __WFI + .globl __WFE + .globl __SEV + .globl __ISB + .globl __DSB + .globl __DMB + .globl __SVC + .globl __MRS_CONTROL + .globl __MSR_CONTROL + .globl __MRS_PSP + .globl __MSR_PSP + .globl __MRS_MSP + .globl __MSR_MSP + .globl __RESETPRIMASK + .globl __SETPRIMASK + .globl __READ_PRIMASK + .globl __RESETFAULTMASK + .globl __SETFAULTMASK + .globl __READ_FAULTMASK + .globl __BASEPRICONFIG + .globl __GetBASEPRI + .globl __REV_HalfWord + .globl __REV_Word + + + + + + + +.thumb_func +__WFI: + + WFI + BX r14 + + + + + + + +.thumb_func +__WFE: + + WFE + BX r14 + + + + + + + +.thumb_func +__SEV: + + SEV + BX r14 + + + + + + + +.thumb_func +__ISB: + + ISB + BX r14 + + + + + + + +.thumb_func +__DSB: + + DSB + BX r14 + + + + + + + +.thumb_func +__DMB: + + DMB + BX r14 + + + + + + + +.thumb_func +__SVC: + + SVC 0x01 + BX r14 + + + + + + + +.thumb_func +__MRS_CONTROL: + + MRS r0,control + BX r14 + + + + + + + +.thumb_func +__MSR_CONTROL: + + MSR control, r0 + ISB + BX r14 + + + + + + +.thumb_func +__MRS_PSP: + + MRS r0, psp + BX r14 + + + + + + + +.thumb_func +__MSR_PSP: + + MSR psp, r0 + BX r14 + + + + + + + +.thumb_func +__MRS_MSP: + + MRS r0, msp + BX r14 + + + + + + + +.thumb_func +__MSR_MSP: + + MSR msp, r0 + BX r14 + + + + + + + +.thumb_func +__RESETPRIMASK: + + CPSIE i + BX r14 + + + + + + + +.thumb_func +__SETPRIMASK: + + CPSID i + BX r14 + + + + + + + +.thumb_func +__READ_PRIMASK: + + MRS r0, PRIMASK + BX r14 + + + + + + + +.thumb_func +__RESETFAULTMASK: + + CPSIE f + BX r14 + + + + + + + +.thumb_func +__SETFAULTMASK: + + CPSID f + BX r14 + + + + + + + +.thumb_func +__READ_FAULTMASK: + + MRS r0, FAULTMASK + BX r14 + + + + + + + +.thumb_func +__BASEPRICONFIG: + + MSR basepri, r0 + BX r14 + + + + + + + +.thumb_func +__GetBASEPRI: + + MRS r0, basepri_max + BX r14 + + + + + + +.thumb_func +__REV_HalfWord: + + REV16 r0, r0 + BX r14 + + + + + + + +.thumb_func +__REV_Word: + + REV r0, r0 + BX r14 + +.end diff --git a/Libmaple/maple-bootloader/stm32_lib/stm32f10x.h b/Libmaple/maple-bootloader/stm32_lib/stm32f10x.h index 7bbb4b98..7e84f45c 100644 --- a/Libmaple/maple-bootloader/stm32_lib/stm32f10x.h +++ b/Libmaple/maple-bootloader/stm32_lib/stm32f10x.h @@ -1,7851 +1,7851 @@ -/** - ****************************************************************************** - * @file stm32f10x.h - * @author MCD Application Team - * @version V3.1.1 - * @date 07/27/2009 - * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File. - * This file contains all the peripheral register's definitions, bits - * definitions and memory mapping for STM32F10x Connectivity line, High - * density, Medium density and Low density devices. - ****************************************************************************** - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2009 STMicroelectronics

- ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32f10x - * @{ - */ - -#ifndef __STM32F10x_H -#define __STM32F10x_H - -#ifdef __cplusplus - extern "C" { -#endif - -/** @addtogroup Library_configuration_section - * @{ - */ - -/* Uncomment the line below according to the target STM32 device used in your - application - */ - -#if !defined (STM32F10X_LD) && !defined (STM32F10X_MD) && !defined (STM32F10X_HD) && !defined (STM32F10X_CL) - /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */ - /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */ - /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */ - #define STM32F10X_CL /*!< STM32F10X_CL: STM32 Connectivity line devices */ -#endif -/* Tip: To avoid modifying this file each time you need to switch between these - devices, you can define the device in your toolchain compiler preprocessor. - - - Low density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers - where the Flash memory density ranges between 16 and 32 Kbytes. - - Medium density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers - where the Flash memory density ranges between 64 and 128 Kbytes. - - High density devices are STM32F101xx and STM32F103xx microcontrollers where - the Flash memory density ranges between 256 and 512 Kbytes. - - Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers. - */ - -#if !defined USE_STDPERIPH_DRIVER -/** - * @brief Comment the line below if you will not use the peripherals drivers. - In this case, these drivers will not be included and the application code will - be based on direct access to peripherals registers - */ - /*#define USE_STDPERIPH_DRIVER*/ -#endif - -/** - * @brief In the following line adjust the value of External High Speed oscillator (HSE) - used in your application - - Tip: To avoid modifying this file each time you need to use different HSE, you - can define the HSE value in your toolchain compiler preprocessor. - */ -#if !defined HSE_Value - #ifdef STM32F10X_CL - #define HSE_Value ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ - #else - #define HSE_Value ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ - #endif /* STM32F10X_CL */ -#endif /* HSE_Value */ - - -/** - * @brief In the following line adjust the External High Speed oscillator (HSE) Startup - Timeout value - */ -#define HSEStartUp_TimeOut ((uint16_t)0x0500) /*!< Time out for HSE start up */ - -#define HSI_Value ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ - -/** - * @brief STM32F10x Standard Peripheral Library version number - */ -#define __STM32F10X_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:16] STM32F10x Standard Peripheral Library main version */ -#define __STM32F10X_STDPERIPH_VERSION_SUB1 (0x01) /*!< [15:8] STM32F10x Standard Peripheral Library sub1 version */ -#define __STM32F10X_STDPERIPH_VERSION_SUB2 (0x00) /*!< [7:0] STM32F10x Standard Peripheral Library sub2 version */ -#define __STM32F10X_STDPERIPH_VERSION ((__STM32F10X_STDPERIPH_VERSION_MAIN << 16)\ - | (__STM32F10X_STDPERIPH_VERSION_SUB1 << 8)\ - | __STM32F10X_STDPERIPH_VERSION_SUB2) - -/** - * @} - */ - -/** @addtogroup Configuration_section_for_CMSIS - * @{ - */ - -/** - * @brief Configuration of the Cortex-M3 Processor and Core Peripherals - */ -#define __MPU_PRESENT 0 /*!< STM32 does not provide an MPU */ -#define __NVIC_PRIO_BITS 4 /*!< STM32 uses 4 Bits for the Priority Levels */ -#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ - -/** - * @brief STM32F10x Interrupt Number Definition, according to the selected device - * in @ref Library_configuration_section - */ -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 */ - -/****** STM32 specific Interrupt Numbers *********************************************************/ - WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ - PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ - TAMPER_IRQn = 2, /*!< Tamper Interrupt */ - RTC_IRQn = 3, /*!< RTC global Interrupt */ - FLASH_IRQn = 4, /*!< FLASH global Interrupt */ - RCC_IRQn = 5, /*!< RCC global Interrupt */ - EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ - EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ - EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ - EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ - EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ - DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */ - DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */ - DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */ - DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */ - DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */ - DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */ - DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */ - ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ - -#ifdef STM32F10X_LD - USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ - USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ - TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ - TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ -#endif /* STM32F10X_LD */ - -#ifdef STM32F10X_MD - USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ - USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ - TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ - TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ -#endif /* STM32F10X_MD */ - -#ifdef STM32F10X_HD - USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ - USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ - TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ - TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ - TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */ - TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */ - TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt */ - TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ - ADC3_IRQn = 47, /*!< ADC3 global Interrupt */ - FSMC_IRQn = 48, /*!< FSMC global Interrupt */ - SDIO_IRQn = 49, /*!< SDIO global Interrupt */ - TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ - SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ - UART4_IRQn = 52, /*!< UART4 global Interrupt */ - UART5_IRQn = 53, /*!< UART5 global Interrupt */ - TIM6_IRQn = 54, /*!< TIM6 global Interrupt */ - TIM7_IRQn = 55, /*!< TIM7 global Interrupt */ - DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */ - DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */ - DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */ - DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */ -#endif /* STM32F10X_HD */ - -#ifdef STM32F10X_CL - CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ - CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ - TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ - TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS WakeUp from suspend through EXTI Line Interrupt */ - TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ - SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ - UART4_IRQn = 52, /*!< UART4 global Interrupt */ - UART5_IRQn = 53, /*!< UART5 global Interrupt */ - TIM6_IRQn = 54, /*!< TIM6 global Interrupt */ - TIM7_IRQn = 55, /*!< TIM7 global Interrupt */ - DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */ - DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */ - DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */ - DMA2_Channel4_IRQn = 59, /*!< DMA2 Channel 4 global Interrupt */ - DMA2_Channel5_IRQn = 60, /*!< DMA2 Channel 5 global Interrupt */ - ETH_IRQn = 61, /*!< Ethernet global Interrupt */ - ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ - CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ - CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ - CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ - CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ - OTG_FS_IRQn = 67 /*!< USB OTG FS global Interrupt */ -#endif /* STM32F10X_CL */ -} IRQn_Type; - -/** - * @} - */ - -#include "core_cm3.h" -#include "system_stm32f10x.h" -#include - -/** @addtogroup Exported_types - * @{ - */ - -/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -typedef const int32_t sc32; /*!< Read Only */ -typedef const int16_t sc16; /*!< Read Only */ -typedef const int8_t sc8; /*!< Read Only */ - -typedef __IO int32_t vs32; -typedef __IO int16_t vs16; -typedef __IO int8_t vs8; - -typedef __I int32_t vsc32; /*!< Read Only */ -typedef __I int16_t vsc16; /*!< Read Only */ -typedef __I int8_t vsc8; /*!< Read Only */ - -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -typedef const uint32_t uc32; /*!< Read Only */ -typedef const uint16_t uc16; /*!< Read Only */ -typedef const uint8_t uc8; /*!< Read Only */ - -typedef __IO uint32_t vu32; -typedef __IO uint16_t vu16; -typedef __IO uint8_t vu8; - -typedef __I uint32_t vuc32; /*!< Read Only */ -typedef __I uint16_t vuc16; /*!< Read Only */ -typedef __I uint8_t vuc8; /*!< Read Only */ - -#ifndef __cplusplus -typedef enum {FALSE = 0, TRUE = !FALSE} bool; -#endif - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; -#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) - -typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; - -/** - * @} - */ - -/** @addtogroup Peripheral_registers_structures - * @{ - */ - -/** - * @brief Analog to Digital Converter - */ - -typedef struct -{ - __IO uint32_t SR; - __IO uint32_t CR1; - __IO uint32_t CR2; - __IO uint32_t SMPR1; - __IO uint32_t SMPR2; - __IO uint32_t JOFR1; - __IO uint32_t JOFR2; - __IO uint32_t JOFR3; - __IO uint32_t JOFR4; - __IO uint32_t HTR; - __IO uint32_t LTR; - __IO uint32_t SQR1; - __IO uint32_t SQR2; - __IO uint32_t SQR3; - __IO uint32_t JSQR; - __IO uint32_t JDR1; - __IO uint32_t JDR2; - __IO uint32_t JDR3; - __IO uint32_t JDR4; - __IO uint32_t DR; -} ADC_TypeDef; - -/** - * @brief Backup Registers - */ - -typedef struct -{ - uint32_t RESERVED0; - __IO uint16_t DR1; - uint16_t RESERVED1; - __IO uint16_t DR2; - uint16_t RESERVED2; - __IO uint16_t DR3; - uint16_t RESERVED3; - __IO uint16_t DR4; - uint16_t RESERVED4; - __IO uint16_t DR5; - uint16_t RESERVED5; - __IO uint16_t DR6; - uint16_t RESERVED6; - __IO uint16_t DR7; - uint16_t RESERVED7; - __IO uint16_t DR8; - uint16_t RESERVED8; - __IO uint16_t DR9; - uint16_t RESERVED9; - __IO uint16_t DR10; - uint16_t RESERVED10; - __IO uint16_t RTCCR; - uint16_t RESERVED11; - __IO uint16_t CR; - uint16_t RESERVED12; - __IO uint16_t CSR; - uint16_t RESERVED13[5]; - __IO uint16_t DR11; - uint16_t RESERVED14; - __IO uint16_t DR12; - uint16_t RESERVED15; - __IO uint16_t DR13; - uint16_t RESERVED16; - __IO uint16_t DR14; - uint16_t RESERVED17; - __IO uint16_t DR15; - uint16_t RESERVED18; - __IO uint16_t DR16; - uint16_t RESERVED19; - __IO uint16_t DR17; - uint16_t RESERVED20; - __IO uint16_t DR18; - uint16_t RESERVED21; - __IO uint16_t DR19; - uint16_t RESERVED22; - __IO uint16_t DR20; - uint16_t RESERVED23; - __IO uint16_t DR21; - uint16_t RESERVED24; - __IO uint16_t DR22; - uint16_t RESERVED25; - __IO uint16_t DR23; - uint16_t RESERVED26; - __IO uint16_t DR24; - uint16_t RESERVED27; - __IO uint16_t DR25; - uint16_t RESERVED28; - __IO uint16_t DR26; - uint16_t RESERVED29; - __IO uint16_t DR27; - uint16_t RESERVED30; - __IO uint16_t DR28; - uint16_t RESERVED31; - __IO uint16_t DR29; - uint16_t RESERVED32; - __IO uint16_t DR30; - uint16_t RESERVED33; - __IO uint16_t DR31; - uint16_t RESERVED34; - __IO uint16_t DR32; - uint16_t RESERVED35; - __IO uint16_t DR33; - uint16_t RESERVED36; - __IO uint16_t DR34; - uint16_t RESERVED37; - __IO uint16_t DR35; - uint16_t RESERVED38; - __IO uint16_t DR36; - uint16_t RESERVED39; - __IO uint16_t DR37; - uint16_t RESERVED40; - __IO uint16_t DR38; - uint16_t RESERVED41; - __IO uint16_t DR39; - uint16_t RESERVED42; - __IO uint16_t DR40; - uint16_t RESERVED43; - __IO uint16_t DR41; - uint16_t RESERVED44; - __IO uint16_t DR42; - uint16_t RESERVED45; -} BKP_TypeDef; - -/** - * @brief Controller Area Network TxMailBox - */ - -typedef struct -{ - __IO uint32_t TIR; - __IO uint32_t TDTR; - __IO uint32_t TDLR; - __IO uint32_t TDHR; -} CAN_TxMailBox_TypeDef; - -/** - * @brief Controller Area Network FIFOMailBox - */ - -typedef struct -{ - __IO uint32_t RIR; - __IO uint32_t RDTR; - __IO uint32_t RDLR; - __IO uint32_t RDHR; -} CAN_FIFOMailBox_TypeDef; - -/** - * @brief Controller Area Network FilterRegister - */ - -typedef struct -{ - __IO uint32_t FR1; - __IO uint32_t FR2; -} CAN_FilterRegister_TypeDef; - -/** - * @brief Controller Area Network - */ - -typedef struct -{ - __IO uint32_t MCR; - __IO uint32_t MSR; - __IO uint32_t TSR; - __IO uint32_t RF0R; - __IO uint32_t RF1R; - __IO uint32_t IER; - __IO uint32_t ESR; - __IO uint32_t BTR; - uint32_t RESERVED0[88]; - CAN_TxMailBox_TypeDef sTxMailBox[3]; - CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; - uint32_t RESERVED1[12]; - __IO uint32_t FMR; - __IO uint32_t FM1R; - uint32_t RESERVED2; - __IO uint32_t FS1R; - uint32_t RESERVED3; - __IO uint32_t FFA1R; - uint32_t RESERVED4; - __IO uint32_t FA1R; - uint32_t RESERVED5[8]; -#ifndef STM32F10X_CL - CAN_FilterRegister_TypeDef sFilterRegister[14]; -#else - CAN_FilterRegister_TypeDef sFilterRegister[28]; -#endif /* STM32F10X_CL */ -} CAN_TypeDef; - -/** - * @brief CRC calculation unit - */ - -typedef struct -{ - __IO uint32_t DR; - __IO uint8_t IDR; - uint8_t RESERVED0; - uint16_t RESERVED1; - __IO uint32_t CR; -} CRC_TypeDef; - -/** - * @brief Digital to Analog Converter - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t SWTRIGR; - __IO uint32_t DHR12R1; - __IO uint32_t DHR12L1; - __IO uint32_t DHR8R1; - __IO uint32_t DHR12R2; - __IO uint32_t DHR12L2; - __IO uint32_t DHR8R2; - __IO uint32_t DHR12RD; - __IO uint32_t DHR12LD; - __IO uint32_t DHR8RD; - __IO uint32_t DOR1; - __IO uint32_t DOR2; -} DAC_TypeDef; - -/** - * @brief Debug MCU - */ - -typedef struct -{ - __IO uint32_t IDCODE; - __IO uint32_t CR; -}DBGMCU_TypeDef; - -/** - * @brief DMA Controller - */ - -typedef struct -{ - __IO uint32_t CCR; - __IO uint32_t CNDTR; - __IO uint32_t CPAR; - __IO uint32_t CMAR; -} DMA_Channel_TypeDef; - -typedef struct -{ - __IO uint32_t ISR; - __IO uint32_t IFCR; -} DMA_TypeDef; - -/** - * @brief Ethernet MAC - */ - -typedef struct -{ - __IO uint32_t MACCR; - __IO uint32_t MACFFR; - __IO uint32_t MACHTHR; - __IO uint32_t MACHTLR; - __IO uint32_t MACMIIAR; - __IO uint32_t MACMIIDR; - __IO uint32_t MACFCR; - __IO uint32_t MACVLANTR; /* 8 */ - uint32_t RESERVED0[2]; - __IO uint32_t MACRWUFFR; /* 11 */ - __IO uint32_t MACPMTCSR; - uint32_t RESERVED1[2]; - __IO uint32_t MACSR; /* 15 */ - __IO uint32_t MACIMR; - __IO uint32_t MACA0HR; - __IO uint32_t MACA0LR; - __IO uint32_t MACA1HR; - __IO uint32_t MACA1LR; - __IO uint32_t MACA2HR; - __IO uint32_t MACA2LR; - __IO uint32_t MACA3HR; - __IO uint32_t MACA3LR; /* 24 */ - uint32_t RESERVED2[40]; - __IO uint32_t MMCCR; /* 65 */ - __IO uint32_t MMCRIR; - __IO uint32_t MMCTIR; - __IO uint32_t MMCRIMR; - __IO uint32_t MMCTIMR; /* 69 */ - uint32_t RESERVED3[14]; - __IO uint32_t MMCTGFSCCR; /* 84 */ - __IO uint32_t MMCTGFMSCCR; - uint32_t RESERVED4[5]; - __IO uint32_t MMCTGFCR; - uint32_t RESERVED5[10]; - __IO uint32_t MMCRFCECR; - __IO uint32_t MMCRFAECR; - uint32_t RESERVED6[10]; - __IO uint32_t MMCRGUFCR; - uint32_t RESERVED7[334]; - __IO uint32_t PTPTSCR; - __IO uint32_t PTPSSIR; - __IO uint32_t PTPTSHR; - __IO uint32_t PTPTSLR; - __IO uint32_t PTPTSHUR; - __IO uint32_t PTPTSLUR; - __IO uint32_t PTPTSAR; - __IO uint32_t PTPTTHR; - __IO uint32_t PTPTTLR; - uint32_t RESERVED8[567]; - __IO uint32_t DMABMR; - __IO uint32_t DMATPDR; - __IO uint32_t DMARPDR; - __IO uint32_t DMARDLAR; - __IO uint32_t DMATDLAR; - __IO uint32_t DMASR; - __IO uint32_t DMAOMR; - __IO uint32_t DMAIER; - __IO uint32_t DMAMFBOCR; - uint32_t RESERVED9[9]; - __IO uint32_t DMACHTDR; - __IO uint32_t DMACHRDR; - __IO uint32_t DMACHTBAR; - __IO uint32_t DMACHRBAR; -} ETH_TypeDef; - -/** - * @brief External Interrupt/Event Controller - */ - -typedef struct -{ - __IO uint32_t IMR; - __IO uint32_t EMR; - __IO uint32_t RTSR; - __IO uint32_t FTSR; - __IO uint32_t SWIER; - __IO uint32_t PR; -} EXTI_TypeDef; - -/** - * @brief FLASH Registers - */ - -typedef struct -{ - __IO uint32_t ACR; - __IO uint32_t KEYR; - __IO uint32_t OPTKEYR; - __IO uint32_t SR; - __IO uint32_t CR; - __IO uint32_t AR; - __IO uint32_t RESERVED; - __IO uint32_t OBR; - __IO uint32_t WRPR; -} FLASH_TypeDef; - -/** - * @brief Option Bytes Registers - */ - -typedef struct -{ - __IO uint16_t RDP; - __IO uint16_t USER; - __IO uint16_t Data0; - __IO uint16_t Data1; - __IO uint16_t WRP0; - __IO uint16_t WRP1; - __IO uint16_t WRP2; - __IO uint16_t WRP3; -} OB_TypeDef; - -/** - * @brief Flexible Static Memory Controller - */ - -typedef struct -{ - __IO uint32_t BTCR[8]; -} FSMC_Bank1_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank1E - */ - -typedef struct -{ - __IO uint32_t BWTR[7]; -} FSMC_Bank1E_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank2 - */ - -typedef struct -{ - __IO uint32_t PCR2; - __IO uint32_t SR2; - __IO uint32_t PMEM2; - __IO uint32_t PATT2; - uint32_t RESERVED0; - __IO uint32_t ECCR2; -} FSMC_Bank2_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank3 - */ - -typedef struct -{ - __IO uint32_t PCR3; - __IO uint32_t SR3; - __IO uint32_t PMEM3; - __IO uint32_t PATT3; - uint32_t RESERVED0; - __IO uint32_t ECCR3; -} FSMC_Bank3_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank4 - */ - -typedef struct -{ - __IO uint32_t PCR4; - __IO uint32_t SR4; - __IO uint32_t PMEM4; - __IO uint32_t PATT4; - __IO uint32_t PIO4; -} FSMC_Bank4_TypeDef; - -/** - * @brief General Purpose I/O - */ - -typedef struct -{ - __IO uint32_t CRL; - __IO uint32_t CRH; - __IO uint32_t IDR; - __IO uint32_t ODR; - __IO uint32_t BSRR; - __IO uint32_t BRR; - __IO uint32_t LCKR; -} GPIO_TypeDef; - -/** - * @brief Alternate Function I/O - */ - -typedef struct -{ - __IO uint32_t EVCR; - __IO uint32_t MAPR; - __IO uint32_t EXTICR[4]; -} AFIO_TypeDef; -/** - * @brief Inter-integrated Circuit Interface - */ - -typedef struct -{ - __IO uint16_t CR1; - uint16_t RESERVED0; - __IO uint16_t CR2; - uint16_t RESERVED1; - __IO uint16_t OAR1; - uint16_t RESERVED2; - __IO uint16_t OAR2; - uint16_t RESERVED3; - __IO uint16_t DR; - uint16_t RESERVED4; - __IO uint16_t SR1; - uint16_t RESERVED5; - __IO uint16_t SR2; - uint16_t RESERVED6; - __IO uint16_t CCR; - uint16_t RESERVED7; - __IO uint16_t TRISE; - uint16_t RESERVED8; -} I2C_TypeDef; - -/** - * @brief Independent WATCHDOG - */ - -typedef struct -{ - __IO uint32_t KR; - __IO uint32_t PR; - __IO uint32_t RLR; - __IO uint32_t SR; -} IWDG_TypeDef; - -/** - * @brief Power Control - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t CSR; -} PWR_TypeDef; - -/** - * @brief Reset and Clock Control - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t CFGR; - __IO uint32_t CIR; - __IO uint32_t APB2RSTR; - __IO uint32_t APB1RSTR; - __IO uint32_t AHBENR; - __IO uint32_t APB2ENR; - __IO uint32_t APB1ENR; - __IO uint32_t BDCR; - __IO uint32_t CSR; -#ifdef STM32F10X_CL - __IO uint32_t AHBRSTR; - __IO uint32_t CFGR2; -#endif /* STM32F10X_CL */ -} RCC_TypeDef; - -/** - * @brief Real-Time Clock - */ - -typedef struct -{ - __IO uint16_t CRH; - uint16_t RESERVED0; - __IO uint16_t CRL; - uint16_t RESERVED1; - __IO uint16_t PRLH; - uint16_t RESERVED2; - __IO uint16_t PRLL; - uint16_t RESERVED3; - __IO uint16_t DIVH; - uint16_t RESERVED4; - __IO uint16_t DIVL; - uint16_t RESERVED5; - __IO uint16_t CNTH; - uint16_t RESERVED6; - __IO uint16_t CNTL; - uint16_t RESERVED7; - __IO uint16_t ALRH; - uint16_t RESERVED8; - __IO uint16_t ALRL; - uint16_t RESERVED9; -} RTC_TypeDef; - -/** - * @brief SD host Interface - */ - -typedef struct -{ - __IO uint32_t POWER; - __IO uint32_t CLKCR; - __IO uint32_t ARG; - __IO uint32_t CMD; - __I uint32_t RESPCMD; - __I uint32_t RESP1; - __I uint32_t RESP2; - __I uint32_t RESP3; - __I uint32_t RESP4; - __IO uint32_t DTIMER; - __IO uint32_t DLEN; - __IO uint32_t DCTRL; - __I uint32_t DCOUNT; - __I uint32_t STA; - __IO uint32_t ICR; - __IO uint32_t MASK; - uint32_t RESERVED0[2]; - __I uint32_t FIFOCNT; - uint32_t RESERVED1[13]; - __IO uint32_t FIFO; -} SDIO_TypeDef; - -/** - * @brief Serial Peripheral Interface - */ - -typedef struct -{ - __IO uint16_t CR1; - uint16_t RESERVED0; - __IO uint16_t CR2; - uint16_t RESERVED1; - __IO uint16_t SR; - uint16_t RESERVED2; - __IO uint16_t DR; - uint16_t RESERVED3; - __IO uint16_t CRCPR; - uint16_t RESERVED4; - __IO uint16_t RXCRCR; - uint16_t RESERVED5; - __IO uint16_t TXCRCR; - uint16_t RESERVED6; - __IO uint16_t I2SCFGR; - uint16_t RESERVED7; - __IO uint16_t I2SPR; - uint16_t RESERVED8; -} SPI_TypeDef; - -/** - * @brief TIM - */ - -typedef struct -{ - __IO uint16_t CR1; - uint16_t RESERVED0; - __IO uint16_t CR2; - uint16_t RESERVED1; - __IO uint16_t SMCR; - uint16_t RESERVED2; - __IO uint16_t DIER; - uint16_t RESERVED3; - __IO uint16_t SR; - uint16_t RESERVED4; - __IO uint16_t EGR; - uint16_t RESERVED5; - __IO uint16_t CCMR1; - uint16_t RESERVED6; - __IO uint16_t CCMR2; - uint16_t RESERVED7; - __IO uint16_t CCER; - uint16_t RESERVED8; - __IO uint16_t CNT; - uint16_t RESERVED9; - __IO uint16_t PSC; - uint16_t RESERVED10; - __IO uint16_t ARR; - uint16_t RESERVED11; - __IO uint16_t RCR; - uint16_t RESERVED12; - __IO uint16_t CCR1; - uint16_t RESERVED13; - __IO uint16_t CCR2; - uint16_t RESERVED14; - __IO uint16_t CCR3; - uint16_t RESERVED15; - __IO uint16_t CCR4; - uint16_t RESERVED16; - __IO uint16_t BDTR; - uint16_t RESERVED17; - __IO uint16_t DCR; - uint16_t RESERVED18; - __IO uint16_t DMAR; - uint16_t RESERVED19; -} TIM_TypeDef; - -/** - * @brief Universal Synchronous Asynchronous Receiver Transmitter - */ - -typedef struct -{ - __IO uint16_t SR; - uint16_t RESERVED0; - __IO uint16_t DR; - uint16_t RESERVED1; - __IO uint16_t BRR; - uint16_t RESERVED2; - __IO uint16_t CR1; - uint16_t RESERVED3; - __IO uint16_t CR2; - uint16_t RESERVED4; - __IO uint16_t CR3; - uint16_t RESERVED5; - __IO uint16_t GTPR; - uint16_t RESERVED6; -} USART_TypeDef; - -/** - * @brief Window WATCHDOG - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t CFR; - __IO uint32_t SR; -} WWDG_TypeDef; - -/** - * @} - */ - -/** @addtogroup Peripheral_memory_map - * @{ - */ - -#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the alias region */ -#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the alias region */ - -#define SRAM_BASE ((uint32_t)0x20000000) /*!< Peripheral base address in the bit-band region */ -#define PERIPH_BASE ((uint32_t)0x40000000) /*!< SRAM base address in the bit-band region */ - -#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ - -/*!< Peripheral memory map */ -#define APB1PERIPH_BASE PERIPH_BASE -#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) -#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) - -#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) -#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) -#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) -#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) -#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) -#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) -#define RTC_BASE (APB1PERIPH_BASE + 0x2800) -#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) -#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) -#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) -#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) -#define USART2_BASE (APB1PERIPH_BASE + 0x4400) -#define USART3_BASE (APB1PERIPH_BASE + 0x4800) -#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) -#define UART5_BASE (APB1PERIPH_BASE + 0x5000) -#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) -#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) -#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) -#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) -#define BKP_BASE (APB1PERIPH_BASE + 0x6C00) -#define PWR_BASE (APB1PERIPH_BASE + 0x7000) -#define DAC_BASE (APB1PERIPH_BASE + 0x7400) - -#define AFIO_BASE (APB2PERIPH_BASE + 0x0000) -#define EXTI_BASE (APB2PERIPH_BASE + 0x0400) -#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) -#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) -#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) -#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) -#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) -#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00) -#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000) -#define ADC1_BASE (APB2PERIPH_BASE + 0x2400) -#define ADC2_BASE (APB2PERIPH_BASE + 0x2800) -#define TIM1_BASE (APB2PERIPH_BASE + 0x2C00) -#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) -#define TIM8_BASE (APB2PERIPH_BASE + 0x3400) -#define USART1_BASE (APB2PERIPH_BASE + 0x3800) -#define ADC3_BASE (APB2PERIPH_BASE + 0x3C00) - -#define SDIO_BASE (PERIPH_BASE + 0x18000) - -#define DMA1_BASE (AHBPERIPH_BASE + 0x0000) -#define DMA1_Channel1_BASE (AHBPERIPH_BASE + 0x0008) -#define DMA1_Channel2_BASE (AHBPERIPH_BASE + 0x001C) -#define DMA1_Channel3_BASE (AHBPERIPH_BASE + 0x0030) -#define DMA1_Channel4_BASE (AHBPERIPH_BASE + 0x0044) -#define DMA1_Channel5_BASE (AHBPERIPH_BASE + 0x0058) -#define DMA1_Channel6_BASE (AHBPERIPH_BASE + 0x006C) -#define DMA1_Channel7_BASE (AHBPERIPH_BASE + 0x0080) -#define DMA2_BASE (AHBPERIPH_BASE + 0x0400) -#define DMA2_Channel1_BASE (AHBPERIPH_BASE + 0x0408) -#define DMA2_Channel2_BASE (AHBPERIPH_BASE + 0x041C) -#define DMA2_Channel3_BASE (AHBPERIPH_BASE + 0x0430) -#define DMA2_Channel4_BASE (AHBPERIPH_BASE + 0x0444) -#define DMA2_Channel5_BASE (AHBPERIPH_BASE + 0x0458) -#define RCC_BASE (AHBPERIPH_BASE + 0x1000) -#define CRC_BASE (AHBPERIPH_BASE + 0x3000) - -#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000) /*!< Flash registers base address */ -#define OB_BASE ((uint32_t)0x1FFFF800) /*!< Flash Option Bytes base address */ - -#define ETH_BASE (AHBPERIPH_BASE + 0x8000) -#define ETH_MAC_BASE (ETH_BASE) -#define ETH_MMC_BASE (ETH_BASE + 0x0100) -#define ETH_PTP_BASE (ETH_BASE + 0x0700) -#define ETH_DMA_BASE (ETH_BASE + 0x1000) - -#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) /*!< FSMC Bank1 registers base address */ -#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) /*!< FSMC Bank1E registers base address */ -#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) /*!< FSMC Bank2 registers base address */ -#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) /*!< FSMC Bank3 registers base address */ -#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) /*!< FSMC Bank4 registers base address */ - -#define DBGMCU_BASE ((uint32_t)0xE0042000) /*!< Debug MCU registers base address */ - -/** - * @} - */ - -/** @addtogroup Peripheral_declaration - * @{ - */ - -#define TIM2 ((TIM_TypeDef *) TIM2_BASE) -#define TIM3 ((TIM_TypeDef *) TIM3_BASE) -#define TIM4 ((TIM_TypeDef *) TIM4_BASE) -#define TIM5 ((TIM_TypeDef *) TIM5_BASE) -#define TIM6 ((TIM_TypeDef *) TIM6_BASE) -#define TIM7 ((TIM_TypeDef *) TIM7_BASE) -#define RTC ((RTC_TypeDef *) RTC_BASE) -#define WWDG ((WWDG_TypeDef *) WWDG_BASE) -#define IWDG ((IWDG_TypeDef *) IWDG_BASE) -#define SPI2 ((SPI_TypeDef *) SPI2_BASE) -#define SPI3 ((SPI_TypeDef *) SPI3_BASE) -#define USART2 ((USART_TypeDef *) USART2_BASE) -#define USART3 ((USART_TypeDef *) USART3_BASE) -#define UART4 ((USART_TypeDef *) UART4_BASE) -#define UART5 ((USART_TypeDef *) UART5_BASE) -#define I2C1 ((I2C_TypeDef *) I2C1_BASE) -#define I2C2 ((I2C_TypeDef *) I2C2_BASE) -#define CAN1 ((CAN_TypeDef *) CAN1_BASE) -#define CAN2 ((CAN_TypeDef *) CAN2_BASE) -#define BKP ((BKP_TypeDef *) BKP_BASE) -#define PWR ((PWR_TypeDef *) PWR_BASE) -#define DAC ((DAC_TypeDef *) DAC_BASE) -#define AFIO ((AFIO_TypeDef *) AFIO_BASE) -#define EXTI ((EXTI_TypeDef *) EXTI_BASE) -#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) -#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) -#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) -#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) -#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) -#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) -#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) -#define ADC1 ((ADC_TypeDef *) ADC1_BASE) -#define ADC2 ((ADC_TypeDef *) ADC2_BASE) -#define TIM1 ((TIM_TypeDef *) TIM1_BASE) -#define SPI1 ((SPI_TypeDef *) SPI1_BASE) -#define TIM8 ((TIM_TypeDef *) TIM8_BASE) -#define USART1 ((USART_TypeDef *) USART1_BASE) -#define ADC3 ((ADC_TypeDef *) ADC3_BASE) -#define SDIO ((SDIO_TypeDef *) SDIO_BASE) -#define DMA1 ((DMA_TypeDef *) DMA1_BASE) -#define DMA2 ((DMA_TypeDef *) DMA2_BASE) -#define DMA1_Channel1 ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE) -#define DMA1_Channel2 ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE) -#define DMA1_Channel3 ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE) -#define DMA1_Channel4 ((DMA_Channel_TypeDef *) DMA1_Channel4_BASE) -#define DMA1_Channel5 ((DMA_Channel_TypeDef *) DMA1_Channel5_BASE) -#define DMA1_Channel6 ((DMA_Channel_TypeDef *) DMA1_Channel6_BASE) -#define DMA1_Channel7 ((DMA_Channel_TypeDef *) DMA1_Channel7_BASE) -#define DMA2_Channel1 ((DMA_Channel_TypeDef *) DMA2_Channel1_BASE) -#define DMA2_Channel2 ((DMA_Channel_TypeDef *) DMA2_Channel2_BASE) -#define DMA2_Channel3 ((DMA_Channel_TypeDef *) DMA2_Channel3_BASE) -#define DMA2_Channel4 ((DMA_Channel_TypeDef *) DMA2_Channel4_BASE) -#define DMA2_Channel5 ((DMA_Channel_TypeDef *) DMA2_Channel5_BASE) -#define RCC ((RCC_TypeDef *) RCC_BASE) -#define CRC ((CRC_TypeDef *) CRC_BASE) -#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) -#define OB ((OB_TypeDef *) OB_BASE) -#define ETH ((ETH_TypeDef *) ETH_BASE) -#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) -#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) -#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE) -#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE) -#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE) -#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) - -/** - * @} - */ - -/** @addtogroup Exported_constants - * @{ - */ - - /** @addtogroup Peripheral_Registers_Bits_Definition - * @{ - */ - -/******************************************************************************/ -/* Peripheral Registers_Bits_Definition */ -/******************************************************************************/ - -/******************************************************************************/ -/* */ -/* CRC calculation unit */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for CRC_DR register *********************/ -#define CRC_DR_DR ((uint32_t)0xFFFFFFFF) /*!< Data register bits */ - - -/******************* Bit definition for CRC_IDR register ********************/ -#define CRC_IDR_IDR ((uint8_t)0xFF) /*!< General-purpose 8-bit data register bits */ - - -/******************** Bit definition for CRC_CR register ********************/ -#define CRC_CR_RESET ((uint8_t)0x01) /*!< RESET bit */ - -/******************************************************************************/ -/* */ -/* Power Control */ -/* */ -/******************************************************************************/ - -/******************** Bit definition for PWR_CR register ********************/ -#define PWR_CR_LPDS ((uint16_t)0x0001) /*!< Low-Power Deepsleep */ -#define PWR_CR_PDDS ((uint16_t)0x0002) /*!< Power Down Deepsleep */ -#define PWR_CR_CWUF ((uint16_t)0x0004) /*!< Clear Wakeup Flag */ -#define PWR_CR_CSBF ((uint16_t)0x0008) /*!< Clear Standby Flag */ -#define PWR_CR_PVDE ((uint16_t)0x0010) /*!< Power Voltage Detector Enable */ - -#define PWR_CR_PLS ((uint16_t)0x00E0) /*!< PLS[2:0] bits (PVD Level Selection) */ -#define PWR_CR_PLS_0 ((uint16_t)0x0020) /*!< Bit 0 */ -#define PWR_CR_PLS_1 ((uint16_t)0x0040) /*!< Bit 1 */ -#define PWR_CR_PLS_2 ((uint16_t)0x0080) /*!< Bit 2 */ - -/*!< PVD level configuration */ -#define PWR_CR_PLS_2V2 ((uint16_t)0x0000) /*!< PVD level 2.2V */ -#define PWR_CR_PLS_2V3 ((uint16_t)0x0020) /*!< PVD level 2.3V */ -#define PWR_CR_PLS_2V4 ((uint16_t)0x0040) /*!< PVD level 2.4V */ -#define PWR_CR_PLS_2V5 ((uint16_t)0x0060) /*!< PVD level 2.5V */ -#define PWR_CR_PLS_2V6 ((uint16_t)0x0080) /*!< PVD level 2.6V */ -#define PWR_CR_PLS_2V7 ((uint16_t)0x00A0) /*!< PVD level 2.7V */ -#define PWR_CR_PLS_2V8 ((uint16_t)0x00C0) /*!< PVD level 2.8V */ -#define PWR_CR_PLS_2V9 ((uint16_t)0x00E0) /*!< PVD level 2.9V */ - -#define PWR_CR_DBP ((uint16_t)0x0100) /*!< Disable Backup Domain write protection */ - - -/******************* Bit definition for PWR_CSR register ********************/ -#define PWR_CSR_WUF ((uint16_t)0x0001) /*!< Wakeup Flag */ -#define PWR_CSR_SBF ((uint16_t)0x0002) /*!< Standby Flag */ -#define PWR_CSR_PVDO ((uint16_t)0x0004) /*!< PVD Output */ -#define PWR_CSR_EWUP ((uint16_t)0x0100) /*!< Enable WKUP pin */ - -/******************************************************************************/ -/* */ -/* Backup registers */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for BKP_DR1 register ********************/ -#define BKP_DR1_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR2 register ********************/ -#define BKP_DR2_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR3 register ********************/ -#define BKP_DR3_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR4 register ********************/ -#define BKP_DR4_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR5 register ********************/ -#define BKP_DR5_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR6 register ********************/ -#define BKP_DR6_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR7 register ********************/ -#define BKP_DR7_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR8 register ********************/ -#define BKP_DR8_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR9 register ********************/ -#define BKP_DR9_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR10 register *******************/ -#define BKP_DR10_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR11 register *******************/ -#define BKP_DR11_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR12 register *******************/ -#define BKP_DR12_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR13 register *******************/ -#define BKP_DR13_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR14 register *******************/ -#define BKP_DR14_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR15 register *******************/ -#define BKP_DR15_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR16 register *******************/ -#define BKP_DR16_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR17 register *******************/ -#define BKP_DR17_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/****************** Bit definition for BKP_DR18 register ********************/ -#define BKP_DR18_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR19 register *******************/ -#define BKP_DR19_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR20 register *******************/ -#define BKP_DR20_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR21 register *******************/ -#define BKP_DR21_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR22 register *******************/ -#define BKP_DR22_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR23 register *******************/ -#define BKP_DR23_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR24 register *******************/ -#define BKP_DR24_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR25 register *******************/ -#define BKP_DR25_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR26 register *******************/ -#define BKP_DR26_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR27 register *******************/ -#define BKP_DR27_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR28 register *******************/ -#define BKP_DR28_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR29 register *******************/ -#define BKP_DR29_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR30 register *******************/ -#define BKP_DR30_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR31 register *******************/ -#define BKP_DR31_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR32 register *******************/ -#define BKP_DR32_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR33 register *******************/ -#define BKP_DR33_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR34 register *******************/ -#define BKP_DR34_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR35 register *******************/ -#define BKP_DR35_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR36 register *******************/ -#define BKP_DR36_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR37 register *******************/ -#define BKP_DR37_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR38 register *******************/ -#define BKP_DR38_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR39 register *******************/ -#define BKP_DR39_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR40 register *******************/ -#define BKP_DR40_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR41 register *******************/ -#define BKP_DR41_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR42 register *******************/ -#define BKP_DR42_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/****************** Bit definition for BKP_RTCCR register *******************/ -#define BKP_RTCCR_CAL ((uint16_t)0x007F) /*!< Calibration value */ -#define BKP_RTCCR_CCO ((uint16_t)0x0080) /*!< Calibration Clock Output */ -#define BKP_RTCCR_ASOE ((uint16_t)0x0100) /*!< Alarm or Second Output Enable */ -#define BKP_RTCCR_ASOS ((uint16_t)0x0200) /*!< Alarm or Second Output Selection */ - -/******************** Bit definition for BKP_CR register ********************/ -#define BKP_CR_TPE ((uint8_t)0x01) /*!< TAMPER pin enable */ -#define BKP_CR_TPAL ((uint8_t)0x02) /*!< TAMPER pin active level */ - -/******************* Bit definition for BKP_CSR register ********************/ -#define BKP_CSR_CTE ((uint16_t)0x0001) /*!< Clear Tamper event */ -#define BKP_CSR_CTI ((uint16_t)0x0002) /*!< Clear Tamper Interrupt */ -#define BKP_CSR_TPIE ((uint16_t)0x0004) /*!< TAMPER Pin interrupt enable */ -#define BKP_CSR_TEF ((uint16_t)0x0100) /*!< Tamper Event Flag */ -#define BKP_CSR_TIF ((uint16_t)0x0200) /*!< Tamper Interrupt Flag */ - -/******************************************************************************/ -/* */ -/* Reset and Clock Control */ -/* */ -/******************************************************************************/ - -/******************** Bit definition for RCC_CR register ********************/ -#define RCC_CR_HSION ((uint32_t)0x00000001) /*!< Internal High Speed clock enable */ -#define RCC_CR_HSIRDY ((uint32_t)0x00000002) /*!< Internal High Speed clock ready flag */ -#define RCC_CR_HSITRIM ((uint32_t)0x000000F8) /*!< Internal High Speed clock trimming */ -#define RCC_CR_HSICAL ((uint32_t)0x0000FF00) /*!< Internal High Speed clock Calibration */ -#define RCC_CR_HSEON ((uint32_t)0x00010000) /*!< External High Speed clock enable */ -#define RCC_CR_HSERDY ((uint32_t)0x00020000) /*!< External High Speed clock ready flag */ -#define RCC_CR_HSEBYP ((uint32_t)0x00040000) /*!< External High Speed clock Bypass */ -#define RCC_CR_CSSON ((uint32_t)0x00080000) /*!< Clock Security System enable */ -#define RCC_CR_PLLON ((uint32_t)0x01000000) /*!< PLL enable */ -#define RCC_CR_PLLRDY ((uint32_t)0x02000000) /*!< PLL clock ready flag */ - -#ifdef STM32F10X_CL - #define RCC_CR_PLL2ON ((uint32_t)0x04000000) /*!< PLL2 enable */ - #define RCC_CR_PLL2RDY ((uint32_t)0x08000000) /*!< PLL2 clock ready flag */ - #define RCC_CR_PLL3ON ((uint32_t)0x10000000) /*!< PLL3 enable */ - #define RCC_CR_PLL3RDY ((uint32_t)0x20000000) /*!< PLL3 clock ready flag */ -#endif /* STM32F10X_CL */ - -/******************* Bit definition for RCC_CFGR register *******************/ -/*!< SW configuration */ -#define RCC_CFGR_SW ((uint32_t)0x00000003) /*!< SW[1:0] bits (System clock Switch) */ -#define RCC_CFGR_SW_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define RCC_CFGR_SW_1 ((uint32_t)0x00000002) /*!< Bit 1 */ - -#define RCC_CFGR_SW_HSI ((uint32_t)0x00000000) /*!< HSI selected as system clock */ -#define RCC_CFGR_SW_HSE ((uint32_t)0x00000001) /*!< HSE selected as system clock */ -#define RCC_CFGR_SW_PLL ((uint32_t)0x00000002) /*!< PLL selected as system clock */ - -/*!< SWS configuration */ -#define RCC_CFGR_SWS ((uint32_t)0x0000000C) /*!< SWS[1:0] bits (System Clock Switch Status) */ -#define RCC_CFGR_SWS_0 ((uint32_t)0x00000004) /*!< Bit 0 */ -#define RCC_CFGR_SWS_1 ((uint32_t)0x00000008) /*!< Bit 1 */ - -#define RCC_CFGR_SWS_HSI ((uint32_t)0x00000000) /*!< HSI oscillator used as system clock */ -#define RCC_CFGR_SWS_HSE ((uint32_t)0x00000004) /*!< HSE oscillator used as system clock */ -#define RCC_CFGR_SWS_PLL ((uint32_t)0x00000008) /*!< PLL used as system clock */ - -/*!< HPRE configuration */ -#define RCC_CFGR_HPRE ((uint32_t)0x000000F0) /*!< HPRE[3:0] bits (AHB prescaler) */ -#define RCC_CFGR_HPRE_0 ((uint32_t)0x00000010) /*!< Bit 0 */ -#define RCC_CFGR_HPRE_1 ((uint32_t)0x00000020) /*!< Bit 1 */ -#define RCC_CFGR_HPRE_2 ((uint32_t)0x00000040) /*!< Bit 2 */ -#define RCC_CFGR_HPRE_3 ((uint32_t)0x00000080) /*!< Bit 3 */ - -#define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x00000000) /*!< SYSCLK not divided */ -#define RCC_CFGR_HPRE_DIV2 ((uint32_t)0x00000080) /*!< SYSCLK divided by 2 */ -#define RCC_CFGR_HPRE_DIV4 ((uint32_t)0x00000090) /*!< SYSCLK divided by 4 */ -#define RCC_CFGR_HPRE_DIV8 ((uint32_t)0x000000A0) /*!< SYSCLK divided by 8 */ -#define RCC_CFGR_HPRE_DIV16 ((uint32_t)0x000000B0) /*!< SYSCLK divided by 16 */ -#define RCC_CFGR_HPRE_DIV64 ((uint32_t)0x000000C0) /*!< SYSCLK divided by 64 */ -#define RCC_CFGR_HPRE_DIV128 ((uint32_t)0x000000D0) /*!< SYSCLK divided by 128 */ -#define RCC_CFGR_HPRE_DIV256 ((uint32_t)0x000000E0) /*!< SYSCLK divided by 256 */ -#define RCC_CFGR_HPRE_DIV512 ((uint32_t)0x000000F0) /*!< SYSCLK divided by 512 */ - -/*!< PPRE1 configuration */ -#define RCC_CFGR_PPRE1 ((uint32_t)0x00000700) /*!< PRE1[2:0] bits (APB1 prescaler) */ -#define RCC_CFGR_PPRE1_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define RCC_CFGR_PPRE1_1 ((uint32_t)0x00000200) /*!< Bit 1 */ -#define RCC_CFGR_PPRE1_2 ((uint32_t)0x00000400) /*!< Bit 2 */ - -#define RCC_CFGR_PPRE1_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */ -#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400) /*!< HCLK divided by 2 */ -#define RCC_CFGR_PPRE1_DIV4 ((uint32_t)0x00000500) /*!< HCLK divided by 4 */ -#define RCC_CFGR_PPRE1_DIV8 ((uint32_t)0x00000600) /*!< HCLK divided by 8 */ -#define RCC_CFGR_PPRE1_DIV16 ((uint32_t)0x00000700) /*!< HCLK divided by 16 */ - -/*!< PPRE2 configuration */ -#define RCC_CFGR_PPRE2 ((uint32_t)0x00003800) /*!< PRE2[2:0] bits (APB2 prescaler) */ -#define RCC_CFGR_PPRE2_0 ((uint32_t)0x00000800) /*!< Bit 0 */ -#define RCC_CFGR_PPRE2_1 ((uint32_t)0x00001000) /*!< Bit 1 */ -#define RCC_CFGR_PPRE2_2 ((uint32_t)0x00002000) /*!< Bit 2 */ - -#define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */ -#define RCC_CFGR_PPRE2_DIV2 ((uint32_t)0x00002000) /*!< HCLK divided by 2 */ -#define RCC_CFGR_PPRE2_DIV4 ((uint32_t)0x00002800) /*!< HCLK divided by 4 */ -#define RCC_CFGR_PPRE2_DIV8 ((uint32_t)0x00003000) /*!< HCLK divided by 8 */ -#define RCC_CFGR_PPRE2_DIV16 ((uint32_t)0x00003800) /*!< HCLK divided by 16 */ - -/*!< ADCPPRE configuration */ -#define RCC_CFGR_ADCPRE ((uint32_t)0x0000C000) /*!< ADCPRE[1:0] bits (ADC prescaler) */ -#define RCC_CFGR_ADCPRE_0 ((uint32_t)0x00004000) /*!< Bit 0 */ -#define RCC_CFGR_ADCPRE_1 ((uint32_t)0x00008000) /*!< Bit 1 */ - -#define RCC_CFGR_ADCPRE_DIV2 ((uint32_t)0x00000000) /*!< PCLK2 divided by 2 */ -#define RCC_CFGR_ADCPRE_DIV4 ((uint32_t)0x00004000) /*!< PCLK2 divided by 4 */ -#define RCC_CFGR_ADCPRE_DIV6 ((uint32_t)0x00008000) /*!< PCLK2 divided by 6 */ -#define RCC_CFGR_ADCPRE_DIV8 ((uint32_t)0x0000C000) /*!< PCLK2 divided by 8 */ - -#define RCC_CFGR_PLLSRC ((uint32_t)0x00010000) /*!< PLL entry clock source */ - -#define RCC_CFGR_PLLXTPRE ((uint32_t)0x00020000) /*!< HSE divider for PLL entry */ - -/*!< PLLMUL configuration */ -#define RCC_CFGR_PLLMULL ((uint32_t)0x003C0000) /*!< PLLMUL[3:0] bits (PLL multiplication factor) */ -#define RCC_CFGR_PLLMULL_0 ((uint32_t)0x00040000) /*!< Bit 0 */ -#define RCC_CFGR_PLLMULL_1 ((uint32_t)0x00080000) /*!< Bit 1 */ -#define RCC_CFGR_PLLMULL_2 ((uint32_t)0x00100000) /*!< Bit 2 */ -#define RCC_CFGR_PLLMULL_3 ((uint32_t)0x00200000) /*!< Bit 3 */ - -#ifdef STM32F10X_CL - #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */ - #define RCC_CFGR_PLLSRC_PREDIV1 ((uint32_t)0x00010000) /*!< PREDIV1 clock selected as PLL entry clock source */ - - #define RCC_CFGR_PLLXTPRE_PREDIV1 ((uint32_t)0x00000000) /*!< PREDIV1 clock not divided for PLL entry */ - #define RCC_CFGR_PLLXTPRE_PREDIV1_Div2 ((uint32_t)0x00020000) /*!< PREDIV1 clock divided by 2 for PLL entry */ - - #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock * 4 */ - #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock * 5 */ - #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock * 6 */ - #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock * 7 */ - #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock * 8 */ - #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock * 9 */ - #define RCC_CFGR_PLLMULL6_5 ((uint32_t)0x00340000) /*!< PLL input clock * 6.5 */ - - #define RCC_CFGR_OTGFSPRE ((uint32_t)0x00400000) /*!< USB OTG FS prescaler */ - -/*!< MCO configuration */ - #define RCC_CFGR_MCO ((uint32_t)0x0F000000) /*!< MCO[3:0] bits (Microcontroller Clock Output) */ - #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */ - #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */ - #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */ - #define RCC_CFGR_MCO_3 ((uint32_t)0x08000000) /*!< Bit 3 */ - - #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ - #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */ - #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */ - #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */ - #define RCC_CFGR_MCO_PLLCLK_Div2 ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */ - #define RCC_CFGR_MCO_PLL2CLK ((uint32_t)0x08000000) /*!< PLL2 clock selected as MCO source*/ - #define RCC_CFGR_MCO_PLL3CLK_Div2 ((uint32_t)0x09000000) /*!< PLL3 clock divided by 2 selected as MCO source*/ - #define RCC_CFGR_MCO_Ext_HSE ((uint32_t)0x0A000000) /*!< XT1 external 3-25 MHz oscillator clock selected as MCO source */ - #define RCC_CFGR_MCO_PLL3CLK ((uint32_t)0x0B000000) /*!< PLL3 clock selected as MCO source */ -#else - #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */ - #define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000) /*!< HSE clock selected as PLL entry clock source */ - - #define RCC_CFGR_PLLXTPRE_HSE ((uint32_t)0x00000000) /*!< HSE clock not divided for PLL entry */ - #define RCC_CFGR_PLLXTPRE_HSE_Div2 ((uint32_t)0x00020000) /*!< HSE clock divided by 2 for PLL entry */ - - #define RCC_CFGR_PLLMULL2 ((uint32_t)0x00000000) /*!< PLL input clock*2 */ - #define RCC_CFGR_PLLMULL3 ((uint32_t)0x00040000) /*!< PLL input clock*3 */ - #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock*4 */ - #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock*5 */ - #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock*6 */ - #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock*7 */ - #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock*8 */ - #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock*9 */ - #define RCC_CFGR_PLLMULL10 ((uint32_t)0x00200000) /*!< PLL input clock10 */ - #define RCC_CFGR_PLLMULL11 ((uint32_t)0x00240000) /*!< PLL input clock*11 */ - #define RCC_CFGR_PLLMULL12 ((uint32_t)0x00280000) /*!< PLL input clock*12 */ - #define RCC_CFGR_PLLMULL13 ((uint32_t)0x002C0000) /*!< PLL input clock*13 */ - #define RCC_CFGR_PLLMULL14 ((uint32_t)0x00300000) /*!< PLL input clock*14 */ - #define RCC_CFGR_PLLMULL15 ((uint32_t)0x00340000) /*!< PLL input clock*15 */ - #define RCC_CFGR_PLLMULL16 ((uint32_t)0x00380000) /*!< PLL input clock*16 */ - #define RCC_CFGR_USBPRE ((uint32_t)0x00400000) /*!< USB Device prescaler */ - -/*!< MCO configuration */ - #define RCC_CFGR_MCO ((uint32_t)0x07000000) /*!< MCO[2:0] bits (Microcontroller Clock Output) */ - #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */ - #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */ - #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */ - - #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ - #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */ - #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */ - #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */ - #define RCC_CFGR_MCO_PLL ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */ -#endif /* STM32F10X_CL */ - -/*!<****************** Bit definition for RCC_CIR register ********************/ -#define RCC_CIR_LSIRDYF ((uint32_t)0x00000001) /*!< LSI Ready Interrupt flag */ -#define RCC_CIR_LSERDYF ((uint32_t)0x00000002) /*!< LSE Ready Interrupt flag */ -#define RCC_CIR_HSIRDYF ((uint32_t)0x00000004) /*!< HSI Ready Interrupt flag */ -#define RCC_CIR_HSERDYF ((uint32_t)0x00000008) /*!< HSE Ready Interrupt flag */ -#define RCC_CIR_PLLRDYF ((uint32_t)0x00000010) /*!< PLL Ready Interrupt flag */ -#define RCC_CIR_CSSF ((uint32_t)0x00000080) /*!< Clock Security System Interrupt flag */ -#define RCC_CIR_LSIRDYIE ((uint32_t)0x00000100) /*!< LSI Ready Interrupt Enable */ -#define RCC_CIR_LSERDYIE ((uint32_t)0x00000200) /*!< LSE Ready Interrupt Enable */ -#define RCC_CIR_HSIRDYIE ((uint32_t)0x00000400) /*!< HSI Ready Interrupt Enable */ -#define RCC_CIR_HSERDYIE ((uint32_t)0x00000800) /*!< HSE Ready Interrupt Enable */ -#define RCC_CIR_PLLRDYIE ((uint32_t)0x00001000) /*!< PLL Ready Interrupt Enable */ -#define RCC_CIR_LSIRDYC ((uint32_t)0x00010000) /*!< LSI Ready Interrupt Clear */ -#define RCC_CIR_LSERDYC ((uint32_t)0x00020000) /*!< LSE Ready Interrupt Clear */ -#define RCC_CIR_HSIRDYC ((uint32_t)0x00040000) /*!< HSI Ready Interrupt Clear */ -#define RCC_CIR_HSERDYC ((uint32_t)0x00080000) /*!< HSE Ready Interrupt Clear */ -#define RCC_CIR_PLLRDYC ((uint32_t)0x00100000) /*!< PLL Ready Interrupt Clear */ -#define RCC_CIR_CSSC ((uint32_t)0x00800000) /*!< Clock Security System Interrupt Clear */ - -#ifdef STM32F10X_CL - #define RCC_CIR_PLL2RDYF ((uint32_t)0x00000020) /*!< PLL2 Ready Interrupt flag */ - #define RCC_CIR_PLL3RDYF ((uint32_t)0x00000040) /*!< PLL3 Ready Interrupt flag */ - #define RCC_CIR_PLL2RDYIE ((uint32_t)0x00002000) /*!< PLL2 Ready Interrupt Enable */ - #define RCC_CIR_PLL3RDYIE ((uint32_t)0x00004000) /*!< PLL3 Ready Interrupt Enable */ - #define RCC_CIR_PLL2RDYC ((uint32_t)0x00200000) /*!< PLL2 Ready Interrupt Clear */ - #define RCC_CIR_PLL3RDYC ((uint32_t)0x00400000) /*!< PLL3 Ready Interrupt Clear */ -#endif /* STM32F10X_CL */ - -/***************** Bit definition for RCC_APB2RSTR register *****************/ -#define RCC_APB2RSTR_AFIORST ((uint16_t)0x0001) /*!< Alternate Function I/O reset */ -#define RCC_APB2RSTR_IOPARST ((uint16_t)0x0004) /*!< I/O port A reset */ -#define RCC_APB2RSTR_IOPBRST ((uint16_t)0x0008) /*!< I/O port B reset */ -#define RCC_APB2RSTR_IOPCRST ((uint16_t)0x0010) /*!< I/O port C reset */ -#define RCC_APB2RSTR_IOPDRST ((uint16_t)0x0020) /*!< I/O port D reset */ -#define RCC_APB2RSTR_ADC1RST ((uint16_t)0x0200) /*!< ADC 1 interface reset */ -#define RCC_APB2RSTR_ADC2RST ((uint16_t)0x0400) /*!< ADC 2 interface reset */ -#define RCC_APB2RSTR_TIM1RST ((uint16_t)0x0800) /*!< TIM1 Timer reset */ -#define RCC_APB2RSTR_SPI1RST ((uint16_t)0x1000) /*!< SPI 1 reset */ -#define RCC_APB2RSTR_USART1RST ((uint16_t)0x4000) /*!< USART1 reset */ - -#ifndef STM32F10X_LD - #define RCC_APB2RSTR_IOPERST ((uint16_t)0x0040) /*!< I/O port E reset */ -#endif /* STM32F10X_HD */ - -#ifdef STM32F10X_HD - #define RCC_APB2RSTR_IOPFRST ((uint16_t)0x0080) /*!< I/O port F reset */ - #define RCC_APB2RSTR_IOPGRST ((uint16_t)0x0100) /*!< I/O port G reset */ - #define RCC_APB2RSTR_TIM8RST ((uint16_t)0x2000) /*!< TIM8 Timer reset */ - #define RCC_APB2RSTR_ADC3RST ((uint16_t)0x8000) /*!< ADC3 interface reset */ -#endif /* STM32F10X_HD */ - -/***************** Bit definition for RCC_APB1RSTR register *****************/ -#define RCC_APB1RSTR_TIM2RST ((uint32_t)0x00000001) /*!< Timer 2 reset */ -#define RCC_APB1RSTR_TIM3RST ((uint32_t)0x00000002) /*!< Timer 3 reset */ -#define RCC_APB1RSTR_WWDGRST ((uint32_t)0x00000800) /*!< Window Watchdog reset */ -#define RCC_APB1RSTR_USART2RST ((uint32_t)0x00020000) /*!< USART 2 reset */ -#define RCC_APB1RSTR_I2C1RST ((uint32_t)0x00200000) /*!< I2C 1 reset */ -#define RCC_APB1RSTR_CAN1RST ((uint32_t)0x02000000) /*!< CAN1 reset */ -#define RCC_APB1RSTR_BKPRST ((uint32_t)0x08000000) /*!< Backup interface reset */ -#define RCC_APB1RSTR_PWRRST ((uint32_t)0x10000000) /*!< Power interface reset */ - -#ifndef STM32F10X_LD - #define RCC_APB1RSTR_TIM4RST ((uint32_t)0x00000004) /*!< Timer 4 reset */ - #define RCC_APB1RSTR_SPI2RST ((uint32_t)0x00004000) /*!< SPI 2 reset */ - #define RCC_APB1RSTR_USART3RST ((uint32_t)0x00040000) /*!< RUSART 3 reset */ - #define RCC_APB1RSTR_I2C2RST ((uint32_t)0x00400000) /*!< I2C 2 reset */ -#endif /* STM32F10X_HD */ - -#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD) - #define RCC_APB1RSTR_USBRST ((uint32_t)0x00800000) /*!< USB Device reset */ -#endif - -#if defined (STM32F10X_HD) || defined (STM32F10X_CL) - #define RCC_APB1RSTR_TIM5RST ((uint32_t)0x00000008) /*!< Timer 5 reset */ - #define RCC_APB1RSTR_TIM6RST ((uint32_t)0x00000010) /*!< Timer 6 reset */ - #define RCC_APB1RSTR_TIM7RST ((uint32_t)0x00000020) /*!< Timer 7 reset */ - #define RCC_APB1RSTR_SPI3RST ((uint32_t)0x00008000) /*!< SPI 3 reset */ - #define RCC_APB1RSTR_UART4RST ((uint32_t)0x00080000) /*!< UART 4 reset */ - #define RCC_APB1RSTR_UART5RST ((uint32_t)0x00100000) /*!< UART 5 reset */ - #define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */ -#endif - -#ifdef STM32F10X_CL - #define RCC_APB1RSTR_CAN2RST ((uint32_t)0x08000000) /*!< CAN2 reset */ -#endif /* STM32F10X_CL */ - -/****************** Bit definition for RCC_AHBENR register ******************/ -#define RCC_AHBENR_DMA1EN ((uint16_t)0x0001) /*!< DMA1 clock enable */ -#define RCC_AHBENR_SRAMEN ((uint16_t)0x0004) /*!< SRAM interface clock enable */ -#define RCC_AHBENR_FLITFEN ((uint16_t)0x0010) /*!< FLITF clock enable */ -#define RCC_AHBENR_CRCEN ((uint16_t)0x0040) /*!< CRC clock enable */ - -#if defined (STM32F10X_HD) || defined (STM32F10X_CL) - #define RCC_AHBENR_DMA2EN ((uint16_t)0x0002) /*!< DMA2 clock enable */ -#endif - -#ifdef STM32F10X_HD - #define RCC_AHBENR_FSMCEN ((uint16_t)0x0100) /*!< FSMC clock enable */ - #define RCC_AHBENR_SDIOEN ((uint16_t)0x0400) /*!< SDIO clock enable */ -#endif /* STM32F10X_HD */ - -#ifdef STM32F10X_CL - #define RCC_AHBENR_OTGFSEN ((uint32_t)0x00001000) /*!< USB OTG FS clock enable */ - #define RCC_AHBENR_ETHMACEN ((uint32_t)0x00004000) /*!< ETHERNET MAC clock enable */ - #define RCC_AHBENR_ETHMACTXEN ((uint32_t)0x00008000) /*!< ETHERNET MAC Tx clock enable */ - #define RCC_AHBENR_ETHMACRXEN ((uint32_t)0x00010000) /*!< ETHERNET MAC Rx clock enable */ -#endif /* STM32F10X_CL */ - -/****************** Bit definition for RCC_APB2ENR register *****************/ -#define RCC_APB2ENR_AFIOEN ((uint16_t)0x0001) /*!< Alternate Function I/O clock enable */ -#define RCC_APB2ENR_IOPAEN ((uint16_t)0x0004) /*!< I/O port A clock enable */ -#define RCC_APB2ENR_IOPBEN ((uint16_t)0x0008) /*!< I/O port B clock enable */ -#define RCC_APB2ENR_IOPCEN ((uint16_t)0x0010) /*!< I/O port C clock enable */ -#define RCC_APB2ENR_IOPDEN ((uint16_t)0x0020) /*!< I/O port D clock enable */ -#define RCC_APB2ENR_ADC1EN ((uint16_t)0x0200) /*!< ADC 1 interface clock enable */ -#define RCC_APB2ENR_ADC2EN ((uint16_t)0x0400) /*!< ADC 2 interface clock enable */ -#define RCC_APB2ENR_TIM1EN ((uint16_t)0x0800) /*!< TIM1 Timer clock enable */ -#define RCC_APB2ENR_SPI1EN ((uint16_t)0x1000) /*!< SPI 1 clock enable */ -#define RCC_APB2ENR_USART1EN ((uint16_t)0x4000) /*!< USART1 clock enable */ - -#ifndef STM32F10X_LD - #define RCC_APB2ENR_IOPEEN ((uint16_t)0x0040) /*!< I/O port E clock enable */ -#endif /* STM32F10X_HD */ - -#ifdef STM32F10X_HD - #define RCC_APB2ENR_IOPFEN ((uint16_t)0x0080) /*!< I/O port F clock enable */ - #define RCC_APB2ENR_IOPGEN ((uint16_t)0x0100) /*!< I/O port G clock enable */ - #define RCC_APB2ENR_TIM8EN ((uint16_t)0x2000) /*!< TIM8 Timer clock enable */ - #define RCC_APB2ENR_ADC3EN ((uint16_t)0x8000) /*!< DMA1 clock enable */ -#endif /* STM32F10X_HD */ - -/***************** Bit definition for RCC_APB1ENR register ******************/ -#define RCC_APB1ENR_TIM2EN ((uint32_t)0x00000001) /*!< Timer 2 clock enabled*/ -#define RCC_APB1ENR_TIM3EN ((uint32_t)0x00000002) /*!< Timer 3 clock enable */ -#define RCC_APB1ENR_WWDGEN ((uint32_t)0x00000800) /*!< Window Watchdog clock enable */ -#define RCC_APB1ENR_USART2EN ((uint32_t)0x00020000) /*!< USART 2 clock enable */ -#define RCC_APB1ENR_I2C1EN ((uint32_t)0x00200000) /*!< I2C 1 clock enable */ -#define RCC_APB1ENR_CAN1EN ((uint32_t)0x02000000) /*!< CAN1 clock enable */ -#define RCC_APB1ENR_BKPEN ((uint32_t)0x08000000) /*!< Backup interface clock enable */ -#define RCC_APB1ENR_PWREN ((uint32_t)0x10000000) /*!< Power interface clock enable */ - -#ifndef STM32F10X_LD - #define RCC_APB1ENR_TIM4EN ((uint32_t)0x00000004) /*!< Timer 4 clock enable */ - #define RCC_APB1ENR_SPI2EN ((uint32_t)0x00004000) /*!< SPI 2 clock enable */ - #define RCC_APB1ENR_USART3EN ((uint32_t)0x00040000) /*!< USART 3 clock enable */ - #define RCC_APB1ENR_I2C2EN ((uint32_t)0x00400000) /*!< I2C 2 clock enable */ -#endif /* STM32F10X_HD */ - -#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD) - #define RCC_APB1ENR_USBEN ((uint32_t)0x00800000) /*!< USB Device clock enable */ -#endif - -#if defined (STM32F10X_HD) || defined (STM32F10X_CL) - #define RCC_APB1ENR_TIM5EN ((uint32_t)0x00000008) /*!< Timer 5 clock enable */ - #define RCC_APB1ENR_TIM6EN ((uint32_t)0x00000010) /*!< Timer 6 clock enable */ - #define RCC_APB1ENR_TIM7EN ((uint32_t)0x00000020) /*!< Timer 7 clock enable */ - #define RCC_APB1ENR_SPI3EN ((uint32_t)0x00008000) /*!< SPI 3 clock enable */ - #define RCC_APB1ENR_UART4EN ((uint32_t)0x00080000) /*!< UART 4 clock enable */ - #define RCC_APB1ENR_UART5EN ((uint32_t)0x00100000) /*!< UART 5 clock enable */ - #define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */ -#endif - -#ifdef STM32F10X_CL - #define RCC_APB1ENR_CAN2EN ((uint32_t)0x08000000) /*!< CAN2 clock enable */ -#endif /* STM32F10X_CL */ - -/******************* Bit definition for RCC_BDCR register *******************/ -#define RCC_BDCR_LSEON ((uint32_t)0x00000001) /*!< External Low Speed oscillator enable */ -#define RCC_BDCR_LSERDY ((uint32_t)0x00000002) /*!< External Low Speed oscillator Ready */ -#define RCC_BDCR_LSEBYP ((uint32_t)0x00000004) /*!< External Low Speed oscillator Bypass */ - -#define RCC_BDCR_RTCSEL ((uint32_t)0x00000300) /*!< RTCSEL[1:0] bits (RTC clock source selection) */ -#define RCC_BDCR_RTCSEL_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define RCC_BDCR_RTCSEL_1 ((uint32_t)0x00000200) /*!< Bit 1 */ - -/*!< RTC congiguration */ -#define RCC_BDCR_RTCSEL_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ -#define RCC_BDCR_RTCSEL_LSE ((uint32_t)0x00000100) /*!< LSE oscillator clock used as RTC clock */ -#define RCC_BDCR_RTCSEL_LSI ((uint32_t)0x00000200) /*!< LSI oscillator clock used as RTC clock */ -#define RCC_BDCR_RTCSEL_HSE ((uint32_t)0x00000300) /*!< HSE oscillator clock divided by 128 used as RTC clock */ - -#define RCC_BDCR_RTCEN ((uint32_t)0x00008000) /*!< RTC clock enable */ -#define RCC_BDCR_BDRST ((uint32_t)0x00010000) /*!< Backup domain software reset */ - -/******************* Bit definition for RCC_CSR register ********************/ -#define RCC_CSR_LSION ((uint32_t)0x00000001) /*!< Internal Low Speed oscillator enable */ -#define RCC_CSR_LSIRDY ((uint32_t)0x00000002) /*!< Internal Low Speed oscillator Ready */ -#define RCC_CSR_RMVF ((uint32_t)0x01000000) /*!< Remove reset flag */ -#define RCC_CSR_PINRSTF ((uint32_t)0x04000000) /*!< PIN reset flag */ -#define RCC_CSR_PORRSTF ((uint32_t)0x08000000) /*!< POR/PDR reset flag */ -#define RCC_CSR_SFTRSTF ((uint32_t)0x10000000) /*!< Software Reset flag */ -#define RCC_CSR_IWDGRSTF ((uint32_t)0x20000000) /*!< Independent Watchdog reset flag */ -#define RCC_CSR_WWDGRSTF ((uint32_t)0x40000000) /*!< Window watchdog reset flag */ -#define RCC_CSR_LPWRRSTF ((uint32_t)0x80000000) /*!< Low-Power reset flag */ - -#ifdef STM32F10X_CL -/******************* Bit definition for RCC_AHBRSTR register ****************/ - #define RCC_AHBRSTR_OTGFSRST ((uint32_t)0x00001000) /*!< USB OTG FS reset */ - #define RCC_AHBRSTR_ETHMACRST ((uint32_t)0x00004000) /*!< ETHERNET MAC reset */ - -/******************* Bit definition for RCC_CFGR2 register ******************/ -/*!< PREDIV1 configuration */ - #define RCC_CFGR2_PREDIV1 ((uint32_t)0x0000000F) /*!< PREDIV1[3:0] bits */ - #define RCC_CFGR2_PREDIV1_0 ((uint32_t)0x00000001) /*!< Bit 0 */ - #define RCC_CFGR2_PREDIV1_1 ((uint32_t)0x00000002) /*!< Bit 1 */ - #define RCC_CFGR2_PREDIV1_2 ((uint32_t)0x00000004) /*!< Bit 2 */ - #define RCC_CFGR2_PREDIV1_3 ((uint32_t)0x00000008) /*!< Bit 3 */ - - #define RCC_CFGR2_PREDIV1_DIV1 ((uint32_t)0x00000000) /*!< PREDIV1 input clock not divided */ - #define RCC_CFGR2_PREDIV1_DIV2 ((uint32_t)0x00000001) /*!< PREDIV1 input clock divided by 2 */ - #define RCC_CFGR2_PREDIV1_DIV3 ((uint32_t)0x00000002) /*!< PREDIV1 input clock divided by 3 */ - #define RCC_CFGR2_PREDIV1_DIV4 ((uint32_t)0x00000003) /*!< PREDIV1 input clock divided by 4 */ - #define RCC_CFGR2_PREDIV1_DIV5 ((uint32_t)0x00000004) /*!< PREDIV1 input clock divided by 5 */ - #define RCC_CFGR2_PREDIV1_DIV6 ((uint32_t)0x00000005) /*!< PREDIV1 input clock divided by 6 */ - #define RCC_CFGR2_PREDIV1_DIV7 ((uint32_t)0x00000006) /*!< PREDIV1 input clock divided by 7 */ - #define RCC_CFGR2_PREDIV1_DIV8 ((uint32_t)0x00000007) /*!< PREDIV1 input clock divided by 8 */ - #define RCC_CFGR2_PREDIV1_DIV9 ((uint32_t)0x00000008) /*!< PREDIV1 input clock divided by 9 */ - #define RCC_CFGR2_PREDIV1_DIV10 ((uint32_t)0x00000009) /*!< PREDIV1 input clock divided by 10 */ - #define RCC_CFGR2_PREDIV1_DIV11 ((uint32_t)0x0000000A) /*!< PREDIV1 input clock divided by 11 */ - #define RCC_CFGR2_PREDIV1_DIV12 ((uint32_t)0x0000000B) /*!< PREDIV1 input clock divided by 12 */ - #define RCC_CFGR2_PREDIV1_DIV13 ((uint32_t)0x0000000C) /*!< PREDIV1 input clock divided by 13 */ - #define RCC_CFGR2_PREDIV1_DIV14 ((uint32_t)0x0000000D) /*!< PREDIV1 input clock divided by 14 */ - #define RCC_CFGR2_PREDIV1_DIV15 ((uint32_t)0x0000000E) /*!< PREDIV1 input clock divided by 15 */ - #define RCC_CFGR2_PREDIV1_DIV16 ((uint32_t)0x0000000F) /*!< PREDIV1 input clock divided by 16 */ - -/*!< PREDIV2 configuration */ - #define RCC_CFGR2_PREDIV2 ((uint32_t)0x000000F0) /*!< PREDIV2[3:0] bits */ - #define RCC_CFGR2_PREDIV2_0 ((uint32_t)0x00000010) /*!< Bit 0 */ - #define RCC_CFGR2_PREDIV2_1 ((uint32_t)0x00000020) /*!< Bit 1 */ - #define RCC_CFGR2_PREDIV2_2 ((uint32_t)0x00000040) /*!< Bit 2 */ - #define RCC_CFGR2_PREDIV2_3 ((uint32_t)0x00000080) /*!< Bit 3 */ - - #define RCC_CFGR2_PREDIV2_DIV1 ((uint32_t)0x00000000) /*!< PREDIV2 input clock not divided */ - #define RCC_CFGR2_PREDIV2_DIV2 ((uint32_t)0x00000010) /*!< PREDIV2 input clock divided by 2 */ - #define RCC_CFGR2_PREDIV2_DIV3 ((uint32_t)0x00000020) /*!< PREDIV2 input clock divided by 3 */ - #define RCC_CFGR2_PREDIV2_DIV4 ((uint32_t)0x00000030) /*!< PREDIV2 input clock divided by 4 */ - #define RCC_CFGR2_PREDIV2_DIV5 ((uint32_t)0x00000040) /*!< PREDIV2 input clock divided by 5 */ - #define RCC_CFGR2_PREDIV2_DIV6 ((uint32_t)0x00000050) /*!< PREDIV2 input clock divided by 6 */ - #define RCC_CFGR2_PREDIV2_DIV7 ((uint32_t)0x00000060) /*!< PREDIV2 input clock divided by 7 */ - #define RCC_CFGR2_PREDIV2_DIV8 ((uint32_t)0x00000070) /*!< PREDIV2 input clock divided by 8 */ - #define RCC_CFGR2_PREDIV2_DIV9 ((uint32_t)0x00000080) /*!< PREDIV2 input clock divided by 9 */ - #define RCC_CFGR2_PREDIV2_DIV10 ((uint32_t)0x00000090) /*!< PREDIV2 input clock divided by 10 */ - #define RCC_CFGR2_PREDIV2_DIV11 ((uint32_t)0x000000A0) /*!< PREDIV2 input clock divided by 11 */ - #define RCC_CFGR2_PREDIV2_DIV12 ((uint32_t)0x000000B0) /*!< PREDIV2 input clock divided by 12 */ - #define RCC_CFGR2_PREDIV2_DIV13 ((uint32_t)0x000000C0) /*!< PREDIV2 input clock divided by 13 */ - #define RCC_CFGR2_PREDIV2_DIV14 ((uint32_t)0x000000D0) /*!< PREDIV2 input clock divided by 14 */ - #define RCC_CFGR2_PREDIV2_DIV15 ((uint32_t)0x000000E0) /*!< PREDIV2 input clock divided by 15 */ - #define RCC_CFGR2_PREDIV2_DIV16 ((uint32_t)0x000000F0) /*!< PREDIV2 input clock divided by 16 */ - -/*!< PLL2MUL configuration */ - #define RCC_CFGR2_PLL2MUL ((uint32_t)0x00000F00) /*!< PLL2MUL[3:0] bits */ - #define RCC_CFGR2_PLL2MUL_0 ((uint32_t)0x00000100) /*!< Bit 0 */ - #define RCC_CFGR2_PLL2MUL_1 ((uint32_t)0x00000200) /*!< Bit 1 */ - #define RCC_CFGR2_PLL2MUL_2 ((uint32_t)0x00000400) /*!< Bit 2 */ - #define RCC_CFGR2_PLL2MUL_3 ((uint32_t)0x00000800) /*!< Bit 3 */ - - #define RCC_CFGR2_PLL2MUL8 ((uint32_t)0x00000600) /*!< PLL2 input clock * 8 */ - #define RCC_CFGR2_PLL2MUL9 ((uint32_t)0x00000700) /*!< PLL2 input clock * 9 */ - #define RCC_CFGR2_PLL2MUL10 ((uint32_t)0x00000800) /*!< PLL2 input clock * 10 */ - #define RCC_CFGR2_PLL2MUL11 ((uint32_t)0x00000900) /*!< PLL2 input clock * 11 */ - #define RCC_CFGR2_PLL2MUL12 ((uint32_t)0x00000A00) /*!< PLL2 input clock * 12 */ - #define RCC_CFGR2_PLL2MUL13 ((uint32_t)0x00000B00) /*!< PLL2 input clock * 13 */ - #define RCC_CFGR2_PLL2MUL14 ((uint32_t)0x00000C00) /*!< PLL2 input clock * 14 */ - #define RCC_CFGR2_PLL2MUL16 ((uint32_t)0x00000E00) /*!< PLL2 input clock * 16 */ - #define RCC_CFGR2_PLL2MUL20 ((uint32_t)0x00000F00) /*!< PLL2 input clock * 20 */ - -/*!< PLL3MUL configuration */ - #define RCC_CFGR2_PLL3MUL ((uint32_t)0x0000F000) /*!< PLL3MUL[3:0] bits */ - #define RCC_CFGR2_PLL3MUL_0 ((uint32_t)0x00001000) /*!< Bit 0 */ - #define RCC_CFGR2_PLL3MUL_1 ((uint32_t)0x00002000) /*!< Bit 1 */ - #define RCC_CFGR2_PLL3MUL_2 ((uint32_t)0x00004000) /*!< Bit 2 */ - #define RCC_CFGR2_PLL3MUL_3 ((uint32_t)0x00008000) /*!< Bit 3 */ - - #define RCC_CFGR2_PLL3MUL8 ((uint32_t)0x00006000) /*!< PLL3 input clock * 8 */ - #define RCC_CFGR2_PLL3MUL9 ((uint32_t)0x00007000) /*!< PLL3 input clock * 9 */ - #define RCC_CFGR2_PLL3MUL10 ((uint32_t)0x00008000) /*!< PLL3 input clock * 10 */ - #define RCC_CFGR2_PLL3MUL11 ((uint32_t)0x00009000) /*!< PLL3 input clock * 11 */ - #define RCC_CFGR2_PLL3MUL12 ((uint32_t)0x0000A000) /*!< PLL3 input clock * 12 */ - #define RCC_CFGR2_PLL3MUL13 ((uint32_t)0x0000B000) /*!< PLL3 input clock * 13 */ - #define RCC_CFGR2_PLL3MUL14 ((uint32_t)0x0000C000) /*!< PLL3 input clock * 14 */ - #define RCC_CFGR2_PLL3MUL16 ((uint32_t)0x0000E000) /*!< PLL3 input clock * 16 */ - #define RCC_CFGR2_PLL3MUL20 ((uint32_t)0x0000F000) /*!< PLL3 input clock * 20 */ - - #define RCC_CFGR2_PREDIV1SRC ((uint32_t)0x00010000) /*!< PREDIV1 entry clock source */ - #define RCC_CFGR2_PREDIV1SRC_PLL2 ((uint32_t)0x00010000) /*!< PLL2 selected as PREDIV1 entry clock source */ - #define RCC_CFGR2_PREDIV1SRC_HSE ((uint32_t)0x00000000) /*!< HSE selected as PREDIV1 entry clock source */ - #define RCC_CFGR2_I2S2SRC ((uint32_t)0x00020000) /*!< I2S2 entry clock source */ - #define RCC_CFGR2_I2S3SRC ((uint32_t)0x00040000) /*!< I2S3 clock source */ -#endif /* STM32F10X_CL */ - -/******************************************************************************/ -/* */ -/* General Purpose and Alternate Function I/O */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for GPIO_CRL register *******************/ -#define GPIO_CRL_MODE ((uint32_t)0x33333333) /*!< Port x mode bits */ - -#define GPIO_CRL_MODE0 ((uint32_t)0x00000003) /*!< MODE0[1:0] bits (Port x mode bits, pin 0) */ -#define GPIO_CRL_MODE0_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define GPIO_CRL_MODE0_1 ((uint32_t)0x00000002) /*!< Bit 1 */ - -#define GPIO_CRL_MODE1 ((uint32_t)0x00000030) /*!< MODE1[1:0] bits (Port x mode bits, pin 1) */ -#define GPIO_CRL_MODE1_0 ((uint32_t)0x00000010) /*!< Bit 0 */ -#define GPIO_CRL_MODE1_1 ((uint32_t)0x00000020) /*!< Bit 1 */ - -#define GPIO_CRL_MODE2 ((uint32_t)0x00000300) /*!< MODE2[1:0] bits (Port x mode bits, pin 2) */ -#define GPIO_CRL_MODE2_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define GPIO_CRL_MODE2_1 ((uint32_t)0x00000200) /*!< Bit 1 */ - -#define GPIO_CRL_MODE3 ((uint32_t)0x00003000) /*!< MODE3[1:0] bits (Port x mode bits, pin 3) */ -#define GPIO_CRL_MODE3_0 ((uint32_t)0x00001000) /*!< Bit 0 */ -#define GPIO_CRL_MODE3_1 ((uint32_t)0x00002000) /*!< Bit 1 */ - -#define GPIO_CRL_MODE4 ((uint32_t)0x00030000) /*!< MODE4[1:0] bits (Port x mode bits, pin 4) */ -#define GPIO_CRL_MODE4_0 ((uint32_t)0x00010000) /*!< Bit 0 */ -#define GPIO_CRL_MODE4_1 ((uint32_t)0x00020000) /*!< Bit 1 */ - -#define GPIO_CRL_MODE5 ((uint32_t)0x00300000) /*!< MODE5[1:0] bits (Port x mode bits, pin 5) */ -#define GPIO_CRL_MODE5_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define GPIO_CRL_MODE5_1 ((uint32_t)0x00200000) /*!< Bit 1 */ - -#define GPIO_CRL_MODE6 ((uint32_t)0x03000000) /*!< MODE6[1:0] bits (Port x mode bits, pin 6) */ -#define GPIO_CRL_MODE6_0 ((uint32_t)0x01000000) /*!< Bit 0 */ -#define GPIO_CRL_MODE6_1 ((uint32_t)0x02000000) /*!< Bit 1 */ - -#define GPIO_CRL_MODE7 ((uint32_t)0x30000000) /*!< MODE7[1:0] bits (Port x mode bits, pin 7) */ -#define GPIO_CRL_MODE7_0 ((uint32_t)0x10000000) /*!< Bit 0 */ -#define GPIO_CRL_MODE7_1 ((uint32_t)0x20000000) /*!< Bit 1 */ - -#define GPIO_CRL_CNF ((uint32_t)0xCCCCCCCC) /*!< Port x configuration bits */ - -#define GPIO_CRL_CNF0 ((uint32_t)0x0000000C) /*!< CNF0[1:0] bits (Port x configuration bits, pin 0) */ -#define GPIO_CRL_CNF0_0 ((uint32_t)0x00000004) /*!< Bit 0 */ -#define GPIO_CRL_CNF0_1 ((uint32_t)0x00000008) /*!< Bit 1 */ - -#define GPIO_CRL_CNF1 ((uint32_t)0x000000C0) /*!< CNF1[1:0] bits (Port x configuration bits, pin 1) */ -#define GPIO_CRL_CNF1_0 ((uint32_t)0x00000040) /*!< Bit 0 */ -#define GPIO_CRL_CNF1_1 ((uint32_t)0x00000080) /*!< Bit 1 */ - -#define GPIO_CRL_CNF2 ((uint32_t)0x00000C00) /*!< CNF2[1:0] bits (Port x configuration bits, pin 2) */ -#define GPIO_CRL_CNF2_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define GPIO_CRL_CNF2_1 ((uint32_t)0x00000800) /*!< Bit 1 */ - -#define GPIO_CRL_CNF3 ((uint32_t)0x0000C000) /*!< CNF3[1:0] bits (Port x configuration bits, pin 3) */ -#define GPIO_CRL_CNF3_0 ((uint32_t)0x00004000) /*!< Bit 0 */ -#define GPIO_CRL_CNF3_1 ((uint32_t)0x00008000) /*!< Bit 1 */ - -#define GPIO_CRL_CNF4 ((uint32_t)0x000C0000) /*!< CNF4[1:0] bits (Port x configuration bits, pin 4) */ -#define GPIO_CRL_CNF4_0 ((uint32_t)0x00040000) /*!< Bit 0 */ -#define GPIO_CRL_CNF4_1 ((uint32_t)0x00080000) /*!< Bit 1 */ - -#define GPIO_CRL_CNF5 ((uint32_t)0x00C00000) /*!< CNF5[1:0] bits (Port x configuration bits, pin 5) */ -#define GPIO_CRL_CNF5_0 ((uint32_t)0x00400000) /*!< Bit 0 */ -#define GPIO_CRL_CNF5_1 ((uint32_t)0x00800000) /*!< Bit 1 */ - -#define GPIO_CRL_CNF6 ((uint32_t)0x0C000000) /*!< CNF6[1:0] bits (Port x configuration bits, pin 6) */ -#define GPIO_CRL_CNF6_0 ((uint32_t)0x04000000) /*!< Bit 0 */ -#define GPIO_CRL_CNF6_1 ((uint32_t)0x08000000) /*!< Bit 1 */ - -#define GPIO_CRL_CNF7 ((uint32_t)0xC0000000) /*!< CNF7[1:0] bits (Port x configuration bits, pin 7) */ -#define GPIO_CRL_CNF7_0 ((uint32_t)0x40000000) /*!< Bit 0 */ -#define GPIO_CRL_CNF7_1 ((uint32_t)0x80000000) /*!< Bit 1 */ - -/******************* Bit definition for GPIO_CRH register *******************/ -#define GPIO_CRH_MODE ((uint32_t)0x33333333) /*!< Port x mode bits */ - -#define GPIO_CRH_MODE8 ((uint32_t)0x00000003) /*!< MODE8[1:0] bits (Port x mode bits, pin 8) */ -#define GPIO_CRH_MODE8_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define GPIO_CRH_MODE8_1 ((uint32_t)0x00000002) /*!< Bit 1 */ - -#define GPIO_CRH_MODE9 ((uint32_t)0x00000030) /*!< MODE9[1:0] bits (Port x mode bits, pin 9) */ -#define GPIO_CRH_MODE9_0 ((uint32_t)0x00000010) /*!< Bit 0 */ -#define GPIO_CRH_MODE9_1 ((uint32_t)0x00000020) /*!< Bit 1 */ - -#define GPIO_CRH_MODE10 ((uint32_t)0x00000300) /*!< MODE10[1:0] bits (Port x mode bits, pin 10) */ -#define GPIO_CRH_MODE10_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define GPIO_CRH_MODE10_1 ((uint32_t)0x00000200) /*!< Bit 1 */ - -#define GPIO_CRH_MODE11 ((uint32_t)0x00003000) /*!< MODE11[1:0] bits (Port x mode bits, pin 11) */ -#define GPIO_CRH_MODE11_0 ((uint32_t)0x00001000) /*!< Bit 0 */ -#define GPIO_CRH_MODE11_1 ((uint32_t)0x00002000) /*!< Bit 1 */ - -#define GPIO_CRH_MODE12 ((uint32_t)0x00030000) /*!< MODE12[1:0] bits (Port x mode bits, pin 12) */ -#define GPIO_CRH_MODE12_0 ((uint32_t)0x00010000) /*!< Bit 0 */ -#define GPIO_CRH_MODE12_1 ((uint32_t)0x00020000) /*!< Bit 1 */ - -#define GPIO_CRH_MODE13 ((uint32_t)0x00300000) /*!< MODE13[1:0] bits (Port x mode bits, pin 13) */ -#define GPIO_CRH_MODE13_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define GPIO_CRH_MODE13_1 ((uint32_t)0x00200000) /*!< Bit 1 */ - -#define GPIO_CRH_MODE14 ((uint32_t)0x03000000) /*!< MODE14[1:0] bits (Port x mode bits, pin 14) */ -#define GPIO_CRH_MODE14_0 ((uint32_t)0x01000000) /*!< Bit 0 */ -#define GPIO_CRH_MODE14_1 ((uint32_t)0x02000000) /*!< Bit 1 */ - -#define GPIO_CRH_MODE15 ((uint32_t)0x30000000) /*!< MODE15[1:0] bits (Port x mode bits, pin 15) */ -#define GPIO_CRH_MODE15_0 ((uint32_t)0x10000000) /*!< Bit 0 */ -#define GPIO_CRH_MODE15_1 ((uint32_t)0x20000000) /*!< Bit 1 */ - -#define GPIO_CRH_CNF ((uint32_t)0xCCCCCCCC) /*!< Port x configuration bits */ - -#define GPIO_CRH_CNF8 ((uint32_t)0x0000000C) /*!< CNF8[1:0] bits (Port x configuration bits, pin 8) */ -#define GPIO_CRH_CNF8_0 ((uint32_t)0x00000004) /*!< Bit 0 */ -#define GPIO_CRH_CNF8_1 ((uint32_t)0x00000008) /*!< Bit 1 */ - -#define GPIO_CRH_CNF9 ((uint32_t)0x000000C0) /*!< CNF9[1:0] bits (Port x configuration bits, pin 9) */ -#define GPIO_CRH_CNF9_0 ((uint32_t)0x00000040) /*!< Bit 0 */ -#define GPIO_CRH_CNF9_1 ((uint32_t)0x00000080) /*!< Bit 1 */ - -#define GPIO_CRH_CNF10 ((uint32_t)0x00000C00) /*!< CNF10[1:0] bits (Port x configuration bits, pin 10) */ -#define GPIO_CRH_CNF10_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define GPIO_CRH_CNF10_1 ((uint32_t)0x00000800) /*!< Bit 1 */ - -#define GPIO_CRH_CNF11 ((uint32_t)0x0000C000) /*!< CNF11[1:0] bits (Port x configuration bits, pin 11) */ -#define GPIO_CRH_CNF11_0 ((uint32_t)0x00004000) /*!< Bit 0 */ -#define GPIO_CRH_CNF11_1 ((uint32_t)0x00008000) /*!< Bit 1 */ - -#define GPIO_CRH_CNF12 ((uint32_t)0x000C0000) /*!< CNF12[1:0] bits (Port x configuration bits, pin 12) */ -#define GPIO_CRH_CNF12_0 ((uint32_t)0x00040000) /*!< Bit 0 */ -#define GPIO_CRH_CNF12_1 ((uint32_t)0x00080000) /*!< Bit 1 */ - -#define GPIO_CRH_CNF13 ((uint32_t)0x00C00000) /*!< CNF13[1:0] bits (Port x configuration bits, pin 13) */ -#define GPIO_CRH_CNF13_0 ((uint32_t)0x00400000) /*!< Bit 0 */ -#define GPIO_CRH_CNF13_1 ((uint32_t)0x00800000) /*!< Bit 1 */ - -#define GPIO_CRH_CNF14 ((uint32_t)0x0C000000) /*!< CNF14[1:0] bits (Port x configuration bits, pin 14) */ -#define GPIO_CRH_CNF14_0 ((uint32_t)0x04000000) /*!< Bit 0 */ -#define GPIO_CRH_CNF14_1 ((uint32_t)0x08000000) /*!< Bit 1 */ - -#define GPIO_CRH_CNF15 ((uint32_t)0xC0000000) /*!< CNF15[1:0] bits (Port x configuration bits, pin 15) */ -#define GPIO_CRH_CNF15_0 ((uint32_t)0x40000000) /*!< Bit 0 */ -#define GPIO_CRH_CNF15_1 ((uint32_t)0x80000000) /*!< Bit 1 */ - -/*!<****************** Bit definition for GPIO_IDR register *******************/ -#define GPIO_IDR_IDR0 ((uint16_t)0x0001) /*!< Port input data, bit 0 */ -#define GPIO_IDR_IDR1 ((uint16_t)0x0002) /*!< Port input data, bit 1 */ -#define GPIO_IDR_IDR2 ((uint16_t)0x0004) /*!< Port input data, bit 2 */ -#define GPIO_IDR_IDR3 ((uint16_t)0x0008) /*!< Port input data, bit 3 */ -#define GPIO_IDR_IDR4 ((uint16_t)0x0010) /*!< Port input data, bit 4 */ -#define GPIO_IDR_IDR5 ((uint16_t)0x0020) /*!< Port input data, bit 5 */ -#define GPIO_IDR_IDR6 ((uint16_t)0x0040) /*!< Port input data, bit 6 */ -#define GPIO_IDR_IDR7 ((uint16_t)0x0080) /*!< Port input data, bit 7 */ -#define GPIO_IDR_IDR8 ((uint16_t)0x0100) /*!< Port input data, bit 8 */ -#define GPIO_IDR_IDR9 ((uint16_t)0x0200) /*!< Port input data, bit 9 */ -#define GPIO_IDR_IDR10 ((uint16_t)0x0400) /*!< Port input data, bit 10 */ -#define GPIO_IDR_IDR11 ((uint16_t)0x0800) /*!< Port input data, bit 11 */ -#define GPIO_IDR_IDR12 ((uint16_t)0x1000) /*!< Port input data, bit 12 */ -#define GPIO_IDR_IDR13 ((uint16_t)0x2000) /*!< Port input data, bit 13 */ -#define GPIO_IDR_IDR14 ((uint16_t)0x4000) /*!< Port input data, bit 14 */ -#define GPIO_IDR_IDR15 ((uint16_t)0x8000) /*!< Port input data, bit 15 */ - -/******************* Bit definition for GPIO_ODR register *******************/ -#define GPIO_ODR_ODR0 ((uint16_t)0x0001) /*!< Port output data, bit 0 */ -#define GPIO_ODR_ODR1 ((uint16_t)0x0002) /*!< Port output data, bit 1 */ -#define GPIO_ODR_ODR2 ((uint16_t)0x0004) /*!< Port output data, bit 2 */ -#define GPIO_ODR_ODR3 ((uint16_t)0x0008) /*!< Port output data, bit 3 */ -#define GPIO_ODR_ODR4 ((uint16_t)0x0010) /*!< Port output data, bit 4 */ -#define GPIO_ODR_ODR5 ((uint16_t)0x0020) /*!< Port output data, bit 5 */ -#define GPIO_ODR_ODR6 ((uint16_t)0x0040) /*!< Port output data, bit 6 */ -#define GPIO_ODR_ODR7 ((uint16_t)0x0080) /*!< Port output data, bit 7 */ -#define GPIO_ODR_ODR8 ((uint16_t)0x0100) /*!< Port output data, bit 8 */ -#define GPIO_ODR_ODR9 ((uint16_t)0x0200) /*!< Port output data, bit 9 */ -#define GPIO_ODR_ODR10 ((uint16_t)0x0400) /*!< Port output data, bit 10 */ -#define GPIO_ODR_ODR11 ((uint16_t)0x0800) /*!< Port output data, bit 11 */ -#define GPIO_ODR_ODR12 ((uint16_t)0x1000) /*!< Port output data, bit 12 */ -#define GPIO_ODR_ODR13 ((uint16_t)0x2000) /*!< Port output data, bit 13 */ -#define GPIO_ODR_ODR14 ((uint16_t)0x4000) /*!< Port output data, bit 14 */ -#define GPIO_ODR_ODR15 ((uint16_t)0x8000) /*!< Port output data, bit 15 */ - -/****************** Bit definition for GPIO_BSRR register *******************/ -#define GPIO_BSRR_BS0 ((uint32_t)0x00000001) /*!< Port x Set bit 0 */ -#define GPIO_BSRR_BS1 ((uint32_t)0x00000002) /*!< Port x Set bit 1 */ -#define GPIO_BSRR_BS2 ((uint32_t)0x00000004) /*!< Port x Set bit 2 */ -#define GPIO_BSRR_BS3 ((uint32_t)0x00000008) /*!< Port x Set bit 3 */ -#define GPIO_BSRR_BS4 ((uint32_t)0x00000010) /*!< Port x Set bit 4 */ -#define GPIO_BSRR_BS5 ((uint32_t)0x00000020) /*!< Port x Set bit 5 */ -#define GPIO_BSRR_BS6 ((uint32_t)0x00000040) /*!< Port x Set bit 6 */ -#define GPIO_BSRR_BS7 ((uint32_t)0x00000080) /*!< Port x Set bit 7 */ -#define GPIO_BSRR_BS8 ((uint32_t)0x00000100) /*!< Port x Set bit 8 */ -#define GPIO_BSRR_BS9 ((uint32_t)0x00000200) /*!< Port x Set bit 9 */ -#define GPIO_BSRR_BS10 ((uint32_t)0x00000400) /*!< Port x Set bit 10 */ -#define GPIO_BSRR_BS11 ((uint32_t)0x00000800) /*!< Port x Set bit 11 */ -#define GPIO_BSRR_BS12 ((uint32_t)0x00001000) /*!< Port x Set bit 12 */ -#define GPIO_BSRR_BS13 ((uint32_t)0x00002000) /*!< Port x Set bit 13 */ -#define GPIO_BSRR_BS14 ((uint32_t)0x00004000) /*!< Port x Set bit 14 */ -#define GPIO_BSRR_BS15 ((uint32_t)0x00008000) /*!< Port x Set bit 15 */ - -#define GPIO_BSRR_BR0 ((uint32_t)0x00010000) /*!< Port x Reset bit 0 */ -#define GPIO_BSRR_BR1 ((uint32_t)0x00020000) /*!< Port x Reset bit 1 */ -#define GPIO_BSRR_BR2 ((uint32_t)0x00040000) /*!< Port x Reset bit 2 */ -#define GPIO_BSRR_BR3 ((uint32_t)0x00080000) /*!< Port x Reset bit 3 */ -#define GPIO_BSRR_BR4 ((uint32_t)0x00100000) /*!< Port x Reset bit 4 */ -#define GPIO_BSRR_BR5 ((uint32_t)0x00200000) /*!< Port x Reset bit 5 */ -#define GPIO_BSRR_BR6 ((uint32_t)0x00400000) /*!< Port x Reset bit 6 */ -#define GPIO_BSRR_BR7 ((uint32_t)0x00800000) /*!< Port x Reset bit 7 */ -#define GPIO_BSRR_BR8 ((uint32_t)0x01000000) /*!< Port x Reset bit 8 */ -#define GPIO_BSRR_BR9 ((uint32_t)0x02000000) /*!< Port x Reset bit 9 */ -#define GPIO_BSRR_BR10 ((uint32_t)0x04000000) /*!< Port x Reset bit 10 */ -#define GPIO_BSRR_BR11 ((uint32_t)0x08000000) /*!< Port x Reset bit 11 */ -#define GPIO_BSRR_BR12 ((uint32_t)0x10000000) /*!< Port x Reset bit 12 */ -#define GPIO_BSRR_BR13 ((uint32_t)0x20000000) /*!< Port x Reset bit 13 */ -#define GPIO_BSRR_BR14 ((uint32_t)0x40000000) /*!< Port x Reset bit 14 */ -#define GPIO_BSRR_BR15 ((uint32_t)0x80000000) /*!< Port x Reset bit 15 */ - -/******************* Bit definition for GPIO_BRR register *******************/ -#define GPIO_BRR_BR0 ((uint16_t)0x0001) /*!< Port x Reset bit 0 */ -#define GPIO_BRR_BR1 ((uint16_t)0x0002) /*!< Port x Reset bit 1 */ -#define GPIO_BRR_BR2 ((uint16_t)0x0004) /*!< Port x Reset bit 2 */ -#define GPIO_BRR_BR3 ((uint16_t)0x0008) /*!< Port x Reset bit 3 */ -#define GPIO_BRR_BR4 ((uint16_t)0x0010) /*!< Port x Reset bit 4 */ -#define GPIO_BRR_BR5 ((uint16_t)0x0020) /*!< Port x Reset bit 5 */ -#define GPIO_BRR_BR6 ((uint16_t)0x0040) /*!< Port x Reset bit 6 */ -#define GPIO_BRR_BR7 ((uint16_t)0x0080) /*!< Port x Reset bit 7 */ -#define GPIO_BRR_BR8 ((uint16_t)0x0100) /*!< Port x Reset bit 8 */ -#define GPIO_BRR_BR9 ((uint16_t)0x0200) /*!< Port x Reset bit 9 */ -#define GPIO_BRR_BR10 ((uint16_t)0x0400) /*!< Port x Reset bit 10 */ -#define GPIO_BRR_BR11 ((uint16_t)0x0800) /*!< Port x Reset bit 11 */ -#define GPIO_BRR_BR12 ((uint16_t)0x1000) /*!< Port x Reset bit 12 */ -#define GPIO_BRR_BR13 ((uint16_t)0x2000) /*!< Port x Reset bit 13 */ -#define GPIO_BRR_BR14 ((uint16_t)0x4000) /*!< Port x Reset bit 14 */ -#define GPIO_BRR_BR15 ((uint16_t)0x8000) /*!< Port x Reset bit 15 */ - -/****************** Bit definition for GPIO_LCKR register *******************/ -#define GPIO_LCKR_LCK0 ((uint32_t)0x00000001) /*!< Port x Lock bit 0 */ -#define GPIO_LCKR_LCK1 ((uint32_t)0x00000002) /*!< Port x Lock bit 1 */ -#define GPIO_LCKR_LCK2 ((uint32_t)0x00000004) /*!< Port x Lock bit 2 */ -#define GPIO_LCKR_LCK3 ((uint32_t)0x00000008) /*!< Port x Lock bit 3 */ -#define GPIO_LCKR_LCK4 ((uint32_t)0x00000010) /*!< Port x Lock bit 4 */ -#define GPIO_LCKR_LCK5 ((uint32_t)0x00000020) /*!< Port x Lock bit 5 */ -#define GPIO_LCKR_LCK6 ((uint32_t)0x00000040) /*!< Port x Lock bit 6 */ -#define GPIO_LCKR_LCK7 ((uint32_t)0x00000080) /*!< Port x Lock bit 7 */ -#define GPIO_LCKR_LCK8 ((uint32_t)0x00000100) /*!< Port x Lock bit 8 */ -#define GPIO_LCKR_LCK9 ((uint32_t)0x00000200) /*!< Port x Lock bit 9 */ -#define GPIO_LCKR_LCK10 ((uint32_t)0x00000400) /*!< Port x Lock bit 10 */ -#define GPIO_LCKR_LCK11 ((uint32_t)0x00000800) /*!< Port x Lock bit 11 */ -#define GPIO_LCKR_LCK12 ((uint32_t)0x00001000) /*!< Port x Lock bit 12 */ -#define GPIO_LCKR_LCK13 ((uint32_t)0x00002000) /*!< Port x Lock bit 13 */ -#define GPIO_LCKR_LCK14 ((uint32_t)0x00004000) /*!< Port x Lock bit 14 */ -#define GPIO_LCKR_LCK15 ((uint32_t)0x00008000) /*!< Port x Lock bit 15 */ -#define GPIO_LCKR_LCKK ((uint32_t)0x00010000) /*!< Lock key */ - -/*----------------------------------------------------------------------------*/ - -/****************** Bit definition for AFIO_EVCR register *******************/ -#define AFIO_EVCR_PIN ((uint8_t)0x0F) /*!< PIN[3:0] bits (Pin selection) */ -#define AFIO_EVCR_PIN_0 ((uint8_t)0x01) /*!< Bit 0 */ -#define AFIO_EVCR_PIN_1 ((uint8_t)0x02) /*!< Bit 1 */ -#define AFIO_EVCR_PIN_2 ((uint8_t)0x04) /*!< Bit 2 */ -#define AFIO_EVCR_PIN_3 ((uint8_t)0x08) /*!< Bit 3 */ - -/*!< PIN configuration */ -#define AFIO_EVCR_PIN_PX0 ((uint8_t)0x00) /*!< Pin 0 selected */ -#define AFIO_EVCR_PIN_PX1 ((uint8_t)0x01) /*!< Pin 1 selected */ -#define AFIO_EVCR_PIN_PX2 ((uint8_t)0x02) /*!< Pin 2 selected */ -#define AFIO_EVCR_PIN_PX3 ((uint8_t)0x03) /*!< Pin 3 selected */ -#define AFIO_EVCR_PIN_PX4 ((uint8_t)0x04) /*!< Pin 4 selected */ -#define AFIO_EVCR_PIN_PX5 ((uint8_t)0x05) /*!< Pin 5 selected */ -#define AFIO_EVCR_PIN_PX6 ((uint8_t)0x06) /*!< Pin 6 selected */ -#define AFIO_EVCR_PIN_PX7 ((uint8_t)0x07) /*!< Pin 7 selected */ -#define AFIO_EVCR_PIN_PX8 ((uint8_t)0x08) /*!< Pin 8 selected */ -#define AFIO_EVCR_PIN_PX9 ((uint8_t)0x09) /*!< Pin 9 selected */ -#define AFIO_EVCR_PIN_PX10 ((uint8_t)0x0A) /*!< Pin 10 selected */ -#define AFIO_EVCR_PIN_PX11 ((uint8_t)0x0B) /*!< Pin 11 selected */ -#define AFIO_EVCR_PIN_PX12 ((uint8_t)0x0C) /*!< Pin 12 selected */ -#define AFIO_EVCR_PIN_PX13 ((uint8_t)0x0D) /*!< Pin 13 selected */ -#define AFIO_EVCR_PIN_PX14 ((uint8_t)0x0E) /*!< Pin 14 selected */ -#define AFIO_EVCR_PIN_PX15 ((uint8_t)0x0F) /*!< Pin 15 selected */ - -#define AFIO_EVCR_PORT ((uint8_t)0x70) /*!< PORT[2:0] bits (Port selection) */ -#define AFIO_EVCR_PORT_0 ((uint8_t)0x10) /*!< Bit 0 */ -#define AFIO_EVCR_PORT_1 ((uint8_t)0x20) /*!< Bit 1 */ -#define AFIO_EVCR_PORT_2 ((uint8_t)0x40) /*!< Bit 2 */ - -/*!< PORT configuration */ -#define AFIO_EVCR_PORT_PA ((uint8_t)0x00) /*!< Port A selected */ -#define AFIO_EVCR_PORT_PB ((uint8_t)0x10) /*!< Port B selected */ -#define AFIO_EVCR_PORT_PC ((uint8_t)0x20) /*!< Port C selected */ -#define AFIO_EVCR_PORT_PD ((uint8_t)0x30) /*!< Port D selected */ -#define AFIO_EVCR_PORT_PE ((uint8_t)0x40) /*!< Port E selected */ - -#define AFIO_EVCR_EVOE ((uint8_t)0x80) /*!< Event Output Enable */ - -/****************** Bit definition for AFIO_MAPR register *******************/ -#define AFIO_MAPR_SPI1_REMAP ((uint32_t)0x00000001) /*!< SPI1 remapping */ -#define AFIO_MAPR_I2C1_REMAP ((uint32_t)0x00000002) /*!< I2C1 remapping */ -#define AFIO_MAPR_USART1_REMAP ((uint32_t)0x00000004) /*!< USART1 remapping */ -#define AFIO_MAPR_USART2_REMAP ((uint32_t)0x00000008) /*!< USART2 remapping */ - -#define AFIO_MAPR_USART3_REMAP ((uint32_t)0x00000030) /*!< USART3_REMAP[1:0] bits (USART3 remapping) */ -#define AFIO_MAPR_USART3_REMAP_0 ((uint32_t)0x00000010) /*!< Bit 0 */ -#define AFIO_MAPR_USART3_REMAP_1 ((uint32_t)0x00000020) /*!< Bit 1 */ - -/* USART3_REMAP configuration */ -#define AFIO_MAPR_USART3_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (TX/PB10, RX/PB11, CK/PB12, CTS/PB13, RTS/PB14) */ -#define AFIO_MAPR_USART3_REMAP_PARTIALREMAP ((uint32_t)0x00000010) /*!< Partial remap (TX/PC10, RX/PC11, CK/PC12, CTS/PB13, RTS/PB14) */ -#define AFIO_MAPR_USART3_REMAP_FULLREMAP ((uint32_t)0x00000030) /*!< Full remap (TX/PD8, RX/PD9, CK/PD10, CTS/PD11, RTS/PD12) */ - -#define AFIO_MAPR_TIM1_REMAP ((uint32_t)0x000000C0) /*!< TIM1_REMAP[1:0] bits (TIM1 remapping) */ -#define AFIO_MAPR_TIM1_REMAP_0 ((uint32_t)0x00000040) /*!< Bit 0 */ -#define AFIO_MAPR_TIM1_REMAP_1 ((uint32_t)0x00000080) /*!< Bit 1 */ - -/*!< TIM1_REMAP configuration */ -#define AFIO_MAPR_TIM1_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PB12, CH1N/PB13, CH2N/PB14, CH3N/PB15) */ -#define AFIO_MAPR_TIM1_REMAP_PARTIALREMAP ((uint32_t)0x00000040) /*!< Partial remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PA6, CH1N/PA7, CH2N/PB0, CH3N/PB1) */ -#define AFIO_MAPR_TIM1_REMAP_FULLREMAP ((uint32_t)0x000000C0) /*!< Full remap (ETR/PE7, CH1/PE9, CH2/PE11, CH3/PE13, CH4/PE14, BKIN/PE15, CH1N/PE8, CH2N/PE10, CH3N/PE12) */ - -#define AFIO_MAPR_TIM2_REMAP ((uint32_t)0x00000300) /*!< TIM2_REMAP[1:0] bits (TIM2 remapping) */ -#define AFIO_MAPR_TIM2_REMAP_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define AFIO_MAPR_TIM2_REMAP_1 ((uint32_t)0x00000200) /*!< Bit 1 */ - -/*!< TIM2_REMAP configuration */ -#define AFIO_MAPR_TIM2_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (CH1/ETR/PA0, CH2/PA1, CH3/PA2, CH4/PA3) */ -#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1 ((uint32_t)0x00000100) /*!< Partial remap (CH1/ETR/PA15, CH2/PB3, CH3/PA2, CH4/PA3) */ -#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2 ((uint32_t)0x00000200) /*!< Partial remap (CH1/ETR/PA0, CH2/PA1, CH3/PB10, CH4/PB11) */ -#define AFIO_MAPR_TIM2_REMAP_FULLREMAP ((uint32_t)0x00000300) /*!< Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11) */ - -#define AFIO_MAPR_TIM3_REMAP ((uint32_t)0x00000C00) /*!< TIM3_REMAP[1:0] bits (TIM3 remapping) */ -#define AFIO_MAPR_TIM3_REMAP_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define AFIO_MAPR_TIM3_REMAP_1 ((uint32_t)0x00000800) /*!< Bit 1 */ - -/*!< TIM3_REMAP configuration */ -#define AFIO_MAPR_TIM3_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (CH1/PA6, CH2/PA7, CH3/PB0, CH4/PB1) */ -#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP ((uint32_t)0x00000800) /*!< Partial remap (CH1/PB4, CH2/PB5, CH3/PB0, CH4/PB1) */ -#define AFIO_MAPR_TIM3_REMAP_FULLREMAP ((uint32_t)0x00000C00) /*!< Full remap (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9) */ - -#define AFIO_MAPR_TIM4_REMAP ((uint32_t)0x00001000) /*!< TIM4_REMAP bit (TIM4 remapping) */ - -#define AFIO_MAPR_CAN_REMAP ((uint32_t)0x00006000) /*!< CAN_REMAP[1:0] bits (CAN Alternate function remapping) */ -#define AFIO_MAPR_CAN_REMAP_0 ((uint32_t)0x00002000) /*!< Bit 0 */ -#define AFIO_MAPR_CAN_REMAP_1 ((uint32_t)0x00004000) /*!< Bit 1 */ - -/*!< CAN_REMAP configuration */ -#define AFIO_MAPR_CAN_REMAP_REMAP1 ((uint32_t)0x00000000) /*!< CANRX mapped to PA11, CANTX mapped to PA12 */ -#define AFIO_MAPR_CAN_REMAP_REMAP2 ((uint32_t)0x00004000) /*!< CANRX mapped to PB8, CANTX mapped to PB9 */ -#define AFIO_MAPR_CAN_REMAP_REMAP3 ((uint32_t)0x00006000) /*!< CANRX mapped to PD0, CANTX mapped to PD1 */ - -#define AFIO_MAPR_PD01_REMAP ((uint32_t)0x00008000) /*!< Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ -#define AFIO_MAPR_TIM5CH4_IREMAP ((uint32_t)0x00010000) /*!< TIM5 Channel4 Internal Remap */ -#define AFIO_MAPR_ADC1_ETRGINJ_REMAP ((uint32_t)0x00020000) /*!< ADC 1 External Trigger Injected Conversion remapping */ -#define AFIO_MAPR_ADC1_ETRGREG_REMAP ((uint32_t)0x00040000) /*!< ADC 1 External Trigger Regular Conversion remapping */ -#define AFIO_MAPR_ADC2_ETRGINJ_REMAP ((uint32_t)0x00080000) /*!< ADC 2 External Trigger Injected Conversion remapping */ -#define AFIO_MAPR_ADC2_ETRGREG_REMAP ((uint32_t)0x00100000) /*!< ADC 2 External Trigger Regular Conversion remapping */ - -/*!< SWJ_CFG configuration */ -#define AFIO_MAPR_SWJ_CFG ((uint32_t)0x07000000) /*!< SWJ_CFG[2:0] bits (Serial Wire JTAG configuration) */ -#define AFIO_MAPR_SWJ_CFG_0 ((uint32_t)0x01000000) /*!< Bit 0 */ -#define AFIO_MAPR_SWJ_CFG_1 ((uint32_t)0x02000000) /*!< Bit 1 */ -#define AFIO_MAPR_SWJ_CFG_2 ((uint32_t)0x04000000) /*!< Bit 2 */ - -#define AFIO_MAPR_SWJ_CFG_RESET ((uint32_t)0x00000000) /*!< Full SWJ (JTAG-DP + SW-DP) : Reset State */ -#define AFIO_MAPR_SWJ_CFG_NOJNTRST ((uint32_t)0x01000000) /*!< Full SWJ (JTAG-DP + SW-DP) but without JNTRST */ -#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE ((uint32_t)0x02000000) /*!< JTAG-DP Disabled and SW-DP Enabled */ -#define AFIO_MAPR_SWJ_CFG_DISABLE ((uint32_t)0x04000000) /*!< JTAG-DP Disabled and SW-DP Disabled */ - -#ifdef STM32F10X_CL -/*!< ETH_REMAP configuration */ - #define AFIO_MAPR_ETH_REMAP ((uint32_t)0x00200000) /*!< SPI3_REMAP bit (Ethernet MAC I/O remapping) */ - -/*!< CAN2_REMAP configuration */ - #define AFIO_MAPR_CAN2_REMAP ((uint32_t)0x00400000) /*!< CAN2_REMAP bit (CAN2 I/O remapping) */ - -/*!< MII_RMII_SEL configuration */ - #define AFIO_MAPR_MII_RMII_SEL ((uint32_t)0x00800000) /*!< MII_RMII_SEL bit (Ethernet MII or RMII selection) */ - -/*!< SPI3_REMAP configuration */ - #define AFIO_MAPR_SPI3_REMAP ((uint32_t)0x10000000) /*!< SPI3_REMAP bit (SPI3 remapping) */ - -/*!< TIM2ITR1_IREMAP configuration */ - #define AFIO_MAPR_TIM2ITR1_IREMAP ((uint32_t)0x20000000) /*!< TIM2ITR1_IREMAP bit (TIM2 internal trigger 1 remapping) */ - -/*!< PTP_PPS_REMAP configuration */ - #define AFIO_MAPR_PTP_PPS_REMAP ((uint32_t)0x20000000) /*!< PTP_PPS_REMAP bit (Ethernet PTP PPS remapping) */ -#endif - -/***************** Bit definition for AFIO_EXTICR1 register *****************/ -#define AFIO_EXTICR1_EXTI0 ((uint16_t)0x000F) /*!< EXTI 0 configuration */ -#define AFIO_EXTICR1_EXTI1 ((uint16_t)0x00F0) /*!< EXTI 1 configuration */ -#define AFIO_EXTICR1_EXTI2 ((uint16_t)0x0F00) /*!< EXTI 2 configuration */ -#define AFIO_EXTICR1_EXTI3 ((uint16_t)0xF000) /*!< EXTI 3 configuration */ - -/*!< EXTI0 configuration */ -#define AFIO_EXTICR1_EXTI0_PA ((uint16_t)0x0000) /*!< PA[0] pin */ -#define AFIO_EXTICR1_EXTI0_PB ((uint16_t)0x0001) /*!< PB[0] pin */ -#define AFIO_EXTICR1_EXTI0_PC ((uint16_t)0x0002) /*!< PC[0] pin */ -#define AFIO_EXTICR1_EXTI0_PD ((uint16_t)0x0003) /*!< PD[0] pin */ -#define AFIO_EXTICR1_EXTI0_PE ((uint16_t)0x0004) /*!< PE[0] pin */ -#define AFIO_EXTICR1_EXTI0_PF ((uint16_t)0x0005) /*!< PF[0] pin */ -#define AFIO_EXTICR1_EXTI0_PG ((uint16_t)0x0006) /*!< PG[0] pin */ - -/*!< EXTI1 configuration */ -#define AFIO_EXTICR1_EXTI1_PA ((uint16_t)0x0000) /*!< PA[1] pin */ -#define AFIO_EXTICR1_EXTI1_PB ((uint16_t)0x0010) /*!< PB[1] pin */ -#define AFIO_EXTICR1_EXTI1_PC ((uint16_t)0x0020) /*!< PC[1] pin */ -#define AFIO_EXTICR1_EXTI1_PD ((uint16_t)0x0030) /*!< PD[1] pin */ -#define AFIO_EXTICR1_EXTI1_PE ((uint16_t)0x0040) /*!< PE[1] pin */ -#define AFIO_EXTICR1_EXTI1_PF ((uint16_t)0x0050) /*!< PF[1] pin */ -#define AFIO_EXTICR1_EXTI1_PG ((uint16_t)0x0060) /*!< PG[1] pin */ - -/*!< EXTI2 configuration */ -#define AFIO_EXTICR1_EXTI2_PA ((uint16_t)0x0000) /*!< PA[2] pin */ -#define AFIO_EXTICR1_EXTI2_PB ((uint16_t)0x0100) /*!< PB[2] pin */ -#define AFIO_EXTICR1_EXTI2_PC ((uint16_t)0x0200) /*!< PC[2] pin */ -#define AFIO_EXTICR1_EXTI2_PD ((uint16_t)0x0300) /*!< PD[2] pin */ -#define AFIO_EXTICR1_EXTI2_PE ((uint16_t)0x0400) /*!< PE[2] pin */ -#define AFIO_EXTICR1_EXTI2_PF ((uint16_t)0x0500) /*!< PF[2] pin */ -#define AFIO_EXTICR1_EXTI2_PG ((uint16_t)0x0600) /*!< PG[2] pin */ - -/*!< EXTI3 configuration */ -#define AFIO_EXTICR1_EXTI3_PA ((uint16_t)0x0000) /*!< PA[3] pin */ -#define AFIO_EXTICR1_EXTI3_PB ((uint16_t)0x1000) /*!< PB[3] pin */ -#define AFIO_EXTICR1_EXTI3_PC ((uint16_t)0x2000) /*!< PC[3] pin */ -#define AFIO_EXTICR1_EXTI3_PD ((uint16_t)0x3000) /*!< PD[3] pin */ -#define AFIO_EXTICR1_EXTI3_PE ((uint16_t)0x4000) /*!< PE[3] pin */ -#define AFIO_EXTICR1_EXTI3_PF ((uint16_t)0x5000) /*!< PF[3] pin */ -#define AFIO_EXTICR1_EXTI3_PG ((uint16_t)0x6000) /*!< PG[3] pin */ - -/***************** Bit definition for AFIO_EXTICR2 register *****************/ -#define AFIO_EXTICR2_EXTI4 ((uint16_t)0x000F) /*!< EXTI 4 configuration */ -#define AFIO_EXTICR2_EXTI5 ((uint16_t)0x00F0) /*!< EXTI 5 configuration */ -#define AFIO_EXTICR2_EXTI6 ((uint16_t)0x0F00) /*!< EXTI 6 configuration */ -#define AFIO_EXTICR2_EXTI7 ((uint16_t)0xF000) /*!< EXTI 7 configuration */ - -/*!< EXTI4 configuration */ -#define AFIO_EXTICR2_EXTI4_PA ((uint16_t)0x0000) /*!< PA[4] pin */ -#define AFIO_EXTICR2_EXTI4_PB ((uint16_t)0x0001) /*!< PB[4] pin */ -#define AFIO_EXTICR2_EXTI4_PC ((uint16_t)0x0002) /*!< PC[4] pin */ -#define AFIO_EXTICR2_EXTI4_PD ((uint16_t)0x0003) /*!< PD[4] pin */ -#define AFIO_EXTICR2_EXTI4_PE ((uint16_t)0x0004) /*!< PE[4] pin */ -#define AFIO_EXTICR2_EXTI4_PF ((uint16_t)0x0005) /*!< PF[4] pin */ -#define AFIO_EXTICR2_EXTI4_PG ((uint16_t)0x0006) /*!< PG[4] pin */ - -/* EXTI5 configuration */ -#define AFIO_EXTICR2_EXTI5_PA ((uint16_t)0x0000) /*!< PA[5] pin */ -#define AFIO_EXTICR2_EXTI5_PB ((uint16_t)0x0010) /*!< PB[5] pin */ -#define AFIO_EXTICR2_EXTI5_PC ((uint16_t)0x0020) /*!< PC[5] pin */ -#define AFIO_EXTICR2_EXTI5_PD ((uint16_t)0x0030) /*!< PD[5] pin */ -#define AFIO_EXTICR2_EXTI5_PE ((uint16_t)0x0040) /*!< PE[5] pin */ -#define AFIO_EXTICR2_EXTI5_PF ((uint16_t)0x0050) /*!< PF[5] pin */ -#define AFIO_EXTICR2_EXTI5_PG ((uint16_t)0x0060) /*!< PG[5] pin */ - -/*!< EXTI6 configuration */ -#define AFIO_EXTICR2_EXTI6_PA ((uint16_t)0x0000) /*!< PA[6] pin */ -#define AFIO_EXTICR2_EXTI6_PB ((uint16_t)0x0100) /*!< PB[6] pin */ -#define AFIO_EXTICR2_EXTI6_PC ((uint16_t)0x0200) /*!< PC[6] pin */ -#define AFIO_EXTICR2_EXTI6_PD ((uint16_t)0x0300) /*!< PD[6] pin */ -#define AFIO_EXTICR2_EXTI6_PE ((uint16_t)0x0400) /*!< PE[6] pin */ -#define AFIO_EXTICR2_EXTI6_PF ((uint16_t)0x0500) /*!< PF[6] pin */ -#define AFIO_EXTICR2_EXTI6_PG ((uint16_t)0x0600) /*!< PG[6] pin */ - -/*!< EXTI7 configuration */ -#define AFIO_EXTICR2_EXTI7_PA ((uint16_t)0x0000) /*!< PA[7] pin */ -#define AFIO_EXTICR2_EXTI7_PB ((uint16_t)0x1000) /*!< PB[7] pin */ -#define AFIO_EXTICR2_EXTI7_PC ((uint16_t)0x2000) /*!< PC[7] pin */ -#define AFIO_EXTICR2_EXTI7_PD ((uint16_t)0x3000) /*!< PD[7] pin */ -#define AFIO_EXTICR2_EXTI7_PE ((uint16_t)0x4000) /*!< PE[7] pin */ -#define AFIO_EXTICR2_EXTI7_PF ((uint16_t)0x5000) /*!< PF[7] pin */ -#define AFIO_EXTICR2_EXTI7_PG ((uint16_t)0x6000) /*!< PG[7] pin */ - -/***************** Bit definition for AFIO_EXTICR3 register *****************/ -#define AFIO_EXTICR3_EXTI8 ((uint16_t)0x000F) /*!< EXTI 8 configuration */ -#define AFIO_EXTICR3_EXTI9 ((uint16_t)0x00F0) /*!< EXTI 9 configuration */ -#define AFIO_EXTICR3_EXTI10 ((uint16_t)0x0F00) /*!< EXTI 10 configuration */ -#define AFIO_EXTICR3_EXTI11 ((uint16_t)0xF000) /*!< EXTI 11 configuration */ - -/*!< EXTI8 configuration */ -#define AFIO_EXTICR3_EXTI8_PA ((uint16_t)0x0000) /*!< PA[8] pin */ -#define AFIO_EXTICR3_EXTI8_PB ((uint16_t)0x0001) /*!< PB[8] pin */ -#define AFIO_EXTICR3_EXTI8_PC ((uint16_t)0x0002) /*!< PC[8] pin */ -#define AFIO_EXTICR3_EXTI8_PD ((uint16_t)0x0003) /*!< PD[8] pin */ -#define AFIO_EXTICR3_EXTI8_PE ((uint16_t)0x0004) /*!< PE[8] pin */ -#define AFIO_EXTICR3_EXTI8_PF ((uint16_t)0x0005) /*!< PF[8] pin */ -#define AFIO_EXTICR3_EXTI8_PG ((uint16_t)0x0006) /*!< PG[8] pin */ - -/*!< EXTI9 configuration */ -#define AFIO_EXTICR3_EXTI9_PA ((uint16_t)0x0000) /*!< PA[9] pin */ -#define AFIO_EXTICR3_EXTI9_PB ((uint16_t)0x0010) /*!< PB[9] pin */ -#define AFIO_EXTICR3_EXTI9_PC ((uint16_t)0x0020) /*!< PC[9] pin */ -#define AFIO_EXTICR3_EXTI9_PD ((uint16_t)0x0030) /*!< PD[9] pin */ -#define AFIO_EXTICR3_EXTI9_PE ((uint16_t)0x0040) /*!< PE[9] pin */ -#define AFIO_EXTICR3_EXTI9_PF ((uint16_t)0x0050) /*!< PF[9] pin */ -#define AFIO_EXTICR3_EXTI9_PG ((uint16_t)0x0060) /*!< PG[9] pin */ - -/*!< EXTI10 configuration */ -#define AFIO_EXTICR3_EXTI10_PA ((uint16_t)0x0000) /*!< PA[10] pin */ -#define AFIO_EXTICR3_EXTI10_PB ((uint16_t)0x0100) /*!< PB[10] pin */ -#define AFIO_EXTICR3_EXTI10_PC ((uint16_t)0x0200) /*!< PC[10] pin */ -#define AFIO_EXTICR3_EXTI10_PD ((uint16_t)0x0300) /*!< PD[10] pin */ -#define AFIO_EXTICR3_EXTI10_PE ((uint16_t)0x0400) /*!< PE[10] pin */ -#define AFIO_EXTICR3_EXTI10_PF ((uint16_t)0x0500) /*!< PF[10] pin */ -#define AFIO_EXTICR3_EXTI10_PG ((uint16_t)0x0600) /*!< PG[10] pin */ - -/*!< EXTI11 configuration */ -#define AFIO_EXTICR3_EXTI11_PA ((uint16_t)0x0000) /*!< PA[11] pin */ -#define AFIO_EXTICR3_EXTI11_PB ((uint16_t)0x1000) /*!< PB[11] pin */ -#define AFIO_EXTICR3_EXTI11_PC ((uint16_t)0x2000) /*!< PC[11] pin */ -#define AFIO_EXTICR3_EXTI11_PD ((uint16_t)0x3000) /*!< PD[11] pin */ -#define AFIO_EXTICR3_EXTI11_PE ((uint16_t)0x4000) /*!< PE[11] pin */ -#define AFIO_EXTICR3_EXTI11_PF ((uint16_t)0x5000) /*!< PF[11] pin */ -#define AFIO_EXTICR3_EXTI11_PG ((uint16_t)0x6000) /*!< PG[11] pin */ - -/***************** Bit definition for AFIO_EXTICR4 register *****************/ -#define AFIO_EXTICR4_EXTI12 ((uint16_t)0x000F) /*!< EXTI 12 configuration */ -#define AFIO_EXTICR4_EXTI13 ((uint16_t)0x00F0) /*!< EXTI 13 configuration */ -#define AFIO_EXTICR4_EXTI14 ((uint16_t)0x0F00) /*!< EXTI 14 configuration */ -#define AFIO_EXTICR4_EXTI15 ((uint16_t)0xF000) /*!< EXTI 15 configuration */ - -/* EXTI12 configuration */ -#define AFIO_EXTICR4_EXTI12_PA ((uint16_t)0x0000) /*!< PA[12] pin */ -#define AFIO_EXTICR4_EXTI12_PB ((uint16_t)0x0001) /*!< PB[12] pin */ -#define AFIO_EXTICR4_EXTI12_PC ((uint16_t)0x0002) /*!< PC[12] pin */ -#define AFIO_EXTICR4_EXTI12_PD ((uint16_t)0x0003) /*!< PD[12] pin */ -#define AFIO_EXTICR4_EXTI12_PE ((uint16_t)0x0004) /*!< PE[12] pin */ -#define AFIO_EXTICR4_EXTI12_PF ((uint16_t)0x0005) /*!< PF[12] pin */ -#define AFIO_EXTICR4_EXTI12_PG ((uint16_t)0x0006) /*!< PG[12] pin */ - -/* EXTI13 configuration */ -#define AFIO_EXTICR4_EXTI13_PA ((uint16_t)0x0000) /*!< PA[13] pin */ -#define AFIO_EXTICR4_EXTI13_PB ((uint16_t)0x0010) /*!< PB[13] pin */ -#define AFIO_EXTICR4_EXTI13_PC ((uint16_t)0x0020) /*!< PC[13] pin */ -#define AFIO_EXTICR4_EXTI13_PD ((uint16_t)0x0030) /*!< PD[13] pin */ -#define AFIO_EXTICR4_EXTI13_PE ((uint16_t)0x0040) /*!< PE[13] pin */ -#define AFIO_EXTICR4_EXTI13_PF ((uint16_t)0x0050) /*!< PF[13] pin */ -#define AFIO_EXTICR4_EXTI13_PG ((uint16_t)0x0060) /*!< PG[13] pin */ - -/*!< EXTI14 configuration */ -#define AFIO_EXTICR4_EXTI14_PA ((uint16_t)0x0000) /*!< PA[14] pin */ -#define AFIO_EXTICR4_EXTI14_PB ((uint16_t)0x0100) /*!< PB[14] pin */ -#define AFIO_EXTICR4_EXTI14_PC ((uint16_t)0x0200) /*!< PC[14] pin */ -#define AFIO_EXTICR4_EXTI14_PD ((uint16_t)0x0300) /*!< PD[14] pin */ -#define AFIO_EXTICR4_EXTI14_PE ((uint16_t)0x0400) /*!< PE[14] pin */ -#define AFIO_EXTICR4_EXTI14_PF ((uint16_t)0x0500) /*!< PF[14] pin */ -#define AFIO_EXTICR4_EXTI14_PG ((uint16_t)0x0600) /*!< PG[14] pin */ - -/*!< EXTI15 configuration */ -#define AFIO_EXTICR4_EXTI15_PA ((uint16_t)0x0000) /*!< PA[15] pin */ -#define AFIO_EXTICR4_EXTI15_PB ((uint16_t)0x1000) /*!< PB[15] pin */ -#define AFIO_EXTICR4_EXTI15_PC ((uint16_t)0x2000) /*!< PC[15] pin */ -#define AFIO_EXTICR4_EXTI15_PD ((uint16_t)0x3000) /*!< PD[15] pin */ -#define AFIO_EXTICR4_EXTI15_PE ((uint16_t)0x4000) /*!< PE[15] pin */ -#define AFIO_EXTICR4_EXTI15_PF ((uint16_t)0x5000) /*!< PF[15] pin */ -#define AFIO_EXTICR4_EXTI15_PG ((uint16_t)0x6000) /*!< PG[15] pin */ - -/******************************************************************************/ -/* */ -/* SystemTick */ -/* */ -/******************************************************************************/ - -/***************** Bit definition for SysTick_CTRL register *****************/ -#define SysTick_CTRL_ENABLE ((uint32_t)0x00000001) /*!< Counter enable */ -#define SysTick_CTRL_TICKINT ((uint32_t)0x00000002) /*!< Counting down to 0 pends the SysTick handler */ -#define SysTick_CTRL_CLKSOURCE ((uint32_t)0x00000004) /*!< Clock source */ -#define SysTick_CTRL_COUNTFLAG ((uint32_t)0x00010000) /*!< Count Flag */ - -/***************** Bit definition for SysTick_LOAD register *****************/ -#define SysTick_LOAD_RELOAD ((uint32_t)0x00FFFFFF) /*!< Value to load into the SysTick Current Value Register when the counter reaches 0 */ - -/***************** Bit definition for SysTick_VAL register ******************/ -#define SysTick_VAL_CURRENT ((uint32_t)0x00FFFFFF) /*!< Current value at the time the register is accessed */ - -/***************** Bit definition for SysTick_CALIB register ****************/ -#define SysTick_CALIB_TENMS ((uint32_t)0x00FFFFFF) /*!< Reload value to use for 10ms timing */ -#define SysTick_CALIB_SKEW ((uint32_t)0x40000000) /*!< Calibration value is not exactly 10 ms */ -#define SysTick_CALIB_NOREF ((uint32_t)0x80000000) /*!< The reference clock is not provided */ - -/******************************************************************************/ -/* */ -/* Nested Vectored Interrupt Controller */ -/* */ -/******************************************************************************/ - -/****************** Bit definition for NVIC_ISER register *******************/ -#define NVIC_ISER_SETENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt set enable bits */ -#define NVIC_ISER_SETENA_0 ((uint32_t)0x00000001) /*!< bit 0 */ -#define NVIC_ISER_SETENA_1 ((uint32_t)0x00000002) /*!< bit 1 */ -#define NVIC_ISER_SETENA_2 ((uint32_t)0x00000004) /*!< bit 2 */ -#define NVIC_ISER_SETENA_3 ((uint32_t)0x00000008) /*!< bit 3 */ -#define NVIC_ISER_SETENA_4 ((uint32_t)0x00000010) /*!< bit 4 */ -#define NVIC_ISER_SETENA_5 ((uint32_t)0x00000020) /*!< bit 5 */ -#define NVIC_ISER_SETENA_6 ((uint32_t)0x00000040) /*!< bit 6 */ -#define NVIC_ISER_SETENA_7 ((uint32_t)0x00000080) /*!< bit 7 */ -#define NVIC_ISER_SETENA_8 ((uint32_t)0x00000100) /*!< bit 8 */ -#define NVIC_ISER_SETENA_9 ((uint32_t)0x00000200) /*!< bit 9 */ -#define NVIC_ISER_SETENA_10 ((uint32_t)0x00000400) /*!< bit 10 */ -#define NVIC_ISER_SETENA_11 ((uint32_t)0x00000800) /*!< bit 11 */ -#define NVIC_ISER_SETENA_12 ((uint32_t)0x00001000) /*!< bit 12 */ -#define NVIC_ISER_SETENA_13 ((uint32_t)0x00002000) /*!< bit 13 */ -#define NVIC_ISER_SETENA_14 ((uint32_t)0x00004000) /*!< bit 14 */ -#define NVIC_ISER_SETENA_15 ((uint32_t)0x00008000) /*!< bit 15 */ -#define NVIC_ISER_SETENA_16 ((uint32_t)0x00010000) /*!< bit 16 */ -#define NVIC_ISER_SETENA_17 ((uint32_t)0x00020000) /*!< bit 17 */ -#define NVIC_ISER_SETENA_18 ((uint32_t)0x00040000) /*!< bit 18 */ -#define NVIC_ISER_SETENA_19 ((uint32_t)0x00080000) /*!< bit 19 */ -#define NVIC_ISER_SETENA_20 ((uint32_t)0x00100000) /*!< bit 20 */ -#define NVIC_ISER_SETENA_21 ((uint32_t)0x00200000) /*!< bit 21 */ -#define NVIC_ISER_SETENA_22 ((uint32_t)0x00400000) /*!< bit 22 */ -#define NVIC_ISER_SETENA_23 ((uint32_t)0x00800000) /*!< bit 23 */ -#define NVIC_ISER_SETENA_24 ((uint32_t)0x01000000) /*!< bit 24 */ -#define NVIC_ISER_SETENA_25 ((uint32_t)0x02000000) /*!< bit 25 */ -#define NVIC_ISER_SETENA_26 ((uint32_t)0x04000000) /*!< bit 26 */ -#define NVIC_ISER_SETENA_27 ((uint32_t)0x08000000) /*!< bit 27 */ -#define NVIC_ISER_SETENA_28 ((uint32_t)0x10000000) /*!< bit 28 */ -#define NVIC_ISER_SETENA_29 ((uint32_t)0x20000000) /*!< bit 29 */ -#define NVIC_ISER_SETENA_30 ((uint32_t)0x40000000) /*!< bit 30 */ -#define NVIC_ISER_SETENA_31 ((uint32_t)0x80000000) /*!< bit 31 */ - -/****************** Bit definition for NVIC_ICER register *******************/ -#define NVIC_ICER_CLRENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-enable bits */ -#define NVIC_ICER_CLRENA_0 ((uint32_t)0x00000001) /*!< bit 0 */ -#define NVIC_ICER_CLRENA_1 ((uint32_t)0x00000002) /*!< bit 1 */ -#define NVIC_ICER_CLRENA_2 ((uint32_t)0x00000004) /*!< bit 2 */ -#define NVIC_ICER_CLRENA_3 ((uint32_t)0x00000008) /*!< bit 3 */ -#define NVIC_ICER_CLRENA_4 ((uint32_t)0x00000010) /*!< bit 4 */ -#define NVIC_ICER_CLRENA_5 ((uint32_t)0x00000020) /*!< bit 5 */ -#define NVIC_ICER_CLRENA_6 ((uint32_t)0x00000040) /*!< bit 6 */ -#define NVIC_ICER_CLRENA_7 ((uint32_t)0x00000080) /*!< bit 7 */ -#define NVIC_ICER_CLRENA_8 ((uint32_t)0x00000100) /*!< bit 8 */ -#define NVIC_ICER_CLRENA_9 ((uint32_t)0x00000200) /*!< bit 9 */ -#define NVIC_ICER_CLRENA_10 ((uint32_t)0x00000400) /*!< bit 10 */ -#define NVIC_ICER_CLRENA_11 ((uint32_t)0x00000800) /*!< bit 11 */ -#define NVIC_ICER_CLRENA_12 ((uint32_t)0x00001000) /*!< bit 12 */ -#define NVIC_ICER_CLRENA_13 ((uint32_t)0x00002000) /*!< bit 13 */ -#define NVIC_ICER_CLRENA_14 ((uint32_t)0x00004000) /*!< bit 14 */ -#define NVIC_ICER_CLRENA_15 ((uint32_t)0x00008000) /*!< bit 15 */ -#define NVIC_ICER_CLRENA_16 ((uint32_t)0x00010000) /*!< bit 16 */ -#define NVIC_ICER_CLRENA_17 ((uint32_t)0x00020000) /*!< bit 17 */ -#define NVIC_ICER_CLRENA_18 ((uint32_t)0x00040000) /*!< bit 18 */ -#define NVIC_ICER_CLRENA_19 ((uint32_t)0x00080000) /*!< bit 19 */ -#define NVIC_ICER_CLRENA_20 ((uint32_t)0x00100000) /*!< bit 20 */ -#define NVIC_ICER_CLRENA_21 ((uint32_t)0x00200000) /*!< bit 21 */ -#define NVIC_ICER_CLRENA_22 ((uint32_t)0x00400000) /*!< bit 22 */ -#define NVIC_ICER_CLRENA_23 ((uint32_t)0x00800000) /*!< bit 23 */ -#define NVIC_ICER_CLRENA_24 ((uint32_t)0x01000000) /*!< bit 24 */ -#define NVIC_ICER_CLRENA_25 ((uint32_t)0x02000000) /*!< bit 25 */ -#define NVIC_ICER_CLRENA_26 ((uint32_t)0x04000000) /*!< bit 26 */ -#define NVIC_ICER_CLRENA_27 ((uint32_t)0x08000000) /*!< bit 27 */ -#define NVIC_ICER_CLRENA_28 ((uint32_t)0x10000000) /*!< bit 28 */ -#define NVIC_ICER_CLRENA_29 ((uint32_t)0x20000000) /*!< bit 29 */ -#define NVIC_ICER_CLRENA_30 ((uint32_t)0x40000000) /*!< bit 30 */ -#define NVIC_ICER_CLRENA_31 ((uint32_t)0x80000000) /*!< bit 31 */ - -/****************** Bit definition for NVIC_ISPR register *******************/ -#define NVIC_ISPR_SETPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt set-pending bits */ -#define NVIC_ISPR_SETPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */ -#define NVIC_ISPR_SETPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */ -#define NVIC_ISPR_SETPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */ -#define NVIC_ISPR_SETPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */ -#define NVIC_ISPR_SETPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */ -#define NVIC_ISPR_SETPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */ -#define NVIC_ISPR_SETPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */ -#define NVIC_ISPR_SETPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */ -#define NVIC_ISPR_SETPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */ -#define NVIC_ISPR_SETPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */ -#define NVIC_ISPR_SETPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */ -#define NVIC_ISPR_SETPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */ -#define NVIC_ISPR_SETPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */ -#define NVIC_ISPR_SETPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */ -#define NVIC_ISPR_SETPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */ -#define NVIC_ISPR_SETPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */ -#define NVIC_ISPR_SETPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */ -#define NVIC_ISPR_SETPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */ -#define NVIC_ISPR_SETPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */ -#define NVIC_ISPR_SETPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */ -#define NVIC_ISPR_SETPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */ -#define NVIC_ISPR_SETPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */ -#define NVIC_ISPR_SETPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */ -#define NVIC_ISPR_SETPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */ -#define NVIC_ISPR_SETPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */ -#define NVIC_ISPR_SETPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */ -#define NVIC_ISPR_SETPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */ -#define NVIC_ISPR_SETPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */ -#define NVIC_ISPR_SETPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */ -#define NVIC_ISPR_SETPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */ -#define NVIC_ISPR_SETPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */ -#define NVIC_ISPR_SETPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */ - -/****************** Bit definition for NVIC_ICPR register *******************/ -#define NVIC_ICPR_CLRPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-pending bits */ -#define NVIC_ICPR_CLRPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */ -#define NVIC_ICPR_CLRPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */ -#define NVIC_ICPR_CLRPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */ -#define NVIC_ICPR_CLRPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */ -#define NVIC_ICPR_CLRPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */ -#define NVIC_ICPR_CLRPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */ -#define NVIC_ICPR_CLRPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */ -#define NVIC_ICPR_CLRPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */ -#define NVIC_ICPR_CLRPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */ -#define NVIC_ICPR_CLRPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */ -#define NVIC_ICPR_CLRPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */ -#define NVIC_ICPR_CLRPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */ -#define NVIC_ICPR_CLRPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */ -#define NVIC_ICPR_CLRPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */ -#define NVIC_ICPR_CLRPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */ -#define NVIC_ICPR_CLRPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */ -#define NVIC_ICPR_CLRPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */ -#define NVIC_ICPR_CLRPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */ -#define NVIC_ICPR_CLRPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */ -#define NVIC_ICPR_CLRPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */ -#define NVIC_ICPR_CLRPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */ -#define NVIC_ICPR_CLRPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */ -#define NVIC_ICPR_CLRPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */ -#define NVIC_ICPR_CLRPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */ -#define NVIC_ICPR_CLRPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */ -#define NVIC_ICPR_CLRPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */ -#define NVIC_ICPR_CLRPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */ -#define NVIC_ICPR_CLRPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */ -#define NVIC_ICPR_CLRPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */ -#define NVIC_ICPR_CLRPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */ -#define NVIC_ICPR_CLRPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */ -#define NVIC_ICPR_CLRPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */ - -/****************** Bit definition for NVIC_IABR register *******************/ -#define NVIC_IABR_ACTIVE ((uint32_t)0xFFFFFFFF) /*!< Interrupt active flags */ -#define NVIC_IABR_ACTIVE_0 ((uint32_t)0x00000001) /*!< bit 0 */ -#define NVIC_IABR_ACTIVE_1 ((uint32_t)0x00000002) /*!< bit 1 */ -#define NVIC_IABR_ACTIVE_2 ((uint32_t)0x00000004) /*!< bit 2 */ -#define NVIC_IABR_ACTIVE_3 ((uint32_t)0x00000008) /*!< bit 3 */ -#define NVIC_IABR_ACTIVE_4 ((uint32_t)0x00000010) /*!< bit 4 */ -#define NVIC_IABR_ACTIVE_5 ((uint32_t)0x00000020) /*!< bit 5 */ -#define NVIC_IABR_ACTIVE_6 ((uint32_t)0x00000040) /*!< bit 6 */ -#define NVIC_IABR_ACTIVE_7 ((uint32_t)0x00000080) /*!< bit 7 */ -#define NVIC_IABR_ACTIVE_8 ((uint32_t)0x00000100) /*!< bit 8 */ -#define NVIC_IABR_ACTIVE_9 ((uint32_t)0x00000200) /*!< bit 9 */ -#define NVIC_IABR_ACTIVE_10 ((uint32_t)0x00000400) /*!< bit 10 */ -#define NVIC_IABR_ACTIVE_11 ((uint32_t)0x00000800) /*!< bit 11 */ -#define NVIC_IABR_ACTIVE_12 ((uint32_t)0x00001000) /*!< bit 12 */ -#define NVIC_IABR_ACTIVE_13 ((uint32_t)0x00002000) /*!< bit 13 */ -#define NVIC_IABR_ACTIVE_14 ((uint32_t)0x00004000) /*!< bit 14 */ -#define NVIC_IABR_ACTIVE_15 ((uint32_t)0x00008000) /*!< bit 15 */ -#define NVIC_IABR_ACTIVE_16 ((uint32_t)0x00010000) /*!< bit 16 */ -#define NVIC_IABR_ACTIVE_17 ((uint32_t)0x00020000) /*!< bit 17 */ -#define NVIC_IABR_ACTIVE_18 ((uint32_t)0x00040000) /*!< bit 18 */ -#define NVIC_IABR_ACTIVE_19 ((uint32_t)0x00080000) /*!< bit 19 */ -#define NVIC_IABR_ACTIVE_20 ((uint32_t)0x00100000) /*!< bit 20 */ -#define NVIC_IABR_ACTIVE_21 ((uint32_t)0x00200000) /*!< bit 21 */ -#define NVIC_IABR_ACTIVE_22 ((uint32_t)0x00400000) /*!< bit 22 */ -#define NVIC_IABR_ACTIVE_23 ((uint32_t)0x00800000) /*!< bit 23 */ -#define NVIC_IABR_ACTIVE_24 ((uint32_t)0x01000000) /*!< bit 24 */ -#define NVIC_IABR_ACTIVE_25 ((uint32_t)0x02000000) /*!< bit 25 */ -#define NVIC_IABR_ACTIVE_26 ((uint32_t)0x04000000) /*!< bit 26 */ -#define NVIC_IABR_ACTIVE_27 ((uint32_t)0x08000000) /*!< bit 27 */ -#define NVIC_IABR_ACTIVE_28 ((uint32_t)0x10000000) /*!< bit 28 */ -#define NVIC_IABR_ACTIVE_29 ((uint32_t)0x20000000) /*!< bit 29 */ -#define NVIC_IABR_ACTIVE_30 ((uint32_t)0x40000000) /*!< bit 30 */ -#define NVIC_IABR_ACTIVE_31 ((uint32_t)0x80000000) /*!< bit 31 */ - -/****************** Bit definition for NVIC_PRI0 register *******************/ -#define NVIC_IPR0_PRI_0 ((uint32_t)0x000000FF) /*!< Priority of interrupt 0 */ -#define NVIC_IPR0_PRI_1 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 1 */ -#define NVIC_IPR0_PRI_2 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 2 */ -#define NVIC_IPR0_PRI_3 ((uint32_t)0xFF000000) /*!< Priority of interrupt 3 */ - -/****************** Bit definition for NVIC_PRI1 register *******************/ -#define NVIC_IPR1_PRI_4 ((uint32_t)0x000000FF) /*!< Priority of interrupt 4 */ -#define NVIC_IPR1_PRI_5 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 5 */ -#define NVIC_IPR1_PRI_6 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 6 */ -#define NVIC_IPR1_PRI_7 ((uint32_t)0xFF000000) /*!< Priority of interrupt 7 */ - -/****************** Bit definition for NVIC_PRI2 register *******************/ -#define NVIC_IPR2_PRI_8 ((uint32_t)0x000000FF) /*!< Priority of interrupt 8 */ -#define NVIC_IPR2_PRI_9 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 9 */ -#define NVIC_IPR2_PRI_10 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 10 */ -#define NVIC_IPR2_PRI_11 ((uint32_t)0xFF000000) /*!< Priority of interrupt 11 */ - -/****************** Bit definition for NVIC_PRI3 register *******************/ -#define NVIC_IPR3_PRI_12 ((uint32_t)0x000000FF) /*!< Priority of interrupt 12 */ -#define NVIC_IPR3_PRI_13 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 13 */ -#define NVIC_IPR3_PRI_14 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 14 */ -#define NVIC_IPR3_PRI_15 ((uint32_t)0xFF000000) /*!< Priority of interrupt 15 */ - -/****************** Bit definition for NVIC_PRI4 register *******************/ -#define NVIC_IPR4_PRI_16 ((uint32_t)0x000000FF) /*!< Priority of interrupt 16 */ -#define NVIC_IPR4_PRI_17 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 17 */ -#define NVIC_IPR4_PRI_18 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 18 */ -#define NVIC_IPR4_PRI_19 ((uint32_t)0xFF000000) /*!< Priority of interrupt 19 */ - -/****************** Bit definition for NVIC_PRI5 register *******************/ -#define NVIC_IPR5_PRI_20 ((uint32_t)0x000000FF) /*!< Priority of interrupt 20 */ -#define NVIC_IPR5_PRI_21 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 21 */ -#define NVIC_IPR5_PRI_22 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 22 */ -#define NVIC_IPR5_PRI_23 ((uint32_t)0xFF000000) /*!< Priority of interrupt 23 */ - -/****************** Bit definition for NVIC_PRI6 register *******************/ -#define NVIC_IPR6_PRI_24 ((uint32_t)0x000000FF) /*!< Priority of interrupt 24 */ -#define NVIC_IPR6_PRI_25 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 25 */ -#define NVIC_IPR6_PRI_26 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 26 */ -#define NVIC_IPR6_PRI_27 ((uint32_t)0xFF000000) /*!< Priority of interrupt 27 */ - -/****************** Bit definition for NVIC_PRI7 register *******************/ -#define NVIC_IPR7_PRI_28 ((uint32_t)0x000000FF) /*!< Priority of interrupt 28 */ -#define NVIC_IPR7_PRI_29 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 29 */ -#define NVIC_IPR7_PRI_30 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 30 */ -#define NVIC_IPR7_PRI_31 ((uint32_t)0xFF000000) /*!< Priority of interrupt 31 */ - -/****************** Bit definition for SCB_CPUID register *******************/ -#define SCB_CPUID_REVISION ((uint32_t)0x0000000F) /*!< Implementation defined revision number */ -#define SCB_CPUID_PARTNO ((uint32_t)0x0000FFF0) /*!< Number of processor within family */ -#define SCB_CPUID_Constant ((uint32_t)0x000F0000) /*!< Reads as 0x0F */ -#define SCB_CPUID_VARIANT ((uint32_t)0x00F00000) /*!< Implementation defined variant number */ -#define SCB_CPUID_IMPLEMENTER ((uint32_t)0xFF000000) /*!< Implementer code. ARM is 0x41 */ - -/******************* Bit definition for SCB_ICSR register *******************/ -#define SCB_ICSR_VECTACTIVE ((uint32_t)0x000001FF) /*!< Active ISR number field */ -#define SCB_ICSR_RETTOBASE ((uint32_t)0x00000800) /*!< All active exceptions minus the IPSR_current_exception yields the empty set */ -#define SCB_ICSR_VECTPENDING ((uint32_t)0x003FF000) /*!< Pending ISR number field */ -#define SCB_ICSR_ISRPENDING ((uint32_t)0x00400000) /*!< Interrupt pending flag */ -#define SCB_ICSR_ISRPREEMPT ((uint32_t)0x00800000) /*!< It indicates that a pending interrupt becomes active in the next running cycle */ -#define SCB_ICSR_PENDSTCLR ((uint32_t)0x02000000) /*!< Clear pending SysTick bit */ -#define SCB_ICSR_PENDSTSET ((uint32_t)0x04000000) /*!< Set pending SysTick bit */ -#define SCB_ICSR_PENDSVCLR ((uint32_t)0x08000000) /*!< Clear pending pendSV bit */ -#define SCB_ICSR_PENDSVSET ((uint32_t)0x10000000) /*!< Set pending pendSV bit */ -#define SCB_ICSR_NMIPENDSET ((uint32_t)0x80000000) /*!< Set pending NMI bit */ - -/******************* Bit definition for SCB_VTOR register *******************/ -#define SCB_VTOR_TBLOFF ((uint32_t)0x1FFFFF80) /*!< Vector table base offset field */ -#define SCB_VTOR_TBLBASE ((uint32_t)0x20000000) /*!< Table base in code(0) or RAM(1) */ - -/*!<***************** Bit definition for SCB_AIRCR register *******************/ -#define SCB_AIRCR_VECTRESET ((uint32_t)0x00000001) /*!< System Reset bit */ -#define SCB_AIRCR_VECTCLRACTIVE ((uint32_t)0x00000002) /*!< Clear active vector bit */ -#define SCB_AIRCR_SYSRESETREQ ((uint32_t)0x00000004) /*!< Requests chip control logic to generate a reset */ - -#define SCB_AIRCR_PRIGROUP ((uint32_t)0x00000700) /*!< PRIGROUP[2:0] bits (Priority group) */ -#define SCB_AIRCR_PRIGROUP_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define SCB_AIRCR_PRIGROUP_1 ((uint32_t)0x00000200) /*!< Bit 1 */ -#define SCB_AIRCR_PRIGROUP_2 ((uint32_t)0x00000400) /*!< Bit 2 */ - -/* prority group configuration */ -#define SCB_AIRCR_PRIGROUP0 ((uint32_t)0x00000000) /*!< Priority group=0 (7 bits of pre-emption priority, 1 bit of subpriority) */ -#define SCB_AIRCR_PRIGROUP1 ((uint32_t)0x00000100) /*!< Priority group=1 (6 bits of pre-emption priority, 2 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP2 ((uint32_t)0x00000200) /*!< Priority group=2 (5 bits of pre-emption priority, 3 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP3 ((uint32_t)0x00000300) /*!< Priority group=3 (4 bits of pre-emption priority, 4 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP4 ((uint32_t)0x00000400) /*!< Priority group=4 (3 bits of pre-emption priority, 5 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP5 ((uint32_t)0x00000500) /*!< Priority group=5 (2 bits of pre-emption priority, 6 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP6 ((uint32_t)0x00000600) /*!< Priority group=6 (1 bit of pre-emption priority, 7 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP7 ((uint32_t)0x00000700) /*!< Priority group=7 (no pre-emption priority, 8 bits of subpriority) */ - -#define SCB_AIRCR_ENDIANESS ((uint32_t)0x00008000) /*!< Data endianness bit */ -#define SCB_AIRCR_VECTKEY ((uint32_t)0xFFFF0000) /*!< Register key (VECTKEY) - Reads as 0xFA05 (VECTKEYSTAT) */ - -/******************* Bit definition for SCB_SCR register ********************/ -#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< Sleep on exit bit */ -#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< Sleep deep bit */ -#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< Wake up from WFE */ - -/******************** Bit definition for SCB_CCR register *******************/ -#define SCB_CCR_NONBASETHRDENA ((uint16_t)0x0001) /*!< Thread mode can be entered from any level in Handler mode by controlled return value */ -#define SCB_CCR_USERSETMPEND ((uint16_t)0x0002) /*!< Enables user code to write the Software Trigger Interrupt register to trigger (pend) a Main exception */ -#define SCB_CCR_UNALIGN_TRP ((uint16_t)0x0008) /*!< Trap for unaligned access */ -#define SCB_CCR_DIV_0_TRP ((uint16_t)0x0010) /*!< Trap on Divide by 0 */ -#define SCB_CCR_BFHFNMIGN ((uint16_t)0x0100) /*!< Handlers running at priority -1 and -2 */ -#define SCB_CCR_STKALIGN ((uint16_t)0x0200) /*!< On exception entry, the SP used prior to the exception is adjusted to be 8-byte aligned */ - -/******************* Bit definition for SCB_SHPR register ********************/ -#define SCB_SHPR_PRI_N ((uint32_t)0x000000FF) /*!< Priority of system handler 4,8, and 12. Mem Manage, reserved and Debug Monitor */ -#define SCB_SHPR_PRI_N1 ((uint32_t)0x0000FF00) /*!< Priority of system handler 5,9, and 13. Bus Fault, reserved and reserved */ -#define SCB_SHPR_PRI_N2 ((uint32_t)0x00FF0000) /*!< Priority of system handler 6,10, and 14. Usage Fault, reserved and PendSV */ -#define SCB_SHPR_PRI_N3 ((uint32_t)0xFF000000) /*!< Priority of system handler 7,11, and 15. Reserved, SVCall and SysTick */ - -/****************** Bit definition for SCB_SHCSR register *******************/ -#define SCB_SHCSR_MEMFAULTACT ((uint32_t)0x00000001) /*!< MemManage is active */ -#define SCB_SHCSR_BUSFAULTACT ((uint32_t)0x00000002) /*!< BusFault is active */ -#define SCB_SHCSR_USGFAULTACT ((uint32_t)0x00000008) /*!< UsageFault is active */ -#define SCB_SHCSR_SVCALLACT ((uint32_t)0x00000080) /*!< SVCall is active */ -#define SCB_SHCSR_MONITORACT ((uint32_t)0x00000100) /*!< Monitor is active */ -#define SCB_SHCSR_PENDSVACT ((uint32_t)0x00000400) /*!< PendSV is active */ -#define SCB_SHCSR_SYSTICKACT ((uint32_t)0x00000800) /*!< SysTick is active */ -#define SCB_SHCSR_USGFAULTPENDED ((uint32_t)0x00001000) /*!< Usage Fault is pended */ -#define SCB_SHCSR_MEMFAULTPENDED ((uint32_t)0x00002000) /*!< MemManage is pended */ -#define SCB_SHCSR_BUSFAULTPENDED ((uint32_t)0x00004000) /*!< Bus Fault is pended */ -#define SCB_SHCSR_SVCALLPENDED ((uint32_t)0x00008000) /*!< SVCall is pended */ -#define SCB_SHCSR_MEMFAULTENA ((uint32_t)0x00010000) /*!< MemManage enable */ -#define SCB_SHCSR_BUSFAULTENA ((uint32_t)0x00020000) /*!< Bus Fault enable */ -#define SCB_SHCSR_USGFAULTENA ((uint32_t)0x00040000) /*!< UsageFault enable */ - -/******************* Bit definition for SCB_CFSR register *******************/ -/*!< MFSR */ -#define SCB_CFSR_IACCVIOL ((uint32_t)0x00000001) /*!< Instruction access violation */ -#define SCB_CFSR_DACCVIOL ((uint32_t)0x00000002) /*!< Data access violation */ -#define SCB_CFSR_MUNSTKERR ((uint32_t)0x00000008) /*!< Unstacking error */ -#define SCB_CFSR_MSTKERR ((uint32_t)0x00000010) /*!< Stacking error */ -#define SCB_CFSR_MMARVALID ((uint32_t)0x00000080) /*!< Memory Manage Address Register address valid flag */ -/*!< BFSR */ -#define SCB_CFSR_IBUSERR ((uint32_t)0x00000100) /*!< Instruction bus error flag */ -#define SCB_CFSR_PRECISERR ((uint32_t)0x00000200) /*!< Precise data bus error */ -#define SCB_CFSR_IMPRECISERR ((uint32_t)0x00000400) /*!< Imprecise data bus error */ -#define SCB_CFSR_UNSTKERR ((uint32_t)0x00000800) /*!< Unstacking error */ -#define SCB_CFSR_STKERR ((uint32_t)0x00001000) /*!< Stacking error */ -#define SCB_CFSR_BFARVALID ((uint32_t)0x00008000) /*!< Bus Fault Address Register address valid flag */ -/*!< UFSR */ -#define SCB_CFSR_UNDEFINSTR ((uint32_t)0x00010000) /*!< The processor attempt to excecute an undefined instruction */ -#define SCB_CFSR_INVSTATE ((uint32_t)0x00020000) /*!< Invalid combination of EPSR and instruction */ -#define SCB_CFSR_INVPC ((uint32_t)0x00040000) /*!< Attempt to load EXC_RETURN into pc illegally */ -#define SCB_CFSR_NOCP ((uint32_t)0x00080000) /*!< Attempt to use a coprocessor instruction */ -#define SCB_CFSR_UNALIGNED ((uint32_t)0x01000000) /*!< Fault occurs when there is an attempt to make an unaligned memory access */ -#define SCB_CFSR_DIVBYZERO ((uint32_t)0x02000000) /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */ - -/******************* Bit definition for SCB_HFSR register *******************/ -#define SCB_HFSR_VECTTBL ((uint32_t)0x00000002) /*!< Fault occures because of vector table read on exception processing */ -#define SCB_HFSR_FORCED ((uint32_t)0x40000000) /*!< Hard Fault activated when a configurable Fault was received and cannot activate */ -#define SCB_HFSR_DEBUGEVT ((uint32_t)0x80000000) /*!< Fault related to debug */ - -/******************* Bit definition for SCB_DFSR register *******************/ -#define SCB_DFSR_HALTED ((uint8_t)0x01) /*!< Halt request flag */ -#define SCB_DFSR_BKPT ((uint8_t)0x02) /*!< BKPT flag */ -#define SCB_DFSR_DWTTRAP ((uint8_t)0x04) /*!< Data Watchpoint and Trace (DWT) flag */ -#define SCB_DFSR_VCATCH ((uint8_t)0x08) /*!< Vector catch flag */ -#define SCB_DFSR_EXTERNAL ((uint8_t)0x10) /*!< External debug request flag */ - -/******************* Bit definition for SCB_MMFAR register ******************/ -#define SCB_MMFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Mem Manage fault address field */ - -/******************* Bit definition for SCB_BFAR register *******************/ -#define SCB_BFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Bus fault address field */ - -/******************* Bit definition for SCB_afsr register *******************/ -#define SCB_AFSR_IMPDEF ((uint32_t)0xFFFFFFFF) /*!< Implementation defined */ - -/******************************************************************************/ -/* */ -/* External Interrupt/Event Controller */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for EXTI_IMR register *******************/ -#define EXTI_IMR_MR0 ((uint32_t)0x00000001) /*!< Interrupt Mask on line 0 */ -#define EXTI_IMR_MR1 ((uint32_t)0x00000002) /*!< Interrupt Mask on line 1 */ -#define EXTI_IMR_MR2 ((uint32_t)0x00000004) /*!< Interrupt Mask on line 2 */ -#define EXTI_IMR_MR3 ((uint32_t)0x00000008) /*!< Interrupt Mask on line 3 */ -#define EXTI_IMR_MR4 ((uint32_t)0x00000010) /*!< Interrupt Mask on line 4 */ -#define EXTI_IMR_MR5 ((uint32_t)0x00000020) /*!< Interrupt Mask on line 5 */ -#define EXTI_IMR_MR6 ((uint32_t)0x00000040) /*!< Interrupt Mask on line 6 */ -#define EXTI_IMR_MR7 ((uint32_t)0x00000080) /*!< Interrupt Mask on line 7 */ -#define EXTI_IMR_MR8 ((uint32_t)0x00000100) /*!< Interrupt Mask on line 8 */ -#define EXTI_IMR_MR9 ((uint32_t)0x00000200) /*!< Interrupt Mask on line 9 */ -#define EXTI_IMR_MR10 ((uint32_t)0x00000400) /*!< Interrupt Mask on line 10 */ -#define EXTI_IMR_MR11 ((uint32_t)0x00000800) /*!< Interrupt Mask on line 11 */ -#define EXTI_IMR_MR12 ((uint32_t)0x00001000) /*!< Interrupt Mask on line 12 */ -#define EXTI_IMR_MR13 ((uint32_t)0x00002000) /*!< Interrupt Mask on line 13 */ -#define EXTI_IMR_MR14 ((uint32_t)0x00004000) /*!< Interrupt Mask on line 14 */ -#define EXTI_IMR_MR15 ((uint32_t)0x00008000) /*!< Interrupt Mask on line 15 */ -#define EXTI_IMR_MR16 ((uint32_t)0x00010000) /*!< Interrupt Mask on line 16 */ -#define EXTI_IMR_MR17 ((uint32_t)0x00020000) /*!< Interrupt Mask on line 17 */ -#define EXTI_IMR_MR18 ((uint32_t)0x00040000) /*!< Interrupt Mask on line 18 */ -#define EXTI_IMR_MR19 ((uint32_t)0x00080000) /*!< Interrupt Mask on line 19 */ - -/******************* Bit definition for EXTI_EMR register *******************/ -#define EXTI_EMR_MR0 ((uint32_t)0x00000001) /*!< Event Mask on line 0 */ -#define EXTI_EMR_MR1 ((uint32_t)0x00000002) /*!< Event Mask on line 1 */ -#define EXTI_EMR_MR2 ((uint32_t)0x00000004) /*!< Event Mask on line 2 */ -#define EXTI_EMR_MR3 ((uint32_t)0x00000008) /*!< Event Mask on line 3 */ -#define EXTI_EMR_MR4 ((uint32_t)0x00000010) /*!< Event Mask on line 4 */ -#define EXTI_EMR_MR5 ((uint32_t)0x00000020) /*!< Event Mask on line 5 */ -#define EXTI_EMR_MR6 ((uint32_t)0x00000040) /*!< Event Mask on line 6 */ -#define EXTI_EMR_MR7 ((uint32_t)0x00000080) /*!< Event Mask on line 7 */ -#define EXTI_EMR_MR8 ((uint32_t)0x00000100) /*!< Event Mask on line 8 */ -#define EXTI_EMR_MR9 ((uint32_t)0x00000200) /*!< Event Mask on line 9 */ -#define EXTI_EMR_MR10 ((uint32_t)0x00000400) /*!< Event Mask on line 10 */ -#define EXTI_EMR_MR11 ((uint32_t)0x00000800) /*!< Event Mask on line 11 */ -#define EXTI_EMR_MR12 ((uint32_t)0x00001000) /*!< Event Mask on line 12 */ -#define EXTI_EMR_MR13 ((uint32_t)0x00002000) /*!< Event Mask on line 13 */ -#define EXTI_EMR_MR14 ((uint32_t)0x00004000) /*!< Event Mask on line 14 */ -#define EXTI_EMR_MR15 ((uint32_t)0x00008000) /*!< Event Mask on line 15 */ -#define EXTI_EMR_MR16 ((uint32_t)0x00010000) /*!< Event Mask on line 16 */ -#define EXTI_EMR_MR17 ((uint32_t)0x00020000) /*!< Event Mask on line 17 */ -#define EXTI_EMR_MR18 ((uint32_t)0x00040000) /*!< Event Mask on line 18 */ -#define EXTI_EMR_MR19 ((uint32_t)0x00080000) /*!< Event Mask on line 19 */ - -/****************** Bit definition for EXTI_RTSR register *******************/ -#define EXTI_RTSR_TR0 ((uint32_t)0x00000001) /*!< Rising trigger event configuration bit of line 0 */ -#define EXTI_RTSR_TR1 ((uint32_t)0x00000002) /*!< Rising trigger event configuration bit of line 1 */ -#define EXTI_RTSR_TR2 ((uint32_t)0x00000004) /*!< Rising trigger event configuration bit of line 2 */ -#define EXTI_RTSR_TR3 ((uint32_t)0x00000008) /*!< Rising trigger event configuration bit of line 3 */ -#define EXTI_RTSR_TR4 ((uint32_t)0x00000010) /*!< Rising trigger event configuration bit of line 4 */ -#define EXTI_RTSR_TR5 ((uint32_t)0x00000020) /*!< Rising trigger event configuration bit of line 5 */ -#define EXTI_RTSR_TR6 ((uint32_t)0x00000040) /*!< Rising trigger event configuration bit of line 6 */ -#define EXTI_RTSR_TR7 ((uint32_t)0x00000080) /*!< Rising trigger event configuration bit of line 7 */ -#define EXTI_RTSR_TR8 ((uint32_t)0x00000100) /*!< Rising trigger event configuration bit of line 8 */ -#define EXTI_RTSR_TR9 ((uint32_t)0x00000200) /*!< Rising trigger event configuration bit of line 9 */ -#define EXTI_RTSR_TR10 ((uint32_t)0x00000400) /*!< Rising trigger event configuration bit of line 10 */ -#define EXTI_RTSR_TR11 ((uint32_t)0x00000800) /*!< Rising trigger event configuration bit of line 11 */ -#define EXTI_RTSR_TR12 ((uint32_t)0x00001000) /*!< Rising trigger event configuration bit of line 12 */ -#define EXTI_RTSR_TR13 ((uint32_t)0x00002000) /*!< Rising trigger event configuration bit of line 13 */ -#define EXTI_RTSR_TR14 ((uint32_t)0x00004000) /*!< Rising trigger event configuration bit of line 14 */ -#define EXTI_RTSR_TR15 ((uint32_t)0x00008000) /*!< Rising trigger event configuration bit of line 15 */ -#define EXTI_RTSR_TR16 ((uint32_t)0x00010000) /*!< Rising trigger event configuration bit of line 16 */ -#define EXTI_RTSR_TR17 ((uint32_t)0x00020000) /*!< Rising trigger event configuration bit of line 17 */ -#define EXTI_RTSR_TR18 ((uint32_t)0x00040000) /*!< Rising trigger event configuration bit of line 18 */ -#define EXTI_RTSR_TR19 ((uint32_t)0x00080000) /*!< Rising trigger event configuration bit of line 19 */ - -/****************** Bit definition for EXTI_FTSR register *******************/ -#define EXTI_FTSR_TR0 ((uint32_t)0x00000001) /*!< Falling trigger event configuration bit of line 0 */ -#define EXTI_FTSR_TR1 ((uint32_t)0x00000002) /*!< Falling trigger event configuration bit of line 1 */ -#define EXTI_FTSR_TR2 ((uint32_t)0x00000004) /*!< Falling trigger event configuration bit of line 2 */ -#define EXTI_FTSR_TR3 ((uint32_t)0x00000008) /*!< Falling trigger event configuration bit of line 3 */ -#define EXTI_FTSR_TR4 ((uint32_t)0x00000010) /*!< Falling trigger event configuration bit of line 4 */ -#define EXTI_FTSR_TR5 ((uint32_t)0x00000020) /*!< Falling trigger event configuration bit of line 5 */ -#define EXTI_FTSR_TR6 ((uint32_t)0x00000040) /*!< Falling trigger event configuration bit of line 6 */ -#define EXTI_FTSR_TR7 ((uint32_t)0x00000080) /*!< Falling trigger event configuration bit of line 7 */ -#define EXTI_FTSR_TR8 ((uint32_t)0x00000100) /*!< Falling trigger event configuration bit of line 8 */ -#define EXTI_FTSR_TR9 ((uint32_t)0x00000200) /*!< Falling trigger event configuration bit of line 9 */ -#define EXTI_FTSR_TR10 ((uint32_t)0x00000400) /*!< Falling trigger event configuration bit of line 10 */ -#define EXTI_FTSR_TR11 ((uint32_t)0x00000800) /*!< Falling trigger event configuration bit of line 11 */ -#define EXTI_FTSR_TR12 ((uint32_t)0x00001000) /*!< Falling trigger event configuration bit of line 12 */ -#define EXTI_FTSR_TR13 ((uint32_t)0x00002000) /*!< Falling trigger event configuration bit of line 13 */ -#define EXTI_FTSR_TR14 ((uint32_t)0x00004000) /*!< Falling trigger event configuration bit of line 14 */ -#define EXTI_FTSR_TR15 ((uint32_t)0x00008000) /*!< Falling trigger event configuration bit of line 15 */ -#define EXTI_FTSR_TR16 ((uint32_t)0x00010000) /*!< Falling trigger event configuration bit of line 16 */ -#define EXTI_FTSR_TR17 ((uint32_t)0x00020000) /*!< Falling trigger event configuration bit of line 17 */ -#define EXTI_FTSR_TR18 ((uint32_t)0x00040000) /*!< Falling trigger event configuration bit of line 18 */ -#define EXTI_FTSR_TR19 ((uint32_t)0x00080000) /*!< Falling trigger event configuration bit of line 19 */ - -/****************** Bit definition for EXTI_SWIER register ******************/ -#define EXTI_SWIER_SWIER0 ((uint32_t)0x00000001) /*!< Software Interrupt on line 0 */ -#define EXTI_SWIER_SWIER1 ((uint32_t)0x00000002) /*!< Software Interrupt on line 1 */ -#define EXTI_SWIER_SWIER2 ((uint32_t)0x00000004) /*!< Software Interrupt on line 2 */ -#define EXTI_SWIER_SWIER3 ((uint32_t)0x00000008) /*!< Software Interrupt on line 3 */ -#define EXTI_SWIER_SWIER4 ((uint32_t)0x00000010) /*!< Software Interrupt on line 4 */ -#define EXTI_SWIER_SWIER5 ((uint32_t)0x00000020) /*!< Software Interrupt on line 5 */ -#define EXTI_SWIER_SWIER6 ((uint32_t)0x00000040) /*!< Software Interrupt on line 6 */ -#define EXTI_SWIER_SWIER7 ((uint32_t)0x00000080) /*!< Software Interrupt on line 7 */ -#define EXTI_SWIER_SWIER8 ((uint32_t)0x00000100) /*!< Software Interrupt on line 8 */ -#define EXTI_SWIER_SWIER9 ((uint32_t)0x00000200) /*!< Software Interrupt on line 9 */ -#define EXTI_SWIER_SWIER10 ((uint32_t)0x00000400) /*!< Software Interrupt on line 10 */ -#define EXTI_SWIER_SWIER11 ((uint32_t)0x00000800) /*!< Software Interrupt on line 11 */ -#define EXTI_SWIER_SWIER12 ((uint32_t)0x00001000) /*!< Software Interrupt on line 12 */ -#define EXTI_SWIER_SWIER13 ((uint32_t)0x00002000) /*!< Software Interrupt on line 13 */ -#define EXTI_SWIER_SWIER14 ((uint32_t)0x00004000) /*!< Software Interrupt on line 14 */ -#define EXTI_SWIER_SWIER15 ((uint32_t)0x00008000) /*!< Software Interrupt on line 15 */ -#define EXTI_SWIER_SWIER16 ((uint32_t)0x00010000) /*!< Software Interrupt on line 16 */ -#define EXTI_SWIER_SWIER17 ((uint32_t)0x00020000) /*!< Software Interrupt on line 17 */ -#define EXTI_SWIER_SWIER18 ((uint32_t)0x00040000) /*!< Software Interrupt on line 18 */ -#define EXTI_SWIER_SWIER19 ((uint32_t)0x00080000) /*!< Software Interrupt on line 19 */ - -/******************* Bit definition for EXTI_PR register ********************/ -#define EXTI_PR_PR0 ((uint32_t)0x00000001) /*!< Pending bit for line 0 */ -#define EXTI_PR_PR1 ((uint32_t)0x00000002) /*!< Pending bit for line 1 */ -#define EXTI_PR_PR2 ((uint32_t)0x00000004) /*!< Pending bit for line 2 */ -#define EXTI_PR_PR3 ((uint32_t)0x00000008) /*!< Pending bit for line 3 */ -#define EXTI_PR_PR4 ((uint32_t)0x00000010) /*!< Pending bit for line 4 */ -#define EXTI_PR_PR5 ((uint32_t)0x00000020) /*!< Pending bit for line 5 */ -#define EXTI_PR_PR6 ((uint32_t)0x00000040) /*!< Pending bit for line 6 */ -#define EXTI_PR_PR7 ((uint32_t)0x00000080) /*!< Pending bit for line 7 */ -#define EXTI_PR_PR8 ((uint32_t)0x00000100) /*!< Pending bit for line 8 */ -#define EXTI_PR_PR9 ((uint32_t)0x00000200) /*!< Pending bit for line 9 */ -#define EXTI_PR_PR10 ((uint32_t)0x00000400) /*!< Pending bit for line 10 */ -#define EXTI_PR_PR11 ((uint32_t)0x00000800) /*!< Pending bit for line 11 */ -#define EXTI_PR_PR12 ((uint32_t)0x00001000) /*!< Pending bit for line 12 */ -#define EXTI_PR_PR13 ((uint32_t)0x00002000) /*!< Pending bit for line 13 */ -#define EXTI_PR_PR14 ((uint32_t)0x00004000) /*!< Pending bit for line 14 */ -#define EXTI_PR_PR15 ((uint32_t)0x00008000) /*!< Pending bit for line 15 */ -#define EXTI_PR_PR16 ((uint32_t)0x00010000) /*!< Pending bit for line 16 */ -#define EXTI_PR_PR17 ((uint32_t)0x00020000) /*!< Pending bit for line 17 */ -#define EXTI_PR_PR18 ((uint32_t)0x00040000) /*!< Pending bit for line 18 */ -#define EXTI_PR_PR19 ((uint32_t)0x00080000) /*!< Pending bit for line 19 */ - -/******************************************************************************/ -/* */ -/* DMA Controller */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for DMA_ISR register ********************/ -#define DMA_ISR_GIF1 ((uint32_t)0x00000001) /*!< Channel 1 Global interrupt flag */ -#define DMA_ISR_TCIF1 ((uint32_t)0x00000002) /*!< Channel 1 Transfer Complete flag */ -#define DMA_ISR_HTIF1 ((uint32_t)0x00000004) /*!< Channel 1 Half Transfer flag */ -#define DMA_ISR_TEIF1 ((uint32_t)0x00000008) /*!< Channel 1 Transfer Error flag */ -#define DMA_ISR_GIF2 ((uint32_t)0x00000010) /*!< Channel 2 Global interrupt flag */ -#define DMA_ISR_TCIF2 ((uint32_t)0x00000020) /*!< Channel 2 Transfer Complete flag */ -#define DMA_ISR_HTIF2 ((uint32_t)0x00000040) /*!< Channel 2 Half Transfer flag */ -#define DMA_ISR_TEIF2 ((uint32_t)0x00000080) /*!< Channel 2 Transfer Error flag */ -#define DMA_ISR_GIF3 ((uint32_t)0x00000100) /*!< Channel 3 Global interrupt flag */ -#define DMA_ISR_TCIF3 ((uint32_t)0x00000200) /*!< Channel 3 Transfer Complete flag */ -#define DMA_ISR_HTIF3 ((uint32_t)0x00000400) /*!< Channel 3 Half Transfer flag */ -#define DMA_ISR_TEIF3 ((uint32_t)0x00000800) /*!< Channel 3 Transfer Error flag */ -#define DMA_ISR_GIF4 ((uint32_t)0x00001000) /*!< Channel 4 Global interrupt flag */ -#define DMA_ISR_TCIF4 ((uint32_t)0x00002000) /*!< Channel 4 Transfer Complete flag */ -#define DMA_ISR_HTIF4 ((uint32_t)0x00004000) /*!< Channel 4 Half Transfer flag */ -#define DMA_ISR_TEIF4 ((uint32_t)0x00008000) /*!< Channel 4 Transfer Error flag */ -#define DMA_ISR_GIF5 ((uint32_t)0x00010000) /*!< Channel 5 Global interrupt flag */ -#define DMA_ISR_TCIF5 ((uint32_t)0x00020000) /*!< Channel 5 Transfer Complete flag */ -#define DMA_ISR_HTIF5 ((uint32_t)0x00040000) /*!< Channel 5 Half Transfer flag */ -#define DMA_ISR_TEIF5 ((uint32_t)0x00080000) /*!< Channel 5 Transfer Error flag */ -#define DMA_ISR_GIF6 ((uint32_t)0x00100000) /*!< Channel 6 Global interrupt flag */ -#define DMA_ISR_TCIF6 ((uint32_t)0x00200000) /*!< Channel 6 Transfer Complete flag */ -#define DMA_ISR_HTIF6 ((uint32_t)0x00400000) /*!< Channel 6 Half Transfer flag */ -#define DMA_ISR_TEIF6 ((uint32_t)0x00800000) /*!< Channel 6 Transfer Error flag */ -#define DMA_ISR_GIF7 ((uint32_t)0x01000000) /*!< Channel 7 Global interrupt flag */ -#define DMA_ISR_TCIF7 ((uint32_t)0x02000000) /*!< Channel 7 Transfer Complete flag */ -#define DMA_ISR_HTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer flag */ -#define DMA_ISR_TEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error flag */ - -/******************* Bit definition for DMA_IFCR register *******************/ -#define DMA_IFCR_CGIF1 ((uint32_t)0x00000001) /*!< Channel 1 Global interrupt clearr */ -#define DMA_IFCR_CTCIF1 ((uint32_t)0x00000002) /*!< Channel 1 Transfer Complete clear */ -#define DMA_IFCR_CHTIF1 ((uint32_t)0x00000004) /*!< Channel 1 Half Transfer clear */ -#define DMA_IFCR_CTEIF1 ((uint32_t)0x00000008) /*!< Channel 1 Transfer Error clear */ -#define DMA_IFCR_CGIF2 ((uint32_t)0x00000010) /*!< Channel 2 Global interrupt clear */ -#define DMA_IFCR_CTCIF2 ((uint32_t)0x00000020) /*!< Channel 2 Transfer Complete clear */ -#define DMA_IFCR_CHTIF2 ((uint32_t)0x00000040) /*!< Channel 2 Half Transfer clear */ -#define DMA_IFCR_CTEIF2 ((uint32_t)0x00000080) /*!< Channel 2 Transfer Error clear */ -#define DMA_IFCR_CGIF3 ((uint32_t)0x00000100) /*!< Channel 3 Global interrupt clear */ -#define DMA_IFCR_CTCIF3 ((uint32_t)0x00000200) /*!< Channel 3 Transfer Complete clear */ -#define DMA_IFCR_CHTIF3 ((uint32_t)0x00000400) /*!< Channel 3 Half Transfer clear */ -#define DMA_IFCR_CTEIF3 ((uint32_t)0x00000800) /*!< Channel 3 Transfer Error clear */ -#define DMA_IFCR_CGIF4 ((uint32_t)0x00001000) /*!< Channel 4 Global interrupt clear */ -#define DMA_IFCR_CTCIF4 ((uint32_t)0x00002000) /*!< Channel 4 Transfer Complete clear */ -#define DMA_IFCR_CHTIF4 ((uint32_t)0x00004000) /*!< Channel 4 Half Transfer clear */ -#define DMA_IFCR_CTEIF4 ((uint32_t)0x00008000) /*!< Channel 4 Transfer Error clear */ -#define DMA_IFCR_CGIF5 ((uint32_t)0x00010000) /*!< Channel 5 Global interrupt clear */ -#define DMA_IFCR_CTCIF5 ((uint32_t)0x00020000) /*!< Channel 5 Transfer Complete clear */ -#define DMA_IFCR_CHTIF5 ((uint32_t)0x00040000) /*!< Channel 5 Half Transfer clear */ -#define DMA_IFCR_CTEIF5 ((uint32_t)0x00080000) /*!< Channel 5 Transfer Error clear */ -#define DMA_IFCR_CGIF6 ((uint32_t)0x00100000) /*!< Channel 6 Global interrupt clear */ -#define DMA_IFCR_CTCIF6 ((uint32_t)0x00200000) /*!< Channel 6 Transfer Complete clear */ -#define DMA_IFCR_CHTIF6 ((uint32_t)0x00400000) /*!< Channel 6 Half Transfer clear */ -#define DMA_IFCR_CTEIF6 ((uint32_t)0x00800000) /*!< Channel 6 Transfer Error clear */ -#define DMA_IFCR_CGIF7 ((uint32_t)0x01000000) /*!< Channel 7 Global interrupt clear */ -#define DMA_IFCR_CTCIF7 ((uint32_t)0x02000000) /*!< Channel 7 Transfer Complete clear */ -#define DMA_IFCR_CHTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer clear */ -#define DMA_IFCR_CTEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error clear */ - -/******************* Bit definition for DMA_CCR1 register *******************/ -#define DMA_CCR1_EN ((uint16_t)0x0001) /*!< Channel enable*/ -#define DMA_CCR1_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */ -#define DMA_CCR1_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ -#define DMA_CCR1_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ -#define DMA_CCR1_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ -#define DMA_CCR1_CIRC ((uint16_t)0x0020) /*!< Circular mode */ -#define DMA_CCR1_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ -#define DMA_CCR1_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ - -#define DMA_CCR1_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ -#define DMA_CCR1_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ -#define DMA_CCR1_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ - -#define DMA_CCR1_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ -#define DMA_CCR1_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ -#define DMA_CCR1_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ - -#define DMA_CCR1_PL ((uint16_t)0x3000) /*!< PL[1:0] bits(Channel Priority level) */ -#define DMA_CCR1_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ -#define DMA_CCR1_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ - -#define DMA_CCR1_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ - -/******************* Bit definition for DMA_CCR2 register *******************/ -#define DMA_CCR2_EN ((uint16_t)0x0001) /*!< Channel enable */ -#define DMA_CCR2_TCIE ((uint16_t)0x0002) /*!< ransfer complete interrupt enable */ -#define DMA_CCR2_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ -#define DMA_CCR2_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ -#define DMA_CCR2_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ -#define DMA_CCR2_CIRC ((uint16_t)0x0020) /*!< Circular mode */ -#define DMA_CCR2_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ -#define DMA_CCR2_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ - -#define DMA_CCR2_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ -#define DMA_CCR2_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ -#define DMA_CCR2_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ - -#define DMA_CCR2_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ -#define DMA_CCR2_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ -#define DMA_CCR2_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ - -#define DMA_CCR2_PL ((uint16_t)0x3000) /*!< PL[1:0] bits (Channel Priority level) */ -#define DMA_CCR2_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ -#define DMA_CCR2_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ - -#define DMA_CCR2_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ - -/******************* Bit definition for DMA_CCR3 register *******************/ -#define DMA_CCR3_EN ((uint16_t)0x0001) /*!< Channel enable */ -#define DMA_CCR3_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */ -#define DMA_CCR3_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ -#define DMA_CCR3_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ -#define DMA_CCR3_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ -#define DMA_CCR3_CIRC ((uint16_t)0x0020) /*!< Circular mode */ -#define DMA_CCR3_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ -#define DMA_CCR3_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ - -#define DMA_CCR3_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ -#define DMA_CCR3_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ -#define DMA_CCR3_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ - -#define DMA_CCR3_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ -#define DMA_CCR3_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ -#define DMA_CCR3_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ - -#define DMA_CCR3_PL ((uint16_t)0x3000) /*!< PL[1:0] bits (Channel Priority level) */ -#define DMA_CCR3_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ -#define DMA_CCR3_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ - -#define DMA_CCR3_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ - -/*!<****************** Bit definition for DMA_CCR4 register *******************/ -#define DMA_CCR4_EN ((uint16_t)0x0001) /*!
© COPYRIGHT 2009 STMicroelectronics
+ ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f10x + * @{ + */ + +#ifndef __STM32F10x_H +#define __STM32F10x_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup Library_configuration_section + * @{ + */ + +/* Uncomment the line below according to the target STM32 device used in your + application + */ + +#if !defined (STM32F10X_LD) && !defined (STM32F10X_MD) && !defined (STM32F10X_HD) && !defined (STM32F10X_CL) + /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */ + /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */ + /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */ + #define STM32F10X_CL /*!< STM32F10X_CL: STM32 Connectivity line devices */ +#endif +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + + - Low density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers + where the Flash memory density ranges between 16 and 32 Kbytes. + - Medium density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers + where the Flash memory density ranges between 64 and 128 Kbytes. + - High density devices are STM32F101xx and STM32F103xx microcontrollers where + the Flash memory density ranges between 256 and 512 Kbytes. + - Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers. + */ + +#if !defined USE_STDPERIPH_DRIVER +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ + /*#define USE_STDPERIPH_DRIVER*/ +#endif + +/** + * @brief In the following line adjust the value of External High Speed oscillator (HSE) + used in your application + + Tip: To avoid modifying this file each time you need to use different HSE, you + can define the HSE value in your toolchain compiler preprocessor. + */ +#if !defined HSE_Value + #ifdef STM32F10X_CL + #define HSE_Value ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ + #else + #define HSE_Value ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ + #endif /* STM32F10X_CL */ +#endif /* HSE_Value */ + + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + Timeout value + */ +#define HSEStartUp_TimeOut ((uint16_t)0x0500) /*!< Time out for HSE start up */ + +#define HSI_Value ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ + +/** + * @brief STM32F10x Standard Peripheral Library version number + */ +#define __STM32F10X_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:16] STM32F10x Standard Peripheral Library main version */ +#define __STM32F10X_STDPERIPH_VERSION_SUB1 (0x01) /*!< [15:8] STM32F10x Standard Peripheral Library sub1 version */ +#define __STM32F10X_STDPERIPH_VERSION_SUB2 (0x00) /*!< [7:0] STM32F10x Standard Peripheral Library sub2 version */ +#define __STM32F10X_STDPERIPH_VERSION ((__STM32F10X_STDPERIPH_VERSION_MAIN << 16)\ + | (__STM32F10X_STDPERIPH_VERSION_SUB1 << 8)\ + | __STM32F10X_STDPERIPH_VERSION_SUB2) + +/** + * @} + */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief Configuration of the Cortex-M3 Processor and Core Peripherals + */ +#define __MPU_PRESENT 0 /*!< STM32 does not provide an MPU */ +#define __NVIC_PRIO_BITS 4 /*!< STM32 uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * @brief STM32F10x Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ +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 */ + +/****** STM32 specific Interrupt Numbers *********************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ + TAMPER_IRQn = 2, /*!< Tamper Interrupt */ + RTC_IRQn = 3, /*!< RTC global Interrupt */ + FLASH_IRQn = 4, /*!< FLASH global Interrupt */ + RCC_IRQn = 5, /*!< RCC global Interrupt */ + EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ + EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ + EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ + EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ + EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ + DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */ + DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */ + DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */ + DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */ + DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */ + DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */ + DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */ + ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ + +#ifdef STM32F10X_LD + USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ + USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ + TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ + TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ +#endif /* STM32F10X_LD */ + +#ifdef STM32F10X_MD + USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ + USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ + TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ + TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ +#endif /* STM32F10X_MD */ + +#ifdef STM32F10X_HD + USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ + USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ + TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ + TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ + TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */ + TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */ + TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt */ + TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ + ADC3_IRQn = 47, /*!< ADC3 global Interrupt */ + FSMC_IRQn = 48, /*!< FSMC global Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_IRQn = 54, /*!< TIM6 global Interrupt */ + TIM7_IRQn = 55, /*!< TIM7 global Interrupt */ + DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */ + DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */ + DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */ + DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */ +#endif /* STM32F10X_HD */ + +#ifdef STM32F10X_CL + CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ + CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ + TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ + TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS WakeUp from suspend through EXTI Line Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_IRQn = 54, /*!< TIM6 global Interrupt */ + TIM7_IRQn = 55, /*!< TIM7 global Interrupt */ + DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */ + DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */ + DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */ + DMA2_Channel4_IRQn = 59, /*!< DMA2 Channel 4 global Interrupt */ + DMA2_Channel5_IRQn = 60, /*!< DMA2 Channel 5 global Interrupt */ + ETH_IRQn = 61, /*!< Ethernet global Interrupt */ + ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ + CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ + CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ + CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ + CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ + OTG_FS_IRQn = 67 /*!< USB OTG FS global Interrupt */ +#endif /* STM32F10X_CL */ +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm3.h" +#include "system_stm32f10x.h" +#include + +/** @addtogroup Exported_types + * @{ + */ + +/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef const int32_t sc32; /*!< Read Only */ +typedef const int16_t sc16; /*!< Read Only */ +typedef const int8_t sc8; /*!< Read Only */ + +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef __I int32_t vsc32; /*!< Read Only */ +typedef __I int16_t vsc16; /*!< Read Only */ +typedef __I int8_t vsc8; /*!< Read Only */ + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef const uint32_t uc32; /*!< Read Only */ +typedef const uint16_t uc16; /*!< Read Only */ +typedef const uint8_t uc8; /*!< Read Only */ + +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef __I uint32_t vuc32; /*!< Read Only */ +typedef __I uint16_t vuc16; /*!< Read Only */ +typedef __I uint8_t vuc8; /*!< Read Only */ + +#ifndef __cplusplus +typedef enum {FALSE = 0, TRUE = !FALSE} bool; +#endif + +typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; + +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; + +/** + * @} + */ + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t SR; + __IO uint32_t CR1; + __IO uint32_t CR2; + __IO uint32_t SMPR1; + __IO uint32_t SMPR2; + __IO uint32_t JOFR1; + __IO uint32_t JOFR2; + __IO uint32_t JOFR3; + __IO uint32_t JOFR4; + __IO uint32_t HTR; + __IO uint32_t LTR; + __IO uint32_t SQR1; + __IO uint32_t SQR2; + __IO uint32_t SQR3; + __IO uint32_t JSQR; + __IO uint32_t JDR1; + __IO uint32_t JDR2; + __IO uint32_t JDR3; + __IO uint32_t JDR4; + __IO uint32_t DR; +} ADC_TypeDef; + +/** + * @brief Backup Registers + */ + +typedef struct +{ + uint32_t RESERVED0; + __IO uint16_t DR1; + uint16_t RESERVED1; + __IO uint16_t DR2; + uint16_t RESERVED2; + __IO uint16_t DR3; + uint16_t RESERVED3; + __IO uint16_t DR4; + uint16_t RESERVED4; + __IO uint16_t DR5; + uint16_t RESERVED5; + __IO uint16_t DR6; + uint16_t RESERVED6; + __IO uint16_t DR7; + uint16_t RESERVED7; + __IO uint16_t DR8; + uint16_t RESERVED8; + __IO uint16_t DR9; + uint16_t RESERVED9; + __IO uint16_t DR10; + uint16_t RESERVED10; + __IO uint16_t RTCCR; + uint16_t RESERVED11; + __IO uint16_t CR; + uint16_t RESERVED12; + __IO uint16_t CSR; + uint16_t RESERVED13[5]; + __IO uint16_t DR11; + uint16_t RESERVED14; + __IO uint16_t DR12; + uint16_t RESERVED15; + __IO uint16_t DR13; + uint16_t RESERVED16; + __IO uint16_t DR14; + uint16_t RESERVED17; + __IO uint16_t DR15; + uint16_t RESERVED18; + __IO uint16_t DR16; + uint16_t RESERVED19; + __IO uint16_t DR17; + uint16_t RESERVED20; + __IO uint16_t DR18; + uint16_t RESERVED21; + __IO uint16_t DR19; + uint16_t RESERVED22; + __IO uint16_t DR20; + uint16_t RESERVED23; + __IO uint16_t DR21; + uint16_t RESERVED24; + __IO uint16_t DR22; + uint16_t RESERVED25; + __IO uint16_t DR23; + uint16_t RESERVED26; + __IO uint16_t DR24; + uint16_t RESERVED27; + __IO uint16_t DR25; + uint16_t RESERVED28; + __IO uint16_t DR26; + uint16_t RESERVED29; + __IO uint16_t DR27; + uint16_t RESERVED30; + __IO uint16_t DR28; + uint16_t RESERVED31; + __IO uint16_t DR29; + uint16_t RESERVED32; + __IO uint16_t DR30; + uint16_t RESERVED33; + __IO uint16_t DR31; + uint16_t RESERVED34; + __IO uint16_t DR32; + uint16_t RESERVED35; + __IO uint16_t DR33; + uint16_t RESERVED36; + __IO uint16_t DR34; + uint16_t RESERVED37; + __IO uint16_t DR35; + uint16_t RESERVED38; + __IO uint16_t DR36; + uint16_t RESERVED39; + __IO uint16_t DR37; + uint16_t RESERVED40; + __IO uint16_t DR38; + uint16_t RESERVED41; + __IO uint16_t DR39; + uint16_t RESERVED42; + __IO uint16_t DR40; + uint16_t RESERVED43; + __IO uint16_t DR41; + uint16_t RESERVED44; + __IO uint16_t DR42; + uint16_t RESERVED45; +} BKP_TypeDef; + +/** + * @brief Controller Area Network TxMailBox + */ + +typedef struct +{ + __IO uint32_t TIR; + __IO uint32_t TDTR; + __IO uint32_t TDLR; + __IO uint32_t TDHR; +} CAN_TxMailBox_TypeDef; + +/** + * @brief Controller Area Network FIFOMailBox + */ + +typedef struct +{ + __IO uint32_t RIR; + __IO uint32_t RDTR; + __IO uint32_t RDLR; + __IO uint32_t RDHR; +} CAN_FIFOMailBox_TypeDef; + +/** + * @brief Controller Area Network FilterRegister + */ + +typedef struct +{ + __IO uint32_t FR1; + __IO uint32_t FR2; +} CAN_FilterRegister_TypeDef; + +/** + * @brief Controller Area Network + */ + +typedef struct +{ + __IO uint32_t MCR; + __IO uint32_t MSR; + __IO uint32_t TSR; + __IO uint32_t RF0R; + __IO uint32_t RF1R; + __IO uint32_t IER; + __IO uint32_t ESR; + __IO uint32_t BTR; + uint32_t RESERVED0[88]; + CAN_TxMailBox_TypeDef sTxMailBox[3]; + CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; + uint32_t RESERVED1[12]; + __IO uint32_t FMR; + __IO uint32_t FM1R; + uint32_t RESERVED2; + __IO uint32_t FS1R; + uint32_t RESERVED3; + __IO uint32_t FFA1R; + uint32_t RESERVED4; + __IO uint32_t FA1R; + uint32_t RESERVED5[8]; +#ifndef STM32F10X_CL + CAN_FilterRegister_TypeDef sFilterRegister[14]; +#else + CAN_FilterRegister_TypeDef sFilterRegister[28]; +#endif /* STM32F10X_CL */ +} CAN_TypeDef; + +/** + * @brief CRC calculation unit + */ + +typedef struct +{ + __IO uint32_t DR; + __IO uint8_t IDR; + uint8_t RESERVED0; + uint16_t RESERVED1; + __IO uint32_t CR; +} CRC_TypeDef; + +/** + * @brief Digital to Analog Converter + */ + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t SWTRIGR; + __IO uint32_t DHR12R1; + __IO uint32_t DHR12L1; + __IO uint32_t DHR8R1; + __IO uint32_t DHR12R2; + __IO uint32_t DHR12L2; + __IO uint32_t DHR8R2; + __IO uint32_t DHR12RD; + __IO uint32_t DHR12LD; + __IO uint32_t DHR8RD; + __IO uint32_t DOR1; + __IO uint32_t DOR2; +} DAC_TypeDef; + +/** + * @brief Debug MCU + */ + +typedef struct +{ + __IO uint32_t IDCODE; + __IO uint32_t CR; +}DBGMCU_TypeDef; + +/** + * @brief DMA Controller + */ + +typedef struct +{ + __IO uint32_t CCR; + __IO uint32_t CNDTR; + __IO uint32_t CPAR; + __IO uint32_t CMAR; +} DMA_Channel_TypeDef; + +typedef struct +{ + __IO uint32_t ISR; + __IO uint32_t IFCR; +} DMA_TypeDef; + +/** + * @brief Ethernet MAC + */ + +typedef struct +{ + __IO uint32_t MACCR; + __IO uint32_t MACFFR; + __IO uint32_t MACHTHR; + __IO uint32_t MACHTLR; + __IO uint32_t MACMIIAR; + __IO uint32_t MACMIIDR; + __IO uint32_t MACFCR; + __IO uint32_t MACVLANTR; /* 8 */ + uint32_t RESERVED0[2]; + __IO uint32_t MACRWUFFR; /* 11 */ + __IO uint32_t MACPMTCSR; + uint32_t RESERVED1[2]; + __IO uint32_t MACSR; /* 15 */ + __IO uint32_t MACIMR; + __IO uint32_t MACA0HR; + __IO uint32_t MACA0LR; + __IO uint32_t MACA1HR; + __IO uint32_t MACA1LR; + __IO uint32_t MACA2HR; + __IO uint32_t MACA2LR; + __IO uint32_t MACA3HR; + __IO uint32_t MACA3LR; /* 24 */ + uint32_t RESERVED2[40]; + __IO uint32_t MMCCR; /* 65 */ + __IO uint32_t MMCRIR; + __IO uint32_t MMCTIR; + __IO uint32_t MMCRIMR; + __IO uint32_t MMCTIMR; /* 69 */ + uint32_t RESERVED3[14]; + __IO uint32_t MMCTGFSCCR; /* 84 */ + __IO uint32_t MMCTGFMSCCR; + uint32_t RESERVED4[5]; + __IO uint32_t MMCTGFCR; + uint32_t RESERVED5[10]; + __IO uint32_t MMCRFCECR; + __IO uint32_t MMCRFAECR; + uint32_t RESERVED6[10]; + __IO uint32_t MMCRGUFCR; + uint32_t RESERVED7[334]; + __IO uint32_t PTPTSCR; + __IO uint32_t PTPSSIR; + __IO uint32_t PTPTSHR; + __IO uint32_t PTPTSLR; + __IO uint32_t PTPTSHUR; + __IO uint32_t PTPTSLUR; + __IO uint32_t PTPTSAR; + __IO uint32_t PTPTTHR; + __IO uint32_t PTPTTLR; + uint32_t RESERVED8[567]; + __IO uint32_t DMABMR; + __IO uint32_t DMATPDR; + __IO uint32_t DMARPDR; + __IO uint32_t DMARDLAR; + __IO uint32_t DMATDLAR; + __IO uint32_t DMASR; + __IO uint32_t DMAOMR; + __IO uint32_t DMAIER; + __IO uint32_t DMAMFBOCR; + uint32_t RESERVED9[9]; + __IO uint32_t DMACHTDR; + __IO uint32_t DMACHRDR; + __IO uint32_t DMACHTBAR; + __IO uint32_t DMACHRBAR; +} ETH_TypeDef; + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ + __IO uint32_t IMR; + __IO uint32_t EMR; + __IO uint32_t RTSR; + __IO uint32_t FTSR; + __IO uint32_t SWIER; + __IO uint32_t PR; +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ + +typedef struct +{ + __IO uint32_t ACR; + __IO uint32_t KEYR; + __IO uint32_t OPTKEYR; + __IO uint32_t SR; + __IO uint32_t CR; + __IO uint32_t AR; + __IO uint32_t RESERVED; + __IO uint32_t OBR; + __IO uint32_t WRPR; +} FLASH_TypeDef; + +/** + * @brief Option Bytes Registers + */ + +typedef struct +{ + __IO uint16_t RDP; + __IO uint16_t USER; + __IO uint16_t Data0; + __IO uint16_t Data1; + __IO uint16_t WRP0; + __IO uint16_t WRP1; + __IO uint16_t WRP2; + __IO uint16_t WRP3; +} OB_TypeDef; + +/** + * @brief Flexible Static Memory Controller + */ + +typedef struct +{ + __IO uint32_t BTCR[8]; +} FSMC_Bank1_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank1E + */ + +typedef struct +{ + __IO uint32_t BWTR[7]; +} FSMC_Bank1E_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank2 + */ + +typedef struct +{ + __IO uint32_t PCR2; + __IO uint32_t SR2; + __IO uint32_t PMEM2; + __IO uint32_t PATT2; + uint32_t RESERVED0; + __IO uint32_t ECCR2; +} FSMC_Bank2_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank3 + */ + +typedef struct +{ + __IO uint32_t PCR3; + __IO uint32_t SR3; + __IO uint32_t PMEM3; + __IO uint32_t PATT3; + uint32_t RESERVED0; + __IO uint32_t ECCR3; +} FSMC_Bank3_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank4 + */ + +typedef struct +{ + __IO uint32_t PCR4; + __IO uint32_t SR4; + __IO uint32_t PMEM4; + __IO uint32_t PATT4; + __IO uint32_t PIO4; +} FSMC_Bank4_TypeDef; + +/** + * @brief General Purpose I/O + */ + +typedef struct +{ + __IO uint32_t CRL; + __IO uint32_t CRH; + __IO uint32_t IDR; + __IO uint32_t ODR; + __IO uint32_t BSRR; + __IO uint32_t BRR; + __IO uint32_t LCKR; +} GPIO_TypeDef; + +/** + * @brief Alternate Function I/O + */ + +typedef struct +{ + __IO uint32_t EVCR; + __IO uint32_t MAPR; + __IO uint32_t EXTICR[4]; +} AFIO_TypeDef; +/** + * @brief Inter-integrated Circuit Interface + */ + +typedef struct +{ + __IO uint16_t CR1; + uint16_t RESERVED0; + __IO uint16_t CR2; + uint16_t RESERVED1; + __IO uint16_t OAR1; + uint16_t RESERVED2; + __IO uint16_t OAR2; + uint16_t RESERVED3; + __IO uint16_t DR; + uint16_t RESERVED4; + __IO uint16_t SR1; + uint16_t RESERVED5; + __IO uint16_t SR2; + uint16_t RESERVED6; + __IO uint16_t CCR; + uint16_t RESERVED7; + __IO uint16_t TRISE; + uint16_t RESERVED8; +} I2C_TypeDef; + +/** + * @brief Independent WATCHDOG + */ + +typedef struct +{ + __IO uint32_t KR; + __IO uint32_t PR; + __IO uint32_t RLR; + __IO uint32_t SR; +} IWDG_TypeDef; + +/** + * @brief Power Control + */ + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t CSR; +} PWR_TypeDef; + +/** + * @brief Reset and Clock Control + */ + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t CFGR; + __IO uint32_t CIR; + __IO uint32_t APB2RSTR; + __IO uint32_t APB1RSTR; + __IO uint32_t AHBENR; + __IO uint32_t APB2ENR; + __IO uint32_t APB1ENR; + __IO uint32_t BDCR; + __IO uint32_t CSR; +#ifdef STM32F10X_CL + __IO uint32_t AHBRSTR; + __IO uint32_t CFGR2; +#endif /* STM32F10X_CL */ +} RCC_TypeDef; + +/** + * @brief Real-Time Clock + */ + +typedef struct +{ + __IO uint16_t CRH; + uint16_t RESERVED0; + __IO uint16_t CRL; + uint16_t RESERVED1; + __IO uint16_t PRLH; + uint16_t RESERVED2; + __IO uint16_t PRLL; + uint16_t RESERVED3; + __IO uint16_t DIVH; + uint16_t RESERVED4; + __IO uint16_t DIVL; + uint16_t RESERVED5; + __IO uint16_t CNTH; + uint16_t RESERVED6; + __IO uint16_t CNTL; + uint16_t RESERVED7; + __IO uint16_t ALRH; + uint16_t RESERVED8; + __IO uint16_t ALRL; + uint16_t RESERVED9; +} RTC_TypeDef; + +/** + * @brief SD host Interface + */ + +typedef struct +{ + __IO uint32_t POWER; + __IO uint32_t CLKCR; + __IO uint32_t ARG; + __IO uint32_t CMD; + __I uint32_t RESPCMD; + __I uint32_t RESP1; + __I uint32_t RESP2; + __I uint32_t RESP3; + __I uint32_t RESP4; + __IO uint32_t DTIMER; + __IO uint32_t DLEN; + __IO uint32_t DCTRL; + __I uint32_t DCOUNT; + __I uint32_t STA; + __IO uint32_t ICR; + __IO uint32_t MASK; + uint32_t RESERVED0[2]; + __I uint32_t FIFOCNT; + uint32_t RESERVED1[13]; + __IO uint32_t FIFO; +} SDIO_TypeDef; + +/** + * @brief Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint16_t CR1; + uint16_t RESERVED0; + __IO uint16_t CR2; + uint16_t RESERVED1; + __IO uint16_t SR; + uint16_t RESERVED2; + __IO uint16_t DR; + uint16_t RESERVED3; + __IO uint16_t CRCPR; + uint16_t RESERVED4; + __IO uint16_t RXCRCR; + uint16_t RESERVED5; + __IO uint16_t TXCRCR; + uint16_t RESERVED6; + __IO uint16_t I2SCFGR; + uint16_t RESERVED7; + __IO uint16_t I2SPR; + uint16_t RESERVED8; +} SPI_TypeDef; + +/** + * @brief TIM + */ + +typedef struct +{ + __IO uint16_t CR1; + uint16_t RESERVED0; + __IO uint16_t CR2; + uint16_t RESERVED1; + __IO uint16_t SMCR; + uint16_t RESERVED2; + __IO uint16_t DIER; + uint16_t RESERVED3; + __IO uint16_t SR; + uint16_t RESERVED4; + __IO uint16_t EGR; + uint16_t RESERVED5; + __IO uint16_t CCMR1; + uint16_t RESERVED6; + __IO uint16_t CCMR2; + uint16_t RESERVED7; + __IO uint16_t CCER; + uint16_t RESERVED8; + __IO uint16_t CNT; + uint16_t RESERVED9; + __IO uint16_t PSC; + uint16_t RESERVED10; + __IO uint16_t ARR; + uint16_t RESERVED11; + __IO uint16_t RCR; + uint16_t RESERVED12; + __IO uint16_t CCR1; + uint16_t RESERVED13; + __IO uint16_t CCR2; + uint16_t RESERVED14; + __IO uint16_t CCR3; + uint16_t RESERVED15; + __IO uint16_t CCR4; + uint16_t RESERVED16; + __IO uint16_t BDTR; + uint16_t RESERVED17; + __IO uint16_t DCR; + uint16_t RESERVED18; + __IO uint16_t DMAR; + uint16_t RESERVED19; +} TIM_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ + +typedef struct +{ + __IO uint16_t SR; + uint16_t RESERVED0; + __IO uint16_t DR; + uint16_t RESERVED1; + __IO uint16_t BRR; + uint16_t RESERVED2; + __IO uint16_t CR1; + uint16_t RESERVED3; + __IO uint16_t CR2; + uint16_t RESERVED4; + __IO uint16_t CR3; + uint16_t RESERVED5; + __IO uint16_t GTPR; + uint16_t RESERVED6; +} USART_TypeDef; + +/** + * @brief Window WATCHDOG + */ + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t CFR; + __IO uint32_t SR; +} WWDG_TypeDef; + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ + +#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the alias region */ +#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the alias region */ + +#define SRAM_BASE ((uint32_t)0x20000000) /*!< Peripheral base address in the bit-band region */ +#define PERIPH_BASE ((uint32_t)0x40000000) /*!< SRAM base address in the bit-band region */ + +#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) + +#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) +#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) +#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) +#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) +#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) +#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) +#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) +#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) +#define BKP_BASE (APB1PERIPH_BASE + 0x6C00) +#define PWR_BASE (APB1PERIPH_BASE + 0x7000) +#define DAC_BASE (APB1PERIPH_BASE + 0x7400) + +#define AFIO_BASE (APB2PERIPH_BASE + 0x0000) +#define EXTI_BASE (APB2PERIPH_BASE + 0x0400) +#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) +#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) +#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) +#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) +#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) +#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00) +#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2400) +#define ADC2_BASE (APB2PERIPH_BASE + 0x2800) +#define TIM1_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define TIM8_BASE (APB2PERIPH_BASE + 0x3400) +#define USART1_BASE (APB2PERIPH_BASE + 0x3800) +#define ADC3_BASE (APB2PERIPH_BASE + 0x3C00) + +#define SDIO_BASE (PERIPH_BASE + 0x18000) + +#define DMA1_BASE (AHBPERIPH_BASE + 0x0000) +#define DMA1_Channel1_BASE (AHBPERIPH_BASE + 0x0008) +#define DMA1_Channel2_BASE (AHBPERIPH_BASE + 0x001C) +#define DMA1_Channel3_BASE (AHBPERIPH_BASE + 0x0030) +#define DMA1_Channel4_BASE (AHBPERIPH_BASE + 0x0044) +#define DMA1_Channel5_BASE (AHBPERIPH_BASE + 0x0058) +#define DMA1_Channel6_BASE (AHBPERIPH_BASE + 0x006C) +#define DMA1_Channel7_BASE (AHBPERIPH_BASE + 0x0080) +#define DMA2_BASE (AHBPERIPH_BASE + 0x0400) +#define DMA2_Channel1_BASE (AHBPERIPH_BASE + 0x0408) +#define DMA2_Channel2_BASE (AHBPERIPH_BASE + 0x041C) +#define DMA2_Channel3_BASE (AHBPERIPH_BASE + 0x0430) +#define DMA2_Channel4_BASE (AHBPERIPH_BASE + 0x0444) +#define DMA2_Channel5_BASE (AHBPERIPH_BASE + 0x0458) +#define RCC_BASE (AHBPERIPH_BASE + 0x1000) +#define CRC_BASE (AHBPERIPH_BASE + 0x3000) + +#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000) /*!< Flash registers base address */ +#define OB_BASE ((uint32_t)0x1FFFF800) /*!< Flash Option Bytes base address */ + +#define ETH_BASE (AHBPERIPH_BASE + 0x8000) +#define ETH_MAC_BASE (ETH_BASE) +#define ETH_MMC_BASE (ETH_BASE + 0x0100) +#define ETH_PTP_BASE (ETH_BASE + 0x0700) +#define ETH_DMA_BASE (ETH_BASE + 0x1000) + +#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) /*!< FSMC Bank1 registers base address */ +#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) /*!< FSMC Bank1E registers base address */ +#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) /*!< FSMC Bank2 registers base address */ +#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) /*!< FSMC Bank3 registers base address */ +#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) /*!< FSMC Bank4 registers base address */ + +#define DBGMCU_BASE ((uint32_t)0xE0042000) /*!< Debug MCU registers base address */ + +/** + * @} + */ + +/** @addtogroup Peripheral_declaration + * @{ + */ + +#define TIM2 ((TIM_TypeDef *) TIM2_BASE) +#define TIM3 ((TIM_TypeDef *) TIM3_BASE) +#define TIM4 ((TIM_TypeDef *) TIM4_BASE) +#define TIM5 ((TIM_TypeDef *) TIM5_BASE) +#define TIM6 ((TIM_TypeDef *) TIM6_BASE) +#define TIM7 ((TIM_TypeDef *) TIM7_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define UART4 ((USART_TypeDef *) UART4_BASE) +#define UART5 ((USART_TypeDef *) UART5_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define CAN1 ((CAN_TypeDef *) CAN1_BASE) +#define CAN2 ((CAN_TypeDef *) CAN2_BASE) +#define BKP ((BKP_TypeDef *) BKP_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define DAC ((DAC_TypeDef *) DAC_BASE) +#define AFIO ((AFIO_TypeDef *) AFIO_BASE) +#define EXTI ((EXTI_TypeDef *) EXTI_BASE) +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) +#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) +#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADC2 ((ADC_TypeDef *) ADC2_BASE) +#define TIM1 ((TIM_TypeDef *) TIM1_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define TIM8 ((TIM_TypeDef *) TIM8_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define ADC3 ((ADC_TypeDef *) ADC3_BASE) +#define SDIO ((SDIO_TypeDef *) SDIO_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_BASE) +#define DMA2 ((DMA_TypeDef *) DMA2_BASE) +#define DMA1_Channel1 ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE) +#define DMA1_Channel2 ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE) +#define DMA1_Channel3 ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE) +#define DMA1_Channel4 ((DMA_Channel_TypeDef *) DMA1_Channel4_BASE) +#define DMA1_Channel5 ((DMA_Channel_TypeDef *) DMA1_Channel5_BASE) +#define DMA1_Channel6 ((DMA_Channel_TypeDef *) DMA1_Channel6_BASE) +#define DMA1_Channel7 ((DMA_Channel_TypeDef *) DMA1_Channel7_BASE) +#define DMA2_Channel1 ((DMA_Channel_TypeDef *) DMA2_Channel1_BASE) +#define DMA2_Channel2 ((DMA_Channel_TypeDef *) DMA2_Channel2_BASE) +#define DMA2_Channel3 ((DMA_Channel_TypeDef *) DMA2_Channel3_BASE) +#define DMA2_Channel4 ((DMA_Channel_TypeDef *) DMA2_Channel4_BASE) +#define DMA2_Channel5 ((DMA_Channel_TypeDef *) DMA2_Channel5_BASE) +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define OB ((OB_TypeDef *) OB_BASE) +#define ETH ((ETH_TypeDef *) ETH_BASE) +#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) +#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) +#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE) +#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE) +#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE) +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +/** + * @} + */ + +/** @addtogroup Exported_constants + * @{ + */ + + /** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + +/******************************************************************************/ +/* Peripheral Registers_Bits_Definition */ +/******************************************************************************/ + +/******************************************************************************/ +/* */ +/* CRC calculation unit */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for CRC_DR register *********************/ +#define CRC_DR_DR ((uint32_t)0xFFFFFFFF) /*!< Data register bits */ + + +/******************* Bit definition for CRC_IDR register ********************/ +#define CRC_IDR_IDR ((uint8_t)0xFF) /*!< General-purpose 8-bit data register bits */ + + +/******************** Bit definition for CRC_CR register ********************/ +#define CRC_CR_RESET ((uint8_t)0x01) /*!< RESET bit */ + +/******************************************************************************/ +/* */ +/* Power Control */ +/* */ +/******************************************************************************/ + +/******************** Bit definition for PWR_CR register ********************/ +#define PWR_CR_LPDS ((uint16_t)0x0001) /*!< Low-Power Deepsleep */ +#define PWR_CR_PDDS ((uint16_t)0x0002) /*!< Power Down Deepsleep */ +#define PWR_CR_CWUF ((uint16_t)0x0004) /*!< Clear Wakeup Flag */ +#define PWR_CR_CSBF ((uint16_t)0x0008) /*!< Clear Standby Flag */ +#define PWR_CR_PVDE ((uint16_t)0x0010) /*!< Power Voltage Detector Enable */ + +#define PWR_CR_PLS ((uint16_t)0x00E0) /*!< PLS[2:0] bits (PVD Level Selection) */ +#define PWR_CR_PLS_0 ((uint16_t)0x0020) /*!< Bit 0 */ +#define PWR_CR_PLS_1 ((uint16_t)0x0040) /*!< Bit 1 */ +#define PWR_CR_PLS_2 ((uint16_t)0x0080) /*!< Bit 2 */ + +/*!< PVD level configuration */ +#define PWR_CR_PLS_2V2 ((uint16_t)0x0000) /*!< PVD level 2.2V */ +#define PWR_CR_PLS_2V3 ((uint16_t)0x0020) /*!< PVD level 2.3V */ +#define PWR_CR_PLS_2V4 ((uint16_t)0x0040) /*!< PVD level 2.4V */ +#define PWR_CR_PLS_2V5 ((uint16_t)0x0060) /*!< PVD level 2.5V */ +#define PWR_CR_PLS_2V6 ((uint16_t)0x0080) /*!< PVD level 2.6V */ +#define PWR_CR_PLS_2V7 ((uint16_t)0x00A0) /*!< PVD level 2.7V */ +#define PWR_CR_PLS_2V8 ((uint16_t)0x00C0) /*!< PVD level 2.8V */ +#define PWR_CR_PLS_2V9 ((uint16_t)0x00E0) /*!< PVD level 2.9V */ + +#define PWR_CR_DBP ((uint16_t)0x0100) /*!< Disable Backup Domain write protection */ + + +/******************* Bit definition for PWR_CSR register ********************/ +#define PWR_CSR_WUF ((uint16_t)0x0001) /*!< Wakeup Flag */ +#define PWR_CSR_SBF ((uint16_t)0x0002) /*!< Standby Flag */ +#define PWR_CSR_PVDO ((uint16_t)0x0004) /*!< PVD Output */ +#define PWR_CSR_EWUP ((uint16_t)0x0100) /*!< Enable WKUP pin */ + +/******************************************************************************/ +/* */ +/* Backup registers */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for BKP_DR1 register ********************/ +#define BKP_DR1_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR2 register ********************/ +#define BKP_DR2_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR3 register ********************/ +#define BKP_DR3_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR4 register ********************/ +#define BKP_DR4_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR5 register ********************/ +#define BKP_DR5_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR6 register ********************/ +#define BKP_DR6_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR7 register ********************/ +#define BKP_DR7_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR8 register ********************/ +#define BKP_DR8_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR9 register ********************/ +#define BKP_DR9_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR10 register *******************/ +#define BKP_DR10_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR11 register *******************/ +#define BKP_DR11_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR12 register *******************/ +#define BKP_DR12_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR13 register *******************/ +#define BKP_DR13_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR14 register *******************/ +#define BKP_DR14_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR15 register *******************/ +#define BKP_DR15_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR16 register *******************/ +#define BKP_DR16_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR17 register *******************/ +#define BKP_DR17_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/****************** Bit definition for BKP_DR18 register ********************/ +#define BKP_DR18_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR19 register *******************/ +#define BKP_DR19_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR20 register *******************/ +#define BKP_DR20_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR21 register *******************/ +#define BKP_DR21_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR22 register *******************/ +#define BKP_DR22_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR23 register *******************/ +#define BKP_DR23_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR24 register *******************/ +#define BKP_DR24_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR25 register *******************/ +#define BKP_DR25_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR26 register *******************/ +#define BKP_DR26_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR27 register *******************/ +#define BKP_DR27_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR28 register *******************/ +#define BKP_DR28_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR29 register *******************/ +#define BKP_DR29_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR30 register *******************/ +#define BKP_DR30_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR31 register *******************/ +#define BKP_DR31_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR32 register *******************/ +#define BKP_DR32_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR33 register *******************/ +#define BKP_DR33_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR34 register *******************/ +#define BKP_DR34_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR35 register *******************/ +#define BKP_DR35_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR36 register *******************/ +#define BKP_DR36_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR37 register *******************/ +#define BKP_DR37_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR38 register *******************/ +#define BKP_DR38_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR39 register *******************/ +#define BKP_DR39_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR40 register *******************/ +#define BKP_DR40_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR41 register *******************/ +#define BKP_DR41_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR42 register *******************/ +#define BKP_DR42_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/****************** Bit definition for BKP_RTCCR register *******************/ +#define BKP_RTCCR_CAL ((uint16_t)0x007F) /*!< Calibration value */ +#define BKP_RTCCR_CCO ((uint16_t)0x0080) /*!< Calibration Clock Output */ +#define BKP_RTCCR_ASOE ((uint16_t)0x0100) /*!< Alarm or Second Output Enable */ +#define BKP_RTCCR_ASOS ((uint16_t)0x0200) /*!< Alarm or Second Output Selection */ + +/******************** Bit definition for BKP_CR register ********************/ +#define BKP_CR_TPE ((uint8_t)0x01) /*!< TAMPER pin enable */ +#define BKP_CR_TPAL ((uint8_t)0x02) /*!< TAMPER pin active level */ + +/******************* Bit definition for BKP_CSR register ********************/ +#define BKP_CSR_CTE ((uint16_t)0x0001) /*!< Clear Tamper event */ +#define BKP_CSR_CTI ((uint16_t)0x0002) /*!< Clear Tamper Interrupt */ +#define BKP_CSR_TPIE ((uint16_t)0x0004) /*!< TAMPER Pin interrupt enable */ +#define BKP_CSR_TEF ((uint16_t)0x0100) /*!< Tamper Event Flag */ +#define BKP_CSR_TIF ((uint16_t)0x0200) /*!< Tamper Interrupt Flag */ + +/******************************************************************************/ +/* */ +/* Reset and Clock Control */ +/* */ +/******************************************************************************/ + +/******************** Bit definition for RCC_CR register ********************/ +#define RCC_CR_HSION ((uint32_t)0x00000001) /*!< Internal High Speed clock enable */ +#define RCC_CR_HSIRDY ((uint32_t)0x00000002) /*!< Internal High Speed clock ready flag */ +#define RCC_CR_HSITRIM ((uint32_t)0x000000F8) /*!< Internal High Speed clock trimming */ +#define RCC_CR_HSICAL ((uint32_t)0x0000FF00) /*!< Internal High Speed clock Calibration */ +#define RCC_CR_HSEON ((uint32_t)0x00010000) /*!< External High Speed clock enable */ +#define RCC_CR_HSERDY ((uint32_t)0x00020000) /*!< External High Speed clock ready flag */ +#define RCC_CR_HSEBYP ((uint32_t)0x00040000) /*!< External High Speed clock Bypass */ +#define RCC_CR_CSSON ((uint32_t)0x00080000) /*!< Clock Security System enable */ +#define RCC_CR_PLLON ((uint32_t)0x01000000) /*!< PLL enable */ +#define RCC_CR_PLLRDY ((uint32_t)0x02000000) /*!< PLL clock ready flag */ + +#ifdef STM32F10X_CL + #define RCC_CR_PLL2ON ((uint32_t)0x04000000) /*!< PLL2 enable */ + #define RCC_CR_PLL2RDY ((uint32_t)0x08000000) /*!< PLL2 clock ready flag */ + #define RCC_CR_PLL3ON ((uint32_t)0x10000000) /*!< PLL3 enable */ + #define RCC_CR_PLL3RDY ((uint32_t)0x20000000) /*!< PLL3 clock ready flag */ +#endif /* STM32F10X_CL */ + +/******************* Bit definition for RCC_CFGR register *******************/ +/*!< SW configuration */ +#define RCC_CFGR_SW ((uint32_t)0x00000003) /*!< SW[1:0] bits (System clock Switch) */ +#define RCC_CFGR_SW_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define RCC_CFGR_SW_1 ((uint32_t)0x00000002) /*!< Bit 1 */ + +#define RCC_CFGR_SW_HSI ((uint32_t)0x00000000) /*!< HSI selected as system clock */ +#define RCC_CFGR_SW_HSE ((uint32_t)0x00000001) /*!< HSE selected as system clock */ +#define RCC_CFGR_SW_PLL ((uint32_t)0x00000002) /*!< PLL selected as system clock */ + +/*!< SWS configuration */ +#define RCC_CFGR_SWS ((uint32_t)0x0000000C) /*!< SWS[1:0] bits (System Clock Switch Status) */ +#define RCC_CFGR_SWS_0 ((uint32_t)0x00000004) /*!< Bit 0 */ +#define RCC_CFGR_SWS_1 ((uint32_t)0x00000008) /*!< Bit 1 */ + +#define RCC_CFGR_SWS_HSI ((uint32_t)0x00000000) /*!< HSI oscillator used as system clock */ +#define RCC_CFGR_SWS_HSE ((uint32_t)0x00000004) /*!< HSE oscillator used as system clock */ +#define RCC_CFGR_SWS_PLL ((uint32_t)0x00000008) /*!< PLL used as system clock */ + +/*!< HPRE configuration */ +#define RCC_CFGR_HPRE ((uint32_t)0x000000F0) /*!< HPRE[3:0] bits (AHB prescaler) */ +#define RCC_CFGR_HPRE_0 ((uint32_t)0x00000010) /*!< Bit 0 */ +#define RCC_CFGR_HPRE_1 ((uint32_t)0x00000020) /*!< Bit 1 */ +#define RCC_CFGR_HPRE_2 ((uint32_t)0x00000040) /*!< Bit 2 */ +#define RCC_CFGR_HPRE_3 ((uint32_t)0x00000080) /*!< Bit 3 */ + +#define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x00000000) /*!< SYSCLK not divided */ +#define RCC_CFGR_HPRE_DIV2 ((uint32_t)0x00000080) /*!< SYSCLK divided by 2 */ +#define RCC_CFGR_HPRE_DIV4 ((uint32_t)0x00000090) /*!< SYSCLK divided by 4 */ +#define RCC_CFGR_HPRE_DIV8 ((uint32_t)0x000000A0) /*!< SYSCLK divided by 8 */ +#define RCC_CFGR_HPRE_DIV16 ((uint32_t)0x000000B0) /*!< SYSCLK divided by 16 */ +#define RCC_CFGR_HPRE_DIV64 ((uint32_t)0x000000C0) /*!< SYSCLK divided by 64 */ +#define RCC_CFGR_HPRE_DIV128 ((uint32_t)0x000000D0) /*!< SYSCLK divided by 128 */ +#define RCC_CFGR_HPRE_DIV256 ((uint32_t)0x000000E0) /*!< SYSCLK divided by 256 */ +#define RCC_CFGR_HPRE_DIV512 ((uint32_t)0x000000F0) /*!< SYSCLK divided by 512 */ + +/*!< PPRE1 configuration */ +#define RCC_CFGR_PPRE1 ((uint32_t)0x00000700) /*!< PRE1[2:0] bits (APB1 prescaler) */ +#define RCC_CFGR_PPRE1_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define RCC_CFGR_PPRE1_1 ((uint32_t)0x00000200) /*!< Bit 1 */ +#define RCC_CFGR_PPRE1_2 ((uint32_t)0x00000400) /*!< Bit 2 */ + +#define RCC_CFGR_PPRE1_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */ +#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400) /*!< HCLK divided by 2 */ +#define RCC_CFGR_PPRE1_DIV4 ((uint32_t)0x00000500) /*!< HCLK divided by 4 */ +#define RCC_CFGR_PPRE1_DIV8 ((uint32_t)0x00000600) /*!< HCLK divided by 8 */ +#define RCC_CFGR_PPRE1_DIV16 ((uint32_t)0x00000700) /*!< HCLK divided by 16 */ + +/*!< PPRE2 configuration */ +#define RCC_CFGR_PPRE2 ((uint32_t)0x00003800) /*!< PRE2[2:0] bits (APB2 prescaler) */ +#define RCC_CFGR_PPRE2_0 ((uint32_t)0x00000800) /*!< Bit 0 */ +#define RCC_CFGR_PPRE2_1 ((uint32_t)0x00001000) /*!< Bit 1 */ +#define RCC_CFGR_PPRE2_2 ((uint32_t)0x00002000) /*!< Bit 2 */ + +#define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */ +#define RCC_CFGR_PPRE2_DIV2 ((uint32_t)0x00002000) /*!< HCLK divided by 2 */ +#define RCC_CFGR_PPRE2_DIV4 ((uint32_t)0x00002800) /*!< HCLK divided by 4 */ +#define RCC_CFGR_PPRE2_DIV8 ((uint32_t)0x00003000) /*!< HCLK divided by 8 */ +#define RCC_CFGR_PPRE2_DIV16 ((uint32_t)0x00003800) /*!< HCLK divided by 16 */ + +/*!< ADCPPRE configuration */ +#define RCC_CFGR_ADCPRE ((uint32_t)0x0000C000) /*!< ADCPRE[1:0] bits (ADC prescaler) */ +#define RCC_CFGR_ADCPRE_0 ((uint32_t)0x00004000) /*!< Bit 0 */ +#define RCC_CFGR_ADCPRE_1 ((uint32_t)0x00008000) /*!< Bit 1 */ + +#define RCC_CFGR_ADCPRE_DIV2 ((uint32_t)0x00000000) /*!< PCLK2 divided by 2 */ +#define RCC_CFGR_ADCPRE_DIV4 ((uint32_t)0x00004000) /*!< PCLK2 divided by 4 */ +#define RCC_CFGR_ADCPRE_DIV6 ((uint32_t)0x00008000) /*!< PCLK2 divided by 6 */ +#define RCC_CFGR_ADCPRE_DIV8 ((uint32_t)0x0000C000) /*!< PCLK2 divided by 8 */ + +#define RCC_CFGR_PLLSRC ((uint32_t)0x00010000) /*!< PLL entry clock source */ + +#define RCC_CFGR_PLLXTPRE ((uint32_t)0x00020000) /*!< HSE divider for PLL entry */ + +/*!< PLLMUL configuration */ +#define RCC_CFGR_PLLMULL ((uint32_t)0x003C0000) /*!< PLLMUL[3:0] bits (PLL multiplication factor) */ +#define RCC_CFGR_PLLMULL_0 ((uint32_t)0x00040000) /*!< Bit 0 */ +#define RCC_CFGR_PLLMULL_1 ((uint32_t)0x00080000) /*!< Bit 1 */ +#define RCC_CFGR_PLLMULL_2 ((uint32_t)0x00100000) /*!< Bit 2 */ +#define RCC_CFGR_PLLMULL_3 ((uint32_t)0x00200000) /*!< Bit 3 */ + +#ifdef STM32F10X_CL + #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */ + #define RCC_CFGR_PLLSRC_PREDIV1 ((uint32_t)0x00010000) /*!< PREDIV1 clock selected as PLL entry clock source */ + + #define RCC_CFGR_PLLXTPRE_PREDIV1 ((uint32_t)0x00000000) /*!< PREDIV1 clock not divided for PLL entry */ + #define RCC_CFGR_PLLXTPRE_PREDIV1_Div2 ((uint32_t)0x00020000) /*!< PREDIV1 clock divided by 2 for PLL entry */ + + #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock * 4 */ + #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock * 5 */ + #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock * 6 */ + #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock * 7 */ + #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock * 8 */ + #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock * 9 */ + #define RCC_CFGR_PLLMULL6_5 ((uint32_t)0x00340000) /*!< PLL input clock * 6.5 */ + + #define RCC_CFGR_OTGFSPRE ((uint32_t)0x00400000) /*!< USB OTG FS prescaler */ + +/*!< MCO configuration */ + #define RCC_CFGR_MCO ((uint32_t)0x0F000000) /*!< MCO[3:0] bits (Microcontroller Clock Output) */ + #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */ + #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */ + #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */ + #define RCC_CFGR_MCO_3 ((uint32_t)0x08000000) /*!< Bit 3 */ + + #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ + #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */ + #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */ + #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */ + #define RCC_CFGR_MCO_PLLCLK_Div2 ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */ + #define RCC_CFGR_MCO_PLL2CLK ((uint32_t)0x08000000) /*!< PLL2 clock selected as MCO source*/ + #define RCC_CFGR_MCO_PLL3CLK_Div2 ((uint32_t)0x09000000) /*!< PLL3 clock divided by 2 selected as MCO source*/ + #define RCC_CFGR_MCO_Ext_HSE ((uint32_t)0x0A000000) /*!< XT1 external 3-25 MHz oscillator clock selected as MCO source */ + #define RCC_CFGR_MCO_PLL3CLK ((uint32_t)0x0B000000) /*!< PLL3 clock selected as MCO source */ +#else + #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */ + #define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000) /*!< HSE clock selected as PLL entry clock source */ + + #define RCC_CFGR_PLLXTPRE_HSE ((uint32_t)0x00000000) /*!< HSE clock not divided for PLL entry */ + #define RCC_CFGR_PLLXTPRE_HSE_Div2 ((uint32_t)0x00020000) /*!< HSE clock divided by 2 for PLL entry */ + + #define RCC_CFGR_PLLMULL2 ((uint32_t)0x00000000) /*!< PLL input clock*2 */ + #define RCC_CFGR_PLLMULL3 ((uint32_t)0x00040000) /*!< PLL input clock*3 */ + #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock*4 */ + #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock*5 */ + #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock*6 */ + #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock*7 */ + #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock*8 */ + #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock*9 */ + #define RCC_CFGR_PLLMULL10 ((uint32_t)0x00200000) /*!< PLL input clock10 */ + #define RCC_CFGR_PLLMULL11 ((uint32_t)0x00240000) /*!< PLL input clock*11 */ + #define RCC_CFGR_PLLMULL12 ((uint32_t)0x00280000) /*!< PLL input clock*12 */ + #define RCC_CFGR_PLLMULL13 ((uint32_t)0x002C0000) /*!< PLL input clock*13 */ + #define RCC_CFGR_PLLMULL14 ((uint32_t)0x00300000) /*!< PLL input clock*14 */ + #define RCC_CFGR_PLLMULL15 ((uint32_t)0x00340000) /*!< PLL input clock*15 */ + #define RCC_CFGR_PLLMULL16 ((uint32_t)0x00380000) /*!< PLL input clock*16 */ + #define RCC_CFGR_USBPRE ((uint32_t)0x00400000) /*!< USB Device prescaler */ + +/*!< MCO configuration */ + #define RCC_CFGR_MCO ((uint32_t)0x07000000) /*!< MCO[2:0] bits (Microcontroller Clock Output) */ + #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */ + #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */ + #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */ + + #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ + #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */ + #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */ + #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */ + #define RCC_CFGR_MCO_PLL ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */ +#endif /* STM32F10X_CL */ + +/*!<****************** Bit definition for RCC_CIR register ********************/ +#define RCC_CIR_LSIRDYF ((uint32_t)0x00000001) /*!< LSI Ready Interrupt flag */ +#define RCC_CIR_LSERDYF ((uint32_t)0x00000002) /*!< LSE Ready Interrupt flag */ +#define RCC_CIR_HSIRDYF ((uint32_t)0x00000004) /*!< HSI Ready Interrupt flag */ +#define RCC_CIR_HSERDYF ((uint32_t)0x00000008) /*!< HSE Ready Interrupt flag */ +#define RCC_CIR_PLLRDYF ((uint32_t)0x00000010) /*!< PLL Ready Interrupt flag */ +#define RCC_CIR_CSSF ((uint32_t)0x00000080) /*!< Clock Security System Interrupt flag */ +#define RCC_CIR_LSIRDYIE ((uint32_t)0x00000100) /*!< LSI Ready Interrupt Enable */ +#define RCC_CIR_LSERDYIE ((uint32_t)0x00000200) /*!< LSE Ready Interrupt Enable */ +#define RCC_CIR_HSIRDYIE ((uint32_t)0x00000400) /*!< HSI Ready Interrupt Enable */ +#define RCC_CIR_HSERDYIE ((uint32_t)0x00000800) /*!< HSE Ready Interrupt Enable */ +#define RCC_CIR_PLLRDYIE ((uint32_t)0x00001000) /*!< PLL Ready Interrupt Enable */ +#define RCC_CIR_LSIRDYC ((uint32_t)0x00010000) /*!< LSI Ready Interrupt Clear */ +#define RCC_CIR_LSERDYC ((uint32_t)0x00020000) /*!< LSE Ready Interrupt Clear */ +#define RCC_CIR_HSIRDYC ((uint32_t)0x00040000) /*!< HSI Ready Interrupt Clear */ +#define RCC_CIR_HSERDYC ((uint32_t)0x00080000) /*!< HSE Ready Interrupt Clear */ +#define RCC_CIR_PLLRDYC ((uint32_t)0x00100000) /*!< PLL Ready Interrupt Clear */ +#define RCC_CIR_CSSC ((uint32_t)0x00800000) /*!< Clock Security System Interrupt Clear */ + +#ifdef STM32F10X_CL + #define RCC_CIR_PLL2RDYF ((uint32_t)0x00000020) /*!< PLL2 Ready Interrupt flag */ + #define RCC_CIR_PLL3RDYF ((uint32_t)0x00000040) /*!< PLL3 Ready Interrupt flag */ + #define RCC_CIR_PLL2RDYIE ((uint32_t)0x00002000) /*!< PLL2 Ready Interrupt Enable */ + #define RCC_CIR_PLL3RDYIE ((uint32_t)0x00004000) /*!< PLL3 Ready Interrupt Enable */ + #define RCC_CIR_PLL2RDYC ((uint32_t)0x00200000) /*!< PLL2 Ready Interrupt Clear */ + #define RCC_CIR_PLL3RDYC ((uint32_t)0x00400000) /*!< PLL3 Ready Interrupt Clear */ +#endif /* STM32F10X_CL */ + +/***************** Bit definition for RCC_APB2RSTR register *****************/ +#define RCC_APB2RSTR_AFIORST ((uint16_t)0x0001) /*!< Alternate Function I/O reset */ +#define RCC_APB2RSTR_IOPARST ((uint16_t)0x0004) /*!< I/O port A reset */ +#define RCC_APB2RSTR_IOPBRST ((uint16_t)0x0008) /*!< I/O port B reset */ +#define RCC_APB2RSTR_IOPCRST ((uint16_t)0x0010) /*!< I/O port C reset */ +#define RCC_APB2RSTR_IOPDRST ((uint16_t)0x0020) /*!< I/O port D reset */ +#define RCC_APB2RSTR_ADC1RST ((uint16_t)0x0200) /*!< ADC 1 interface reset */ +#define RCC_APB2RSTR_ADC2RST ((uint16_t)0x0400) /*!< ADC 2 interface reset */ +#define RCC_APB2RSTR_TIM1RST ((uint16_t)0x0800) /*!< TIM1 Timer reset */ +#define RCC_APB2RSTR_SPI1RST ((uint16_t)0x1000) /*!< SPI 1 reset */ +#define RCC_APB2RSTR_USART1RST ((uint16_t)0x4000) /*!< USART1 reset */ + +#ifndef STM32F10X_LD + #define RCC_APB2RSTR_IOPERST ((uint16_t)0x0040) /*!< I/O port E reset */ +#endif /* STM32F10X_HD */ + +#ifdef STM32F10X_HD + #define RCC_APB2RSTR_IOPFRST ((uint16_t)0x0080) /*!< I/O port F reset */ + #define RCC_APB2RSTR_IOPGRST ((uint16_t)0x0100) /*!< I/O port G reset */ + #define RCC_APB2RSTR_TIM8RST ((uint16_t)0x2000) /*!< TIM8 Timer reset */ + #define RCC_APB2RSTR_ADC3RST ((uint16_t)0x8000) /*!< ADC3 interface reset */ +#endif /* STM32F10X_HD */ + +/***************** Bit definition for RCC_APB1RSTR register *****************/ +#define RCC_APB1RSTR_TIM2RST ((uint32_t)0x00000001) /*!< Timer 2 reset */ +#define RCC_APB1RSTR_TIM3RST ((uint32_t)0x00000002) /*!< Timer 3 reset */ +#define RCC_APB1RSTR_WWDGRST ((uint32_t)0x00000800) /*!< Window Watchdog reset */ +#define RCC_APB1RSTR_USART2RST ((uint32_t)0x00020000) /*!< USART 2 reset */ +#define RCC_APB1RSTR_I2C1RST ((uint32_t)0x00200000) /*!< I2C 1 reset */ +#define RCC_APB1RSTR_CAN1RST ((uint32_t)0x02000000) /*!< CAN1 reset */ +#define RCC_APB1RSTR_BKPRST ((uint32_t)0x08000000) /*!< Backup interface reset */ +#define RCC_APB1RSTR_PWRRST ((uint32_t)0x10000000) /*!< Power interface reset */ + +#ifndef STM32F10X_LD + #define RCC_APB1RSTR_TIM4RST ((uint32_t)0x00000004) /*!< Timer 4 reset */ + #define RCC_APB1RSTR_SPI2RST ((uint32_t)0x00004000) /*!< SPI 2 reset */ + #define RCC_APB1RSTR_USART3RST ((uint32_t)0x00040000) /*!< RUSART 3 reset */ + #define RCC_APB1RSTR_I2C2RST ((uint32_t)0x00400000) /*!< I2C 2 reset */ +#endif /* STM32F10X_HD */ + +#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD) + #define RCC_APB1RSTR_USBRST ((uint32_t)0x00800000) /*!< USB Device reset */ +#endif + +#if defined (STM32F10X_HD) || defined (STM32F10X_CL) + #define RCC_APB1RSTR_TIM5RST ((uint32_t)0x00000008) /*!< Timer 5 reset */ + #define RCC_APB1RSTR_TIM6RST ((uint32_t)0x00000010) /*!< Timer 6 reset */ + #define RCC_APB1RSTR_TIM7RST ((uint32_t)0x00000020) /*!< Timer 7 reset */ + #define RCC_APB1RSTR_SPI3RST ((uint32_t)0x00008000) /*!< SPI 3 reset */ + #define RCC_APB1RSTR_UART4RST ((uint32_t)0x00080000) /*!< UART 4 reset */ + #define RCC_APB1RSTR_UART5RST ((uint32_t)0x00100000) /*!< UART 5 reset */ + #define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */ +#endif + +#ifdef STM32F10X_CL + #define RCC_APB1RSTR_CAN2RST ((uint32_t)0x08000000) /*!< CAN2 reset */ +#endif /* STM32F10X_CL */ + +/****************** Bit definition for RCC_AHBENR register ******************/ +#define RCC_AHBENR_DMA1EN ((uint16_t)0x0001) /*!< DMA1 clock enable */ +#define RCC_AHBENR_SRAMEN ((uint16_t)0x0004) /*!< SRAM interface clock enable */ +#define RCC_AHBENR_FLITFEN ((uint16_t)0x0010) /*!< FLITF clock enable */ +#define RCC_AHBENR_CRCEN ((uint16_t)0x0040) /*!< CRC clock enable */ + +#if defined (STM32F10X_HD) || defined (STM32F10X_CL) + #define RCC_AHBENR_DMA2EN ((uint16_t)0x0002) /*!< DMA2 clock enable */ +#endif + +#ifdef STM32F10X_HD + #define RCC_AHBENR_FSMCEN ((uint16_t)0x0100) /*!< FSMC clock enable */ + #define RCC_AHBENR_SDIOEN ((uint16_t)0x0400) /*!< SDIO clock enable */ +#endif /* STM32F10X_HD */ + +#ifdef STM32F10X_CL + #define RCC_AHBENR_OTGFSEN ((uint32_t)0x00001000) /*!< USB OTG FS clock enable */ + #define RCC_AHBENR_ETHMACEN ((uint32_t)0x00004000) /*!< ETHERNET MAC clock enable */ + #define RCC_AHBENR_ETHMACTXEN ((uint32_t)0x00008000) /*!< ETHERNET MAC Tx clock enable */ + #define RCC_AHBENR_ETHMACRXEN ((uint32_t)0x00010000) /*!< ETHERNET MAC Rx clock enable */ +#endif /* STM32F10X_CL */ + +/****************** Bit definition for RCC_APB2ENR register *****************/ +#define RCC_APB2ENR_AFIOEN ((uint16_t)0x0001) /*!< Alternate Function I/O clock enable */ +#define RCC_APB2ENR_IOPAEN ((uint16_t)0x0004) /*!< I/O port A clock enable */ +#define RCC_APB2ENR_IOPBEN ((uint16_t)0x0008) /*!< I/O port B clock enable */ +#define RCC_APB2ENR_IOPCEN ((uint16_t)0x0010) /*!< I/O port C clock enable */ +#define RCC_APB2ENR_IOPDEN ((uint16_t)0x0020) /*!< I/O port D clock enable */ +#define RCC_APB2ENR_ADC1EN ((uint16_t)0x0200) /*!< ADC 1 interface clock enable */ +#define RCC_APB2ENR_ADC2EN ((uint16_t)0x0400) /*!< ADC 2 interface clock enable */ +#define RCC_APB2ENR_TIM1EN ((uint16_t)0x0800) /*!< TIM1 Timer clock enable */ +#define RCC_APB2ENR_SPI1EN ((uint16_t)0x1000) /*!< SPI 1 clock enable */ +#define RCC_APB2ENR_USART1EN ((uint16_t)0x4000) /*!< USART1 clock enable */ + +#ifndef STM32F10X_LD + #define RCC_APB2ENR_IOPEEN ((uint16_t)0x0040) /*!< I/O port E clock enable */ +#endif /* STM32F10X_HD */ + +#ifdef STM32F10X_HD + #define RCC_APB2ENR_IOPFEN ((uint16_t)0x0080) /*!< I/O port F clock enable */ + #define RCC_APB2ENR_IOPGEN ((uint16_t)0x0100) /*!< I/O port G clock enable */ + #define RCC_APB2ENR_TIM8EN ((uint16_t)0x2000) /*!< TIM8 Timer clock enable */ + #define RCC_APB2ENR_ADC3EN ((uint16_t)0x8000) /*!< DMA1 clock enable */ +#endif /* STM32F10X_HD */ + +/***************** Bit definition for RCC_APB1ENR register ******************/ +#define RCC_APB1ENR_TIM2EN ((uint32_t)0x00000001) /*!< Timer 2 clock enabled*/ +#define RCC_APB1ENR_TIM3EN ((uint32_t)0x00000002) /*!< Timer 3 clock enable */ +#define RCC_APB1ENR_WWDGEN ((uint32_t)0x00000800) /*!< Window Watchdog clock enable */ +#define RCC_APB1ENR_USART2EN ((uint32_t)0x00020000) /*!< USART 2 clock enable */ +#define RCC_APB1ENR_I2C1EN ((uint32_t)0x00200000) /*!< I2C 1 clock enable */ +#define RCC_APB1ENR_CAN1EN ((uint32_t)0x02000000) /*!< CAN1 clock enable */ +#define RCC_APB1ENR_BKPEN ((uint32_t)0x08000000) /*!< Backup interface clock enable */ +#define RCC_APB1ENR_PWREN ((uint32_t)0x10000000) /*!< Power interface clock enable */ + +#ifndef STM32F10X_LD + #define RCC_APB1ENR_TIM4EN ((uint32_t)0x00000004) /*!< Timer 4 clock enable */ + #define RCC_APB1ENR_SPI2EN ((uint32_t)0x00004000) /*!< SPI 2 clock enable */ + #define RCC_APB1ENR_USART3EN ((uint32_t)0x00040000) /*!< USART 3 clock enable */ + #define RCC_APB1ENR_I2C2EN ((uint32_t)0x00400000) /*!< I2C 2 clock enable */ +#endif /* STM32F10X_HD */ + +#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD) + #define RCC_APB1ENR_USBEN ((uint32_t)0x00800000) /*!< USB Device clock enable */ +#endif + +#if defined (STM32F10X_HD) || defined (STM32F10X_CL) + #define RCC_APB1ENR_TIM5EN ((uint32_t)0x00000008) /*!< Timer 5 clock enable */ + #define RCC_APB1ENR_TIM6EN ((uint32_t)0x00000010) /*!< Timer 6 clock enable */ + #define RCC_APB1ENR_TIM7EN ((uint32_t)0x00000020) /*!< Timer 7 clock enable */ + #define RCC_APB1ENR_SPI3EN ((uint32_t)0x00008000) /*!< SPI 3 clock enable */ + #define RCC_APB1ENR_UART4EN ((uint32_t)0x00080000) /*!< UART 4 clock enable */ + #define RCC_APB1ENR_UART5EN ((uint32_t)0x00100000) /*!< UART 5 clock enable */ + #define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */ +#endif + +#ifdef STM32F10X_CL + #define RCC_APB1ENR_CAN2EN ((uint32_t)0x08000000) /*!< CAN2 clock enable */ +#endif /* STM32F10X_CL */ + +/******************* Bit definition for RCC_BDCR register *******************/ +#define RCC_BDCR_LSEON ((uint32_t)0x00000001) /*!< External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY ((uint32_t)0x00000002) /*!< External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP ((uint32_t)0x00000004) /*!< External Low Speed oscillator Bypass */ + +#define RCC_BDCR_RTCSEL ((uint32_t)0x00000300) /*!< RTCSEL[1:0] bits (RTC clock source selection) */ +#define RCC_BDCR_RTCSEL_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define RCC_BDCR_RTCSEL_1 ((uint32_t)0x00000200) /*!< Bit 1 */ + +/*!< RTC congiguration */ +#define RCC_BDCR_RTCSEL_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ +#define RCC_BDCR_RTCSEL_LSE ((uint32_t)0x00000100) /*!< LSE oscillator clock used as RTC clock */ +#define RCC_BDCR_RTCSEL_LSI ((uint32_t)0x00000200) /*!< LSI oscillator clock used as RTC clock */ +#define RCC_BDCR_RTCSEL_HSE ((uint32_t)0x00000300) /*!< HSE oscillator clock divided by 128 used as RTC clock */ + +#define RCC_BDCR_RTCEN ((uint32_t)0x00008000) /*!< RTC clock enable */ +#define RCC_BDCR_BDRST ((uint32_t)0x00010000) /*!< Backup domain software reset */ + +/******************* Bit definition for RCC_CSR register ********************/ +#define RCC_CSR_LSION ((uint32_t)0x00000001) /*!< Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY ((uint32_t)0x00000002) /*!< Internal Low Speed oscillator Ready */ +#define RCC_CSR_RMVF ((uint32_t)0x01000000) /*!< Remove reset flag */ +#define RCC_CSR_PINRSTF ((uint32_t)0x04000000) /*!< PIN reset flag */ +#define RCC_CSR_PORRSTF ((uint32_t)0x08000000) /*!< POR/PDR reset flag */ +#define RCC_CSR_SFTRSTF ((uint32_t)0x10000000) /*!< Software Reset flag */ +#define RCC_CSR_IWDGRSTF ((uint32_t)0x20000000) /*!< Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF ((uint32_t)0x40000000) /*!< Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF ((uint32_t)0x80000000) /*!< Low-Power reset flag */ + +#ifdef STM32F10X_CL +/******************* Bit definition for RCC_AHBRSTR register ****************/ + #define RCC_AHBRSTR_OTGFSRST ((uint32_t)0x00001000) /*!< USB OTG FS reset */ + #define RCC_AHBRSTR_ETHMACRST ((uint32_t)0x00004000) /*!< ETHERNET MAC reset */ + +/******************* Bit definition for RCC_CFGR2 register ******************/ +/*!< PREDIV1 configuration */ + #define RCC_CFGR2_PREDIV1 ((uint32_t)0x0000000F) /*!< PREDIV1[3:0] bits */ + #define RCC_CFGR2_PREDIV1_0 ((uint32_t)0x00000001) /*!< Bit 0 */ + #define RCC_CFGR2_PREDIV1_1 ((uint32_t)0x00000002) /*!< Bit 1 */ + #define RCC_CFGR2_PREDIV1_2 ((uint32_t)0x00000004) /*!< Bit 2 */ + #define RCC_CFGR2_PREDIV1_3 ((uint32_t)0x00000008) /*!< Bit 3 */ + + #define RCC_CFGR2_PREDIV1_DIV1 ((uint32_t)0x00000000) /*!< PREDIV1 input clock not divided */ + #define RCC_CFGR2_PREDIV1_DIV2 ((uint32_t)0x00000001) /*!< PREDIV1 input clock divided by 2 */ + #define RCC_CFGR2_PREDIV1_DIV3 ((uint32_t)0x00000002) /*!< PREDIV1 input clock divided by 3 */ + #define RCC_CFGR2_PREDIV1_DIV4 ((uint32_t)0x00000003) /*!< PREDIV1 input clock divided by 4 */ + #define RCC_CFGR2_PREDIV1_DIV5 ((uint32_t)0x00000004) /*!< PREDIV1 input clock divided by 5 */ + #define RCC_CFGR2_PREDIV1_DIV6 ((uint32_t)0x00000005) /*!< PREDIV1 input clock divided by 6 */ + #define RCC_CFGR2_PREDIV1_DIV7 ((uint32_t)0x00000006) /*!< PREDIV1 input clock divided by 7 */ + #define RCC_CFGR2_PREDIV1_DIV8 ((uint32_t)0x00000007) /*!< PREDIV1 input clock divided by 8 */ + #define RCC_CFGR2_PREDIV1_DIV9 ((uint32_t)0x00000008) /*!< PREDIV1 input clock divided by 9 */ + #define RCC_CFGR2_PREDIV1_DIV10 ((uint32_t)0x00000009) /*!< PREDIV1 input clock divided by 10 */ + #define RCC_CFGR2_PREDIV1_DIV11 ((uint32_t)0x0000000A) /*!< PREDIV1 input clock divided by 11 */ + #define RCC_CFGR2_PREDIV1_DIV12 ((uint32_t)0x0000000B) /*!< PREDIV1 input clock divided by 12 */ + #define RCC_CFGR2_PREDIV1_DIV13 ((uint32_t)0x0000000C) /*!< PREDIV1 input clock divided by 13 */ + #define RCC_CFGR2_PREDIV1_DIV14 ((uint32_t)0x0000000D) /*!< PREDIV1 input clock divided by 14 */ + #define RCC_CFGR2_PREDIV1_DIV15 ((uint32_t)0x0000000E) /*!< PREDIV1 input clock divided by 15 */ + #define RCC_CFGR2_PREDIV1_DIV16 ((uint32_t)0x0000000F) /*!< PREDIV1 input clock divided by 16 */ + +/*!< PREDIV2 configuration */ + #define RCC_CFGR2_PREDIV2 ((uint32_t)0x000000F0) /*!< PREDIV2[3:0] bits */ + #define RCC_CFGR2_PREDIV2_0 ((uint32_t)0x00000010) /*!< Bit 0 */ + #define RCC_CFGR2_PREDIV2_1 ((uint32_t)0x00000020) /*!< Bit 1 */ + #define RCC_CFGR2_PREDIV2_2 ((uint32_t)0x00000040) /*!< Bit 2 */ + #define RCC_CFGR2_PREDIV2_3 ((uint32_t)0x00000080) /*!< Bit 3 */ + + #define RCC_CFGR2_PREDIV2_DIV1 ((uint32_t)0x00000000) /*!< PREDIV2 input clock not divided */ + #define RCC_CFGR2_PREDIV2_DIV2 ((uint32_t)0x00000010) /*!< PREDIV2 input clock divided by 2 */ + #define RCC_CFGR2_PREDIV2_DIV3 ((uint32_t)0x00000020) /*!< PREDIV2 input clock divided by 3 */ + #define RCC_CFGR2_PREDIV2_DIV4 ((uint32_t)0x00000030) /*!< PREDIV2 input clock divided by 4 */ + #define RCC_CFGR2_PREDIV2_DIV5 ((uint32_t)0x00000040) /*!< PREDIV2 input clock divided by 5 */ + #define RCC_CFGR2_PREDIV2_DIV6 ((uint32_t)0x00000050) /*!< PREDIV2 input clock divided by 6 */ + #define RCC_CFGR2_PREDIV2_DIV7 ((uint32_t)0x00000060) /*!< PREDIV2 input clock divided by 7 */ + #define RCC_CFGR2_PREDIV2_DIV8 ((uint32_t)0x00000070) /*!< PREDIV2 input clock divided by 8 */ + #define RCC_CFGR2_PREDIV2_DIV9 ((uint32_t)0x00000080) /*!< PREDIV2 input clock divided by 9 */ + #define RCC_CFGR2_PREDIV2_DIV10 ((uint32_t)0x00000090) /*!< PREDIV2 input clock divided by 10 */ + #define RCC_CFGR2_PREDIV2_DIV11 ((uint32_t)0x000000A0) /*!< PREDIV2 input clock divided by 11 */ + #define RCC_CFGR2_PREDIV2_DIV12 ((uint32_t)0x000000B0) /*!< PREDIV2 input clock divided by 12 */ + #define RCC_CFGR2_PREDIV2_DIV13 ((uint32_t)0x000000C0) /*!< PREDIV2 input clock divided by 13 */ + #define RCC_CFGR2_PREDIV2_DIV14 ((uint32_t)0x000000D0) /*!< PREDIV2 input clock divided by 14 */ + #define RCC_CFGR2_PREDIV2_DIV15 ((uint32_t)0x000000E0) /*!< PREDIV2 input clock divided by 15 */ + #define RCC_CFGR2_PREDIV2_DIV16 ((uint32_t)0x000000F0) /*!< PREDIV2 input clock divided by 16 */ + +/*!< PLL2MUL configuration */ + #define RCC_CFGR2_PLL2MUL ((uint32_t)0x00000F00) /*!< PLL2MUL[3:0] bits */ + #define RCC_CFGR2_PLL2MUL_0 ((uint32_t)0x00000100) /*!< Bit 0 */ + #define RCC_CFGR2_PLL2MUL_1 ((uint32_t)0x00000200) /*!< Bit 1 */ + #define RCC_CFGR2_PLL2MUL_2 ((uint32_t)0x00000400) /*!< Bit 2 */ + #define RCC_CFGR2_PLL2MUL_3 ((uint32_t)0x00000800) /*!< Bit 3 */ + + #define RCC_CFGR2_PLL2MUL8 ((uint32_t)0x00000600) /*!< PLL2 input clock * 8 */ + #define RCC_CFGR2_PLL2MUL9 ((uint32_t)0x00000700) /*!< PLL2 input clock * 9 */ + #define RCC_CFGR2_PLL2MUL10 ((uint32_t)0x00000800) /*!< PLL2 input clock * 10 */ + #define RCC_CFGR2_PLL2MUL11 ((uint32_t)0x00000900) /*!< PLL2 input clock * 11 */ + #define RCC_CFGR2_PLL2MUL12 ((uint32_t)0x00000A00) /*!< PLL2 input clock * 12 */ + #define RCC_CFGR2_PLL2MUL13 ((uint32_t)0x00000B00) /*!< PLL2 input clock * 13 */ + #define RCC_CFGR2_PLL2MUL14 ((uint32_t)0x00000C00) /*!< PLL2 input clock * 14 */ + #define RCC_CFGR2_PLL2MUL16 ((uint32_t)0x00000E00) /*!< PLL2 input clock * 16 */ + #define RCC_CFGR2_PLL2MUL20 ((uint32_t)0x00000F00) /*!< PLL2 input clock * 20 */ + +/*!< PLL3MUL configuration */ + #define RCC_CFGR2_PLL3MUL ((uint32_t)0x0000F000) /*!< PLL3MUL[3:0] bits */ + #define RCC_CFGR2_PLL3MUL_0 ((uint32_t)0x00001000) /*!< Bit 0 */ + #define RCC_CFGR2_PLL3MUL_1 ((uint32_t)0x00002000) /*!< Bit 1 */ + #define RCC_CFGR2_PLL3MUL_2 ((uint32_t)0x00004000) /*!< Bit 2 */ + #define RCC_CFGR2_PLL3MUL_3 ((uint32_t)0x00008000) /*!< Bit 3 */ + + #define RCC_CFGR2_PLL3MUL8 ((uint32_t)0x00006000) /*!< PLL3 input clock * 8 */ + #define RCC_CFGR2_PLL3MUL9 ((uint32_t)0x00007000) /*!< PLL3 input clock * 9 */ + #define RCC_CFGR2_PLL3MUL10 ((uint32_t)0x00008000) /*!< PLL3 input clock * 10 */ + #define RCC_CFGR2_PLL3MUL11 ((uint32_t)0x00009000) /*!< PLL3 input clock * 11 */ + #define RCC_CFGR2_PLL3MUL12 ((uint32_t)0x0000A000) /*!< PLL3 input clock * 12 */ + #define RCC_CFGR2_PLL3MUL13 ((uint32_t)0x0000B000) /*!< PLL3 input clock * 13 */ + #define RCC_CFGR2_PLL3MUL14 ((uint32_t)0x0000C000) /*!< PLL3 input clock * 14 */ + #define RCC_CFGR2_PLL3MUL16 ((uint32_t)0x0000E000) /*!< PLL3 input clock * 16 */ + #define RCC_CFGR2_PLL3MUL20 ((uint32_t)0x0000F000) /*!< PLL3 input clock * 20 */ + + #define RCC_CFGR2_PREDIV1SRC ((uint32_t)0x00010000) /*!< PREDIV1 entry clock source */ + #define RCC_CFGR2_PREDIV1SRC_PLL2 ((uint32_t)0x00010000) /*!< PLL2 selected as PREDIV1 entry clock source */ + #define RCC_CFGR2_PREDIV1SRC_HSE ((uint32_t)0x00000000) /*!< HSE selected as PREDIV1 entry clock source */ + #define RCC_CFGR2_I2S2SRC ((uint32_t)0x00020000) /*!< I2S2 entry clock source */ + #define RCC_CFGR2_I2S3SRC ((uint32_t)0x00040000) /*!< I2S3 clock source */ +#endif /* STM32F10X_CL */ + +/******************************************************************************/ +/* */ +/* General Purpose and Alternate Function I/O */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for GPIO_CRL register *******************/ +#define GPIO_CRL_MODE ((uint32_t)0x33333333) /*!< Port x mode bits */ + +#define GPIO_CRL_MODE0 ((uint32_t)0x00000003) /*!< MODE0[1:0] bits (Port x mode bits, pin 0) */ +#define GPIO_CRL_MODE0_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define GPIO_CRL_MODE0_1 ((uint32_t)0x00000002) /*!< Bit 1 */ + +#define GPIO_CRL_MODE1 ((uint32_t)0x00000030) /*!< MODE1[1:0] bits (Port x mode bits, pin 1) */ +#define GPIO_CRL_MODE1_0 ((uint32_t)0x00000010) /*!< Bit 0 */ +#define GPIO_CRL_MODE1_1 ((uint32_t)0x00000020) /*!< Bit 1 */ + +#define GPIO_CRL_MODE2 ((uint32_t)0x00000300) /*!< MODE2[1:0] bits (Port x mode bits, pin 2) */ +#define GPIO_CRL_MODE2_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define GPIO_CRL_MODE2_1 ((uint32_t)0x00000200) /*!< Bit 1 */ + +#define GPIO_CRL_MODE3 ((uint32_t)0x00003000) /*!< MODE3[1:0] bits (Port x mode bits, pin 3) */ +#define GPIO_CRL_MODE3_0 ((uint32_t)0x00001000) /*!< Bit 0 */ +#define GPIO_CRL_MODE3_1 ((uint32_t)0x00002000) /*!< Bit 1 */ + +#define GPIO_CRL_MODE4 ((uint32_t)0x00030000) /*!< MODE4[1:0] bits (Port x mode bits, pin 4) */ +#define GPIO_CRL_MODE4_0 ((uint32_t)0x00010000) /*!< Bit 0 */ +#define GPIO_CRL_MODE4_1 ((uint32_t)0x00020000) /*!< Bit 1 */ + +#define GPIO_CRL_MODE5 ((uint32_t)0x00300000) /*!< MODE5[1:0] bits (Port x mode bits, pin 5) */ +#define GPIO_CRL_MODE5_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define GPIO_CRL_MODE5_1 ((uint32_t)0x00200000) /*!< Bit 1 */ + +#define GPIO_CRL_MODE6 ((uint32_t)0x03000000) /*!< MODE6[1:0] bits (Port x mode bits, pin 6) */ +#define GPIO_CRL_MODE6_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define GPIO_CRL_MODE6_1 ((uint32_t)0x02000000) /*!< Bit 1 */ + +#define GPIO_CRL_MODE7 ((uint32_t)0x30000000) /*!< MODE7[1:0] bits (Port x mode bits, pin 7) */ +#define GPIO_CRL_MODE7_0 ((uint32_t)0x10000000) /*!< Bit 0 */ +#define GPIO_CRL_MODE7_1 ((uint32_t)0x20000000) /*!< Bit 1 */ + +#define GPIO_CRL_CNF ((uint32_t)0xCCCCCCCC) /*!< Port x configuration bits */ + +#define GPIO_CRL_CNF0 ((uint32_t)0x0000000C) /*!< CNF0[1:0] bits (Port x configuration bits, pin 0) */ +#define GPIO_CRL_CNF0_0 ((uint32_t)0x00000004) /*!< Bit 0 */ +#define GPIO_CRL_CNF0_1 ((uint32_t)0x00000008) /*!< Bit 1 */ + +#define GPIO_CRL_CNF1 ((uint32_t)0x000000C0) /*!< CNF1[1:0] bits (Port x configuration bits, pin 1) */ +#define GPIO_CRL_CNF1_0 ((uint32_t)0x00000040) /*!< Bit 0 */ +#define GPIO_CRL_CNF1_1 ((uint32_t)0x00000080) /*!< Bit 1 */ + +#define GPIO_CRL_CNF2 ((uint32_t)0x00000C00) /*!< CNF2[1:0] bits (Port x configuration bits, pin 2) */ +#define GPIO_CRL_CNF2_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define GPIO_CRL_CNF2_1 ((uint32_t)0x00000800) /*!< Bit 1 */ + +#define GPIO_CRL_CNF3 ((uint32_t)0x0000C000) /*!< CNF3[1:0] bits (Port x configuration bits, pin 3) */ +#define GPIO_CRL_CNF3_0 ((uint32_t)0x00004000) /*!< Bit 0 */ +#define GPIO_CRL_CNF3_1 ((uint32_t)0x00008000) /*!< Bit 1 */ + +#define GPIO_CRL_CNF4 ((uint32_t)0x000C0000) /*!< CNF4[1:0] bits (Port x configuration bits, pin 4) */ +#define GPIO_CRL_CNF4_0 ((uint32_t)0x00040000) /*!< Bit 0 */ +#define GPIO_CRL_CNF4_1 ((uint32_t)0x00080000) /*!< Bit 1 */ + +#define GPIO_CRL_CNF5 ((uint32_t)0x00C00000) /*!< CNF5[1:0] bits (Port x configuration bits, pin 5) */ +#define GPIO_CRL_CNF5_0 ((uint32_t)0x00400000) /*!< Bit 0 */ +#define GPIO_CRL_CNF5_1 ((uint32_t)0x00800000) /*!< Bit 1 */ + +#define GPIO_CRL_CNF6 ((uint32_t)0x0C000000) /*!< CNF6[1:0] bits (Port x configuration bits, pin 6) */ +#define GPIO_CRL_CNF6_0 ((uint32_t)0x04000000) /*!< Bit 0 */ +#define GPIO_CRL_CNF6_1 ((uint32_t)0x08000000) /*!< Bit 1 */ + +#define GPIO_CRL_CNF7 ((uint32_t)0xC0000000) /*!< CNF7[1:0] bits (Port x configuration bits, pin 7) */ +#define GPIO_CRL_CNF7_0 ((uint32_t)0x40000000) /*!< Bit 0 */ +#define GPIO_CRL_CNF7_1 ((uint32_t)0x80000000) /*!< Bit 1 */ + +/******************* Bit definition for GPIO_CRH register *******************/ +#define GPIO_CRH_MODE ((uint32_t)0x33333333) /*!< Port x mode bits */ + +#define GPIO_CRH_MODE8 ((uint32_t)0x00000003) /*!< MODE8[1:0] bits (Port x mode bits, pin 8) */ +#define GPIO_CRH_MODE8_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define GPIO_CRH_MODE8_1 ((uint32_t)0x00000002) /*!< Bit 1 */ + +#define GPIO_CRH_MODE9 ((uint32_t)0x00000030) /*!< MODE9[1:0] bits (Port x mode bits, pin 9) */ +#define GPIO_CRH_MODE9_0 ((uint32_t)0x00000010) /*!< Bit 0 */ +#define GPIO_CRH_MODE9_1 ((uint32_t)0x00000020) /*!< Bit 1 */ + +#define GPIO_CRH_MODE10 ((uint32_t)0x00000300) /*!< MODE10[1:0] bits (Port x mode bits, pin 10) */ +#define GPIO_CRH_MODE10_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define GPIO_CRH_MODE10_1 ((uint32_t)0x00000200) /*!< Bit 1 */ + +#define GPIO_CRH_MODE11 ((uint32_t)0x00003000) /*!< MODE11[1:0] bits (Port x mode bits, pin 11) */ +#define GPIO_CRH_MODE11_0 ((uint32_t)0x00001000) /*!< Bit 0 */ +#define GPIO_CRH_MODE11_1 ((uint32_t)0x00002000) /*!< Bit 1 */ + +#define GPIO_CRH_MODE12 ((uint32_t)0x00030000) /*!< MODE12[1:0] bits (Port x mode bits, pin 12) */ +#define GPIO_CRH_MODE12_0 ((uint32_t)0x00010000) /*!< Bit 0 */ +#define GPIO_CRH_MODE12_1 ((uint32_t)0x00020000) /*!< Bit 1 */ + +#define GPIO_CRH_MODE13 ((uint32_t)0x00300000) /*!< MODE13[1:0] bits (Port x mode bits, pin 13) */ +#define GPIO_CRH_MODE13_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define GPIO_CRH_MODE13_1 ((uint32_t)0x00200000) /*!< Bit 1 */ + +#define GPIO_CRH_MODE14 ((uint32_t)0x03000000) /*!< MODE14[1:0] bits (Port x mode bits, pin 14) */ +#define GPIO_CRH_MODE14_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define GPIO_CRH_MODE14_1 ((uint32_t)0x02000000) /*!< Bit 1 */ + +#define GPIO_CRH_MODE15 ((uint32_t)0x30000000) /*!< MODE15[1:0] bits (Port x mode bits, pin 15) */ +#define GPIO_CRH_MODE15_0 ((uint32_t)0x10000000) /*!< Bit 0 */ +#define GPIO_CRH_MODE15_1 ((uint32_t)0x20000000) /*!< Bit 1 */ + +#define GPIO_CRH_CNF ((uint32_t)0xCCCCCCCC) /*!< Port x configuration bits */ + +#define GPIO_CRH_CNF8 ((uint32_t)0x0000000C) /*!< CNF8[1:0] bits (Port x configuration bits, pin 8) */ +#define GPIO_CRH_CNF8_0 ((uint32_t)0x00000004) /*!< Bit 0 */ +#define GPIO_CRH_CNF8_1 ((uint32_t)0x00000008) /*!< Bit 1 */ + +#define GPIO_CRH_CNF9 ((uint32_t)0x000000C0) /*!< CNF9[1:0] bits (Port x configuration bits, pin 9) */ +#define GPIO_CRH_CNF9_0 ((uint32_t)0x00000040) /*!< Bit 0 */ +#define GPIO_CRH_CNF9_1 ((uint32_t)0x00000080) /*!< Bit 1 */ + +#define GPIO_CRH_CNF10 ((uint32_t)0x00000C00) /*!< CNF10[1:0] bits (Port x configuration bits, pin 10) */ +#define GPIO_CRH_CNF10_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define GPIO_CRH_CNF10_1 ((uint32_t)0x00000800) /*!< Bit 1 */ + +#define GPIO_CRH_CNF11 ((uint32_t)0x0000C000) /*!< CNF11[1:0] bits (Port x configuration bits, pin 11) */ +#define GPIO_CRH_CNF11_0 ((uint32_t)0x00004000) /*!< Bit 0 */ +#define GPIO_CRH_CNF11_1 ((uint32_t)0x00008000) /*!< Bit 1 */ + +#define GPIO_CRH_CNF12 ((uint32_t)0x000C0000) /*!< CNF12[1:0] bits (Port x configuration bits, pin 12) */ +#define GPIO_CRH_CNF12_0 ((uint32_t)0x00040000) /*!< Bit 0 */ +#define GPIO_CRH_CNF12_1 ((uint32_t)0x00080000) /*!< Bit 1 */ + +#define GPIO_CRH_CNF13 ((uint32_t)0x00C00000) /*!< CNF13[1:0] bits (Port x configuration bits, pin 13) */ +#define GPIO_CRH_CNF13_0 ((uint32_t)0x00400000) /*!< Bit 0 */ +#define GPIO_CRH_CNF13_1 ((uint32_t)0x00800000) /*!< Bit 1 */ + +#define GPIO_CRH_CNF14 ((uint32_t)0x0C000000) /*!< CNF14[1:0] bits (Port x configuration bits, pin 14) */ +#define GPIO_CRH_CNF14_0 ((uint32_t)0x04000000) /*!< Bit 0 */ +#define GPIO_CRH_CNF14_1 ((uint32_t)0x08000000) /*!< Bit 1 */ + +#define GPIO_CRH_CNF15 ((uint32_t)0xC0000000) /*!< CNF15[1:0] bits (Port x configuration bits, pin 15) */ +#define GPIO_CRH_CNF15_0 ((uint32_t)0x40000000) /*!< Bit 0 */ +#define GPIO_CRH_CNF15_1 ((uint32_t)0x80000000) /*!< Bit 1 */ + +/*!<****************** Bit definition for GPIO_IDR register *******************/ +#define GPIO_IDR_IDR0 ((uint16_t)0x0001) /*!< Port input data, bit 0 */ +#define GPIO_IDR_IDR1 ((uint16_t)0x0002) /*!< Port input data, bit 1 */ +#define GPIO_IDR_IDR2 ((uint16_t)0x0004) /*!< Port input data, bit 2 */ +#define GPIO_IDR_IDR3 ((uint16_t)0x0008) /*!< Port input data, bit 3 */ +#define GPIO_IDR_IDR4 ((uint16_t)0x0010) /*!< Port input data, bit 4 */ +#define GPIO_IDR_IDR5 ((uint16_t)0x0020) /*!< Port input data, bit 5 */ +#define GPIO_IDR_IDR6 ((uint16_t)0x0040) /*!< Port input data, bit 6 */ +#define GPIO_IDR_IDR7 ((uint16_t)0x0080) /*!< Port input data, bit 7 */ +#define GPIO_IDR_IDR8 ((uint16_t)0x0100) /*!< Port input data, bit 8 */ +#define GPIO_IDR_IDR9 ((uint16_t)0x0200) /*!< Port input data, bit 9 */ +#define GPIO_IDR_IDR10 ((uint16_t)0x0400) /*!< Port input data, bit 10 */ +#define GPIO_IDR_IDR11 ((uint16_t)0x0800) /*!< Port input data, bit 11 */ +#define GPIO_IDR_IDR12 ((uint16_t)0x1000) /*!< Port input data, bit 12 */ +#define GPIO_IDR_IDR13 ((uint16_t)0x2000) /*!< Port input data, bit 13 */ +#define GPIO_IDR_IDR14 ((uint16_t)0x4000) /*!< Port input data, bit 14 */ +#define GPIO_IDR_IDR15 ((uint16_t)0x8000) /*!< Port input data, bit 15 */ + +/******************* Bit definition for GPIO_ODR register *******************/ +#define GPIO_ODR_ODR0 ((uint16_t)0x0001) /*!< Port output data, bit 0 */ +#define GPIO_ODR_ODR1 ((uint16_t)0x0002) /*!< Port output data, bit 1 */ +#define GPIO_ODR_ODR2 ((uint16_t)0x0004) /*!< Port output data, bit 2 */ +#define GPIO_ODR_ODR3 ((uint16_t)0x0008) /*!< Port output data, bit 3 */ +#define GPIO_ODR_ODR4 ((uint16_t)0x0010) /*!< Port output data, bit 4 */ +#define GPIO_ODR_ODR5 ((uint16_t)0x0020) /*!< Port output data, bit 5 */ +#define GPIO_ODR_ODR6 ((uint16_t)0x0040) /*!< Port output data, bit 6 */ +#define GPIO_ODR_ODR7 ((uint16_t)0x0080) /*!< Port output data, bit 7 */ +#define GPIO_ODR_ODR8 ((uint16_t)0x0100) /*!< Port output data, bit 8 */ +#define GPIO_ODR_ODR9 ((uint16_t)0x0200) /*!< Port output data, bit 9 */ +#define GPIO_ODR_ODR10 ((uint16_t)0x0400) /*!< Port output data, bit 10 */ +#define GPIO_ODR_ODR11 ((uint16_t)0x0800) /*!< Port output data, bit 11 */ +#define GPIO_ODR_ODR12 ((uint16_t)0x1000) /*!< Port output data, bit 12 */ +#define GPIO_ODR_ODR13 ((uint16_t)0x2000) /*!< Port output data, bit 13 */ +#define GPIO_ODR_ODR14 ((uint16_t)0x4000) /*!< Port output data, bit 14 */ +#define GPIO_ODR_ODR15 ((uint16_t)0x8000) /*!< Port output data, bit 15 */ + +/****************** Bit definition for GPIO_BSRR register *******************/ +#define GPIO_BSRR_BS0 ((uint32_t)0x00000001) /*!< Port x Set bit 0 */ +#define GPIO_BSRR_BS1 ((uint32_t)0x00000002) /*!< Port x Set bit 1 */ +#define GPIO_BSRR_BS2 ((uint32_t)0x00000004) /*!< Port x Set bit 2 */ +#define GPIO_BSRR_BS3 ((uint32_t)0x00000008) /*!< Port x Set bit 3 */ +#define GPIO_BSRR_BS4 ((uint32_t)0x00000010) /*!< Port x Set bit 4 */ +#define GPIO_BSRR_BS5 ((uint32_t)0x00000020) /*!< Port x Set bit 5 */ +#define GPIO_BSRR_BS6 ((uint32_t)0x00000040) /*!< Port x Set bit 6 */ +#define GPIO_BSRR_BS7 ((uint32_t)0x00000080) /*!< Port x Set bit 7 */ +#define GPIO_BSRR_BS8 ((uint32_t)0x00000100) /*!< Port x Set bit 8 */ +#define GPIO_BSRR_BS9 ((uint32_t)0x00000200) /*!< Port x Set bit 9 */ +#define GPIO_BSRR_BS10 ((uint32_t)0x00000400) /*!< Port x Set bit 10 */ +#define GPIO_BSRR_BS11 ((uint32_t)0x00000800) /*!< Port x Set bit 11 */ +#define GPIO_BSRR_BS12 ((uint32_t)0x00001000) /*!< Port x Set bit 12 */ +#define GPIO_BSRR_BS13 ((uint32_t)0x00002000) /*!< Port x Set bit 13 */ +#define GPIO_BSRR_BS14 ((uint32_t)0x00004000) /*!< Port x Set bit 14 */ +#define GPIO_BSRR_BS15 ((uint32_t)0x00008000) /*!< Port x Set bit 15 */ + +#define GPIO_BSRR_BR0 ((uint32_t)0x00010000) /*!< Port x Reset bit 0 */ +#define GPIO_BSRR_BR1 ((uint32_t)0x00020000) /*!< Port x Reset bit 1 */ +#define GPIO_BSRR_BR2 ((uint32_t)0x00040000) /*!< Port x Reset bit 2 */ +#define GPIO_BSRR_BR3 ((uint32_t)0x00080000) /*!< Port x Reset bit 3 */ +#define GPIO_BSRR_BR4 ((uint32_t)0x00100000) /*!< Port x Reset bit 4 */ +#define GPIO_BSRR_BR5 ((uint32_t)0x00200000) /*!< Port x Reset bit 5 */ +#define GPIO_BSRR_BR6 ((uint32_t)0x00400000) /*!< Port x Reset bit 6 */ +#define GPIO_BSRR_BR7 ((uint32_t)0x00800000) /*!< Port x Reset bit 7 */ +#define GPIO_BSRR_BR8 ((uint32_t)0x01000000) /*!< Port x Reset bit 8 */ +#define GPIO_BSRR_BR9 ((uint32_t)0x02000000) /*!< Port x Reset bit 9 */ +#define GPIO_BSRR_BR10 ((uint32_t)0x04000000) /*!< Port x Reset bit 10 */ +#define GPIO_BSRR_BR11 ((uint32_t)0x08000000) /*!< Port x Reset bit 11 */ +#define GPIO_BSRR_BR12 ((uint32_t)0x10000000) /*!< Port x Reset bit 12 */ +#define GPIO_BSRR_BR13 ((uint32_t)0x20000000) /*!< Port x Reset bit 13 */ +#define GPIO_BSRR_BR14 ((uint32_t)0x40000000) /*!< Port x Reset bit 14 */ +#define GPIO_BSRR_BR15 ((uint32_t)0x80000000) /*!< Port x Reset bit 15 */ + +/******************* Bit definition for GPIO_BRR register *******************/ +#define GPIO_BRR_BR0 ((uint16_t)0x0001) /*!< Port x Reset bit 0 */ +#define GPIO_BRR_BR1 ((uint16_t)0x0002) /*!< Port x Reset bit 1 */ +#define GPIO_BRR_BR2 ((uint16_t)0x0004) /*!< Port x Reset bit 2 */ +#define GPIO_BRR_BR3 ((uint16_t)0x0008) /*!< Port x Reset bit 3 */ +#define GPIO_BRR_BR4 ((uint16_t)0x0010) /*!< Port x Reset bit 4 */ +#define GPIO_BRR_BR5 ((uint16_t)0x0020) /*!< Port x Reset bit 5 */ +#define GPIO_BRR_BR6 ((uint16_t)0x0040) /*!< Port x Reset bit 6 */ +#define GPIO_BRR_BR7 ((uint16_t)0x0080) /*!< Port x Reset bit 7 */ +#define GPIO_BRR_BR8 ((uint16_t)0x0100) /*!< Port x Reset bit 8 */ +#define GPIO_BRR_BR9 ((uint16_t)0x0200) /*!< Port x Reset bit 9 */ +#define GPIO_BRR_BR10 ((uint16_t)0x0400) /*!< Port x Reset bit 10 */ +#define GPIO_BRR_BR11 ((uint16_t)0x0800) /*!< Port x Reset bit 11 */ +#define GPIO_BRR_BR12 ((uint16_t)0x1000) /*!< Port x Reset bit 12 */ +#define GPIO_BRR_BR13 ((uint16_t)0x2000) /*!< Port x Reset bit 13 */ +#define GPIO_BRR_BR14 ((uint16_t)0x4000) /*!< Port x Reset bit 14 */ +#define GPIO_BRR_BR15 ((uint16_t)0x8000) /*!< Port x Reset bit 15 */ + +/****************** Bit definition for GPIO_LCKR register *******************/ +#define GPIO_LCKR_LCK0 ((uint32_t)0x00000001) /*!< Port x Lock bit 0 */ +#define GPIO_LCKR_LCK1 ((uint32_t)0x00000002) /*!< Port x Lock bit 1 */ +#define GPIO_LCKR_LCK2 ((uint32_t)0x00000004) /*!< Port x Lock bit 2 */ +#define GPIO_LCKR_LCK3 ((uint32_t)0x00000008) /*!< Port x Lock bit 3 */ +#define GPIO_LCKR_LCK4 ((uint32_t)0x00000010) /*!< Port x Lock bit 4 */ +#define GPIO_LCKR_LCK5 ((uint32_t)0x00000020) /*!< Port x Lock bit 5 */ +#define GPIO_LCKR_LCK6 ((uint32_t)0x00000040) /*!< Port x Lock bit 6 */ +#define GPIO_LCKR_LCK7 ((uint32_t)0x00000080) /*!< Port x Lock bit 7 */ +#define GPIO_LCKR_LCK8 ((uint32_t)0x00000100) /*!< Port x Lock bit 8 */ +#define GPIO_LCKR_LCK9 ((uint32_t)0x00000200) /*!< Port x Lock bit 9 */ +#define GPIO_LCKR_LCK10 ((uint32_t)0x00000400) /*!< Port x Lock bit 10 */ +#define GPIO_LCKR_LCK11 ((uint32_t)0x00000800) /*!< Port x Lock bit 11 */ +#define GPIO_LCKR_LCK12 ((uint32_t)0x00001000) /*!< Port x Lock bit 12 */ +#define GPIO_LCKR_LCK13 ((uint32_t)0x00002000) /*!< Port x Lock bit 13 */ +#define GPIO_LCKR_LCK14 ((uint32_t)0x00004000) /*!< Port x Lock bit 14 */ +#define GPIO_LCKR_LCK15 ((uint32_t)0x00008000) /*!< Port x Lock bit 15 */ +#define GPIO_LCKR_LCKK ((uint32_t)0x00010000) /*!< Lock key */ + +/*----------------------------------------------------------------------------*/ + +/****************** Bit definition for AFIO_EVCR register *******************/ +#define AFIO_EVCR_PIN ((uint8_t)0x0F) /*!< PIN[3:0] bits (Pin selection) */ +#define AFIO_EVCR_PIN_0 ((uint8_t)0x01) /*!< Bit 0 */ +#define AFIO_EVCR_PIN_1 ((uint8_t)0x02) /*!< Bit 1 */ +#define AFIO_EVCR_PIN_2 ((uint8_t)0x04) /*!< Bit 2 */ +#define AFIO_EVCR_PIN_3 ((uint8_t)0x08) /*!< Bit 3 */ + +/*!< PIN configuration */ +#define AFIO_EVCR_PIN_PX0 ((uint8_t)0x00) /*!< Pin 0 selected */ +#define AFIO_EVCR_PIN_PX1 ((uint8_t)0x01) /*!< Pin 1 selected */ +#define AFIO_EVCR_PIN_PX2 ((uint8_t)0x02) /*!< Pin 2 selected */ +#define AFIO_EVCR_PIN_PX3 ((uint8_t)0x03) /*!< Pin 3 selected */ +#define AFIO_EVCR_PIN_PX4 ((uint8_t)0x04) /*!< Pin 4 selected */ +#define AFIO_EVCR_PIN_PX5 ((uint8_t)0x05) /*!< Pin 5 selected */ +#define AFIO_EVCR_PIN_PX6 ((uint8_t)0x06) /*!< Pin 6 selected */ +#define AFIO_EVCR_PIN_PX7 ((uint8_t)0x07) /*!< Pin 7 selected */ +#define AFIO_EVCR_PIN_PX8 ((uint8_t)0x08) /*!< Pin 8 selected */ +#define AFIO_EVCR_PIN_PX9 ((uint8_t)0x09) /*!< Pin 9 selected */ +#define AFIO_EVCR_PIN_PX10 ((uint8_t)0x0A) /*!< Pin 10 selected */ +#define AFIO_EVCR_PIN_PX11 ((uint8_t)0x0B) /*!< Pin 11 selected */ +#define AFIO_EVCR_PIN_PX12 ((uint8_t)0x0C) /*!< Pin 12 selected */ +#define AFIO_EVCR_PIN_PX13 ((uint8_t)0x0D) /*!< Pin 13 selected */ +#define AFIO_EVCR_PIN_PX14 ((uint8_t)0x0E) /*!< Pin 14 selected */ +#define AFIO_EVCR_PIN_PX15 ((uint8_t)0x0F) /*!< Pin 15 selected */ + +#define AFIO_EVCR_PORT ((uint8_t)0x70) /*!< PORT[2:0] bits (Port selection) */ +#define AFIO_EVCR_PORT_0 ((uint8_t)0x10) /*!< Bit 0 */ +#define AFIO_EVCR_PORT_1 ((uint8_t)0x20) /*!< Bit 1 */ +#define AFIO_EVCR_PORT_2 ((uint8_t)0x40) /*!< Bit 2 */ + +/*!< PORT configuration */ +#define AFIO_EVCR_PORT_PA ((uint8_t)0x00) /*!< Port A selected */ +#define AFIO_EVCR_PORT_PB ((uint8_t)0x10) /*!< Port B selected */ +#define AFIO_EVCR_PORT_PC ((uint8_t)0x20) /*!< Port C selected */ +#define AFIO_EVCR_PORT_PD ((uint8_t)0x30) /*!< Port D selected */ +#define AFIO_EVCR_PORT_PE ((uint8_t)0x40) /*!< Port E selected */ + +#define AFIO_EVCR_EVOE ((uint8_t)0x80) /*!< Event Output Enable */ + +/****************** Bit definition for AFIO_MAPR register *******************/ +#define AFIO_MAPR_SPI1_REMAP ((uint32_t)0x00000001) /*!< SPI1 remapping */ +#define AFIO_MAPR_I2C1_REMAP ((uint32_t)0x00000002) /*!< I2C1 remapping */ +#define AFIO_MAPR_USART1_REMAP ((uint32_t)0x00000004) /*!< USART1 remapping */ +#define AFIO_MAPR_USART2_REMAP ((uint32_t)0x00000008) /*!< USART2 remapping */ + +#define AFIO_MAPR_USART3_REMAP ((uint32_t)0x00000030) /*!< USART3_REMAP[1:0] bits (USART3 remapping) */ +#define AFIO_MAPR_USART3_REMAP_0 ((uint32_t)0x00000010) /*!< Bit 0 */ +#define AFIO_MAPR_USART3_REMAP_1 ((uint32_t)0x00000020) /*!< Bit 1 */ + +/* USART3_REMAP configuration */ +#define AFIO_MAPR_USART3_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (TX/PB10, RX/PB11, CK/PB12, CTS/PB13, RTS/PB14) */ +#define AFIO_MAPR_USART3_REMAP_PARTIALREMAP ((uint32_t)0x00000010) /*!< Partial remap (TX/PC10, RX/PC11, CK/PC12, CTS/PB13, RTS/PB14) */ +#define AFIO_MAPR_USART3_REMAP_FULLREMAP ((uint32_t)0x00000030) /*!< Full remap (TX/PD8, RX/PD9, CK/PD10, CTS/PD11, RTS/PD12) */ + +#define AFIO_MAPR_TIM1_REMAP ((uint32_t)0x000000C0) /*!< TIM1_REMAP[1:0] bits (TIM1 remapping) */ +#define AFIO_MAPR_TIM1_REMAP_0 ((uint32_t)0x00000040) /*!< Bit 0 */ +#define AFIO_MAPR_TIM1_REMAP_1 ((uint32_t)0x00000080) /*!< Bit 1 */ + +/*!< TIM1_REMAP configuration */ +#define AFIO_MAPR_TIM1_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PB12, CH1N/PB13, CH2N/PB14, CH3N/PB15) */ +#define AFIO_MAPR_TIM1_REMAP_PARTIALREMAP ((uint32_t)0x00000040) /*!< Partial remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PA6, CH1N/PA7, CH2N/PB0, CH3N/PB1) */ +#define AFIO_MAPR_TIM1_REMAP_FULLREMAP ((uint32_t)0x000000C0) /*!< Full remap (ETR/PE7, CH1/PE9, CH2/PE11, CH3/PE13, CH4/PE14, BKIN/PE15, CH1N/PE8, CH2N/PE10, CH3N/PE12) */ + +#define AFIO_MAPR_TIM2_REMAP ((uint32_t)0x00000300) /*!< TIM2_REMAP[1:0] bits (TIM2 remapping) */ +#define AFIO_MAPR_TIM2_REMAP_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define AFIO_MAPR_TIM2_REMAP_1 ((uint32_t)0x00000200) /*!< Bit 1 */ + +/*!< TIM2_REMAP configuration */ +#define AFIO_MAPR_TIM2_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (CH1/ETR/PA0, CH2/PA1, CH3/PA2, CH4/PA3) */ +#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1 ((uint32_t)0x00000100) /*!< Partial remap (CH1/ETR/PA15, CH2/PB3, CH3/PA2, CH4/PA3) */ +#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2 ((uint32_t)0x00000200) /*!< Partial remap (CH1/ETR/PA0, CH2/PA1, CH3/PB10, CH4/PB11) */ +#define AFIO_MAPR_TIM2_REMAP_FULLREMAP ((uint32_t)0x00000300) /*!< Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11) */ + +#define AFIO_MAPR_TIM3_REMAP ((uint32_t)0x00000C00) /*!< TIM3_REMAP[1:0] bits (TIM3 remapping) */ +#define AFIO_MAPR_TIM3_REMAP_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define AFIO_MAPR_TIM3_REMAP_1 ((uint32_t)0x00000800) /*!< Bit 1 */ + +/*!< TIM3_REMAP configuration */ +#define AFIO_MAPR_TIM3_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (CH1/PA6, CH2/PA7, CH3/PB0, CH4/PB1) */ +#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP ((uint32_t)0x00000800) /*!< Partial remap (CH1/PB4, CH2/PB5, CH3/PB0, CH4/PB1) */ +#define AFIO_MAPR_TIM3_REMAP_FULLREMAP ((uint32_t)0x00000C00) /*!< Full remap (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9) */ + +#define AFIO_MAPR_TIM4_REMAP ((uint32_t)0x00001000) /*!< TIM4_REMAP bit (TIM4 remapping) */ + +#define AFIO_MAPR_CAN_REMAP ((uint32_t)0x00006000) /*!< CAN_REMAP[1:0] bits (CAN Alternate function remapping) */ +#define AFIO_MAPR_CAN_REMAP_0 ((uint32_t)0x00002000) /*!< Bit 0 */ +#define AFIO_MAPR_CAN_REMAP_1 ((uint32_t)0x00004000) /*!< Bit 1 */ + +/*!< CAN_REMAP configuration */ +#define AFIO_MAPR_CAN_REMAP_REMAP1 ((uint32_t)0x00000000) /*!< CANRX mapped to PA11, CANTX mapped to PA12 */ +#define AFIO_MAPR_CAN_REMAP_REMAP2 ((uint32_t)0x00004000) /*!< CANRX mapped to PB8, CANTX mapped to PB9 */ +#define AFIO_MAPR_CAN_REMAP_REMAP3 ((uint32_t)0x00006000) /*!< CANRX mapped to PD0, CANTX mapped to PD1 */ + +#define AFIO_MAPR_PD01_REMAP ((uint32_t)0x00008000) /*!< Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ +#define AFIO_MAPR_TIM5CH4_IREMAP ((uint32_t)0x00010000) /*!< TIM5 Channel4 Internal Remap */ +#define AFIO_MAPR_ADC1_ETRGINJ_REMAP ((uint32_t)0x00020000) /*!< ADC 1 External Trigger Injected Conversion remapping */ +#define AFIO_MAPR_ADC1_ETRGREG_REMAP ((uint32_t)0x00040000) /*!< ADC 1 External Trigger Regular Conversion remapping */ +#define AFIO_MAPR_ADC2_ETRGINJ_REMAP ((uint32_t)0x00080000) /*!< ADC 2 External Trigger Injected Conversion remapping */ +#define AFIO_MAPR_ADC2_ETRGREG_REMAP ((uint32_t)0x00100000) /*!< ADC 2 External Trigger Regular Conversion remapping */ + +/*!< SWJ_CFG configuration */ +#define AFIO_MAPR_SWJ_CFG ((uint32_t)0x07000000) /*!< SWJ_CFG[2:0] bits (Serial Wire JTAG configuration) */ +#define AFIO_MAPR_SWJ_CFG_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define AFIO_MAPR_SWJ_CFG_1 ((uint32_t)0x02000000) /*!< Bit 1 */ +#define AFIO_MAPR_SWJ_CFG_2 ((uint32_t)0x04000000) /*!< Bit 2 */ + +#define AFIO_MAPR_SWJ_CFG_RESET ((uint32_t)0x00000000) /*!< Full SWJ (JTAG-DP + SW-DP) : Reset State */ +#define AFIO_MAPR_SWJ_CFG_NOJNTRST ((uint32_t)0x01000000) /*!< Full SWJ (JTAG-DP + SW-DP) but without JNTRST */ +#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE ((uint32_t)0x02000000) /*!< JTAG-DP Disabled and SW-DP Enabled */ +#define AFIO_MAPR_SWJ_CFG_DISABLE ((uint32_t)0x04000000) /*!< JTAG-DP Disabled and SW-DP Disabled */ + +#ifdef STM32F10X_CL +/*!< ETH_REMAP configuration */ + #define AFIO_MAPR_ETH_REMAP ((uint32_t)0x00200000) /*!< SPI3_REMAP bit (Ethernet MAC I/O remapping) */ + +/*!< CAN2_REMAP configuration */ + #define AFIO_MAPR_CAN2_REMAP ((uint32_t)0x00400000) /*!< CAN2_REMAP bit (CAN2 I/O remapping) */ + +/*!< MII_RMII_SEL configuration */ + #define AFIO_MAPR_MII_RMII_SEL ((uint32_t)0x00800000) /*!< MII_RMII_SEL bit (Ethernet MII or RMII selection) */ + +/*!< SPI3_REMAP configuration */ + #define AFIO_MAPR_SPI3_REMAP ((uint32_t)0x10000000) /*!< SPI3_REMAP bit (SPI3 remapping) */ + +/*!< TIM2ITR1_IREMAP configuration */ + #define AFIO_MAPR_TIM2ITR1_IREMAP ((uint32_t)0x20000000) /*!< TIM2ITR1_IREMAP bit (TIM2 internal trigger 1 remapping) */ + +/*!< PTP_PPS_REMAP configuration */ + #define AFIO_MAPR_PTP_PPS_REMAP ((uint32_t)0x20000000) /*!< PTP_PPS_REMAP bit (Ethernet PTP PPS remapping) */ +#endif + +/***************** Bit definition for AFIO_EXTICR1 register *****************/ +#define AFIO_EXTICR1_EXTI0 ((uint16_t)0x000F) /*!< EXTI 0 configuration */ +#define AFIO_EXTICR1_EXTI1 ((uint16_t)0x00F0) /*!< EXTI 1 configuration */ +#define AFIO_EXTICR1_EXTI2 ((uint16_t)0x0F00) /*!< EXTI 2 configuration */ +#define AFIO_EXTICR1_EXTI3 ((uint16_t)0xF000) /*!< EXTI 3 configuration */ + +/*!< EXTI0 configuration */ +#define AFIO_EXTICR1_EXTI0_PA ((uint16_t)0x0000) /*!< PA[0] pin */ +#define AFIO_EXTICR1_EXTI0_PB ((uint16_t)0x0001) /*!< PB[0] pin */ +#define AFIO_EXTICR1_EXTI0_PC ((uint16_t)0x0002) /*!< PC[0] pin */ +#define AFIO_EXTICR1_EXTI0_PD ((uint16_t)0x0003) /*!< PD[0] pin */ +#define AFIO_EXTICR1_EXTI0_PE ((uint16_t)0x0004) /*!< PE[0] pin */ +#define AFIO_EXTICR1_EXTI0_PF ((uint16_t)0x0005) /*!< PF[0] pin */ +#define AFIO_EXTICR1_EXTI0_PG ((uint16_t)0x0006) /*!< PG[0] pin */ + +/*!< EXTI1 configuration */ +#define AFIO_EXTICR1_EXTI1_PA ((uint16_t)0x0000) /*!< PA[1] pin */ +#define AFIO_EXTICR1_EXTI1_PB ((uint16_t)0x0010) /*!< PB[1] pin */ +#define AFIO_EXTICR1_EXTI1_PC ((uint16_t)0x0020) /*!< PC[1] pin */ +#define AFIO_EXTICR1_EXTI1_PD ((uint16_t)0x0030) /*!< PD[1] pin */ +#define AFIO_EXTICR1_EXTI1_PE ((uint16_t)0x0040) /*!< PE[1] pin */ +#define AFIO_EXTICR1_EXTI1_PF ((uint16_t)0x0050) /*!< PF[1] pin */ +#define AFIO_EXTICR1_EXTI1_PG ((uint16_t)0x0060) /*!< PG[1] pin */ + +/*!< EXTI2 configuration */ +#define AFIO_EXTICR1_EXTI2_PA ((uint16_t)0x0000) /*!< PA[2] pin */ +#define AFIO_EXTICR1_EXTI2_PB ((uint16_t)0x0100) /*!< PB[2] pin */ +#define AFIO_EXTICR1_EXTI2_PC ((uint16_t)0x0200) /*!< PC[2] pin */ +#define AFIO_EXTICR1_EXTI2_PD ((uint16_t)0x0300) /*!< PD[2] pin */ +#define AFIO_EXTICR1_EXTI2_PE ((uint16_t)0x0400) /*!< PE[2] pin */ +#define AFIO_EXTICR1_EXTI2_PF ((uint16_t)0x0500) /*!< PF[2] pin */ +#define AFIO_EXTICR1_EXTI2_PG ((uint16_t)0x0600) /*!< PG[2] pin */ + +/*!< EXTI3 configuration */ +#define AFIO_EXTICR1_EXTI3_PA ((uint16_t)0x0000) /*!< PA[3] pin */ +#define AFIO_EXTICR1_EXTI3_PB ((uint16_t)0x1000) /*!< PB[3] pin */ +#define AFIO_EXTICR1_EXTI3_PC ((uint16_t)0x2000) /*!< PC[3] pin */ +#define AFIO_EXTICR1_EXTI3_PD ((uint16_t)0x3000) /*!< PD[3] pin */ +#define AFIO_EXTICR1_EXTI3_PE ((uint16_t)0x4000) /*!< PE[3] pin */ +#define AFIO_EXTICR1_EXTI3_PF ((uint16_t)0x5000) /*!< PF[3] pin */ +#define AFIO_EXTICR1_EXTI3_PG ((uint16_t)0x6000) /*!< PG[3] pin */ + +/***************** Bit definition for AFIO_EXTICR2 register *****************/ +#define AFIO_EXTICR2_EXTI4 ((uint16_t)0x000F) /*!< EXTI 4 configuration */ +#define AFIO_EXTICR2_EXTI5 ((uint16_t)0x00F0) /*!< EXTI 5 configuration */ +#define AFIO_EXTICR2_EXTI6 ((uint16_t)0x0F00) /*!< EXTI 6 configuration */ +#define AFIO_EXTICR2_EXTI7 ((uint16_t)0xF000) /*!< EXTI 7 configuration */ + +/*!< EXTI4 configuration */ +#define AFIO_EXTICR2_EXTI4_PA ((uint16_t)0x0000) /*!< PA[4] pin */ +#define AFIO_EXTICR2_EXTI4_PB ((uint16_t)0x0001) /*!< PB[4] pin */ +#define AFIO_EXTICR2_EXTI4_PC ((uint16_t)0x0002) /*!< PC[4] pin */ +#define AFIO_EXTICR2_EXTI4_PD ((uint16_t)0x0003) /*!< PD[4] pin */ +#define AFIO_EXTICR2_EXTI4_PE ((uint16_t)0x0004) /*!< PE[4] pin */ +#define AFIO_EXTICR2_EXTI4_PF ((uint16_t)0x0005) /*!< PF[4] pin */ +#define AFIO_EXTICR2_EXTI4_PG ((uint16_t)0x0006) /*!< PG[4] pin */ + +/* EXTI5 configuration */ +#define AFIO_EXTICR2_EXTI5_PA ((uint16_t)0x0000) /*!< PA[5] pin */ +#define AFIO_EXTICR2_EXTI5_PB ((uint16_t)0x0010) /*!< PB[5] pin */ +#define AFIO_EXTICR2_EXTI5_PC ((uint16_t)0x0020) /*!< PC[5] pin */ +#define AFIO_EXTICR2_EXTI5_PD ((uint16_t)0x0030) /*!< PD[5] pin */ +#define AFIO_EXTICR2_EXTI5_PE ((uint16_t)0x0040) /*!< PE[5] pin */ +#define AFIO_EXTICR2_EXTI5_PF ((uint16_t)0x0050) /*!< PF[5] pin */ +#define AFIO_EXTICR2_EXTI5_PG ((uint16_t)0x0060) /*!< PG[5] pin */ + +/*!< EXTI6 configuration */ +#define AFIO_EXTICR2_EXTI6_PA ((uint16_t)0x0000) /*!< PA[6] pin */ +#define AFIO_EXTICR2_EXTI6_PB ((uint16_t)0x0100) /*!< PB[6] pin */ +#define AFIO_EXTICR2_EXTI6_PC ((uint16_t)0x0200) /*!< PC[6] pin */ +#define AFIO_EXTICR2_EXTI6_PD ((uint16_t)0x0300) /*!< PD[6] pin */ +#define AFIO_EXTICR2_EXTI6_PE ((uint16_t)0x0400) /*!< PE[6] pin */ +#define AFIO_EXTICR2_EXTI6_PF ((uint16_t)0x0500) /*!< PF[6] pin */ +#define AFIO_EXTICR2_EXTI6_PG ((uint16_t)0x0600) /*!< PG[6] pin */ + +/*!< EXTI7 configuration */ +#define AFIO_EXTICR2_EXTI7_PA ((uint16_t)0x0000) /*!< PA[7] pin */ +#define AFIO_EXTICR2_EXTI7_PB ((uint16_t)0x1000) /*!< PB[7] pin */ +#define AFIO_EXTICR2_EXTI7_PC ((uint16_t)0x2000) /*!< PC[7] pin */ +#define AFIO_EXTICR2_EXTI7_PD ((uint16_t)0x3000) /*!< PD[7] pin */ +#define AFIO_EXTICR2_EXTI7_PE ((uint16_t)0x4000) /*!< PE[7] pin */ +#define AFIO_EXTICR2_EXTI7_PF ((uint16_t)0x5000) /*!< PF[7] pin */ +#define AFIO_EXTICR2_EXTI7_PG ((uint16_t)0x6000) /*!< PG[7] pin */ + +/***************** Bit definition for AFIO_EXTICR3 register *****************/ +#define AFIO_EXTICR3_EXTI8 ((uint16_t)0x000F) /*!< EXTI 8 configuration */ +#define AFIO_EXTICR3_EXTI9 ((uint16_t)0x00F0) /*!< EXTI 9 configuration */ +#define AFIO_EXTICR3_EXTI10 ((uint16_t)0x0F00) /*!< EXTI 10 configuration */ +#define AFIO_EXTICR3_EXTI11 ((uint16_t)0xF000) /*!< EXTI 11 configuration */ + +/*!< EXTI8 configuration */ +#define AFIO_EXTICR3_EXTI8_PA ((uint16_t)0x0000) /*!< PA[8] pin */ +#define AFIO_EXTICR3_EXTI8_PB ((uint16_t)0x0001) /*!< PB[8] pin */ +#define AFIO_EXTICR3_EXTI8_PC ((uint16_t)0x0002) /*!< PC[8] pin */ +#define AFIO_EXTICR3_EXTI8_PD ((uint16_t)0x0003) /*!< PD[8] pin */ +#define AFIO_EXTICR3_EXTI8_PE ((uint16_t)0x0004) /*!< PE[8] pin */ +#define AFIO_EXTICR3_EXTI8_PF ((uint16_t)0x0005) /*!< PF[8] pin */ +#define AFIO_EXTICR3_EXTI8_PG ((uint16_t)0x0006) /*!< PG[8] pin */ + +/*!< EXTI9 configuration */ +#define AFIO_EXTICR3_EXTI9_PA ((uint16_t)0x0000) /*!< PA[9] pin */ +#define AFIO_EXTICR3_EXTI9_PB ((uint16_t)0x0010) /*!< PB[9] pin */ +#define AFIO_EXTICR3_EXTI9_PC ((uint16_t)0x0020) /*!< PC[9] pin */ +#define AFIO_EXTICR3_EXTI9_PD ((uint16_t)0x0030) /*!< PD[9] pin */ +#define AFIO_EXTICR3_EXTI9_PE ((uint16_t)0x0040) /*!< PE[9] pin */ +#define AFIO_EXTICR3_EXTI9_PF ((uint16_t)0x0050) /*!< PF[9] pin */ +#define AFIO_EXTICR3_EXTI9_PG ((uint16_t)0x0060) /*!< PG[9] pin */ + +/*!< EXTI10 configuration */ +#define AFIO_EXTICR3_EXTI10_PA ((uint16_t)0x0000) /*!< PA[10] pin */ +#define AFIO_EXTICR3_EXTI10_PB ((uint16_t)0x0100) /*!< PB[10] pin */ +#define AFIO_EXTICR3_EXTI10_PC ((uint16_t)0x0200) /*!< PC[10] pin */ +#define AFIO_EXTICR3_EXTI10_PD ((uint16_t)0x0300) /*!< PD[10] pin */ +#define AFIO_EXTICR3_EXTI10_PE ((uint16_t)0x0400) /*!< PE[10] pin */ +#define AFIO_EXTICR3_EXTI10_PF ((uint16_t)0x0500) /*!< PF[10] pin */ +#define AFIO_EXTICR3_EXTI10_PG ((uint16_t)0x0600) /*!< PG[10] pin */ + +/*!< EXTI11 configuration */ +#define AFIO_EXTICR3_EXTI11_PA ((uint16_t)0x0000) /*!< PA[11] pin */ +#define AFIO_EXTICR3_EXTI11_PB ((uint16_t)0x1000) /*!< PB[11] pin */ +#define AFIO_EXTICR3_EXTI11_PC ((uint16_t)0x2000) /*!< PC[11] pin */ +#define AFIO_EXTICR3_EXTI11_PD ((uint16_t)0x3000) /*!< PD[11] pin */ +#define AFIO_EXTICR3_EXTI11_PE ((uint16_t)0x4000) /*!< PE[11] pin */ +#define AFIO_EXTICR3_EXTI11_PF ((uint16_t)0x5000) /*!< PF[11] pin */ +#define AFIO_EXTICR3_EXTI11_PG ((uint16_t)0x6000) /*!< PG[11] pin */ + +/***************** Bit definition for AFIO_EXTICR4 register *****************/ +#define AFIO_EXTICR4_EXTI12 ((uint16_t)0x000F) /*!< EXTI 12 configuration */ +#define AFIO_EXTICR4_EXTI13 ((uint16_t)0x00F0) /*!< EXTI 13 configuration */ +#define AFIO_EXTICR4_EXTI14 ((uint16_t)0x0F00) /*!< EXTI 14 configuration */ +#define AFIO_EXTICR4_EXTI15 ((uint16_t)0xF000) /*!< EXTI 15 configuration */ + +/* EXTI12 configuration */ +#define AFIO_EXTICR4_EXTI12_PA ((uint16_t)0x0000) /*!< PA[12] pin */ +#define AFIO_EXTICR4_EXTI12_PB ((uint16_t)0x0001) /*!< PB[12] pin */ +#define AFIO_EXTICR4_EXTI12_PC ((uint16_t)0x0002) /*!< PC[12] pin */ +#define AFIO_EXTICR4_EXTI12_PD ((uint16_t)0x0003) /*!< PD[12] pin */ +#define AFIO_EXTICR4_EXTI12_PE ((uint16_t)0x0004) /*!< PE[12] pin */ +#define AFIO_EXTICR4_EXTI12_PF ((uint16_t)0x0005) /*!< PF[12] pin */ +#define AFIO_EXTICR4_EXTI12_PG ((uint16_t)0x0006) /*!< PG[12] pin */ + +/* EXTI13 configuration */ +#define AFIO_EXTICR4_EXTI13_PA ((uint16_t)0x0000) /*!< PA[13] pin */ +#define AFIO_EXTICR4_EXTI13_PB ((uint16_t)0x0010) /*!< PB[13] pin */ +#define AFIO_EXTICR4_EXTI13_PC ((uint16_t)0x0020) /*!< PC[13] pin */ +#define AFIO_EXTICR4_EXTI13_PD ((uint16_t)0x0030) /*!< PD[13] pin */ +#define AFIO_EXTICR4_EXTI13_PE ((uint16_t)0x0040) /*!< PE[13] pin */ +#define AFIO_EXTICR4_EXTI13_PF ((uint16_t)0x0050) /*!< PF[13] pin */ +#define AFIO_EXTICR4_EXTI13_PG ((uint16_t)0x0060) /*!< PG[13] pin */ + +/*!< EXTI14 configuration */ +#define AFIO_EXTICR4_EXTI14_PA ((uint16_t)0x0000) /*!< PA[14] pin */ +#define AFIO_EXTICR4_EXTI14_PB ((uint16_t)0x0100) /*!< PB[14] pin */ +#define AFIO_EXTICR4_EXTI14_PC ((uint16_t)0x0200) /*!< PC[14] pin */ +#define AFIO_EXTICR4_EXTI14_PD ((uint16_t)0x0300) /*!< PD[14] pin */ +#define AFIO_EXTICR4_EXTI14_PE ((uint16_t)0x0400) /*!< PE[14] pin */ +#define AFIO_EXTICR4_EXTI14_PF ((uint16_t)0x0500) /*!< PF[14] pin */ +#define AFIO_EXTICR4_EXTI14_PG ((uint16_t)0x0600) /*!< PG[14] pin */ + +/*!< EXTI15 configuration */ +#define AFIO_EXTICR4_EXTI15_PA ((uint16_t)0x0000) /*!< PA[15] pin */ +#define AFIO_EXTICR4_EXTI15_PB ((uint16_t)0x1000) /*!< PB[15] pin */ +#define AFIO_EXTICR4_EXTI15_PC ((uint16_t)0x2000) /*!< PC[15] pin */ +#define AFIO_EXTICR4_EXTI15_PD ((uint16_t)0x3000) /*!< PD[15] pin */ +#define AFIO_EXTICR4_EXTI15_PE ((uint16_t)0x4000) /*!< PE[15] pin */ +#define AFIO_EXTICR4_EXTI15_PF ((uint16_t)0x5000) /*!< PF[15] pin */ +#define AFIO_EXTICR4_EXTI15_PG ((uint16_t)0x6000) /*!< PG[15] pin */ + +/******************************************************************************/ +/* */ +/* SystemTick */ +/* */ +/******************************************************************************/ + +/***************** Bit definition for SysTick_CTRL register *****************/ +#define SysTick_CTRL_ENABLE ((uint32_t)0x00000001) /*!< Counter enable */ +#define SysTick_CTRL_TICKINT ((uint32_t)0x00000002) /*!< Counting down to 0 pends the SysTick handler */ +#define SysTick_CTRL_CLKSOURCE ((uint32_t)0x00000004) /*!< Clock source */ +#define SysTick_CTRL_COUNTFLAG ((uint32_t)0x00010000) /*!< Count Flag */ + +/***************** Bit definition for SysTick_LOAD register *****************/ +#define SysTick_LOAD_RELOAD ((uint32_t)0x00FFFFFF) /*!< Value to load into the SysTick Current Value Register when the counter reaches 0 */ + +/***************** Bit definition for SysTick_VAL register ******************/ +#define SysTick_VAL_CURRENT ((uint32_t)0x00FFFFFF) /*!< Current value at the time the register is accessed */ + +/***************** Bit definition for SysTick_CALIB register ****************/ +#define SysTick_CALIB_TENMS ((uint32_t)0x00FFFFFF) /*!< Reload value to use for 10ms timing */ +#define SysTick_CALIB_SKEW ((uint32_t)0x40000000) /*!< Calibration value is not exactly 10 ms */ +#define SysTick_CALIB_NOREF ((uint32_t)0x80000000) /*!< The reference clock is not provided */ + +/******************************************************************************/ +/* */ +/* Nested Vectored Interrupt Controller */ +/* */ +/******************************************************************************/ + +/****************** Bit definition for NVIC_ISER register *******************/ +#define NVIC_ISER_SETENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt set enable bits */ +#define NVIC_ISER_SETENA_0 ((uint32_t)0x00000001) /*!< bit 0 */ +#define NVIC_ISER_SETENA_1 ((uint32_t)0x00000002) /*!< bit 1 */ +#define NVIC_ISER_SETENA_2 ((uint32_t)0x00000004) /*!< bit 2 */ +#define NVIC_ISER_SETENA_3 ((uint32_t)0x00000008) /*!< bit 3 */ +#define NVIC_ISER_SETENA_4 ((uint32_t)0x00000010) /*!< bit 4 */ +#define NVIC_ISER_SETENA_5 ((uint32_t)0x00000020) /*!< bit 5 */ +#define NVIC_ISER_SETENA_6 ((uint32_t)0x00000040) /*!< bit 6 */ +#define NVIC_ISER_SETENA_7 ((uint32_t)0x00000080) /*!< bit 7 */ +#define NVIC_ISER_SETENA_8 ((uint32_t)0x00000100) /*!< bit 8 */ +#define NVIC_ISER_SETENA_9 ((uint32_t)0x00000200) /*!< bit 9 */ +#define NVIC_ISER_SETENA_10 ((uint32_t)0x00000400) /*!< bit 10 */ +#define NVIC_ISER_SETENA_11 ((uint32_t)0x00000800) /*!< bit 11 */ +#define NVIC_ISER_SETENA_12 ((uint32_t)0x00001000) /*!< bit 12 */ +#define NVIC_ISER_SETENA_13 ((uint32_t)0x00002000) /*!< bit 13 */ +#define NVIC_ISER_SETENA_14 ((uint32_t)0x00004000) /*!< bit 14 */ +#define NVIC_ISER_SETENA_15 ((uint32_t)0x00008000) /*!< bit 15 */ +#define NVIC_ISER_SETENA_16 ((uint32_t)0x00010000) /*!< bit 16 */ +#define NVIC_ISER_SETENA_17 ((uint32_t)0x00020000) /*!< bit 17 */ +#define NVIC_ISER_SETENA_18 ((uint32_t)0x00040000) /*!< bit 18 */ +#define NVIC_ISER_SETENA_19 ((uint32_t)0x00080000) /*!< bit 19 */ +#define NVIC_ISER_SETENA_20 ((uint32_t)0x00100000) /*!< bit 20 */ +#define NVIC_ISER_SETENA_21 ((uint32_t)0x00200000) /*!< bit 21 */ +#define NVIC_ISER_SETENA_22 ((uint32_t)0x00400000) /*!< bit 22 */ +#define NVIC_ISER_SETENA_23 ((uint32_t)0x00800000) /*!< bit 23 */ +#define NVIC_ISER_SETENA_24 ((uint32_t)0x01000000) /*!< bit 24 */ +#define NVIC_ISER_SETENA_25 ((uint32_t)0x02000000) /*!< bit 25 */ +#define NVIC_ISER_SETENA_26 ((uint32_t)0x04000000) /*!< bit 26 */ +#define NVIC_ISER_SETENA_27 ((uint32_t)0x08000000) /*!< bit 27 */ +#define NVIC_ISER_SETENA_28 ((uint32_t)0x10000000) /*!< bit 28 */ +#define NVIC_ISER_SETENA_29 ((uint32_t)0x20000000) /*!< bit 29 */ +#define NVIC_ISER_SETENA_30 ((uint32_t)0x40000000) /*!< bit 30 */ +#define NVIC_ISER_SETENA_31 ((uint32_t)0x80000000) /*!< bit 31 */ + +/****************** Bit definition for NVIC_ICER register *******************/ +#define NVIC_ICER_CLRENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-enable bits */ +#define NVIC_ICER_CLRENA_0 ((uint32_t)0x00000001) /*!< bit 0 */ +#define NVIC_ICER_CLRENA_1 ((uint32_t)0x00000002) /*!< bit 1 */ +#define NVIC_ICER_CLRENA_2 ((uint32_t)0x00000004) /*!< bit 2 */ +#define NVIC_ICER_CLRENA_3 ((uint32_t)0x00000008) /*!< bit 3 */ +#define NVIC_ICER_CLRENA_4 ((uint32_t)0x00000010) /*!< bit 4 */ +#define NVIC_ICER_CLRENA_5 ((uint32_t)0x00000020) /*!< bit 5 */ +#define NVIC_ICER_CLRENA_6 ((uint32_t)0x00000040) /*!< bit 6 */ +#define NVIC_ICER_CLRENA_7 ((uint32_t)0x00000080) /*!< bit 7 */ +#define NVIC_ICER_CLRENA_8 ((uint32_t)0x00000100) /*!< bit 8 */ +#define NVIC_ICER_CLRENA_9 ((uint32_t)0x00000200) /*!< bit 9 */ +#define NVIC_ICER_CLRENA_10 ((uint32_t)0x00000400) /*!< bit 10 */ +#define NVIC_ICER_CLRENA_11 ((uint32_t)0x00000800) /*!< bit 11 */ +#define NVIC_ICER_CLRENA_12 ((uint32_t)0x00001000) /*!< bit 12 */ +#define NVIC_ICER_CLRENA_13 ((uint32_t)0x00002000) /*!< bit 13 */ +#define NVIC_ICER_CLRENA_14 ((uint32_t)0x00004000) /*!< bit 14 */ +#define NVIC_ICER_CLRENA_15 ((uint32_t)0x00008000) /*!< bit 15 */ +#define NVIC_ICER_CLRENA_16 ((uint32_t)0x00010000) /*!< bit 16 */ +#define NVIC_ICER_CLRENA_17 ((uint32_t)0x00020000) /*!< bit 17 */ +#define NVIC_ICER_CLRENA_18 ((uint32_t)0x00040000) /*!< bit 18 */ +#define NVIC_ICER_CLRENA_19 ((uint32_t)0x00080000) /*!< bit 19 */ +#define NVIC_ICER_CLRENA_20 ((uint32_t)0x00100000) /*!< bit 20 */ +#define NVIC_ICER_CLRENA_21 ((uint32_t)0x00200000) /*!< bit 21 */ +#define NVIC_ICER_CLRENA_22 ((uint32_t)0x00400000) /*!< bit 22 */ +#define NVIC_ICER_CLRENA_23 ((uint32_t)0x00800000) /*!< bit 23 */ +#define NVIC_ICER_CLRENA_24 ((uint32_t)0x01000000) /*!< bit 24 */ +#define NVIC_ICER_CLRENA_25 ((uint32_t)0x02000000) /*!< bit 25 */ +#define NVIC_ICER_CLRENA_26 ((uint32_t)0x04000000) /*!< bit 26 */ +#define NVIC_ICER_CLRENA_27 ((uint32_t)0x08000000) /*!< bit 27 */ +#define NVIC_ICER_CLRENA_28 ((uint32_t)0x10000000) /*!< bit 28 */ +#define NVIC_ICER_CLRENA_29 ((uint32_t)0x20000000) /*!< bit 29 */ +#define NVIC_ICER_CLRENA_30 ((uint32_t)0x40000000) /*!< bit 30 */ +#define NVIC_ICER_CLRENA_31 ((uint32_t)0x80000000) /*!< bit 31 */ + +/****************** Bit definition for NVIC_ISPR register *******************/ +#define NVIC_ISPR_SETPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt set-pending bits */ +#define NVIC_ISPR_SETPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */ +#define NVIC_ISPR_SETPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */ +#define NVIC_ISPR_SETPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */ +#define NVIC_ISPR_SETPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */ +#define NVIC_ISPR_SETPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */ +#define NVIC_ISPR_SETPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */ +#define NVIC_ISPR_SETPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */ +#define NVIC_ISPR_SETPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */ +#define NVIC_ISPR_SETPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */ +#define NVIC_ISPR_SETPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */ +#define NVIC_ISPR_SETPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */ +#define NVIC_ISPR_SETPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */ +#define NVIC_ISPR_SETPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */ +#define NVIC_ISPR_SETPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */ +#define NVIC_ISPR_SETPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */ +#define NVIC_ISPR_SETPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */ +#define NVIC_ISPR_SETPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */ +#define NVIC_ISPR_SETPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */ +#define NVIC_ISPR_SETPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */ +#define NVIC_ISPR_SETPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */ +#define NVIC_ISPR_SETPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */ +#define NVIC_ISPR_SETPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */ +#define NVIC_ISPR_SETPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */ +#define NVIC_ISPR_SETPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */ +#define NVIC_ISPR_SETPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */ +#define NVIC_ISPR_SETPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */ +#define NVIC_ISPR_SETPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */ +#define NVIC_ISPR_SETPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */ +#define NVIC_ISPR_SETPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */ +#define NVIC_ISPR_SETPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */ +#define NVIC_ISPR_SETPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */ +#define NVIC_ISPR_SETPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */ + +/****************** Bit definition for NVIC_ICPR register *******************/ +#define NVIC_ICPR_CLRPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-pending bits */ +#define NVIC_ICPR_CLRPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */ +#define NVIC_ICPR_CLRPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */ +#define NVIC_ICPR_CLRPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */ +#define NVIC_ICPR_CLRPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */ +#define NVIC_ICPR_CLRPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */ +#define NVIC_ICPR_CLRPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */ +#define NVIC_ICPR_CLRPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */ +#define NVIC_ICPR_CLRPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */ +#define NVIC_ICPR_CLRPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */ +#define NVIC_ICPR_CLRPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */ +#define NVIC_ICPR_CLRPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */ +#define NVIC_ICPR_CLRPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */ +#define NVIC_ICPR_CLRPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */ +#define NVIC_ICPR_CLRPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */ +#define NVIC_ICPR_CLRPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */ +#define NVIC_ICPR_CLRPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */ +#define NVIC_ICPR_CLRPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */ +#define NVIC_ICPR_CLRPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */ +#define NVIC_ICPR_CLRPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */ +#define NVIC_ICPR_CLRPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */ +#define NVIC_ICPR_CLRPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */ +#define NVIC_ICPR_CLRPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */ +#define NVIC_ICPR_CLRPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */ +#define NVIC_ICPR_CLRPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */ +#define NVIC_ICPR_CLRPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */ +#define NVIC_ICPR_CLRPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */ +#define NVIC_ICPR_CLRPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */ +#define NVIC_ICPR_CLRPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */ +#define NVIC_ICPR_CLRPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */ +#define NVIC_ICPR_CLRPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */ +#define NVIC_ICPR_CLRPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */ +#define NVIC_ICPR_CLRPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */ + +/****************** Bit definition for NVIC_IABR register *******************/ +#define NVIC_IABR_ACTIVE ((uint32_t)0xFFFFFFFF) /*!< Interrupt active flags */ +#define NVIC_IABR_ACTIVE_0 ((uint32_t)0x00000001) /*!< bit 0 */ +#define NVIC_IABR_ACTIVE_1 ((uint32_t)0x00000002) /*!< bit 1 */ +#define NVIC_IABR_ACTIVE_2 ((uint32_t)0x00000004) /*!< bit 2 */ +#define NVIC_IABR_ACTIVE_3 ((uint32_t)0x00000008) /*!< bit 3 */ +#define NVIC_IABR_ACTIVE_4 ((uint32_t)0x00000010) /*!< bit 4 */ +#define NVIC_IABR_ACTIVE_5 ((uint32_t)0x00000020) /*!< bit 5 */ +#define NVIC_IABR_ACTIVE_6 ((uint32_t)0x00000040) /*!< bit 6 */ +#define NVIC_IABR_ACTIVE_7 ((uint32_t)0x00000080) /*!< bit 7 */ +#define NVIC_IABR_ACTIVE_8 ((uint32_t)0x00000100) /*!< bit 8 */ +#define NVIC_IABR_ACTIVE_9 ((uint32_t)0x00000200) /*!< bit 9 */ +#define NVIC_IABR_ACTIVE_10 ((uint32_t)0x00000400) /*!< bit 10 */ +#define NVIC_IABR_ACTIVE_11 ((uint32_t)0x00000800) /*!< bit 11 */ +#define NVIC_IABR_ACTIVE_12 ((uint32_t)0x00001000) /*!< bit 12 */ +#define NVIC_IABR_ACTIVE_13 ((uint32_t)0x00002000) /*!< bit 13 */ +#define NVIC_IABR_ACTIVE_14 ((uint32_t)0x00004000) /*!< bit 14 */ +#define NVIC_IABR_ACTIVE_15 ((uint32_t)0x00008000) /*!< bit 15 */ +#define NVIC_IABR_ACTIVE_16 ((uint32_t)0x00010000) /*!< bit 16 */ +#define NVIC_IABR_ACTIVE_17 ((uint32_t)0x00020000) /*!< bit 17 */ +#define NVIC_IABR_ACTIVE_18 ((uint32_t)0x00040000) /*!< bit 18 */ +#define NVIC_IABR_ACTIVE_19 ((uint32_t)0x00080000) /*!< bit 19 */ +#define NVIC_IABR_ACTIVE_20 ((uint32_t)0x00100000) /*!< bit 20 */ +#define NVIC_IABR_ACTIVE_21 ((uint32_t)0x00200000) /*!< bit 21 */ +#define NVIC_IABR_ACTIVE_22 ((uint32_t)0x00400000) /*!< bit 22 */ +#define NVIC_IABR_ACTIVE_23 ((uint32_t)0x00800000) /*!< bit 23 */ +#define NVIC_IABR_ACTIVE_24 ((uint32_t)0x01000000) /*!< bit 24 */ +#define NVIC_IABR_ACTIVE_25 ((uint32_t)0x02000000) /*!< bit 25 */ +#define NVIC_IABR_ACTIVE_26 ((uint32_t)0x04000000) /*!< bit 26 */ +#define NVIC_IABR_ACTIVE_27 ((uint32_t)0x08000000) /*!< bit 27 */ +#define NVIC_IABR_ACTIVE_28 ((uint32_t)0x10000000) /*!< bit 28 */ +#define NVIC_IABR_ACTIVE_29 ((uint32_t)0x20000000) /*!< bit 29 */ +#define NVIC_IABR_ACTIVE_30 ((uint32_t)0x40000000) /*!< bit 30 */ +#define NVIC_IABR_ACTIVE_31 ((uint32_t)0x80000000) /*!< bit 31 */ + +/****************** Bit definition for NVIC_PRI0 register *******************/ +#define NVIC_IPR0_PRI_0 ((uint32_t)0x000000FF) /*!< Priority of interrupt 0 */ +#define NVIC_IPR0_PRI_1 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 1 */ +#define NVIC_IPR0_PRI_2 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 2 */ +#define NVIC_IPR0_PRI_3 ((uint32_t)0xFF000000) /*!< Priority of interrupt 3 */ + +/****************** Bit definition for NVIC_PRI1 register *******************/ +#define NVIC_IPR1_PRI_4 ((uint32_t)0x000000FF) /*!< Priority of interrupt 4 */ +#define NVIC_IPR1_PRI_5 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 5 */ +#define NVIC_IPR1_PRI_6 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 6 */ +#define NVIC_IPR1_PRI_7 ((uint32_t)0xFF000000) /*!< Priority of interrupt 7 */ + +/****************** Bit definition for NVIC_PRI2 register *******************/ +#define NVIC_IPR2_PRI_8 ((uint32_t)0x000000FF) /*!< Priority of interrupt 8 */ +#define NVIC_IPR2_PRI_9 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 9 */ +#define NVIC_IPR2_PRI_10 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 10 */ +#define NVIC_IPR2_PRI_11 ((uint32_t)0xFF000000) /*!< Priority of interrupt 11 */ + +/****************** Bit definition for NVIC_PRI3 register *******************/ +#define NVIC_IPR3_PRI_12 ((uint32_t)0x000000FF) /*!< Priority of interrupt 12 */ +#define NVIC_IPR3_PRI_13 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 13 */ +#define NVIC_IPR3_PRI_14 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 14 */ +#define NVIC_IPR3_PRI_15 ((uint32_t)0xFF000000) /*!< Priority of interrupt 15 */ + +/****************** Bit definition for NVIC_PRI4 register *******************/ +#define NVIC_IPR4_PRI_16 ((uint32_t)0x000000FF) /*!< Priority of interrupt 16 */ +#define NVIC_IPR4_PRI_17 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 17 */ +#define NVIC_IPR4_PRI_18 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 18 */ +#define NVIC_IPR4_PRI_19 ((uint32_t)0xFF000000) /*!< Priority of interrupt 19 */ + +/****************** Bit definition for NVIC_PRI5 register *******************/ +#define NVIC_IPR5_PRI_20 ((uint32_t)0x000000FF) /*!< Priority of interrupt 20 */ +#define NVIC_IPR5_PRI_21 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 21 */ +#define NVIC_IPR5_PRI_22 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 22 */ +#define NVIC_IPR5_PRI_23 ((uint32_t)0xFF000000) /*!< Priority of interrupt 23 */ + +/****************** Bit definition for NVIC_PRI6 register *******************/ +#define NVIC_IPR6_PRI_24 ((uint32_t)0x000000FF) /*!< Priority of interrupt 24 */ +#define NVIC_IPR6_PRI_25 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 25 */ +#define NVIC_IPR6_PRI_26 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 26 */ +#define NVIC_IPR6_PRI_27 ((uint32_t)0xFF000000) /*!< Priority of interrupt 27 */ + +/****************** Bit definition for NVIC_PRI7 register *******************/ +#define NVIC_IPR7_PRI_28 ((uint32_t)0x000000FF) /*!< Priority of interrupt 28 */ +#define NVIC_IPR7_PRI_29 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 29 */ +#define NVIC_IPR7_PRI_30 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 30 */ +#define NVIC_IPR7_PRI_31 ((uint32_t)0xFF000000) /*!< Priority of interrupt 31 */ + +/****************** Bit definition for SCB_CPUID register *******************/ +#define SCB_CPUID_REVISION ((uint32_t)0x0000000F) /*!< Implementation defined revision number */ +#define SCB_CPUID_PARTNO ((uint32_t)0x0000FFF0) /*!< Number of processor within family */ +#define SCB_CPUID_Constant ((uint32_t)0x000F0000) /*!< Reads as 0x0F */ +#define SCB_CPUID_VARIANT ((uint32_t)0x00F00000) /*!< Implementation defined variant number */ +#define SCB_CPUID_IMPLEMENTER ((uint32_t)0xFF000000) /*!< Implementer code. ARM is 0x41 */ + +/******************* Bit definition for SCB_ICSR register *******************/ +#define SCB_ICSR_VECTACTIVE ((uint32_t)0x000001FF) /*!< Active ISR number field */ +#define SCB_ICSR_RETTOBASE ((uint32_t)0x00000800) /*!< All active exceptions minus the IPSR_current_exception yields the empty set */ +#define SCB_ICSR_VECTPENDING ((uint32_t)0x003FF000) /*!< Pending ISR number field */ +#define SCB_ICSR_ISRPENDING ((uint32_t)0x00400000) /*!< Interrupt pending flag */ +#define SCB_ICSR_ISRPREEMPT ((uint32_t)0x00800000) /*!< It indicates that a pending interrupt becomes active in the next running cycle */ +#define SCB_ICSR_PENDSTCLR ((uint32_t)0x02000000) /*!< Clear pending SysTick bit */ +#define SCB_ICSR_PENDSTSET ((uint32_t)0x04000000) /*!< Set pending SysTick bit */ +#define SCB_ICSR_PENDSVCLR ((uint32_t)0x08000000) /*!< Clear pending pendSV bit */ +#define SCB_ICSR_PENDSVSET ((uint32_t)0x10000000) /*!< Set pending pendSV bit */ +#define SCB_ICSR_NMIPENDSET ((uint32_t)0x80000000) /*!< Set pending NMI bit */ + +/******************* Bit definition for SCB_VTOR register *******************/ +#define SCB_VTOR_TBLOFF ((uint32_t)0x1FFFFF80) /*!< Vector table base offset field */ +#define SCB_VTOR_TBLBASE ((uint32_t)0x20000000) /*!< Table base in code(0) or RAM(1) */ + +/*!<***************** Bit definition for SCB_AIRCR register *******************/ +#define SCB_AIRCR_VECTRESET ((uint32_t)0x00000001) /*!< System Reset bit */ +#define SCB_AIRCR_VECTCLRACTIVE ((uint32_t)0x00000002) /*!< Clear active vector bit */ +#define SCB_AIRCR_SYSRESETREQ ((uint32_t)0x00000004) /*!< Requests chip control logic to generate a reset */ + +#define SCB_AIRCR_PRIGROUP ((uint32_t)0x00000700) /*!< PRIGROUP[2:0] bits (Priority group) */ +#define SCB_AIRCR_PRIGROUP_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define SCB_AIRCR_PRIGROUP_1 ((uint32_t)0x00000200) /*!< Bit 1 */ +#define SCB_AIRCR_PRIGROUP_2 ((uint32_t)0x00000400) /*!< Bit 2 */ + +/* prority group configuration */ +#define SCB_AIRCR_PRIGROUP0 ((uint32_t)0x00000000) /*!< Priority group=0 (7 bits of pre-emption priority, 1 bit of subpriority) */ +#define SCB_AIRCR_PRIGROUP1 ((uint32_t)0x00000100) /*!< Priority group=1 (6 bits of pre-emption priority, 2 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP2 ((uint32_t)0x00000200) /*!< Priority group=2 (5 bits of pre-emption priority, 3 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP3 ((uint32_t)0x00000300) /*!< Priority group=3 (4 bits of pre-emption priority, 4 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP4 ((uint32_t)0x00000400) /*!< Priority group=4 (3 bits of pre-emption priority, 5 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP5 ((uint32_t)0x00000500) /*!< Priority group=5 (2 bits of pre-emption priority, 6 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP6 ((uint32_t)0x00000600) /*!< Priority group=6 (1 bit of pre-emption priority, 7 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP7 ((uint32_t)0x00000700) /*!< Priority group=7 (no pre-emption priority, 8 bits of subpriority) */ + +#define SCB_AIRCR_ENDIANESS ((uint32_t)0x00008000) /*!< Data endianness bit */ +#define SCB_AIRCR_VECTKEY ((uint32_t)0xFFFF0000) /*!< Register key (VECTKEY) - Reads as 0xFA05 (VECTKEYSTAT) */ + +/******************* Bit definition for SCB_SCR register ********************/ +#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< Sleep on exit bit */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< Sleep deep bit */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< Wake up from WFE */ + +/******************** Bit definition for SCB_CCR register *******************/ +#define SCB_CCR_NONBASETHRDENA ((uint16_t)0x0001) /*!< Thread mode can be entered from any level in Handler mode by controlled return value */ +#define SCB_CCR_USERSETMPEND ((uint16_t)0x0002) /*!< Enables user code to write the Software Trigger Interrupt register to trigger (pend) a Main exception */ +#define SCB_CCR_UNALIGN_TRP ((uint16_t)0x0008) /*!< Trap for unaligned access */ +#define SCB_CCR_DIV_0_TRP ((uint16_t)0x0010) /*!< Trap on Divide by 0 */ +#define SCB_CCR_BFHFNMIGN ((uint16_t)0x0100) /*!< Handlers running at priority -1 and -2 */ +#define SCB_CCR_STKALIGN ((uint16_t)0x0200) /*!< On exception entry, the SP used prior to the exception is adjusted to be 8-byte aligned */ + +/******************* Bit definition for SCB_SHPR register ********************/ +#define SCB_SHPR_PRI_N ((uint32_t)0x000000FF) /*!< Priority of system handler 4,8, and 12. Mem Manage, reserved and Debug Monitor */ +#define SCB_SHPR_PRI_N1 ((uint32_t)0x0000FF00) /*!< Priority of system handler 5,9, and 13. Bus Fault, reserved and reserved */ +#define SCB_SHPR_PRI_N2 ((uint32_t)0x00FF0000) /*!< Priority of system handler 6,10, and 14. Usage Fault, reserved and PendSV */ +#define SCB_SHPR_PRI_N3 ((uint32_t)0xFF000000) /*!< Priority of system handler 7,11, and 15. Reserved, SVCall and SysTick */ + +/****************** Bit definition for SCB_SHCSR register *******************/ +#define SCB_SHCSR_MEMFAULTACT ((uint32_t)0x00000001) /*!< MemManage is active */ +#define SCB_SHCSR_BUSFAULTACT ((uint32_t)0x00000002) /*!< BusFault is active */ +#define SCB_SHCSR_USGFAULTACT ((uint32_t)0x00000008) /*!< UsageFault is active */ +#define SCB_SHCSR_SVCALLACT ((uint32_t)0x00000080) /*!< SVCall is active */ +#define SCB_SHCSR_MONITORACT ((uint32_t)0x00000100) /*!< Monitor is active */ +#define SCB_SHCSR_PENDSVACT ((uint32_t)0x00000400) /*!< PendSV is active */ +#define SCB_SHCSR_SYSTICKACT ((uint32_t)0x00000800) /*!< SysTick is active */ +#define SCB_SHCSR_USGFAULTPENDED ((uint32_t)0x00001000) /*!< Usage Fault is pended */ +#define SCB_SHCSR_MEMFAULTPENDED ((uint32_t)0x00002000) /*!< MemManage is pended */ +#define SCB_SHCSR_BUSFAULTPENDED ((uint32_t)0x00004000) /*!< Bus Fault is pended */ +#define SCB_SHCSR_SVCALLPENDED ((uint32_t)0x00008000) /*!< SVCall is pended */ +#define SCB_SHCSR_MEMFAULTENA ((uint32_t)0x00010000) /*!< MemManage enable */ +#define SCB_SHCSR_BUSFAULTENA ((uint32_t)0x00020000) /*!< Bus Fault enable */ +#define SCB_SHCSR_USGFAULTENA ((uint32_t)0x00040000) /*!< UsageFault enable */ + +/******************* Bit definition for SCB_CFSR register *******************/ +/*!< MFSR */ +#define SCB_CFSR_IACCVIOL ((uint32_t)0x00000001) /*!< Instruction access violation */ +#define SCB_CFSR_DACCVIOL ((uint32_t)0x00000002) /*!< Data access violation */ +#define SCB_CFSR_MUNSTKERR ((uint32_t)0x00000008) /*!< Unstacking error */ +#define SCB_CFSR_MSTKERR ((uint32_t)0x00000010) /*!< Stacking error */ +#define SCB_CFSR_MMARVALID ((uint32_t)0x00000080) /*!< Memory Manage Address Register address valid flag */ +/*!< BFSR */ +#define SCB_CFSR_IBUSERR ((uint32_t)0x00000100) /*!< Instruction bus error flag */ +#define SCB_CFSR_PRECISERR ((uint32_t)0x00000200) /*!< Precise data bus error */ +#define SCB_CFSR_IMPRECISERR ((uint32_t)0x00000400) /*!< Imprecise data bus error */ +#define SCB_CFSR_UNSTKERR ((uint32_t)0x00000800) /*!< Unstacking error */ +#define SCB_CFSR_STKERR ((uint32_t)0x00001000) /*!< Stacking error */ +#define SCB_CFSR_BFARVALID ((uint32_t)0x00008000) /*!< Bus Fault Address Register address valid flag */ +/*!< UFSR */ +#define SCB_CFSR_UNDEFINSTR ((uint32_t)0x00010000) /*!< The processor attempt to excecute an undefined instruction */ +#define SCB_CFSR_INVSTATE ((uint32_t)0x00020000) /*!< Invalid combination of EPSR and instruction */ +#define SCB_CFSR_INVPC ((uint32_t)0x00040000) /*!< Attempt to load EXC_RETURN into pc illegally */ +#define SCB_CFSR_NOCP ((uint32_t)0x00080000) /*!< Attempt to use a coprocessor instruction */ +#define SCB_CFSR_UNALIGNED ((uint32_t)0x01000000) /*!< Fault occurs when there is an attempt to make an unaligned memory access */ +#define SCB_CFSR_DIVBYZERO ((uint32_t)0x02000000) /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */ + +/******************* Bit definition for SCB_HFSR register *******************/ +#define SCB_HFSR_VECTTBL ((uint32_t)0x00000002) /*!< Fault occures because of vector table read on exception processing */ +#define SCB_HFSR_FORCED ((uint32_t)0x40000000) /*!< Hard Fault activated when a configurable Fault was received and cannot activate */ +#define SCB_HFSR_DEBUGEVT ((uint32_t)0x80000000) /*!< Fault related to debug */ + +/******************* Bit definition for SCB_DFSR register *******************/ +#define SCB_DFSR_HALTED ((uint8_t)0x01) /*!< Halt request flag */ +#define SCB_DFSR_BKPT ((uint8_t)0x02) /*!< BKPT flag */ +#define SCB_DFSR_DWTTRAP ((uint8_t)0x04) /*!< Data Watchpoint and Trace (DWT) flag */ +#define SCB_DFSR_VCATCH ((uint8_t)0x08) /*!< Vector catch flag */ +#define SCB_DFSR_EXTERNAL ((uint8_t)0x10) /*!< External debug request flag */ + +/******************* Bit definition for SCB_MMFAR register ******************/ +#define SCB_MMFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Mem Manage fault address field */ + +/******************* Bit definition for SCB_BFAR register *******************/ +#define SCB_BFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Bus fault address field */ + +/******************* Bit definition for SCB_afsr register *******************/ +#define SCB_AFSR_IMPDEF ((uint32_t)0xFFFFFFFF) /*!< Implementation defined */ + +/******************************************************************************/ +/* */ +/* External Interrupt/Event Controller */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for EXTI_IMR register *******************/ +#define EXTI_IMR_MR0 ((uint32_t)0x00000001) /*!< Interrupt Mask on line 0 */ +#define EXTI_IMR_MR1 ((uint32_t)0x00000002) /*!< Interrupt Mask on line 1 */ +#define EXTI_IMR_MR2 ((uint32_t)0x00000004) /*!< Interrupt Mask on line 2 */ +#define EXTI_IMR_MR3 ((uint32_t)0x00000008) /*!< Interrupt Mask on line 3 */ +#define EXTI_IMR_MR4 ((uint32_t)0x00000010) /*!< Interrupt Mask on line 4 */ +#define EXTI_IMR_MR5 ((uint32_t)0x00000020) /*!< Interrupt Mask on line 5 */ +#define EXTI_IMR_MR6 ((uint32_t)0x00000040) /*!< Interrupt Mask on line 6 */ +#define EXTI_IMR_MR7 ((uint32_t)0x00000080) /*!< Interrupt Mask on line 7 */ +#define EXTI_IMR_MR8 ((uint32_t)0x00000100) /*!< Interrupt Mask on line 8 */ +#define EXTI_IMR_MR9 ((uint32_t)0x00000200) /*!< Interrupt Mask on line 9 */ +#define EXTI_IMR_MR10 ((uint32_t)0x00000400) /*!< Interrupt Mask on line 10 */ +#define EXTI_IMR_MR11 ((uint32_t)0x00000800) /*!< Interrupt Mask on line 11 */ +#define EXTI_IMR_MR12 ((uint32_t)0x00001000) /*!< Interrupt Mask on line 12 */ +#define EXTI_IMR_MR13 ((uint32_t)0x00002000) /*!< Interrupt Mask on line 13 */ +#define EXTI_IMR_MR14 ((uint32_t)0x00004000) /*!< Interrupt Mask on line 14 */ +#define EXTI_IMR_MR15 ((uint32_t)0x00008000) /*!< Interrupt Mask on line 15 */ +#define EXTI_IMR_MR16 ((uint32_t)0x00010000) /*!< Interrupt Mask on line 16 */ +#define EXTI_IMR_MR17 ((uint32_t)0x00020000) /*!< Interrupt Mask on line 17 */ +#define EXTI_IMR_MR18 ((uint32_t)0x00040000) /*!< Interrupt Mask on line 18 */ +#define EXTI_IMR_MR19 ((uint32_t)0x00080000) /*!< Interrupt Mask on line 19 */ + +/******************* Bit definition for EXTI_EMR register *******************/ +#define EXTI_EMR_MR0 ((uint32_t)0x00000001) /*!< Event Mask on line 0 */ +#define EXTI_EMR_MR1 ((uint32_t)0x00000002) /*!< Event Mask on line 1 */ +#define EXTI_EMR_MR2 ((uint32_t)0x00000004) /*!< Event Mask on line 2 */ +#define EXTI_EMR_MR3 ((uint32_t)0x00000008) /*!< Event Mask on line 3 */ +#define EXTI_EMR_MR4 ((uint32_t)0x00000010) /*!< Event Mask on line 4 */ +#define EXTI_EMR_MR5 ((uint32_t)0x00000020) /*!< Event Mask on line 5 */ +#define EXTI_EMR_MR6 ((uint32_t)0x00000040) /*!< Event Mask on line 6 */ +#define EXTI_EMR_MR7 ((uint32_t)0x00000080) /*!< Event Mask on line 7 */ +#define EXTI_EMR_MR8 ((uint32_t)0x00000100) /*!< Event Mask on line 8 */ +#define EXTI_EMR_MR9 ((uint32_t)0x00000200) /*!< Event Mask on line 9 */ +#define EXTI_EMR_MR10 ((uint32_t)0x00000400) /*!< Event Mask on line 10 */ +#define EXTI_EMR_MR11 ((uint32_t)0x00000800) /*!< Event Mask on line 11 */ +#define EXTI_EMR_MR12 ((uint32_t)0x00001000) /*!< Event Mask on line 12 */ +#define EXTI_EMR_MR13 ((uint32_t)0x00002000) /*!< Event Mask on line 13 */ +#define EXTI_EMR_MR14 ((uint32_t)0x00004000) /*!< Event Mask on line 14 */ +#define EXTI_EMR_MR15 ((uint32_t)0x00008000) /*!< Event Mask on line 15 */ +#define EXTI_EMR_MR16 ((uint32_t)0x00010000) /*!< Event Mask on line 16 */ +#define EXTI_EMR_MR17 ((uint32_t)0x00020000) /*!< Event Mask on line 17 */ +#define EXTI_EMR_MR18 ((uint32_t)0x00040000) /*!< Event Mask on line 18 */ +#define EXTI_EMR_MR19 ((uint32_t)0x00080000) /*!< Event Mask on line 19 */ + +/****************** Bit definition for EXTI_RTSR register *******************/ +#define EXTI_RTSR_TR0 ((uint32_t)0x00000001) /*!< Rising trigger event configuration bit of line 0 */ +#define EXTI_RTSR_TR1 ((uint32_t)0x00000002) /*!< Rising trigger event configuration bit of line 1 */ +#define EXTI_RTSR_TR2 ((uint32_t)0x00000004) /*!< Rising trigger event configuration bit of line 2 */ +#define EXTI_RTSR_TR3 ((uint32_t)0x00000008) /*!< Rising trigger event configuration bit of line 3 */ +#define EXTI_RTSR_TR4 ((uint32_t)0x00000010) /*!< Rising trigger event configuration bit of line 4 */ +#define EXTI_RTSR_TR5 ((uint32_t)0x00000020) /*!< Rising trigger event configuration bit of line 5 */ +#define EXTI_RTSR_TR6 ((uint32_t)0x00000040) /*!< Rising trigger event configuration bit of line 6 */ +#define EXTI_RTSR_TR7 ((uint32_t)0x00000080) /*!< Rising trigger event configuration bit of line 7 */ +#define EXTI_RTSR_TR8 ((uint32_t)0x00000100) /*!< Rising trigger event configuration bit of line 8 */ +#define EXTI_RTSR_TR9 ((uint32_t)0x00000200) /*!< Rising trigger event configuration bit of line 9 */ +#define EXTI_RTSR_TR10 ((uint32_t)0x00000400) /*!< Rising trigger event configuration bit of line 10 */ +#define EXTI_RTSR_TR11 ((uint32_t)0x00000800) /*!< Rising trigger event configuration bit of line 11 */ +#define EXTI_RTSR_TR12 ((uint32_t)0x00001000) /*!< Rising trigger event configuration bit of line 12 */ +#define EXTI_RTSR_TR13 ((uint32_t)0x00002000) /*!< Rising trigger event configuration bit of line 13 */ +#define EXTI_RTSR_TR14 ((uint32_t)0x00004000) /*!< Rising trigger event configuration bit of line 14 */ +#define EXTI_RTSR_TR15 ((uint32_t)0x00008000) /*!< Rising trigger event configuration bit of line 15 */ +#define EXTI_RTSR_TR16 ((uint32_t)0x00010000) /*!< Rising trigger event configuration bit of line 16 */ +#define EXTI_RTSR_TR17 ((uint32_t)0x00020000) /*!< Rising trigger event configuration bit of line 17 */ +#define EXTI_RTSR_TR18 ((uint32_t)0x00040000) /*!< Rising trigger event configuration bit of line 18 */ +#define EXTI_RTSR_TR19 ((uint32_t)0x00080000) /*!< Rising trigger event configuration bit of line 19 */ + +/****************** Bit definition for EXTI_FTSR register *******************/ +#define EXTI_FTSR_TR0 ((uint32_t)0x00000001) /*!< Falling trigger event configuration bit of line 0 */ +#define EXTI_FTSR_TR1 ((uint32_t)0x00000002) /*!< Falling trigger event configuration bit of line 1 */ +#define EXTI_FTSR_TR2 ((uint32_t)0x00000004) /*!< Falling trigger event configuration bit of line 2 */ +#define EXTI_FTSR_TR3 ((uint32_t)0x00000008) /*!< Falling trigger event configuration bit of line 3 */ +#define EXTI_FTSR_TR4 ((uint32_t)0x00000010) /*!< Falling trigger event configuration bit of line 4 */ +#define EXTI_FTSR_TR5 ((uint32_t)0x00000020) /*!< Falling trigger event configuration bit of line 5 */ +#define EXTI_FTSR_TR6 ((uint32_t)0x00000040) /*!< Falling trigger event configuration bit of line 6 */ +#define EXTI_FTSR_TR7 ((uint32_t)0x00000080) /*!< Falling trigger event configuration bit of line 7 */ +#define EXTI_FTSR_TR8 ((uint32_t)0x00000100) /*!< Falling trigger event configuration bit of line 8 */ +#define EXTI_FTSR_TR9 ((uint32_t)0x00000200) /*!< Falling trigger event configuration bit of line 9 */ +#define EXTI_FTSR_TR10 ((uint32_t)0x00000400) /*!< Falling trigger event configuration bit of line 10 */ +#define EXTI_FTSR_TR11 ((uint32_t)0x00000800) /*!< Falling trigger event configuration bit of line 11 */ +#define EXTI_FTSR_TR12 ((uint32_t)0x00001000) /*!< Falling trigger event configuration bit of line 12 */ +#define EXTI_FTSR_TR13 ((uint32_t)0x00002000) /*!< Falling trigger event configuration bit of line 13 */ +#define EXTI_FTSR_TR14 ((uint32_t)0x00004000) /*!< Falling trigger event configuration bit of line 14 */ +#define EXTI_FTSR_TR15 ((uint32_t)0x00008000) /*!< Falling trigger event configuration bit of line 15 */ +#define EXTI_FTSR_TR16 ((uint32_t)0x00010000) /*!< Falling trigger event configuration bit of line 16 */ +#define EXTI_FTSR_TR17 ((uint32_t)0x00020000) /*!< Falling trigger event configuration bit of line 17 */ +#define EXTI_FTSR_TR18 ((uint32_t)0x00040000) /*!< Falling trigger event configuration bit of line 18 */ +#define EXTI_FTSR_TR19 ((uint32_t)0x00080000) /*!< Falling trigger event configuration bit of line 19 */ + +/****************** Bit definition for EXTI_SWIER register ******************/ +#define EXTI_SWIER_SWIER0 ((uint32_t)0x00000001) /*!< Software Interrupt on line 0 */ +#define EXTI_SWIER_SWIER1 ((uint32_t)0x00000002) /*!< Software Interrupt on line 1 */ +#define EXTI_SWIER_SWIER2 ((uint32_t)0x00000004) /*!< Software Interrupt on line 2 */ +#define EXTI_SWIER_SWIER3 ((uint32_t)0x00000008) /*!< Software Interrupt on line 3 */ +#define EXTI_SWIER_SWIER4 ((uint32_t)0x00000010) /*!< Software Interrupt on line 4 */ +#define EXTI_SWIER_SWIER5 ((uint32_t)0x00000020) /*!< Software Interrupt on line 5 */ +#define EXTI_SWIER_SWIER6 ((uint32_t)0x00000040) /*!< Software Interrupt on line 6 */ +#define EXTI_SWIER_SWIER7 ((uint32_t)0x00000080) /*!< Software Interrupt on line 7 */ +#define EXTI_SWIER_SWIER8 ((uint32_t)0x00000100) /*!< Software Interrupt on line 8 */ +#define EXTI_SWIER_SWIER9 ((uint32_t)0x00000200) /*!< Software Interrupt on line 9 */ +#define EXTI_SWIER_SWIER10 ((uint32_t)0x00000400) /*!< Software Interrupt on line 10 */ +#define EXTI_SWIER_SWIER11 ((uint32_t)0x00000800) /*!< Software Interrupt on line 11 */ +#define EXTI_SWIER_SWIER12 ((uint32_t)0x00001000) /*!< Software Interrupt on line 12 */ +#define EXTI_SWIER_SWIER13 ((uint32_t)0x00002000) /*!< Software Interrupt on line 13 */ +#define EXTI_SWIER_SWIER14 ((uint32_t)0x00004000) /*!< Software Interrupt on line 14 */ +#define EXTI_SWIER_SWIER15 ((uint32_t)0x00008000) /*!< Software Interrupt on line 15 */ +#define EXTI_SWIER_SWIER16 ((uint32_t)0x00010000) /*!< Software Interrupt on line 16 */ +#define EXTI_SWIER_SWIER17 ((uint32_t)0x00020000) /*!< Software Interrupt on line 17 */ +#define EXTI_SWIER_SWIER18 ((uint32_t)0x00040000) /*!< Software Interrupt on line 18 */ +#define EXTI_SWIER_SWIER19 ((uint32_t)0x00080000) /*!< Software Interrupt on line 19 */ + +/******************* Bit definition for EXTI_PR register ********************/ +#define EXTI_PR_PR0 ((uint32_t)0x00000001) /*!< Pending bit for line 0 */ +#define EXTI_PR_PR1 ((uint32_t)0x00000002) /*!< Pending bit for line 1 */ +#define EXTI_PR_PR2 ((uint32_t)0x00000004) /*!< Pending bit for line 2 */ +#define EXTI_PR_PR3 ((uint32_t)0x00000008) /*!< Pending bit for line 3 */ +#define EXTI_PR_PR4 ((uint32_t)0x00000010) /*!< Pending bit for line 4 */ +#define EXTI_PR_PR5 ((uint32_t)0x00000020) /*!< Pending bit for line 5 */ +#define EXTI_PR_PR6 ((uint32_t)0x00000040) /*!< Pending bit for line 6 */ +#define EXTI_PR_PR7 ((uint32_t)0x00000080) /*!< Pending bit for line 7 */ +#define EXTI_PR_PR8 ((uint32_t)0x00000100) /*!< Pending bit for line 8 */ +#define EXTI_PR_PR9 ((uint32_t)0x00000200) /*!< Pending bit for line 9 */ +#define EXTI_PR_PR10 ((uint32_t)0x00000400) /*!< Pending bit for line 10 */ +#define EXTI_PR_PR11 ((uint32_t)0x00000800) /*!< Pending bit for line 11 */ +#define EXTI_PR_PR12 ((uint32_t)0x00001000) /*!< Pending bit for line 12 */ +#define EXTI_PR_PR13 ((uint32_t)0x00002000) /*!< Pending bit for line 13 */ +#define EXTI_PR_PR14 ((uint32_t)0x00004000) /*!< Pending bit for line 14 */ +#define EXTI_PR_PR15 ((uint32_t)0x00008000) /*!< Pending bit for line 15 */ +#define EXTI_PR_PR16 ((uint32_t)0x00010000) /*!< Pending bit for line 16 */ +#define EXTI_PR_PR17 ((uint32_t)0x00020000) /*!< Pending bit for line 17 */ +#define EXTI_PR_PR18 ((uint32_t)0x00040000) /*!< Pending bit for line 18 */ +#define EXTI_PR_PR19 ((uint32_t)0x00080000) /*!< Pending bit for line 19 */ + +/******************************************************************************/ +/* */ +/* DMA Controller */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for DMA_ISR register ********************/ +#define DMA_ISR_GIF1 ((uint32_t)0x00000001) /*!< Channel 1 Global interrupt flag */ +#define DMA_ISR_TCIF1 ((uint32_t)0x00000002) /*!< Channel 1 Transfer Complete flag */ +#define DMA_ISR_HTIF1 ((uint32_t)0x00000004) /*!< Channel 1 Half Transfer flag */ +#define DMA_ISR_TEIF1 ((uint32_t)0x00000008) /*!< Channel 1 Transfer Error flag */ +#define DMA_ISR_GIF2 ((uint32_t)0x00000010) /*!< Channel 2 Global interrupt flag */ +#define DMA_ISR_TCIF2 ((uint32_t)0x00000020) /*!< Channel 2 Transfer Complete flag */ +#define DMA_ISR_HTIF2 ((uint32_t)0x00000040) /*!< Channel 2 Half Transfer flag */ +#define DMA_ISR_TEIF2 ((uint32_t)0x00000080) /*!< Channel 2 Transfer Error flag */ +#define DMA_ISR_GIF3 ((uint32_t)0x00000100) /*!< Channel 3 Global interrupt flag */ +#define DMA_ISR_TCIF3 ((uint32_t)0x00000200) /*!< Channel 3 Transfer Complete flag */ +#define DMA_ISR_HTIF3 ((uint32_t)0x00000400) /*!< Channel 3 Half Transfer flag */ +#define DMA_ISR_TEIF3 ((uint32_t)0x00000800) /*!< Channel 3 Transfer Error flag */ +#define DMA_ISR_GIF4 ((uint32_t)0x00001000) /*!< Channel 4 Global interrupt flag */ +#define DMA_ISR_TCIF4 ((uint32_t)0x00002000) /*!< Channel 4 Transfer Complete flag */ +#define DMA_ISR_HTIF4 ((uint32_t)0x00004000) /*!< Channel 4 Half Transfer flag */ +#define DMA_ISR_TEIF4 ((uint32_t)0x00008000) /*!< Channel 4 Transfer Error flag */ +#define DMA_ISR_GIF5 ((uint32_t)0x00010000) /*!< Channel 5 Global interrupt flag */ +#define DMA_ISR_TCIF5 ((uint32_t)0x00020000) /*!< Channel 5 Transfer Complete flag */ +#define DMA_ISR_HTIF5 ((uint32_t)0x00040000) /*!< Channel 5 Half Transfer flag */ +#define DMA_ISR_TEIF5 ((uint32_t)0x00080000) /*!< Channel 5 Transfer Error flag */ +#define DMA_ISR_GIF6 ((uint32_t)0x00100000) /*!< Channel 6 Global interrupt flag */ +#define DMA_ISR_TCIF6 ((uint32_t)0x00200000) /*!< Channel 6 Transfer Complete flag */ +#define DMA_ISR_HTIF6 ((uint32_t)0x00400000) /*!< Channel 6 Half Transfer flag */ +#define DMA_ISR_TEIF6 ((uint32_t)0x00800000) /*!< Channel 6 Transfer Error flag */ +#define DMA_ISR_GIF7 ((uint32_t)0x01000000) /*!< Channel 7 Global interrupt flag */ +#define DMA_ISR_TCIF7 ((uint32_t)0x02000000) /*!< Channel 7 Transfer Complete flag */ +#define DMA_ISR_HTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer flag */ +#define DMA_ISR_TEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error flag */ + +/******************* Bit definition for DMA_IFCR register *******************/ +#define DMA_IFCR_CGIF1 ((uint32_t)0x00000001) /*!< Channel 1 Global interrupt clearr */ +#define DMA_IFCR_CTCIF1 ((uint32_t)0x00000002) /*!< Channel 1 Transfer Complete clear */ +#define DMA_IFCR_CHTIF1 ((uint32_t)0x00000004) /*!< Channel 1 Half Transfer clear */ +#define DMA_IFCR_CTEIF1 ((uint32_t)0x00000008) /*!< Channel 1 Transfer Error clear */ +#define DMA_IFCR_CGIF2 ((uint32_t)0x00000010) /*!< Channel 2 Global interrupt clear */ +#define DMA_IFCR_CTCIF2 ((uint32_t)0x00000020) /*!< Channel 2 Transfer Complete clear */ +#define DMA_IFCR_CHTIF2 ((uint32_t)0x00000040) /*!< Channel 2 Half Transfer clear */ +#define DMA_IFCR_CTEIF2 ((uint32_t)0x00000080) /*!< Channel 2 Transfer Error clear */ +#define DMA_IFCR_CGIF3 ((uint32_t)0x00000100) /*!< Channel 3 Global interrupt clear */ +#define DMA_IFCR_CTCIF3 ((uint32_t)0x00000200) /*!< Channel 3 Transfer Complete clear */ +#define DMA_IFCR_CHTIF3 ((uint32_t)0x00000400) /*!< Channel 3 Half Transfer clear */ +#define DMA_IFCR_CTEIF3 ((uint32_t)0x00000800) /*!< Channel 3 Transfer Error clear */ +#define DMA_IFCR_CGIF4 ((uint32_t)0x00001000) /*!< Channel 4 Global interrupt clear */ +#define DMA_IFCR_CTCIF4 ((uint32_t)0x00002000) /*!< Channel 4 Transfer Complete clear */ +#define DMA_IFCR_CHTIF4 ((uint32_t)0x00004000) /*!< Channel 4 Half Transfer clear */ +#define DMA_IFCR_CTEIF4 ((uint32_t)0x00008000) /*!< Channel 4 Transfer Error clear */ +#define DMA_IFCR_CGIF5 ((uint32_t)0x00010000) /*!< Channel 5 Global interrupt clear */ +#define DMA_IFCR_CTCIF5 ((uint32_t)0x00020000) /*!< Channel 5 Transfer Complete clear */ +#define DMA_IFCR_CHTIF5 ((uint32_t)0x00040000) /*!< Channel 5 Half Transfer clear */ +#define DMA_IFCR_CTEIF5 ((uint32_t)0x00080000) /*!< Channel 5 Transfer Error clear */ +#define DMA_IFCR_CGIF6 ((uint32_t)0x00100000) /*!< Channel 6 Global interrupt clear */ +#define DMA_IFCR_CTCIF6 ((uint32_t)0x00200000) /*!< Channel 6 Transfer Complete clear */ +#define DMA_IFCR_CHTIF6 ((uint32_t)0x00400000) /*!< Channel 6 Half Transfer clear */ +#define DMA_IFCR_CTEIF6 ((uint32_t)0x00800000) /*!< Channel 6 Transfer Error clear */ +#define DMA_IFCR_CGIF7 ((uint32_t)0x01000000) /*!< Channel 7 Global interrupt clear */ +#define DMA_IFCR_CTCIF7 ((uint32_t)0x02000000) /*!< Channel 7 Transfer Complete clear */ +#define DMA_IFCR_CHTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer clear */ +#define DMA_IFCR_CTEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error clear */ + +/******************* Bit definition for DMA_CCR1 register *******************/ +#define DMA_CCR1_EN ((uint16_t)0x0001) /*!< Channel enable*/ +#define DMA_CCR1_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */ +#define DMA_CCR1_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ +#define DMA_CCR1_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ +#define DMA_CCR1_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ +#define DMA_CCR1_CIRC ((uint16_t)0x0020) /*!< Circular mode */ +#define DMA_CCR1_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ +#define DMA_CCR1_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ + +#define DMA_CCR1_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ +#define DMA_CCR1_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ +#define DMA_CCR1_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ + +#define DMA_CCR1_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ +#define DMA_CCR1_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ +#define DMA_CCR1_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ + +#define DMA_CCR1_PL ((uint16_t)0x3000) /*!< PL[1:0] bits(Channel Priority level) */ +#define DMA_CCR1_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ +#define DMA_CCR1_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ + +#define DMA_CCR1_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ + +/******************* Bit definition for DMA_CCR2 register *******************/ +#define DMA_CCR2_EN ((uint16_t)0x0001) /*!< Channel enable */ +#define DMA_CCR2_TCIE ((uint16_t)0x0002) /*!< ransfer complete interrupt enable */ +#define DMA_CCR2_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ +#define DMA_CCR2_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ +#define DMA_CCR2_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ +#define DMA_CCR2_CIRC ((uint16_t)0x0020) /*!< Circular mode */ +#define DMA_CCR2_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ +#define DMA_CCR2_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ + +#define DMA_CCR2_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ +#define DMA_CCR2_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ +#define DMA_CCR2_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ + +#define DMA_CCR2_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ +#define DMA_CCR2_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ +#define DMA_CCR2_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ + +#define DMA_CCR2_PL ((uint16_t)0x3000) /*!< PL[1:0] bits (Channel Priority level) */ +#define DMA_CCR2_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ +#define DMA_CCR2_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ + +#define DMA_CCR2_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ + +/******************* Bit definition for DMA_CCR3 register *******************/ +#define DMA_CCR3_EN ((uint16_t)0x0001) /*!< Channel enable */ +#define DMA_CCR3_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */ +#define DMA_CCR3_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ +#define DMA_CCR3_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ +#define DMA_CCR3_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ +#define DMA_CCR3_CIRC ((uint16_t)0x0020) /*!< Circular mode */ +#define DMA_CCR3_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ +#define DMA_CCR3_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ + +#define DMA_CCR3_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ +#define DMA_CCR3_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ +#define DMA_CCR3_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ + +#define DMA_CCR3_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ +#define DMA_CCR3_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ +#define DMA_CCR3_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ + +#define DMA_CCR3_PL ((uint16_t)0x3000) /*!< PL[1:0] bits (Channel Priority level) */ +#define DMA_CCR3_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ +#define DMA_CCR3_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ + +#define DMA_CCR3_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ + +/*!<****************** Bit definition for DMA_CCR4 register *******************/ +#define DMA_CCR4_EN ((uint16_t)0x0001) /*!
© COPYRIGHT 2011 STMicroelectronics
- ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32f2xx - * @{ - */ - -#ifndef __STM32F2xx_H -#define __STM32F2xx_H - -#ifdef __cplusplus - extern "C" { -#endif /* __cplusplus */ - -/** @addtogroup Library_configuration_section - * @{ - */ - -/* Uncomment the line below according to the target STM32 device used in your - application - */ - -#if !defined (STM32F2XX) - #define STM32F2XX -#endif - -/* Tip: To avoid modifying this file each time you need to switch between these - devices, you can define the device in your toolchain compiler preprocessor. - */ - -#if !defined (STM32F2XX) - #error "Please select first the target STM32F2XX device used in your application (in stm32f2xx.h file)" -#endif - -#if !defined (USE_STDPERIPH_DRIVER) -/** - * @brief Comment the line below if you will not use the peripherals drivers. - In this case, these drivers will not be included and the application code will - be based on direct access to peripherals registers - */ - /*#define USE_STDPERIPH_DRIVER*/ -#endif /* USE_STDPERIPH_DRIVER */ - -/** - * @brief In the following line adjust the value of External High Speed oscillator (HSE) - used in your application - - Tip: To avoid modifying this file each time you need to use different HSE, you - can define the HSE value in your toolchain compiler preprocessor. - */ -#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ - -/** - * @brief In the following line adjust the External High Speed oscillator (HSE) Startup - Timeout value - */ -#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ -#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ - -/** - * @brief STM32F2Xxx Standard Peripherals Library version number V1.0.0 - */ -#define __STM32F2XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ -#define __STM32F2XX_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ -#define __STM32F2XX_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ -#define __STM32F2XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ -#define __STM32F2XX_STDPERIPH_VERSION ((__STM32F2XX_STDPERIPH_VERSION_MAIN << 24)\ - |(__STM32F2XX_STDPERIPH_VERSION_SUB1 << 16)\ - |(__STM32F2XX_STDPERIPH_VERSION_SUB2 << 8)\ - |(__STM32F2XX_STDPERIPH_VERSION_RC)) - -/** - * @} - */ - -/** @addtogroup Configuration_section_for_CMSIS - * @{ - */ - -/** - * @brief Configuration of the Cortex-M3 Processor and Core Peripherals - */ -#define __MPU_PRESENT 1 /*!< STM32F2XX provide an MPU */ -#define __NVIC_PRIO_BITS 4 /*!< STM32F2XX uses 4 Bits for the Priority Levels */ -#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ - -/** - * @brief STM32F2XX Interrupt Number Definition, according to the selected device - * in @ref Library_configuration_section - */ -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 */ -/****** STM32 specific Interrupt Numbers **********************************************************************/ - WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ - PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ - TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */ - RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */ - FLASH_IRQn = 4, /*!< FLASH global Interrupt */ - RCC_IRQn = 5, /*!< RCC global Interrupt */ - EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ - EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ - EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ - EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ - EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ - DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */ - DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */ - DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */ - DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */ - DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */ - DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */ - DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ - ADC_IRQn = 18, /*!< ADC1, ADC2 and ADC3 global Interrupts */ - CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */ - CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ - TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ - TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ - OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ - TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ - TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ - TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ - TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ - DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ - FSMC_IRQn = 48, /*!< FSMC global Interrupt */ - SDIO_IRQn = 49, /*!< SDIO global Interrupt */ - TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ - SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ - UART4_IRQn = 52, /*!< UART4 global Interrupt */ - UART5_IRQn = 53, /*!< UART5 global Interrupt */ - TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */ - TIM7_IRQn = 55, /*!< TIM7 global interrupt */ - DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ - DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ - DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ - DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ - DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ - ETH_IRQn = 61, /*!< Ethernet global Interrupt */ - ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ - CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ - CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ - CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ - CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ - OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ - DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ - DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ - DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ - USART6_IRQn = 71, /*!< USART6 global interrupt */ - I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ - I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ - OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ - OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ - OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */ - OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ - DCMI_IRQn = 78, /*!< DCMI global interrupt */ - CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */ - HASH_RNG_IRQn = 80 /*!< Hash and Rng global interrupt */ -} IRQn_Type; - -/** - * @} - */ - -//#include "core_cm3.h" -//#include "system_stm32f2xx.h" -#include - -/** @addtogroup Exported_types - * @{ - */ -/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -typedef const int32_t sc32; /*!< Read Only */ -typedef const int16_t sc16; /*!< Read Only */ -typedef const int8_t sc8; /*!< Read Only */ - -typedef __IO int32_t vs32; -typedef __IO int16_t vs16; -typedef __IO int8_t vs8; - -typedef __I int32_t vsc32; /*!< Read Only */ -typedef __I int16_t vsc16; /*!< Read Only */ -typedef __I int8_t vsc8; /*!< Read Only */ - -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -typedef const uint32_t uc32; /*!< Read Only */ -typedef const uint16_t uc16; /*!< Read Only */ -typedef const uint8_t uc8; /*!< Read Only */ - -typedef __IO uint32_t vu32; -typedef __IO uint16_t vu16; -typedef __IO uint8_t vu8; - -typedef __I uint32_t vuc32; /*!< Read Only */ -typedef __I uint16_t vuc16; /*!< Read Only */ -typedef __I uint8_t vuc8; /*!< Read Only */ - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; -#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) - -typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; - -/** - * @} - */ - -/** @addtogroup Peripheral_registers_structures - * @{ - */ - -/** - * @brief Analog to Digital Converter - */ - -typedef struct -{ - __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */ - __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ - __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */ - __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */ - __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */ - __IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x14 */ - __IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x18 */ - __IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x1C */ - __IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x20 */ - __IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x24 */ - __IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x28 */ - __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x2C */ - __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x30 */ - __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x34 */ - __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x38*/ - __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x3C */ - __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x40 */ - __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x44 */ - __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x48 */ - __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x4C */ -} ADC_TypeDef; - -typedef struct -{ - __IO uint32_t CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ - __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ - __IO uint32_t CDR; /*!< ADC common regular data register for dual - AND triple modes, Address offset: ADC1 base address + 0x308 */ -} ADC_Common_TypeDef; - - -/** - * @brief Controller Area Network TxMailBox - */ - -typedef struct -{ - __IO uint32_t TIR; /*!< CAN TX mailbox identifier register */ - __IO uint32_t TDTR; /*!< CAN mailbox data length control and time stamp register */ - __IO uint32_t TDLR; /*!< CAN mailbox data low register */ - __IO uint32_t TDHR; /*!< CAN mailbox data high register */ -} CAN_TxMailBox_TypeDef; - -/** - * @brief Controller Area Network FIFOMailBox - */ - -typedef struct -{ - __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ - __IO uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */ - __IO uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */ - __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ -} CAN_FIFOMailBox_TypeDef; - -/** - * @brief Controller Area Network FilterRegister - */ - -typedef struct -{ - __IO uint32_t FR1; /*!< CAN Filter bank register 1 */ - __IO uint32_t FR2; /*!< CAN Filter bank register 1 */ -} CAN_FilterRegister_TypeDef; - -/** - * @brief Controller Area Network - */ - -typedef struct -{ - __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */ - __IO uint32_t MSR; /*!< CAN master status register, Address offset: 0x04 */ - __IO uint32_t TSR; /*!< CAN transmit status register, Address offset: 0x08 */ - __IO uint32_t RF0R; /*!< CAN receive FIFO 0 register, Address offset: 0x0C */ - __IO uint32_t RF1R; /*!< CAN receive FIFO 1 register, Address offset: 0x10 */ - __IO uint32_t IER; /*!< CAN interrupt enable register, Address offset: 0x14 */ - __IO uint32_t ESR; /*!< CAN error status register, Address offset: 0x18 */ - __IO uint32_t BTR; /*!< CAN bit timing register, Address offset: 0x1C */ - uint32_t RESERVED0[88]; /*!< Reserved, 0x020 - 0x17F */ - CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< CAN Tx MailBox, Address offset: 0x180 - 0x1AC */ - CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< CAN FIFO MailBox, Address offset: 0x1B0 - 0x1CC */ - uint32_t RESERVED1[12]; /*!< Reserved, 0x1D0 - 0x1FF */ - __IO uint32_t FMR; /*!< CAN filter master register, Address offset: 0x200 */ - __IO uint32_t FM1R; /*!< CAN filter mode register, Address offset: 0x204 */ - uint32_t RESERVED2; /*!< Reserved, 0x208 */ - __IO uint32_t FS1R; /*!< CAN filter scale register, Address offset: 0x20C */ - uint32_t RESERVED3; /*!< Reserved, 0x210 */ - __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */ - uint32_t RESERVED4; /*!< Reserved, 0x218 */ - __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */ - uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ - CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */ -} CAN_TypeDef; - -/** - * @brief CRC calculation unit - */ - -typedef struct -{ - __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ - __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ - uint8_t RESERVED0; /*!< Reserved, 0x05 */ - uint16_t RESERVED1; /*!< Reserved, 0x06 */ - __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ -} CRC_TypeDef; - -/** - * @brief Digital to Analog Converter - */ - -typedef struct -{ - __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ - __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ - __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ - __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ - __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ - __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ - __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ - __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ - __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ - __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ - __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ - __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ - __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ - __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ -} DAC_TypeDef; - -/** - * @brief Debug MCU - */ - -typedef struct -{ - __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ - __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ - __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ - __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ -}DBGMCU_TypeDef; - -/** - * @brief DCMI - */ - -typedef struct -{ - __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ - __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ - __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ - __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ - __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ - __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ - __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ - __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ - __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ - __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ - __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ -} DCMI_TypeDef; - -/** - * @brief DMA Controller - */ - -typedef struct -{ - __IO uint32_t CR; /*!< DMA stream x configuration register */ - __IO uint32_t NDTR; /*!< DMA stream x number of data register */ - __IO uint32_t PAR; /*!< DMA stream x peripheral address register */ - __IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */ - __IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */ - __IO uint32_t FCR; /*!< DMA stream x FIFO control register */ -} DMA_Stream_TypeDef; - -typedef struct -{ - __IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */ - __IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */ - __IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */ - __IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */ -} DMA_TypeDef; - -/** - * @brief Ethernet MAC - */ - -typedef struct -{ - __IO uint32_t MACCR; - __IO uint32_t MACFFR; - __IO uint32_t MACHTHR; - __IO uint32_t MACHTLR; - __IO uint32_t MACMIIAR; - __IO uint32_t MACMIIDR; - __IO uint32_t MACFCR; - __IO uint32_t MACVLANTR; /* 8 */ - uint32_t RESERVED0[2]; - __IO uint32_t MACRWUFFR; /* 11 */ - __IO uint32_t MACPMTCSR; - uint32_t RESERVED1[2]; - __IO uint32_t MACSR; /* 15 */ - __IO uint32_t MACIMR; - __IO uint32_t MACA0HR; - __IO uint32_t MACA0LR; - __IO uint32_t MACA1HR; - __IO uint32_t MACA1LR; - __IO uint32_t MACA2HR; - __IO uint32_t MACA2LR; - __IO uint32_t MACA3HR; - __IO uint32_t MACA3LR; /* 24 */ - uint32_t RESERVED2[40]; - __IO uint32_t MMCCR; /* 65 */ - __IO uint32_t MMCRIR; - __IO uint32_t MMCTIR; - __IO uint32_t MMCRIMR; - __IO uint32_t MMCTIMR; /* 69 */ - uint32_t RESERVED3[14]; - __IO uint32_t MMCTGFSCCR; /* 84 */ - __IO uint32_t MMCTGFMSCCR; - uint32_t RESERVED4[5]; - __IO uint32_t MMCTGFCR; - uint32_t RESERVED5[10]; - __IO uint32_t MMCRFCECR; - __IO uint32_t MMCRFAECR; - uint32_t RESERVED6[10]; - __IO uint32_t MMCRGUFCR; - uint32_t RESERVED7[334]; - __IO uint32_t PTPTSCR; - __IO uint32_t PTPSSIR; - __IO uint32_t PTPTSHR; - __IO uint32_t PTPTSLR; - __IO uint32_t PTPTSHUR; - __IO uint32_t PTPTSLUR; - __IO uint32_t PTPTSAR; - __IO uint32_t PTPTTHR; - __IO uint32_t PTPTTLR; - __IO uint32_t RESERVED8; - __IO uint32_t PTPTSSR; /* added for STM32F2xx */ - uint32_t RESERVED9[565]; - __IO uint32_t DMABMR; - __IO uint32_t DMATPDR; - __IO uint32_t DMARPDR; - __IO uint32_t DMARDLAR; - __IO uint32_t DMATDLAR; - __IO uint32_t DMASR; - __IO uint32_t DMAOMR; - __IO uint32_t DMAIER; - __IO uint32_t DMAMFBOCR; - __IO uint32_t DMARSWTR; /* added for STM32F2xx */ - uint32_t RESERVED10[8]; - __IO uint32_t DMACHTDR; - __IO uint32_t DMACHRDR; - __IO uint32_t DMACHTBAR; - __IO uint32_t DMACHRBAR; -} ETH_TypeDef; - -/** - * @brief External Interrupt/Event Controller - */ - -typedef struct -{ - __IO uint32_t IMR; /*!< EXTI Interrupt mask register, Address offset: 0x00 */ - __IO uint32_t EMR; /*!< EXTI Event mask register, Address offset: 0x04 */ - __IO uint32_t RTSR; /*!< EXTI Rising trigger selection register, Address offset: 0x08 */ - __IO uint32_t FTSR; /*!< EXTI Falling trigger selection register, Address offset: 0x0C */ - __IO uint32_t SWIER; /*!< EXTI Software interrupt event register, Address offset: 0x10 */ - __IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */ -} EXTI_TypeDef; - -/** - * @brief FLASH Registers - */ - -typedef struct -{ - __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ - __IO uint32_t KEYR; /*!< FLASH key register, Address offset: 0x04 */ - __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ - __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x0C */ - __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x10 */ - __IO uint32_t OPTCR; /*!< FLASH option control register, Address offset: 0x14 */ -} FLASH_TypeDef; - -/** - * @brief Flexible Static Memory Controller - */ - -typedef struct -{ - __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ -} FSMC_Bank1_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank1E - */ - -typedef struct -{ - __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ -} FSMC_Bank1E_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank2 - */ - -typedef struct -{ - __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */ - __IO uint32_t SR2; /*!< NAND Flash FIFO status and interrupt register 2, Address offset: 0x64 */ - __IO uint32_t PMEM2; /*!< NAND Flash Common memory space timing register 2, Address offset: 0x68 */ - __IO uint32_t PATT2; /*!< NAND Flash Attribute memory space timing register 2, Address offset: 0x6C */ - uint32_t RESERVED0; /*!< Reserved, 0x70 */ - __IO uint32_t ECCR2; /*!< NAND Flash ECC result registers 2, Address offset: 0x74 */ -} FSMC_Bank2_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank3 - */ - -typedef struct -{ - __IO uint32_t PCR3; /*!< NAND Flash control register 3, Address offset: 0x80 */ - __IO uint32_t SR3; /*!< NAND Flash FIFO status and interrupt register 3, Address offset: 0x84 */ - __IO uint32_t PMEM3; /*!< NAND Flash Common memory space timing register 3, Address offset: 0x88 */ - __IO uint32_t PATT3; /*!< NAND Flash Attribute memory space timing register 3, Address offset: 0x8C */ - uint32_t RESERVED0; /*!< Reserved, 0x90 */ - __IO uint32_t ECCR3; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */ -} FSMC_Bank3_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank4 - */ - -typedef struct -{ - __IO uint32_t PCR4; /*!< PC Card control register 4, Address offset: 0xA0 */ - __IO uint32_t SR4; /*!< PC Card FIFO status and interrupt register 4, Address offset: 0xA4 */ - __IO uint32_t PMEM4; /*!< PC Card Common memory space timing register 4, Address offset: 0xA8 */ - __IO uint32_t PATT4; /*!< PC Card Attribute memory space timing register 4, Address offset: 0xAC */ - __IO uint32_t PIO4; /*!< PC Card I/O space timing register 4, Address offset: 0xB0 */ -} FSMC_Bank4_TypeDef; - -/** - * @brief General Purpose I/O - */ - -typedef struct -{ - __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ - __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ - __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ - __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ - __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ - __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ - __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ - __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ - __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ - __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x24-0x28 */ -} GPIO_TypeDef; - -/** - * @brief System configuration controller - */ - -typedef struct -{ - __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */ - __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ - __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ - uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */ - __IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */ -} SYSCFG_TypeDef; - -/** - * @brief Inter-integrated Circuit Interface - */ - -typedef struct -{ - __IO uint16_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ - uint16_t RESERVED0; /*!< Reserved, 0x02 */ - __IO uint16_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ - uint16_t RESERVED1; /*!< Reserved, 0x06 */ - __IO uint16_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */ - uint16_t RESERVED2; /*!< Reserved, 0x0A */ - __IO uint16_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */ - uint16_t RESERVED3; /*!< Reserved, 0x0E */ - __IO uint16_t DR; /*!< I2C Data register, Address offset: 0x10 */ - uint16_t RESERVED4; /*!< Reserved, 0x12 */ - __IO uint16_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */ - uint16_t RESERVED5; /*!< Reserved, 0x16 */ - __IO uint16_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */ - uint16_t RESERVED6; /*!< Reserved, 0x1A */ - __IO uint16_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */ - uint16_t RESERVED7; /*!< Reserved, 0x1E */ - __IO uint16_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */ - uint16_t RESERVED8; /*!< Reserved, 0x22 */ -} I2C_TypeDef; - -/** - * @brief Independent WATCHDOG - */ - -typedef struct -{ - __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ - __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ - __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ - __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ -} IWDG_TypeDef; - -/** - * @brief Power Control - */ - -typedef struct -{ - __IO uint32_t CR; /*!< PWR power control register, Address offset: 0x00 */ - __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */ -} PWR_TypeDef; - -/** - * @brief Reset and Clock Control - */ - -typedef struct -{ - __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ - __IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ - __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ - __IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ - __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ - __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ - __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ - uint32_t RESERVED0; /*!< Reserved, 0x1C */ - __IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ - __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ - uint32_t RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ - __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ - __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ - __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ - uint32_t RESERVED2; /*!< Reserved, 0x3C */ - __IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ - __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ - uint32_t RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ - __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ - __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ - __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ - uint32_t RESERVED4; /*!< Reserved, 0x5C */ - __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ - __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ - uint32_t RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ - __IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ - __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ - uint32_t RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ - __IO uint32_t SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ - __IO uint32_t PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ -} RCC_TypeDef; - -/** - * @brief Real-Time Clock - */ - -typedef struct -{ - __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ - __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ - __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ - __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ - __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ - __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ - __IO uint32_t CALIBR; /*!< RTC calibration register, Address offset: 0x18 */ - __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ - __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ - __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ - uint32_t RESERVED1; /*!< Reserved, 0x28 */ - uint32_t RESERVED2; /*!< Reserved, 0x2C */ - __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ - __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ - uint32_t RESERVED3; /*!< Reserved, 0x38 */ - uint32_t RESERVED4; /*!< Reserved, 0x3C */ - __IO uint32_t TAFCR; /*!< RTC tamper and alternate function configuration register, Address offset: 0x40 */ - uint32_t RESERVED5; /*!< Reserved, 0x44 */ - uint32_t RESERVED6; /*!< Reserved, 0x48 */ - uint32_t RESERVED7; /*!< Reserved, 0x4C */ - __IO uint32_t BKP0R; /*!< RTC backup register 1, Address offset: 0x50 */ - __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */ - __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */ - __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */ - __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */ - __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */ - __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */ - __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */ - __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */ - __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */ - __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */ - __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */ - __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */ - __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */ - __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */ - __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */ - __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */ - __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */ - __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */ - __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */ -} RTC_TypeDef; - -/** - * @brief SD host Interface - */ - -typedef struct -{ - __IO uint32_t POWER; /*!< SDIO power control register, Address offset: 0x00 */ - __IO uint32_t CLKCR; /*!< SDI clock control register, Address offset: 0x04 */ - __IO uint32_t ARG; /*!< SDIO argument register, Address offset: 0x08 */ - __IO uint32_t CMD; /*!< SDIO command register, Address offset: 0x0C */ - __I uint32_t RESPCMD; /*!< SDIO command response register, Address offset: 0x10 */ - __I uint32_t RESP1; /*!< SDIO response 1 register, Address offset: 0x14 */ - __I uint32_t RESP2; /*!< SDIO response 2 register, Address offset: 0x18 */ - __I uint32_t RESP3; /*!< SDIO response 3 register, Address offset: 0x1C */ - __I uint32_t RESP4; /*!< SDIO response 4 register, Address offset: 0x20 */ - __IO uint32_t DTIMER; /*!< SDIO data timer register, Address offset: 0x24 */ - __IO uint32_t DLEN; /*!< SDIO data length register, Address offset: 0x28 */ - __IO uint32_t DCTRL; /*!< SDIO data control register, Address offset: 0x2C */ - __I uint32_t DCOUNT; /*!< SDIO data counter register, Address offset: 0x30 */ - __I uint32_t STA; /*!< SDIO status register, Address offset: 0x34 */ - __IO uint32_t ICR; /*!< SDIO interrupt clear register, Address offset: 0x38 */ - __IO uint32_t MASK; /*!< SDIO mask register, Address offset: 0x3C */ - uint32_t RESERVED0[2]; /*!< Reserved, 0x40-0x44 */ - __I uint32_t FIFOCNT; /*!< SDIO FIFO counter register, Address offset: 0x48 */ - uint32_t RESERVED1[13]; /*!< Reserved, 0x4C-0x7C */ - __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */ -} SDIO_TypeDef; - -/** - * @brief Serial Peripheral Interface - */ - -typedef struct -{ - __IO uint16_t CR1; /*!< SPI control register 1 (not used in I2S mode), Address offset: 0x00 */ - uint16_t RESERVED0; /*!< Reserved, 0x02 */ - __IO uint16_t CR2; /*!< SPI control register 2, Address offset: 0x04 */ - uint16_t RESERVED1; /*!< Reserved, 0x06 */ - __IO uint16_t SR; /*!< SPI status register, Address offset: 0x08 */ - uint16_t RESERVED2; /*!< Reserved, 0x0A */ - __IO uint16_t DR; /*!< SPI data register, Address offset: 0x0C */ - uint16_t RESERVED3; /*!< Reserved, 0x0E */ - __IO uint16_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */ - uint16_t RESERVED4; /*!< Reserved, 0x12 */ - __IO uint16_t RXCRCR; /*!< SPI RX CRC register (not used in I2S mode), Address offset: 0x14 */ - uint16_t RESERVED5; /*!< Reserved, 0x16 */ - __IO uint16_t TXCRCR; /*!< SPI TX CRC register (not used in I2S mode), Address offset: 0x18 */ - uint16_t RESERVED6; /*!< Reserved, 0x1A */ - __IO uint16_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */ - uint16_t RESERVED7; /*!< Reserved, 0x1E */ - __IO uint16_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ - uint16_t RESERVED8; /*!< Reserved, 0x22 */ -} SPI_TypeDef; - -/** - * @brief TIM - */ - -typedef struct -{ - __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ - uint16_t RESERVED0; /*!< Reserved, 0x02 */ - __IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ - uint16_t RESERVED1; /*!< Reserved, 0x06 */ - __IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ - uint16_t RESERVED2; /*!< Reserved, 0x0A */ - __IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ - uint16_t RESERVED3; /*!< Reserved, 0x0E */ - __IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */ - uint16_t RESERVED4; /*!< Reserved, 0x12 */ - __IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ - uint16_t RESERVED5; /*!< Reserved, 0x16 */ - __IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ - uint16_t RESERVED6; /*!< Reserved, 0x1A */ - __IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ - uint16_t RESERVED7; /*!< Reserved, 0x1E */ - __IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ - uint16_t RESERVED8; /*!< Reserved, 0x22 */ - __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ - __IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ - uint16_t RESERVED9; /*!< Reserved, 0x2A */ - __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ - __IO uint16_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ - uint16_t RESERVED10; /*!< Reserved, 0x32 */ - __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ - __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ - __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ - __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ - __IO uint16_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ - uint16_t RESERVED11; /*!< Reserved, 0x46 */ - __IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ - uint16_t RESERVED12; /*!< Reserved, 0x4A */ - __IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ - uint16_t RESERVED13; /*!< Reserved, 0x4E */ - __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */ - uint16_t RESERVED14; /*!< Reserved, 0x52 */ -} TIM_TypeDef; - -/** - * @brief Universal Synchronous Asynchronous Receiver Transmitter - */ - -typedef struct -{ - __IO uint16_t SR; /*!< USART Status register, Address offset: 0x00 */ - uint16_t RESERVED0; /*!< Reserved, 0x02 */ - __IO uint16_t DR; /*!< USART Data register, Address offset: 0x04 */ - uint16_t RESERVED1; /*!< Reserved, 0x06 */ - __IO uint16_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */ - uint16_t RESERVED2; /*!< Reserved, 0x0A */ - __IO uint16_t CR1; /*!< USART Control register 1, Address offset: 0x0C */ - uint16_t RESERVED3; /*!< Reserved, 0x0E */ - __IO uint16_t CR2; /*!< USART Control register 2, Address offset: 0x10 */ - uint16_t RESERVED4; /*!< Reserved, 0x12 */ - __IO uint16_t CR3; /*!< USART Control register 3, Address offset: 0x14 */ - uint16_t RESERVED5; /*!< Reserved, 0x16 */ - __IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */ - uint16_t RESERVED6; /*!< Reserved, 0x1A */ -} USART_TypeDef; - -/** - * @brief Window WATCHDOG - */ - -typedef struct -{ - __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ - __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ - __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ -} WWDG_TypeDef; - -/** - * @brief Crypto Processor - */ - -typedef struct -{ - __IO uint32_t CR; /*!< CRYP control register, Address offset: 0x00 */ - __IO uint32_t SR; /*!< CRYP status register, Address offset: 0x04 */ - __IO uint32_t DR; /*!< CRYP data input register, Address offset: 0x08 */ - __IO uint32_t DOUT; /*!< CRYP data output register, Address offset: 0x0C */ - __IO uint32_t DMACR; /*!< CRYP DMA control register, Address offset: 0x10 */ - __IO uint32_t IMSCR; /*!< CRYP interrupt mask set/clear register, Address offset: 0x14 */ - __IO uint32_t RISR; /*!< CRYP raw interrupt status register, Address offset: 0x18 */ - __IO uint32_t MISR; /*!< CRYP masked interrupt status register, Address offset: 0x1C */ - __IO uint32_t K0LR; /*!< CRYP key left register 0, Address offset: 0x20 */ - __IO uint32_t K0RR; /*!< CRYP key right register 0, Address offset: 0x24 */ - __IO uint32_t K1LR; /*!< CRYP key left register 1, Address offset: 0x28 */ - __IO uint32_t K1RR; /*!< CRYP key right register 1, Address offset: 0x2C */ - __IO uint32_t K2LR; /*!< CRYP key left register 2, Address offset: 0x30 */ - __IO uint32_t K2RR; /*!< CRYP key right register 2, Address offset: 0x34 */ - __IO uint32_t K3LR; /*!< CRYP key left register 3, Address offset: 0x38 */ - __IO uint32_t K3RR; /*!< CRYP key right register 3, Address offset: 0x3C */ - __IO uint32_t IV0LR; /*!< CRYP initialization vector left-word register 0, Address offset: 0x40 */ - __IO uint32_t IV0RR; /*!< CRYP initialization vector right-word register 0, Address offset: 0x44 */ - __IO uint32_t IV1LR; /*!< CRYP initialization vector left-word register 1, Address offset: 0x48 */ - __IO uint32_t IV1RR; /*!< CRYP initialization vector right-word register 1, Address offset: 0x4C */ -} CRYP_TypeDef; - -/** - * @brief HASH - */ - -typedef struct -{ - __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ - __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ - __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ - __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ - __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ - __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ - uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ - __IO uint32_t CSR[51]; /*!< HASH context swap registers, Address offset: 0x0F8-0x1C0 */ -} HASH_TypeDef; - -/** - * @brief HASH - */ - -typedef struct -{ - __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ - __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ - __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ -} RNG_TypeDef; - -/** - * @} - */ - -/** @addtogroup Peripheral_memory_map - * @{ - */ - -#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */ -#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the alias region */ -#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */ - -#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the bit-band region */ -#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */ - -#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ - -/*!< Peripheral memory map */ -#define APB1PERIPH_BASE PERIPH_BASE -#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) -#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) -#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) - -/*!< APB1 peripherals */ -#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) -#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) -#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) -#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) -#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) -#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) -#define TIM12_BASE (APB1PERIPH_BASE + 0x1800) -#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00) -#define TIM14_BASE (APB1PERIPH_BASE + 0x2000) -#define RTC_BASE (APB1PERIPH_BASE + 0x2800) -#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) -#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) -#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) -#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) -#define USART2_BASE (APB1PERIPH_BASE + 0x4400) -#define USART3_BASE (APB1PERIPH_BASE + 0x4800) -#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) -#define UART5_BASE (APB1PERIPH_BASE + 0x5000) -#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) -#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) -#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00) -#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) -#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) -#define PWR_BASE (APB1PERIPH_BASE + 0x7000) -#define DAC_BASE (APB1PERIPH_BASE + 0x7400) - -/*!< APB2 peripherals */ -#define TIM1_BASE (APB2PERIPH_BASE + 0x0000) -#define TIM8_BASE (APB2PERIPH_BASE + 0x0400) -#define USART1_BASE (APB2PERIPH_BASE + 0x1000) -#define USART6_BASE (APB2PERIPH_BASE + 0x1400) -#define ADC1_BASE (APB2PERIPH_BASE + 0x2000) -#define ADC2_BASE (APB2PERIPH_BASE + 0x2100) -#define ADC3_BASE (APB2PERIPH_BASE + 0x2200) -#define ADC_BASE (APB2PERIPH_BASE + 0x2300) -#define SDIO_BASE (APB2PERIPH_BASE + 0x2C00) -#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) -#define SYSCFG_BASE (APB2PERIPH_BASE + 0x3800) -#define EXTI_BASE (APB2PERIPH_BASE + 0x3C00) -#define TIM9_BASE (APB2PERIPH_BASE + 0x4000) -#define TIM10_BASE (APB2PERIPH_BASE + 0x4400) -#define TIM11_BASE (APB2PERIPH_BASE + 0x4800) - -/*!< AHB1 peripherals */ -#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) -#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400) -#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) -#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00) -#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000) -#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400) -#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800) -#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00) -#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000) -#define CRC_BASE (AHB1PERIPH_BASE + 0x3000) -#define RCC_BASE (AHB1PERIPH_BASE + 0x3800) -#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) -#define BKPSRAM_BASE (AHB1PERIPH_BASE + 0x4000) -#define DMA1_BASE (AHB1PERIPH_BASE + 0x6000) -#define DMA1_Stream0_BASE (DMA1_BASE + 0x010) -#define DMA1_Stream1_BASE (DMA1_BASE + 0x028) -#define DMA1_Stream2_BASE (DMA1_BASE + 0x040) -#define DMA1_Stream3_BASE (DMA1_BASE + 0x058) -#define DMA1_Stream4_BASE (DMA1_BASE + 0x070) -#define DMA1_Stream5_BASE (DMA1_BASE + 0x088) -#define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0) -#define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8) -#define DMA2_BASE (AHB1PERIPH_BASE + 0x6400) -#define DMA2_Stream0_BASE (DMA2_BASE + 0x010) -#define DMA2_Stream1_BASE (DMA2_BASE + 0x028) -#define DMA2_Stream2_BASE (DMA2_BASE + 0x040) -#define DMA2_Stream3_BASE (DMA2_BASE + 0x058) -#define DMA2_Stream4_BASE (DMA2_BASE + 0x070) -#define DMA2_Stream5_BASE (DMA2_BASE + 0x088) -#define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0) -#define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8) -#define ETH_BASE (AHB1PERIPH_BASE + 0x8000) -#define ETH_MAC_BASE (ETH_BASE) -#define ETH_MMC_BASE (ETH_BASE + 0x0100) -#define ETH_PTP_BASE (ETH_BASE + 0x0700) -#define ETH_DMA_BASE (ETH_BASE + 0x1000) - -/*!< AHB2 peripherals */ -#define DCMI_BASE (AHB2PERIPH_BASE + 0x50000) -#define CRYP_BASE (AHB2PERIPH_BASE + 0x60000) -#define HASH_BASE (AHB2PERIPH_BASE + 0x60400) -#define RNG_BASE (AHB2PERIPH_BASE + 0x60800) - -/*!< FSMC Bankx registers base address */ -#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) -#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) -#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) -#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) -#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) - -/* Debug MCU registers base address */ -#define DBGMCU_BASE ((uint32_t )0xE0042000) - -/** - * @} - */ - -/** @addtogroup Peripheral_declaration - * @{ - */ -#define TIM2 ((TIM_TypeDef *) TIM2_BASE) -#define TIM3 ((TIM_TypeDef *) TIM3_BASE) -#define TIM4 ((TIM_TypeDef *) TIM4_BASE) -#define TIM5 ((TIM_TypeDef *) TIM5_BASE) -#define TIM6 ((TIM_TypeDef *) TIM6_BASE) -#define TIM7 ((TIM_TypeDef *) TIM7_BASE) -#define TIM12 ((TIM_TypeDef *) TIM12_BASE) -#define TIM13 ((TIM_TypeDef *) TIM13_BASE) -#define TIM14 ((TIM_TypeDef *) TIM14_BASE) -#define RTC ((RTC_TypeDef *) RTC_BASE) -#define WWDG ((WWDG_TypeDef *) WWDG_BASE) -#define IWDG ((IWDG_TypeDef *) IWDG_BASE) -#define SPI2 ((SPI_TypeDef *) SPI2_BASE) -#define SPI3 ((SPI_TypeDef *) SPI3_BASE) -#define USART2 ((USART_TypeDef *) USART2_BASE) -#define USART3 ((USART_TypeDef *) USART3_BASE) -#define UART4 ((USART_TypeDef *) UART4_BASE) -#define UART5 ((USART_TypeDef *) UART5_BASE) -#define I2C1 ((I2C_TypeDef *) I2C1_BASE) -#define I2C2 ((I2C_TypeDef *) I2C2_BASE) -#define I2C3 ((I2C_TypeDef *) I2C3_BASE) -#define CAN1 ((CAN_TypeDef *) CAN1_BASE) -#define CAN2 ((CAN_TypeDef *) CAN2_BASE) -#define PWR ((PWR_TypeDef *) PWR_BASE) -#define DAC ((DAC_TypeDef *) DAC_BASE) -#define TIM1 ((TIM_TypeDef *) TIM1_BASE) -#define TIM8 ((TIM_TypeDef *) TIM8_BASE) -#define USART1 ((USART_TypeDef *) USART1_BASE) -#define USART6 ((USART_TypeDef *) USART6_BASE) -#define ADC ((ADC_Common_TypeDef *) ADC_BASE) -#define ADC1 ((ADC_TypeDef *) ADC1_BASE) -#define ADC2 ((ADC_TypeDef *) ADC2_BASE) -#define ADC3 ((ADC_TypeDef *) ADC3_BASE) -#define SDIO ((SDIO_TypeDef *) SDIO_BASE) -#define SPI1 ((SPI_TypeDef *) SPI1_BASE) -#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) -#define EXTI ((EXTI_TypeDef *) EXTI_BASE) -#define TIM9 ((TIM_TypeDef *) TIM9_BASE) -#define TIM10 ((TIM_TypeDef *) TIM10_BASE) -#define TIM11 ((TIM_TypeDef *) TIM11_BASE) -#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) -#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) -#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) -#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) -#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) -#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) -#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) -#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) -#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE) -#define CRC ((CRC_TypeDef *) CRC_BASE) -#define RCC ((RCC_TypeDef *) RCC_BASE) -#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) -#define DMA1 ((DMA_TypeDef *) DMA1_BASE) -#define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE) -#define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE) -#define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE) -#define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE) -#define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE) -#define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE) -#define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE) -#define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE) -#define DMA2 ((DMA_TypeDef *) DMA2_BASE) -#define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE) -#define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE) -#define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE) -#define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE) -#define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) -#define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) -#define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) -#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) -#define ETH ((ETH_TypeDef *) ETH_BASE) -#define DCMI ((DCMI_TypeDef *) DCMI_BASE) -#define CRYP ((CRYP_TypeDef *) CRYP_BASE) -#define HASH ((HASH_TypeDef *) HASH_BASE) -#define RNG ((RNG_TypeDef *) RNG_BASE) -#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) -#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) -#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE) -#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE) -#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE) -#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) - -/** - * @} - */ - -/** @addtogroup Exported_constants - * @{ - */ - - /** @addtogroup Peripheral_Registers_Bits_Definition - * @{ - */ - -/******************************************************************************/ -/* Peripheral Registers_Bits_Definition */ -/******************************************************************************/ - -/******************************************************************************/ -/* */ -/* Analog to Digital Converter */ -/* */ -/******************************************************************************/ -/******************** Bit definition for ADC_SR register ********************/ -#define ADC_SR_AWD ((uint8_t)0x01) /*!
© COPYRIGHT 2011 STMicroelectronics
+ ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f2xx + * @{ + */ + +#ifndef __STM32F2xx_H +#define __STM32F2xx_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/* Uncomment the line below according to the target STM32 device used in your + application + */ + +#if !defined (STM32F2XX) + #define STM32F2XX +#endif + +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + */ + +#if !defined (STM32F2XX) + #error "Please select first the target STM32F2XX device used in your application (in stm32f2xx.h file)" +#endif + +#if !defined (USE_STDPERIPH_DRIVER) +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ + /*#define USE_STDPERIPH_DRIVER*/ +#endif /* USE_STDPERIPH_DRIVER */ + +/** + * @brief In the following line adjust the value of External High Speed oscillator (HSE) + used in your application + + Tip: To avoid modifying this file each time you need to use different HSE, you + can define the HSE value in your toolchain compiler preprocessor. + */ +#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + Timeout value + */ +#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ +#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ + +/** + * @brief STM32F2Xxx Standard Peripherals Library version number V1.0.0 + */ +#define __STM32F2XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __STM32F2XX_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __STM32F2XX_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32F2XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32F2XX_STDPERIPH_VERSION ((__STM32F2XX_STDPERIPH_VERSION_MAIN << 24)\ + |(__STM32F2XX_STDPERIPH_VERSION_SUB1 << 16)\ + |(__STM32F2XX_STDPERIPH_VERSION_SUB2 << 8)\ + |(__STM32F2XX_STDPERIPH_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief Configuration of the Cortex-M3 Processor and Core Peripherals + */ +#define __MPU_PRESENT 1 /*!< STM32F2XX provide an MPU */ +#define __NVIC_PRIO_BITS 4 /*!< STM32F2XX uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * @brief STM32F2XX Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ +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 */ +/****** STM32 specific Interrupt Numbers **********************************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ + TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */ + RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */ + FLASH_IRQn = 4, /*!< FLASH global Interrupt */ + RCC_IRQn = 5, /*!< RCC global Interrupt */ + EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ + EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ + EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ + EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ + EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ + DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */ + DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */ + DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */ + DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */ + DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */ + DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */ + DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ + ADC_IRQn = 18, /*!< ADC1, ADC2 and ADC3 global Interrupts */ + CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */ + CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ + TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ + TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ + TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ + TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ + TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ + TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ + DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ + FSMC_IRQn = 48, /*!< FSMC global Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */ + TIM7_IRQn = 55, /*!< TIM7 global interrupt */ + DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ + DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ + DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ + DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ + DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ + ETH_IRQn = 61, /*!< Ethernet global Interrupt */ + ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ + CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ + CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ + CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ + CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ + OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ + DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ + DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ + DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ + USART6_IRQn = 71, /*!< USART6 global interrupt */ + I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ + OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ + OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ + OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */ + OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ + DCMI_IRQn = 78, /*!< DCMI global interrupt */ + CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */ + HASH_RNG_IRQn = 80 /*!< Hash and Rng global interrupt */ +} IRQn_Type; + +/** + * @} + */ + +//#include "core_cm3.h" +//#include "system_stm32f2xx.h" +#include + +/** @addtogroup Exported_types + * @{ + */ +/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef const int32_t sc32; /*!< Read Only */ +typedef const int16_t sc16; /*!< Read Only */ +typedef const int8_t sc8; /*!< Read Only */ + +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef __I int32_t vsc32; /*!< Read Only */ +typedef __I int16_t vsc16; /*!< Read Only */ +typedef __I int8_t vsc8; /*!< Read Only */ + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef const uint32_t uc32; /*!< Read Only */ +typedef const uint16_t uc16; /*!< Read Only */ +typedef const uint8_t uc8; /*!< Read Only */ + +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef __I uint32_t vuc32; /*!< Read Only */ +typedef __I uint16_t vuc16; /*!< Read Only */ +typedef __I uint8_t vuc8; /*!< Read Only */ + +typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; + +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; + +/** + * @} + */ + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */ + __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */ + __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */ + __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */ + __IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x14 */ + __IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x18 */ + __IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x1C */ + __IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x20 */ + __IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x24 */ + __IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x28 */ + __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x2C */ + __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x30 */ + __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x34 */ + __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x38*/ + __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x3C */ + __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x40 */ + __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x44 */ + __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x48 */ + __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x4C */ +} ADC_TypeDef; + +typedef struct +{ + __IO uint32_t CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ + __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ + __IO uint32_t CDR; /*!< ADC common regular data register for dual + AND triple modes, Address offset: ADC1 base address + 0x308 */ +} ADC_Common_TypeDef; + + +/** + * @brief Controller Area Network TxMailBox + */ + +typedef struct +{ + __IO uint32_t TIR; /*!< CAN TX mailbox identifier register */ + __IO uint32_t TDTR; /*!< CAN mailbox data length control and time stamp register */ + __IO uint32_t TDLR; /*!< CAN mailbox data low register */ + __IO uint32_t TDHR; /*!< CAN mailbox data high register */ +} CAN_TxMailBox_TypeDef; + +/** + * @brief Controller Area Network FIFOMailBox + */ + +typedef struct +{ + __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ + __IO uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */ + __IO uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */ + __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ +} CAN_FIFOMailBox_TypeDef; + +/** + * @brief Controller Area Network FilterRegister + */ + +typedef struct +{ + __IO uint32_t FR1; /*!< CAN Filter bank register 1 */ + __IO uint32_t FR2; /*!< CAN Filter bank register 1 */ +} CAN_FilterRegister_TypeDef; + +/** + * @brief Controller Area Network + */ + +typedef struct +{ + __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */ + __IO uint32_t MSR; /*!< CAN master status register, Address offset: 0x04 */ + __IO uint32_t TSR; /*!< CAN transmit status register, Address offset: 0x08 */ + __IO uint32_t RF0R; /*!< CAN receive FIFO 0 register, Address offset: 0x0C */ + __IO uint32_t RF1R; /*!< CAN receive FIFO 1 register, Address offset: 0x10 */ + __IO uint32_t IER; /*!< CAN interrupt enable register, Address offset: 0x14 */ + __IO uint32_t ESR; /*!< CAN error status register, Address offset: 0x18 */ + __IO uint32_t BTR; /*!< CAN bit timing register, Address offset: 0x1C */ + uint32_t RESERVED0[88]; /*!< Reserved, 0x020 - 0x17F */ + CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< CAN Tx MailBox, Address offset: 0x180 - 0x1AC */ + CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< CAN FIFO MailBox, Address offset: 0x1B0 - 0x1CC */ + uint32_t RESERVED1[12]; /*!< Reserved, 0x1D0 - 0x1FF */ + __IO uint32_t FMR; /*!< CAN filter master register, Address offset: 0x200 */ + __IO uint32_t FM1R; /*!< CAN filter mode register, Address offset: 0x204 */ + uint32_t RESERVED2; /*!< Reserved, 0x208 */ + __IO uint32_t FS1R; /*!< CAN filter scale register, Address offset: 0x20C */ + uint32_t RESERVED3; /*!< Reserved, 0x210 */ + __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */ + uint32_t RESERVED4; /*!< Reserved, 0x218 */ + __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */ + uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ + CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */ +} CAN_TypeDef; + +/** + * @brief CRC calculation unit + */ + +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + uint8_t RESERVED0; /*!< Reserved, 0x05 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ +} CRC_TypeDef; + +/** + * @brief Digital to Analog Converter + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ +} DAC_TypeDef; + +/** + * @brief Debug MCU + */ + +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ + __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ +}DBGMCU_TypeDef; + +/** + * @brief DCMI + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ + __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ + __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ + __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ + __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ + __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ + __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ + __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ + __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ +} DCMI_TypeDef; + +/** + * @brief DMA Controller + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DMA stream x configuration register */ + __IO uint32_t NDTR; /*!< DMA stream x number of data register */ + __IO uint32_t PAR; /*!< DMA stream x peripheral address register */ + __IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */ + __IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */ + __IO uint32_t FCR; /*!< DMA stream x FIFO control register */ +} DMA_Stream_TypeDef; + +typedef struct +{ + __IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */ + __IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */ + __IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */ + __IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */ +} DMA_TypeDef; + +/** + * @brief Ethernet MAC + */ + +typedef struct +{ + __IO uint32_t MACCR; + __IO uint32_t MACFFR; + __IO uint32_t MACHTHR; + __IO uint32_t MACHTLR; + __IO uint32_t MACMIIAR; + __IO uint32_t MACMIIDR; + __IO uint32_t MACFCR; + __IO uint32_t MACVLANTR; /* 8 */ + uint32_t RESERVED0[2]; + __IO uint32_t MACRWUFFR; /* 11 */ + __IO uint32_t MACPMTCSR; + uint32_t RESERVED1[2]; + __IO uint32_t MACSR; /* 15 */ + __IO uint32_t MACIMR; + __IO uint32_t MACA0HR; + __IO uint32_t MACA0LR; + __IO uint32_t MACA1HR; + __IO uint32_t MACA1LR; + __IO uint32_t MACA2HR; + __IO uint32_t MACA2LR; + __IO uint32_t MACA3HR; + __IO uint32_t MACA3LR; /* 24 */ + uint32_t RESERVED2[40]; + __IO uint32_t MMCCR; /* 65 */ + __IO uint32_t MMCRIR; + __IO uint32_t MMCTIR; + __IO uint32_t MMCRIMR; + __IO uint32_t MMCTIMR; /* 69 */ + uint32_t RESERVED3[14]; + __IO uint32_t MMCTGFSCCR; /* 84 */ + __IO uint32_t MMCTGFMSCCR; + uint32_t RESERVED4[5]; + __IO uint32_t MMCTGFCR; + uint32_t RESERVED5[10]; + __IO uint32_t MMCRFCECR; + __IO uint32_t MMCRFAECR; + uint32_t RESERVED6[10]; + __IO uint32_t MMCRGUFCR; + uint32_t RESERVED7[334]; + __IO uint32_t PTPTSCR; + __IO uint32_t PTPSSIR; + __IO uint32_t PTPTSHR; + __IO uint32_t PTPTSLR; + __IO uint32_t PTPTSHUR; + __IO uint32_t PTPTSLUR; + __IO uint32_t PTPTSAR; + __IO uint32_t PTPTTHR; + __IO uint32_t PTPTTLR; + __IO uint32_t RESERVED8; + __IO uint32_t PTPTSSR; /* added for STM32F2xx */ + uint32_t RESERVED9[565]; + __IO uint32_t DMABMR; + __IO uint32_t DMATPDR; + __IO uint32_t DMARPDR; + __IO uint32_t DMARDLAR; + __IO uint32_t DMATDLAR; + __IO uint32_t DMASR; + __IO uint32_t DMAOMR; + __IO uint32_t DMAIER; + __IO uint32_t DMAMFBOCR; + __IO uint32_t DMARSWTR; /* added for STM32F2xx */ + uint32_t RESERVED10[8]; + __IO uint32_t DMACHTDR; + __IO uint32_t DMACHRDR; + __IO uint32_t DMACHTBAR; + __IO uint32_t DMACHRBAR; +} ETH_TypeDef; + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ + __IO uint32_t IMR; /*!< EXTI Interrupt mask register, Address offset: 0x00 */ + __IO uint32_t EMR; /*!< EXTI Event mask register, Address offset: 0x04 */ + __IO uint32_t RTSR; /*!< EXTI Rising trigger selection register, Address offset: 0x08 */ + __IO uint32_t FTSR; /*!< EXTI Falling trigger selection register, Address offset: 0x0C */ + __IO uint32_t SWIER; /*!< EXTI Software interrupt event register, Address offset: 0x10 */ + __IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ + +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __IO uint32_t KEYR; /*!< FLASH key register, Address offset: 0x04 */ + __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x10 */ + __IO uint32_t OPTCR; /*!< FLASH option control register, Address offset: 0x14 */ +} FLASH_TypeDef; + +/** + * @brief Flexible Static Memory Controller + */ + +typedef struct +{ + __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ +} FSMC_Bank1_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank1E + */ + +typedef struct +{ + __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ +} FSMC_Bank1E_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank2 + */ + +typedef struct +{ + __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */ + __IO uint32_t SR2; /*!< NAND Flash FIFO status and interrupt register 2, Address offset: 0x64 */ + __IO uint32_t PMEM2; /*!< NAND Flash Common memory space timing register 2, Address offset: 0x68 */ + __IO uint32_t PATT2; /*!< NAND Flash Attribute memory space timing register 2, Address offset: 0x6C */ + uint32_t RESERVED0; /*!< Reserved, 0x70 */ + __IO uint32_t ECCR2; /*!< NAND Flash ECC result registers 2, Address offset: 0x74 */ +} FSMC_Bank2_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank3 + */ + +typedef struct +{ + __IO uint32_t PCR3; /*!< NAND Flash control register 3, Address offset: 0x80 */ + __IO uint32_t SR3; /*!< NAND Flash FIFO status and interrupt register 3, Address offset: 0x84 */ + __IO uint32_t PMEM3; /*!< NAND Flash Common memory space timing register 3, Address offset: 0x88 */ + __IO uint32_t PATT3; /*!< NAND Flash Attribute memory space timing register 3, Address offset: 0x8C */ + uint32_t RESERVED0; /*!< Reserved, 0x90 */ + __IO uint32_t ECCR3; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */ +} FSMC_Bank3_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank4 + */ + +typedef struct +{ + __IO uint32_t PCR4; /*!< PC Card control register 4, Address offset: 0xA0 */ + __IO uint32_t SR4; /*!< PC Card FIFO status and interrupt register 4, Address offset: 0xA4 */ + __IO uint32_t PMEM4; /*!< PC Card Common memory space timing register 4, Address offset: 0xA8 */ + __IO uint32_t PATT4; /*!< PC Card Attribute memory space timing register 4, Address offset: 0xAC */ + __IO uint32_t PIO4; /*!< PC Card I/O space timing register 4, Address offset: 0xB0 */ +} FSMC_Bank4_TypeDef; + +/** + * @brief General Purpose I/O + */ + +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ + __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x24-0x28 */ +} GPIO_TypeDef; + +/** + * @brief System configuration controller + */ + +typedef struct +{ + __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */ + __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ + __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ + uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */ + __IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */ +} SYSCFG_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t DR; /*!< I2C Data register, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ +} I2C_TypeDef; + +/** + * @brief Independent WATCHDOG + */ + +typedef struct +{ + __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ + __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ + __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ +} IWDG_TypeDef; + +/** + * @brief Power Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< PWR power control register, Address offset: 0x00 */ + __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */ +} PWR_TypeDef; + +/** + * @brief Reset and Clock Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ + __IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ + __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ + __IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ + __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ + uint32_t RESERVED0; /*!< Reserved, 0x1C */ + __IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ + __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ + uint32_t RESERVED2; /*!< Reserved, 0x3C */ + __IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ + __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ + uint32_t RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ + __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ + uint32_t RESERVED4; /*!< Reserved, 0x5C */ + __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ + uint32_t RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ + __IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ + __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ + uint32_t RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ + __IO uint32_t SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ + __IO uint32_t PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ +} RCC_TypeDef; + +/** + * @brief Real-Time Clock + */ + +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ + __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CALIBR; /*!< RTC calibration register, Address offset: 0x18 */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + uint32_t RESERVED1; /*!< Reserved, 0x28 */ + uint32_t RESERVED2; /*!< Reserved, 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + uint32_t RESERVED3; /*!< Reserved, 0x38 */ + uint32_t RESERVED4; /*!< Reserved, 0x3C */ + __IO uint32_t TAFCR; /*!< RTC tamper and alternate function configuration register, Address offset: 0x40 */ + uint32_t RESERVED5; /*!< Reserved, 0x44 */ + uint32_t RESERVED6; /*!< Reserved, 0x48 */ + uint32_t RESERVED7; /*!< Reserved, 0x4C */ + __IO uint32_t BKP0R; /*!< RTC backup register 1, Address offset: 0x50 */ + __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */ + __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */ + __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */ + __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */ + __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */ + __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */ + __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */ + __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */ + __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */ + __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */ + __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */ + __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */ + __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */ + __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */ + __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */ + __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */ + __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */ + __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */ + __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */ +} RTC_TypeDef; + +/** + * @brief SD host Interface + */ + +typedef struct +{ + __IO uint32_t POWER; /*!< SDIO power control register, Address offset: 0x00 */ + __IO uint32_t CLKCR; /*!< SDI clock control register, Address offset: 0x04 */ + __IO uint32_t ARG; /*!< SDIO argument register, Address offset: 0x08 */ + __IO uint32_t CMD; /*!< SDIO command register, Address offset: 0x0C */ + __I uint32_t RESPCMD; /*!< SDIO command response register, Address offset: 0x10 */ + __I uint32_t RESP1; /*!< SDIO response 1 register, Address offset: 0x14 */ + __I uint32_t RESP2; /*!< SDIO response 2 register, Address offset: 0x18 */ + __I uint32_t RESP3; /*!< SDIO response 3 register, Address offset: 0x1C */ + __I uint32_t RESP4; /*!< SDIO response 4 register, Address offset: 0x20 */ + __IO uint32_t DTIMER; /*!< SDIO data timer register, Address offset: 0x24 */ + __IO uint32_t DLEN; /*!< SDIO data length register, Address offset: 0x28 */ + __IO uint32_t DCTRL; /*!< SDIO data control register, Address offset: 0x2C */ + __I uint32_t DCOUNT; /*!< SDIO data counter register, Address offset: 0x30 */ + __I uint32_t STA; /*!< SDIO status register, Address offset: 0x34 */ + __IO uint32_t ICR; /*!< SDIO interrupt clear register, Address offset: 0x38 */ + __IO uint32_t MASK; /*!< SDIO mask register, Address offset: 0x3C */ + uint32_t RESERVED0[2]; /*!< Reserved, 0x40-0x44 */ + __I uint32_t FIFOCNT; /*!< SDIO FIFO counter register, Address offset: 0x48 */ + uint32_t RESERVED1[13]; /*!< Reserved, 0x4C-0x7C */ + __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */ +} SDIO_TypeDef; + +/** + * @brief Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< SPI control register 1 (not used in I2S mode), Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< SPI control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t SR; /*!< SPI status register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t DR; /*!< SPI data register, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t RXCRCR; /*!< SPI RX CRC register (not used in I2S mode), Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t TXCRCR; /*!< SPI TX CRC register (not used in I2S mode), Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ +} SPI_TypeDef; + +/** + * @brief TIM + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + uint16_t RESERVED9; /*!< Reserved, 0x2A */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + __IO uint16_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ + uint16_t RESERVED10; /*!< Reserved, 0x32 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + __IO uint16_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ + uint16_t RESERVED11; /*!< Reserved, 0x46 */ + __IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ + uint16_t RESERVED12; /*!< Reserved, 0x4A */ + __IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ + uint16_t RESERVED13; /*!< Reserved, 0x4E */ + __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */ + uint16_t RESERVED14; /*!< Reserved, 0x52 */ +} TIM_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ + +typedef struct +{ + __IO uint16_t SR; /*!< USART Status register, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t DR; /*!< USART Data register, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t CR1; /*!< USART Control register 1, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t CR2; /*!< USART Control register 2, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t CR3; /*!< USART Control register 3, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ +} USART_TypeDef; + +/** + * @brief Window WATCHDOG + */ + +typedef struct +{ + __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ + __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ + __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ +} WWDG_TypeDef; + +/** + * @brief Crypto Processor + */ + +typedef struct +{ + __IO uint32_t CR; /*!< CRYP control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< CRYP status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< CRYP data input register, Address offset: 0x08 */ + __IO uint32_t DOUT; /*!< CRYP data output register, Address offset: 0x0C */ + __IO uint32_t DMACR; /*!< CRYP DMA control register, Address offset: 0x10 */ + __IO uint32_t IMSCR; /*!< CRYP interrupt mask set/clear register, Address offset: 0x14 */ + __IO uint32_t RISR; /*!< CRYP raw interrupt status register, Address offset: 0x18 */ + __IO uint32_t MISR; /*!< CRYP masked interrupt status register, Address offset: 0x1C */ + __IO uint32_t K0LR; /*!< CRYP key left register 0, Address offset: 0x20 */ + __IO uint32_t K0RR; /*!< CRYP key right register 0, Address offset: 0x24 */ + __IO uint32_t K1LR; /*!< CRYP key left register 1, Address offset: 0x28 */ + __IO uint32_t K1RR; /*!< CRYP key right register 1, Address offset: 0x2C */ + __IO uint32_t K2LR; /*!< CRYP key left register 2, Address offset: 0x30 */ + __IO uint32_t K2RR; /*!< CRYP key right register 2, Address offset: 0x34 */ + __IO uint32_t K3LR; /*!< CRYP key left register 3, Address offset: 0x38 */ + __IO uint32_t K3RR; /*!< CRYP key right register 3, Address offset: 0x3C */ + __IO uint32_t IV0LR; /*!< CRYP initialization vector left-word register 0, Address offset: 0x40 */ + __IO uint32_t IV0RR; /*!< CRYP initialization vector right-word register 0, Address offset: 0x44 */ + __IO uint32_t IV1LR; /*!< CRYP initialization vector left-word register 1, Address offset: 0x48 */ + __IO uint32_t IV1RR; /*!< CRYP initialization vector right-word register 1, Address offset: 0x4C */ +} CRYP_TypeDef; + +/** + * @brief HASH + */ + +typedef struct +{ + __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ + __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ + __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ + __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ + __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ + __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ + uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ + __IO uint32_t CSR[51]; /*!< HASH context swap registers, Address offset: 0x0F8-0x1C0 */ +} HASH_TypeDef; + +/** + * @brief HASH + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ +} RNG_TypeDef; + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ + +#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */ +#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the alias region */ +#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */ + +#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the bit-band region */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */ + +#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) +#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) + +/*!< APB1 peripherals */ +#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) +#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) +#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) +#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) +#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) +#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) +#define TIM12_BASE (APB1PERIPH_BASE + 0x1800) +#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00) +#define TIM14_BASE (APB1PERIPH_BASE + 0x2000) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) +#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) +#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) +#define PWR_BASE (APB1PERIPH_BASE + 0x7000) +#define DAC_BASE (APB1PERIPH_BASE + 0x7400) + +/*!< APB2 peripherals */ +#define TIM1_BASE (APB2PERIPH_BASE + 0x0000) +#define TIM8_BASE (APB2PERIPH_BASE + 0x0400) +#define USART1_BASE (APB2PERIPH_BASE + 0x1000) +#define USART6_BASE (APB2PERIPH_BASE + 0x1400) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2000) +#define ADC2_BASE (APB2PERIPH_BASE + 0x2100) +#define ADC3_BASE (APB2PERIPH_BASE + 0x2200) +#define ADC_BASE (APB2PERIPH_BASE + 0x2300) +#define SDIO_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define SYSCFG_BASE (APB2PERIPH_BASE + 0x3800) +#define EXTI_BASE (APB2PERIPH_BASE + 0x3C00) +#define TIM9_BASE (APB2PERIPH_BASE + 0x4000) +#define TIM10_BASE (APB2PERIPH_BASE + 0x4400) +#define TIM11_BASE (APB2PERIPH_BASE + 0x4800) + +/*!< AHB1 peripherals */ +#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) +#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400) +#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) +#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00) +#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000) +#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400) +#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800) +#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00) +#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000) +#define CRC_BASE (AHB1PERIPH_BASE + 0x3000) +#define RCC_BASE (AHB1PERIPH_BASE + 0x3800) +#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) +#define BKPSRAM_BASE (AHB1PERIPH_BASE + 0x4000) +#define DMA1_BASE (AHB1PERIPH_BASE + 0x6000) +#define DMA1_Stream0_BASE (DMA1_BASE + 0x010) +#define DMA1_Stream1_BASE (DMA1_BASE + 0x028) +#define DMA1_Stream2_BASE (DMA1_BASE + 0x040) +#define DMA1_Stream3_BASE (DMA1_BASE + 0x058) +#define DMA1_Stream4_BASE (DMA1_BASE + 0x070) +#define DMA1_Stream5_BASE (DMA1_BASE + 0x088) +#define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0) +#define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8) +#define DMA2_BASE (AHB1PERIPH_BASE + 0x6400) +#define DMA2_Stream0_BASE (DMA2_BASE + 0x010) +#define DMA2_Stream1_BASE (DMA2_BASE + 0x028) +#define DMA2_Stream2_BASE (DMA2_BASE + 0x040) +#define DMA2_Stream3_BASE (DMA2_BASE + 0x058) +#define DMA2_Stream4_BASE (DMA2_BASE + 0x070) +#define DMA2_Stream5_BASE (DMA2_BASE + 0x088) +#define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0) +#define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8) +#define ETH_BASE (AHB1PERIPH_BASE + 0x8000) +#define ETH_MAC_BASE (ETH_BASE) +#define ETH_MMC_BASE (ETH_BASE + 0x0100) +#define ETH_PTP_BASE (ETH_BASE + 0x0700) +#define ETH_DMA_BASE (ETH_BASE + 0x1000) + +/*!< AHB2 peripherals */ +#define DCMI_BASE (AHB2PERIPH_BASE + 0x50000) +#define CRYP_BASE (AHB2PERIPH_BASE + 0x60000) +#define HASH_BASE (AHB2PERIPH_BASE + 0x60400) +#define RNG_BASE (AHB2PERIPH_BASE + 0x60800) + +/*!< FSMC Bankx registers base address */ +#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) +#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) +#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) +#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) +#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) + +/* Debug MCU registers base address */ +#define DBGMCU_BASE ((uint32_t )0xE0042000) + +/** + * @} + */ + +/** @addtogroup Peripheral_declaration + * @{ + */ +#define TIM2 ((TIM_TypeDef *) TIM2_BASE) +#define TIM3 ((TIM_TypeDef *) TIM3_BASE) +#define TIM4 ((TIM_TypeDef *) TIM4_BASE) +#define TIM5 ((TIM_TypeDef *) TIM5_BASE) +#define TIM6 ((TIM_TypeDef *) TIM6_BASE) +#define TIM7 ((TIM_TypeDef *) TIM7_BASE) +#define TIM12 ((TIM_TypeDef *) TIM12_BASE) +#define TIM13 ((TIM_TypeDef *) TIM13_BASE) +#define TIM14 ((TIM_TypeDef *) TIM14_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define UART4 ((USART_TypeDef *) UART4_BASE) +#define UART5 ((USART_TypeDef *) UART5_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define I2C3 ((I2C_TypeDef *) I2C3_BASE) +#define CAN1 ((CAN_TypeDef *) CAN1_BASE) +#define CAN2 ((CAN_TypeDef *) CAN2_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define DAC ((DAC_TypeDef *) DAC_BASE) +#define TIM1 ((TIM_TypeDef *) TIM1_BASE) +#define TIM8 ((TIM_TypeDef *) TIM8_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define USART6 ((USART_TypeDef *) USART6_BASE) +#define ADC ((ADC_Common_TypeDef *) ADC_BASE) +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADC2 ((ADC_TypeDef *) ADC2_BASE) +#define ADC3 ((ADC_TypeDef *) ADC3_BASE) +#define SDIO ((SDIO_TypeDef *) SDIO_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) +#define EXTI ((EXTI_TypeDef *) EXTI_BASE) +#define TIM9 ((TIM_TypeDef *) TIM9_BASE) +#define TIM10 ((TIM_TypeDef *) TIM10_BASE) +#define TIM11 ((TIM_TypeDef *) TIM11_BASE) +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) +#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) +#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) +#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) +#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_BASE) +#define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE) +#define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE) +#define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE) +#define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE) +#define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE) +#define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE) +#define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE) +#define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE) +#define DMA2 ((DMA_TypeDef *) DMA2_BASE) +#define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE) +#define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE) +#define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE) +#define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE) +#define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) +#define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) +#define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) +#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) +#define ETH ((ETH_TypeDef *) ETH_BASE) +#define DCMI ((DCMI_TypeDef *) DCMI_BASE) +#define CRYP ((CRYP_TypeDef *) CRYP_BASE) +#define HASH ((HASH_TypeDef *) HASH_BASE) +#define RNG ((RNG_TypeDef *) RNG_BASE) +#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) +#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) +#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE) +#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE) +#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE) +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +/** + * @} + */ + +/** @addtogroup Exported_constants + * @{ + */ + + /** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + +/******************************************************************************/ +/* Peripheral Registers_Bits_Definition */ +/******************************************************************************/ + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ +/******************** Bit definition for ADC_SR register ********************/ +#define ADC_SR_AWD ((uint8_t)0x01) /*!AHB1ENR |= RCC_AHB1ENR_USB; - - - GPIO_TypeDef *p = (GPIO_TypeDef *)USB_DISC_BANK; - /* set to output */ - p->MODER |= 1 << (2*USB_DISC); - /* Configure pins speed to 100 MHz */ - //p->OSPEEDR = 0xffffc00f; // 2 bit/port medium speed = %01 - /* Configure pins Output type to open drain */ - p->OTYPER |= 1 << (1*USB_DISC); - /* No pull-up, pull-down for PEx pins */ - //p->PUPDR = 0x00000000; -#endif -#else - pRCC->APB2ENR |= RCC_APB2ENR_USB; - /* Setup USB DISC pin as output open drain */ - #ifdef USB_DISC_OD - SET_REG(USB_DISC_CR, (GET_REG(USB_DISC_CR) & USB_DISC_CR_MASK) | USB_DISC_CR_OUTPUT_OD); // ala42 just pull down external pull up - #else - SET_REG(USB_DISC_CR, (GET_REG(USB_DISC_CR) & USB_DISC_CR_MASK) | USB_DISC_CR_OUTPUT_PP); // ala42 actively pull up USBDP - #endif -#endif -} - -void setupUSB (void) { - setupDisconnectPin(); - disconnectUSB(); - - /* turn on the USB clock */ -#ifdef STM32F2 - pRCC->AHB1ENR |= RCC_AHB1ENR_OTGHSEN; -#else - pRCC->APB1ENR |= RCC_APB1ENR_USB_CLK; -#endif - - /* initialize the usb application */ - connectUSB(); - usbAppInit(); -} - -void usbDsbBus(void) { - disconnectUSB(); -} - -vu32 bDeviceState = UNCONNECTED; - -/* tracks sequential behavior of the ISTR */ -vu16 wIstr; -vu8 bIntPackSOF = 0; - -DEVICE Device_Table = - { - NUM_ENDPTS, - 1 - }; - -DEVICE_PROP Device_Property = - { - usbInit, - usbReset, - usbStatusIn, - usbStatusOut, - usbDataSetup, - usbNoDataSetup, - usbGetInterfaceSetting, - usbGetDeviceDescriptor, - usbGetConfigDescriptor, - usbGetStringDescriptor, - usbGetFunctionalDescriptor, - 0, - bMaxPacketSize - }; - -USER_STANDARD_REQUESTS User_Standard_Requests = - { - usbGetConfiguration, - usbSetConfiguration, - usbGetInterface, - usbSetInterface, - usbGetStatus, - usbClearFeature, - usbSetEndpointFeature, - usbSetDeviceFeature, - usbSetDeviceAddress - }; - -void (*pEpInt_IN[7])(void) = -{ - nothingProc, - nothingProc, - nothingProc, - nothingProc, - nothingProc, - nothingProc, - nothingProc, -}; - -void (*pEpInt_OUT[7])(void) = -{ - nothingProc, - nothingProc, - nothingProc, - nothingProc, - nothingProc, - nothingProc, - nothingProc, -}; - -struct -{ - volatile RESUME_STATE eState; - volatile u8 bESOFcnt; -} ResumeS; - -/* dummy proc */ -void nothingProc(void) { -} - -/* Function Definitions */ -void usbAppInit(void) { - /* hook in to usb_core, depends on all those damn - non encapsulated externs! */ - USB_Init(); -} - -void usbSuspend(void) { - u16 wCNTR; - wCNTR = _GetCNTR(); - wCNTR |= CNTR_FSUSP | CNTR_LPMODE; - _SetCNTR(wCNTR); - - /* run any power reduction handlers */ - bDeviceState = SUSPENDED; -} - -void usbResumeInit(void) { - u16 wCNTR; - - /* restart any clocks that had been stopped */ - - wCNTR = _GetCNTR(); - wCNTR &= (~CNTR_LPMODE); - _SetCNTR(wCNTR); - - /* undo power reduction handlers here */ - - _SetCNTR(ISR_MSK); -} - -void usbResume(RESUME_STATE eResumeSetVal) { - u16 wCNTR; - - if (eResumeSetVal != RESUME_ESOF) - ResumeS.eState = eResumeSetVal; - - switch (ResumeS.eState) - { - case RESUME_EXTERNAL: - usbResumeInit(); - ResumeS.eState = RESUME_OFF; - break; - case RESUME_INTERNAL: - usbResumeInit(); - ResumeS.eState = RESUME_START; - break; - case RESUME_LATER: - ResumeS.bESOFcnt = 2; - ResumeS.eState = RESUME_WAIT; - break; - case RESUME_WAIT: - ResumeS.bESOFcnt--; - if (ResumeS.bESOFcnt == 0) - ResumeS.eState = RESUME_START; - break; - case RESUME_START: - wCNTR = _GetCNTR(); - wCNTR |= CNTR_RESUME; - _SetCNTR(wCNTR); - ResumeS.eState = RESUME_ON; - ResumeS.bESOFcnt = 10; - break; - case RESUME_ON: - ResumeS.bESOFcnt--; - if (ResumeS.bESOFcnt == 0) - { - wCNTR = _GetCNTR(); - wCNTR &= (~CNTR_RESUME); - _SetCNTR(wCNTR); - ResumeS.eState = RESUME_OFF; - } - break; - case RESUME_OFF: - case RESUME_ESOF: - default: - ResumeS.eState = RESUME_OFF; - break; - } -} - -RESULT usbPowerOn(void) { - u16 wRegVal; - - wRegVal = CNTR_FRES; - _SetCNTR(wRegVal); - - wInterrupt_Mask = 0; - _SetCNTR(wInterrupt_Mask); - _SetISTR(0); - wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM; /* the bare minimum */ - _SetCNTR(wInterrupt_Mask); - - return USB_SUCCESS; -} - -RESULT usbPowerOff(void) { - _SetCNTR(CNTR_FRES); - _SetISTR(0); - _SetCNTR(CNTR_FRES + CNTR_PDWN); - - /* note that all weve done here is powerdown the - usb peripheral. we have no disabled the clocks, - pulled the usb_disc pin back up, or reset the - application state machines */ - - return USB_SUCCESS; -} - -void usbInit(void) { - dfuInit(); - - pInformation->Current_Configuration = 0; - usbPowerOn(); - - _SetISTR(0); - wInterrupt_Mask = ISR_MSK; - _SetCNTR(wInterrupt_Mask); - - usbEnbISR(); /* configure the cortex M3 private peripheral NVIC */ - bDeviceState = UNCONNECTED; -} - -void usbReset(void) { - dfuUpdateByReset(); - - pInformation->Current_Configuration = 0; - pInformation->Current_Feature = usbConfigDescriptorDFU.Descriptor[7]; - - _SetBTABLE(BTABLE_ADDRESS); - - /* setup the ctrl endpoint */ - _SetEPType(ENDP0, EP_CONTROL); - _SetEPTxStatus(ENDP0, EP_TX_STALL); - - _SetEPRxAddr(ENDP0, ENDP0_RXADDR); - _SetEPTxAddr(ENDP0, ENDP0_TXADDR); - - Clear_Status_Out(ENDP0); - - SetEPRxCount(ENDP0, pProperty->MaxPacketSize); - // SetEPTxCount(ENDP0, pProperty->MaxPacketSize); - SetEPRxValid(ENDP0); - - bDeviceState = ATTACHED; - SetDeviceAddress(0); /* different than usbSetDeviceAddr! comes from usb_core */ -} - -void usbStatusIn(void) { -} - -void usbStatusOut(void) { -} - -RESULT usbDataSetup(u8 request) { - u8 *(*CopyRoutine)(u16); - CopyRoutine = NULL; - - /* handle dfu class requests */ - if ((pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT)) - { - if (dfuUpdateByRequest()) { - /* successfull state transition, handle the request */ - switch (request) { - case (DFU_GETSTATUS): - CopyRoutine = dfuCopyStatus; - break; - case (DFU_GETSTATE): - CopyRoutine = dfuCopyState; - break; - case (DFU_DNLOAD): - CopyRoutine = dfuCopyDNLOAD; - break; - case (DFU_UPLOAD): - CopyRoutine = dfuCopyUPLOAD; - default: - /* leave copy routine null */ - break; - } - } - } - - if (CopyRoutine != NULL) { - pInformation->Ctrl_Info.CopyData = CopyRoutine; - pInformation->Ctrl_Info.Usb_wOffset = 0; - (*CopyRoutine)(0); - - return USB_SUCCESS; - } - - return USB_UNSUPPORT; -} - -RESULT usbNoDataSetup(u8 request) { - if ((pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { - /* todo, keep track of the destination interface, often stored in wIndex */ - if (dfuUpdateByRequest()) { - return USB_SUCCESS; - } - } - return USB_UNSUPPORT; -} - -RESULT usbGetInterfaceSetting(u8 interface, u8 altSetting) { - /* alt setting 0 -> program RAM, alt setting 1 -> FLASH */ - if (interface > NUM_ALT_SETTINGS) { - return USB_UNSUPPORT; - } else { - return USB_SUCCESS; - } -} - -u8* usbGetDeviceDescriptor(u16 len) { - return Standard_GetDescriptorData(len, &usbDeviceDescriptorDFU); -} - -u8* usbGetConfigDescriptor(u16 len) { - return Standard_GetDescriptorData(len, &usbConfigDescriptorDFU); -} - -u8* usbGetStringDescriptor(u16 len) { - u8 strIndex = pInformation->USBwValue0; - if (strIndex > STR_DESC_LEN) { - return NULL; - } else { - return Standard_GetDescriptorData(len, &usbStringDescriptor[strIndex]); - } -} - -u8* usbGetFunctionalDescriptor(u16 len) { - return Standard_GetDescriptorData(len, &usbFunctionalDescriptor); -} - - - -/***** start of USER STANDARD REQUESTS ****** - * - * These are the USER STANDARD REQUESTS, they are handled - * in the core but we are given these callbacks at the - * application level - *******************************************/ - -void usbGetConfiguration(void) { - /* nothing process */ -} - -void usbSetConfiguration(void) { - if (pInformation->Current_Configuration != 0) - { - bDeviceState = CONFIGURED; - } -} - -void usbGetInterface(void) { - /* nothing process */ -} - -void usbSetInterface(void) { - /* nothing process */ -} - -void usbGetStatus(void) { - /* nothing process */ -} - -void usbClearFeature(void) { - /* nothing process */ -} - -void usbSetEndpointFeature(void) { - /* nothing process */ -} - -void usbSetDeviceFeature(void) { - /* nothing process */ -} - -void usbSetDeviceAddress(void) { - bDeviceState = ADDRESSED; -} -/***** end of USER STANDARD REQUESTS *****/ - - -void usbEnbISR(void) { - NVIC_InitTypeDef NVIC_InitStructure; - - - NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE; - nvicInit(&NVIC_InitStructure); -} - -void usbDsbISR(void) { - NVIC_InitTypeDef NVIC_InitStructure; - NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE; - nvicInit(&NVIC_InitStructure); -} - -void USB_LP_CAN1_RX0_IRQHandler(void) { - wIstr = _GetISTR(); - - /* go nuts with the preproc switches since this is an ISTR and must be FAST */ -#if (ISR_MSK & ISTR_RESET) - if (wIstr & ISTR_RESET & wInterrupt_Mask) - { - _SetISTR((u16)CLR_RESET); - Device_Property.Reset(); - } -#endif - - -#if (ISR_MSK & ISTR_DOVR) - if (wIstr & ISTR_DOVR & wInterrupt_Mask) - { - _SetISTR((u16)CLR_DOVR); - } -#endif - - -#if (ISR_MSK & ISTR_ERR) - if (wIstr & ISTR_ERR & wInterrupt_Mask) - { - _SetISTR((u16)CLR_ERR); - } -#endif - - -#if (ISR_MSK & ISTR_WKUP) - if (wIstr & ISTR_WKUP & wInterrupt_Mask) - { - _SetISTR((u16)CLR_WKUP); - usbResume(RESUME_EXTERNAL); - } -#endif - - /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ -#if (ISR_MSK & ISTR_SUSP) - if (wIstr & ISTR_SUSP & wInterrupt_Mask) - { - - /* check if SUSPEND is possible */ - if (F_SUSPEND_ENABLED) - { - usbSuspend(); - } - else - { - /* if not possible then resume after xx ms */ - usbResume(RESUME_LATER); - } - /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ - _SetISTR((u16)CLR_SUSP); - } -#endif - - -#if (ISR_MSK & ISTR_SOF) - if (wIstr & ISTR_SOF & wInterrupt_Mask) - { - _SetISTR((u16)CLR_SOF); - bIntPackSOF++; - } -#endif - - -#if (ISR_MSK & ISTR_ESOF) - if (wIstr & ISTR_ESOF & wInterrupt_Mask) - { - _SetISTR((u16)CLR_ESOF); - /* resume handling timing is made with ESOFs */ - usbResume(RESUME_ESOF); /* request without change of the machine state */ - } -#endif - - /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ -#if (ISR_MSK & ISTR_CTR) - if (wIstr & ISTR_CTR & wInterrupt_Mask) - { - /* servicing of the endpoint correct transfer interrupt */ - /* clear of the CTR flag into the sub */ - CTR_LP(); /* low priority ISR defined in the usb core lib */ - } -#endif - -} +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +/** + * @file usb.c + * + * @brief usb-specific hardware setup, NVIC, clocks, and usb activities + * in the pre-attached state. includes some of the lower level callbacks + * needed by the usb library, like suspend,resume,init,etc + */ + +#include "usb.h" +#include "dfu.h" + +void connectUSB() { +#if !defined(BOARD_DiscoveryF4) + //resetPin (USB_DISC_BANK,USB_DISC); /* present ourselves to the host */ + setPin (USB_DISC_BANK,USB_DISC); /* ala42: present ourselves to the host */ +#endif +} + +void disconnectUSB() { +#if !defined(BOARD_DiscoveryF4) + //setPin (USB_DISC_BANK,USB_DISC); + resetPin (USB_DISC_BANK,USB_DISC); // ala42 + strobePin(LED_BANK,LED,1,BLINK_SLOW); +#endif +} + +void setupDisconnectPin (void) { + /* enable USB DISC Pin */ +#ifdef STM32F2 +#if !defined(BOARD_DiscoveryF4) + pRCC->AHB1ENR |= RCC_AHB1ENR_USB; + + + GPIO_TypeDef *p = (GPIO_TypeDef *)USB_DISC_BANK; + /* set to output */ + p->MODER |= 1 << (2*USB_DISC); + /* Configure pins speed to 100 MHz */ + //p->OSPEEDR = 0xffffc00f; // 2 bit/port medium speed = %01 + /* Configure pins Output type to open drain */ + p->OTYPER |= 1 << (1*USB_DISC); + /* No pull-up, pull-down for PEx pins */ + //p->PUPDR = 0x00000000; +#endif +#else + pRCC->APB2ENR |= RCC_APB2ENR_USB; + /* Setup USB DISC pin as output open drain */ + #ifdef USB_DISC_OD + SET_REG(USB_DISC_CR, (GET_REG(USB_DISC_CR) & USB_DISC_CR_MASK) | USB_DISC_CR_OUTPUT_OD); // ala42 just pull down external pull up + #else + SET_REG(USB_DISC_CR, (GET_REG(USB_DISC_CR) & USB_DISC_CR_MASK) | USB_DISC_CR_OUTPUT_PP); // ala42 actively pull up USBDP + #endif +#endif +} + +void setupUSB (void) { + setupDisconnectPin(); + disconnectUSB(); + + /* turn on the USB clock */ +#ifdef STM32F2 + pRCC->AHB1ENR |= RCC_AHB1ENR_OTGHSEN; +#else + pRCC->APB1ENR |= RCC_APB1ENR_USB_CLK; +#endif + + /* initialize the usb application */ + connectUSB(); + usbAppInit(); +} + +void usbDsbBus(void) { + disconnectUSB(); +} + +vu32 bDeviceState = UNCONNECTED; + +/* tracks sequential behavior of the ISTR */ +vu16 wIstr; +vu8 bIntPackSOF = 0; + +DEVICE Device_Table = + { + NUM_ENDPTS, + 1 + }; + +DEVICE_PROP Device_Property = + { + usbInit, + usbReset, + usbStatusIn, + usbStatusOut, + usbDataSetup, + usbNoDataSetup, + usbGetInterfaceSetting, + usbGetDeviceDescriptor, + usbGetConfigDescriptor, + usbGetStringDescriptor, + usbGetFunctionalDescriptor, + 0, + bMaxPacketSize + }; + +USER_STANDARD_REQUESTS User_Standard_Requests = + { + usbGetConfiguration, + usbSetConfiguration, + usbGetInterface, + usbSetInterface, + usbGetStatus, + usbClearFeature, + usbSetEndpointFeature, + usbSetDeviceFeature, + usbSetDeviceAddress + }; + +void (*pEpInt_IN[7])(void) = +{ + nothingProc, + nothingProc, + nothingProc, + nothingProc, + nothingProc, + nothingProc, + nothingProc, +}; + +void (*pEpInt_OUT[7])(void) = +{ + nothingProc, + nothingProc, + nothingProc, + nothingProc, + nothingProc, + nothingProc, + nothingProc, +}; + +struct +{ + volatile RESUME_STATE eState; + volatile u8 bESOFcnt; +} ResumeS; + +/* dummy proc */ +void nothingProc(void) { +} + +/* Function Definitions */ +void usbAppInit(void) { + /* hook in to usb_core, depends on all those damn + non encapsulated externs! */ + USB_Init(); +} + +void usbSuspend(void) { + u16 wCNTR; + wCNTR = _GetCNTR(); + wCNTR |= CNTR_FSUSP | CNTR_LPMODE; + _SetCNTR(wCNTR); + + /* run any power reduction handlers */ + bDeviceState = SUSPENDED; +} + +void usbResumeInit(void) { + u16 wCNTR; + + /* restart any clocks that had been stopped */ + + wCNTR = _GetCNTR(); + wCNTR &= (~CNTR_LPMODE); + _SetCNTR(wCNTR); + + /* undo power reduction handlers here */ + + _SetCNTR(ISR_MSK); +} + +void usbResume(RESUME_STATE eResumeSetVal) { + u16 wCNTR; + + if (eResumeSetVal != RESUME_ESOF) + ResumeS.eState = eResumeSetVal; + + switch (ResumeS.eState) + { + case RESUME_EXTERNAL: + usbResumeInit(); + ResumeS.eState = RESUME_OFF; + break; + case RESUME_INTERNAL: + usbResumeInit(); + ResumeS.eState = RESUME_START; + break; + case RESUME_LATER: + ResumeS.bESOFcnt = 2; + ResumeS.eState = RESUME_WAIT; + break; + case RESUME_WAIT: + ResumeS.bESOFcnt--; + if (ResumeS.bESOFcnt == 0) + ResumeS.eState = RESUME_START; + break; + case RESUME_START: + wCNTR = _GetCNTR(); + wCNTR |= CNTR_RESUME; + _SetCNTR(wCNTR); + ResumeS.eState = RESUME_ON; + ResumeS.bESOFcnt = 10; + break; + case RESUME_ON: + ResumeS.bESOFcnt--; + if (ResumeS.bESOFcnt == 0) + { + wCNTR = _GetCNTR(); + wCNTR &= (~CNTR_RESUME); + _SetCNTR(wCNTR); + ResumeS.eState = RESUME_OFF; + } + break; + case RESUME_OFF: + case RESUME_ESOF: + default: + ResumeS.eState = RESUME_OFF; + break; + } +} + +RESULT usbPowerOn(void) { + u16 wRegVal; + + wRegVal = CNTR_FRES; + _SetCNTR(wRegVal); + + wInterrupt_Mask = 0; + _SetCNTR(wInterrupt_Mask); + _SetISTR(0); + wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM; /* the bare minimum */ + _SetCNTR(wInterrupt_Mask); + + return USB_SUCCESS; +} + +RESULT usbPowerOff(void) { + _SetCNTR(CNTR_FRES); + _SetISTR(0); + _SetCNTR(CNTR_FRES + CNTR_PDWN); + + /* note that all weve done here is powerdown the + usb peripheral. we have no disabled the clocks, + pulled the usb_disc pin back up, or reset the + application state machines */ + + return USB_SUCCESS; +} + +void usbInit(void) { + dfuInit(); + + pInformation->Current_Configuration = 0; + usbPowerOn(); + + _SetISTR(0); + wInterrupt_Mask = ISR_MSK; + _SetCNTR(wInterrupt_Mask); + + usbEnbISR(); /* configure the cortex M3 private peripheral NVIC */ + bDeviceState = UNCONNECTED; +} + +void usbReset(void) { + dfuUpdateByReset(); + + pInformation->Current_Configuration = 0; + pInformation->Current_Feature = usbConfigDescriptorDFU.Descriptor[7]; + + _SetBTABLE(BTABLE_ADDRESS); + + /* setup the ctrl endpoint */ + _SetEPType(ENDP0, EP_CONTROL); + _SetEPTxStatus(ENDP0, EP_TX_STALL); + + _SetEPRxAddr(ENDP0, ENDP0_RXADDR); + _SetEPTxAddr(ENDP0, ENDP0_TXADDR); + + Clear_Status_Out(ENDP0); + + SetEPRxCount(ENDP0, pProperty->MaxPacketSize); + // SetEPTxCount(ENDP0, pProperty->MaxPacketSize); + SetEPRxValid(ENDP0); + + bDeviceState = ATTACHED; + SetDeviceAddress(0); /* different than usbSetDeviceAddr! comes from usb_core */ +} + +void usbStatusIn(void) { +} + +void usbStatusOut(void) { +} + +RESULT usbDataSetup(u8 request) { + u8 *(*CopyRoutine)(u16); + CopyRoutine = NULL; + + /* handle dfu class requests */ + if ((pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT)) + { + if (dfuUpdateByRequest()) { + /* successfull state transition, handle the request */ + switch (request) { + case (DFU_GETSTATUS): + CopyRoutine = dfuCopyStatus; + break; + case (DFU_GETSTATE): + CopyRoutine = dfuCopyState; + break; + case (DFU_DNLOAD): + CopyRoutine = dfuCopyDNLOAD; + break; + case (DFU_UPLOAD): + CopyRoutine = dfuCopyUPLOAD; + default: + /* leave copy routine null */ + break; + } + } + } + + if (CopyRoutine != NULL) { + pInformation->Ctrl_Info.CopyData = CopyRoutine; + pInformation->Ctrl_Info.Usb_wOffset = 0; + (*CopyRoutine)(0); + + return USB_SUCCESS; + } + + return USB_UNSUPPORT; +} + +RESULT usbNoDataSetup(u8 request) { + if ((pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { + /* todo, keep track of the destination interface, often stored in wIndex */ + if (dfuUpdateByRequest()) { + return USB_SUCCESS; + } + } + return USB_UNSUPPORT; +} + +RESULT usbGetInterfaceSetting(u8 interface, u8 altSetting) { + /* alt setting 0 -> program RAM, alt setting 1 -> FLASH */ + if (interface > NUM_ALT_SETTINGS) { + return USB_UNSUPPORT; + } else { + return USB_SUCCESS; + } +} + +u8* usbGetDeviceDescriptor(u16 len) { + return Standard_GetDescriptorData(len, &usbDeviceDescriptorDFU); +} + +u8* usbGetConfigDescriptor(u16 len) { + return Standard_GetDescriptorData(len, &usbConfigDescriptorDFU); +} + +u8* usbGetStringDescriptor(u16 len) { + u8 strIndex = pInformation->USBwValue0; + if (strIndex > STR_DESC_LEN) { + return NULL; + } else { + return Standard_GetDescriptorData(len, &usbStringDescriptor[strIndex]); + } +} + +u8* usbGetFunctionalDescriptor(u16 len) { + return Standard_GetDescriptorData(len, &usbFunctionalDescriptor); +} + + + +/***** start of USER STANDARD REQUESTS ****** + * + * These are the USER STANDARD REQUESTS, they are handled + * in the core but we are given these callbacks at the + * application level + *******************************************/ + +void usbGetConfiguration(void) { + /* nothing process */ +} + +void usbSetConfiguration(void) { + if (pInformation->Current_Configuration != 0) + { + bDeviceState = CONFIGURED; + } +} + +void usbGetInterface(void) { + /* nothing process */ +} + +void usbSetInterface(void) { + /* nothing process */ +} + +void usbGetStatus(void) { + /* nothing process */ +} + +void usbClearFeature(void) { + /* nothing process */ +} + +void usbSetEndpointFeature(void) { + /* nothing process */ +} + +void usbSetDeviceFeature(void) { + /* nothing process */ +} + +void usbSetDeviceAddress(void) { + bDeviceState = ADDRESSED; +} +/***** end of USER STANDARD REQUESTS *****/ + + +void usbEnbISR(void) { + NVIC_InitTypeDef NVIC_InitStructure; + + + NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE; + nvicInit(&NVIC_InitStructure); +} + +void usbDsbISR(void) { + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE; + nvicInit(&NVIC_InitStructure); +} + +void USB_LP_CAN1_RX0_IRQHandler(void) { + wIstr = _GetISTR(); + + /* go nuts with the preproc switches since this is an ISTR and must be FAST */ +#if (ISR_MSK & ISTR_RESET) + if (wIstr & ISTR_RESET & wInterrupt_Mask) + { + _SetISTR((u16)CLR_RESET); + Device_Property.Reset(); + } +#endif + + +#if (ISR_MSK & ISTR_DOVR) + if (wIstr & ISTR_DOVR & wInterrupt_Mask) + { + _SetISTR((u16)CLR_DOVR); + } +#endif + + +#if (ISR_MSK & ISTR_ERR) + if (wIstr & ISTR_ERR & wInterrupt_Mask) + { + _SetISTR((u16)CLR_ERR); + } +#endif + + +#if (ISR_MSK & ISTR_WKUP) + if (wIstr & ISTR_WKUP & wInterrupt_Mask) + { + _SetISTR((u16)CLR_WKUP); + usbResume(RESUME_EXTERNAL); + } +#endif + + /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if (ISR_MSK & ISTR_SUSP) + if (wIstr & ISTR_SUSP & wInterrupt_Mask) + { + + /* check if SUSPEND is possible */ + if (F_SUSPEND_ENABLED) + { + usbSuspend(); + } + else + { + /* if not possible then resume after xx ms */ + usbResume(RESUME_LATER); + } + /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ + _SetISTR((u16)CLR_SUSP); + } +#endif + + +#if (ISR_MSK & ISTR_SOF) + if (wIstr & ISTR_SOF & wInterrupt_Mask) + { + _SetISTR((u16)CLR_SOF); + bIntPackSOF++; + } +#endif + + +#if (ISR_MSK & ISTR_ESOF) + if (wIstr & ISTR_ESOF & wInterrupt_Mask) + { + _SetISTR((u16)CLR_ESOF); + /* resume handling timing is made with ESOFs */ + usbResume(RESUME_ESOF); /* request without change of the machine state */ + } +#endif + + /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if (ISR_MSK & ISTR_CTR) + if (wIstr & ISTR_CTR & wInterrupt_Mask) + { + /* servicing of the endpoint correct transfer interrupt */ + /* clear of the CTR flag into the sub */ + CTR_LP(); /* low priority ISR defined in the usb core lib */ + } +#endif + +} diff --git a/Libmaple/maple-bootloader/usb.h b/Libmaple/maple-bootloader/usb.h index 1cc68e2b..8151ae5f 100644 --- a/Libmaple/maple-bootloader/usb.h +++ b/Libmaple/maple-bootloader/usb.h @@ -1,176 +1,176 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *****************************************************************************/ -#ifndef __USB_H -#define __USB_H - -#include "common.h" -#include "usb_lib.h" -#include "usb_descriptor.h" - -/* USB Disc Pin Setup. On the Native, USB DISC is PB8 */ - -#ifdef BOARD_maple_native -#define USB_DISC_BANK GPIOB -#define USB_DISC 8 -#define USB_DISC_CR GPIO_CRH(USB_DISC_BANK) -#define USB_DISC_CR_MASK 0xFFFFFFF0 -#define USB_DISC_CR_OUTPUT_OD 0x00000005 -#define USB_DISC_CR_OUTPUT_PP 0x00000001 -#define RCC_APB2ENR_USB 0x00000008 -#endif - - -#if defined(BOARD_aeroquad32) -#define USB_DISC_BANK GPIOD -#define USB_DISC 11 -#define USB_DISC_CR GPIO_CRH(USB_DISC_BANK) -#define USB_DISC_CR_MASK 0xFFFF0FFF -#define USB_DISC_CR_OUTPUT_OD 0x00005000 -#define USB_DISC_CR_OUTPUT_PP 0x00001000 -#define RCC_APB2ENR_USB 0x00000020 -#define RCC_AHB1ENR_USB 0x00000004 // F2 -#endif - -#ifdef BOARD_aeroquad32mini -#define USB_DISC_BANK GPIOA -#define USB_DISC 8 -#define USB_DISC_CR GPIO_CRH(USB_DISC_BANK) -#define USB_DISC_CR_MASK 0xFFFFFFF0 -#define USB_DISC_CR_OUTPUT_OD 0x00000005 -#define USB_DISC_CR_OUTPUT_PP 0x00000001 -#define RCC_APB2ENR_USB 0x00000008 -#endif - -#define RCC_APB1ENR_USB_CLK 0x00800000 - - - -/* USB configuration params */ -#define BTABLE_ADDRESS 0x00 -#define ENDP0_RXADDR 0x40 -#define ENDP0_TXADDR 0x80 /* gives 64 bytes i/o buflen */ -#define ENDP1_TXADDR 0xC0 -#define ENDP2_TXADDR 0x100 -#define ENDP3_RXADDR 0x110 - -#define bMaxPacketSize 0x40 /* 64B, maximum for usb FS devices */ -#define wTransferSize FLASH_PAGE_SIZE /* 2048B, want: maxpacket < - wtransfer < 10KB (to ensure - everything can live in - ram */ - -#define NUM_ENDPTS 0x01 - -/* do we gracefully implement usb suspend? */ -#define F_SUSPEND_ENABLED 1 - -/* defines which interrupts are handled */ -#define ISR_MSK (CNTR_CTRM | \ - CNTR_WKUPM | \ - CNTR_SUSPM | \ - CNTR_ERRM | \ - CNTR_SOFM | \ - CNTR_ESOFM | \ - CNTR_RESETM \ - ) - -typedef enum _RESUME_STATE - { - RESUME_EXTERNAL, - RESUME_INTERNAL, - RESUME_LATER, - RESUME_WAIT, - RESUME_START, - RESUME_ON, - RESUME_OFF, - RESUME_ESOF - } RESUME_STATE; - -typedef enum _DEVICE_STATE - { - UNCONNECTED, - ATTACHED, - POWERED, - SUSPENDED, - ADDRESSED, - CONFIGURED - } DEVICE_STATE; - -void setupUSB(void); -void usbDsbBus(void); -void usbAppInit(void); /* singleton usb initializer */ - -void usbSuspend(void); -void usbResumeInit(void); -void usbResume(RESUME_STATE state); -RESULT usbPowerOn(void); -RESULT usbPowerOff(void); - -/* internal functions (as per the usb_core pProperty structure) */ -void usbInit(void); -void usbReset(void); -void usbStatusIn(void); -void usbStatusOut(void); - -RESULT usbDataSetup(u8 request); -RESULT usbNoDataSetup(u8 request); -RESULT usbGetInterfaceSetting(u8,u8); - -u8* usbGetDeviceDescriptor(u16 length); -u8* usbGetConfigDescriptor(u16 length); -u8* usbGetStringDescriptor(u16 length); -u8* usbGetFunctionalDescriptor(u16 length); - -/* internal callbacks to respond to standard requests */ -void usbGetConfiguration(void); -void usbSetConfiguration(void); -void usbGetInterface(void); -void usbSetInterface(void); -void usbGetStatus(void); -void usbClearFeature(void); -void usbSetEndpointFeature(void); -void usbSetDeviceFeature(void); -void usbSetDeviceAddress(void); - -/* the small number of comm emulator functions to - eventually be migrated into their own usart sources -*/ -u8* vcomGetLineCoding(u16 length); -u8* vcomSetLineCoding(u16 length); -void vcomEp1In(void); -void vcomEp3Out(void); - -/* Interrupt setup/handling exposed only so that - its obvious from main what interrupts are overloaded - from c_only_startup.s (see the top of main.c) */ -void usbDsbISR(void); -void usbEnbISR(void); - -/* override the weakly defined isr in linker */ -void USB_LP_CAN1_RX0_IRQHandler(void); - - -void nothingProc(void); - -#endif +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *****************************************************************************/ +#ifndef __USB_H +#define __USB_H + +#include "common.h" +#include "usb_lib.h" +#include "usb_descriptor.h" + +/* USB Disc Pin Setup. On the Native, USB DISC is PB8 */ + +#ifdef BOARD_maple_native +#define USB_DISC_BANK GPIOB +#define USB_DISC 8 +#define USB_DISC_CR GPIO_CRH(USB_DISC_BANK) +#define USB_DISC_CR_MASK 0xFFFFFFF0 +#define USB_DISC_CR_OUTPUT_OD 0x00000005 +#define USB_DISC_CR_OUTPUT_PP 0x00000001 +#define RCC_APB2ENR_USB 0x00000008 +#endif + + +#if defined(BOARD_aeroquad32) +#define USB_DISC_BANK GPIOD +#define USB_DISC 11 +#define USB_DISC_CR GPIO_CRH(USB_DISC_BANK) +#define USB_DISC_CR_MASK 0xFFFF0FFF +#define USB_DISC_CR_OUTPUT_OD 0x00005000 +#define USB_DISC_CR_OUTPUT_PP 0x00001000 +#define RCC_APB2ENR_USB 0x00000020 +#define RCC_AHB1ENR_USB 0x00000004 // F2 +#endif + +#ifdef BOARD_aeroquad32mini +#define USB_DISC_BANK GPIOA +#define USB_DISC 8 +#define USB_DISC_CR GPIO_CRH(USB_DISC_BANK) +#define USB_DISC_CR_MASK 0xFFFFFFF0 +#define USB_DISC_CR_OUTPUT_OD 0x00000005 +#define USB_DISC_CR_OUTPUT_PP 0x00000001 +#define RCC_APB2ENR_USB 0x00000008 +#endif + +#define RCC_APB1ENR_USB_CLK 0x00800000 + + + +/* USB configuration params */ +#define BTABLE_ADDRESS 0x00 +#define ENDP0_RXADDR 0x40 +#define ENDP0_TXADDR 0x80 /* gives 64 bytes i/o buflen */ +#define ENDP1_TXADDR 0xC0 +#define ENDP2_TXADDR 0x100 +#define ENDP3_RXADDR 0x110 + +#define bMaxPacketSize 0x40 /* 64B, maximum for usb FS devices */ +#define wTransferSize FLASH_PAGE_SIZE /* 2048B, want: maxpacket < + wtransfer < 10KB (to ensure + everything can live in + ram */ + +#define NUM_ENDPTS 0x01 + +/* do we gracefully implement usb suspend? */ +#define F_SUSPEND_ENABLED 1 + +/* defines which interrupts are handled */ +#define ISR_MSK (CNTR_CTRM | \ + CNTR_WKUPM | \ + CNTR_SUSPM | \ + CNTR_ERRM | \ + CNTR_SOFM | \ + CNTR_ESOFM | \ + CNTR_RESETM \ + ) + +typedef enum _RESUME_STATE + { + RESUME_EXTERNAL, + RESUME_INTERNAL, + RESUME_LATER, + RESUME_WAIT, + RESUME_START, + RESUME_ON, + RESUME_OFF, + RESUME_ESOF + } RESUME_STATE; + +typedef enum _DEVICE_STATE + { + UNCONNECTED, + ATTACHED, + POWERED, + SUSPENDED, + ADDRESSED, + CONFIGURED + } DEVICE_STATE; + +void setupUSB(void); +void usbDsbBus(void); +void usbAppInit(void); /* singleton usb initializer */ + +void usbSuspend(void); +void usbResumeInit(void); +void usbResume(RESUME_STATE state); +RESULT usbPowerOn(void); +RESULT usbPowerOff(void); + +/* internal functions (as per the usb_core pProperty structure) */ +void usbInit(void); +void usbReset(void); +void usbStatusIn(void); +void usbStatusOut(void); + +RESULT usbDataSetup(u8 request); +RESULT usbNoDataSetup(u8 request); +RESULT usbGetInterfaceSetting(u8,u8); + +u8* usbGetDeviceDescriptor(u16 length); +u8* usbGetConfigDescriptor(u16 length); +u8* usbGetStringDescriptor(u16 length); +u8* usbGetFunctionalDescriptor(u16 length); + +/* internal callbacks to respond to standard requests */ +void usbGetConfiguration(void); +void usbSetConfiguration(void); +void usbGetInterface(void); +void usbSetInterface(void); +void usbGetStatus(void); +void usbClearFeature(void); +void usbSetEndpointFeature(void); +void usbSetDeviceFeature(void); +void usbSetDeviceAddress(void); + +/* the small number of comm emulator functions to + eventually be migrated into their own usart sources +*/ +u8* vcomGetLineCoding(u16 length); +u8* vcomSetLineCoding(u16 length); +void vcomEp1In(void); +void vcomEp3Out(void); + +/* Interrupt setup/handling exposed only so that + its obvious from main what interrupts are overloaded + from c_only_startup.s (see the top of main.c) */ +void usbDsbISR(void); +void usbEnbISR(void); + +/* override the weakly defined isr in linker */ +void USB_LP_CAN1_RX0_IRQHandler(void); + + +void nothingProc(void); + +#endif diff --git a/Libmaple/maple-bootloader/usb_callbacks.c b/Libmaple/maple-bootloader/usb_callbacks.c index 036de273..09b0ae46 100644 --- a/Libmaple/maple-bootloader/usb_callbacks.c +++ b/Libmaple/maple-bootloader/usb_callbacks.c @@ -1,31 +1,31 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -/** - * @file usb_callbacks.c - * - * @brief aka endpoints: handling data transfer when "Configured". calls out to - * application specific callbacks (eg DFU) - * - */ +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +/** + * @file usb_callbacks.c + * + * @brief aka endpoints: handling data transfer when "Configured". calls out to + * application specific callbacks (eg DFU) + * + */ diff --git a/Libmaple/maple-bootloader/usb_descriptor.c b/Libmaple/maple-bootloader/usb_descriptor.c index 4cb83fd8..b560a10a 100644 --- a/Libmaple/maple-bootloader/usb_descriptor.c +++ b/Libmaple/maple-bootloader/usb_descriptor.c @@ -1,210 +1,210 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - - -/** - * @file usb_descriptor.c - * - * @brief aka application descriptor; big static struct and callbacks for sending - * the descriptor. - * - */ - - -#include "usb_descriptor.h" - -u8 u8_usbDeviceDescriptorDFU[18] = - { - 0x12, /* bLength */ - 0x01, /* bDescriptorType */ - 0x00, /* bcdUSB, version 1.00 */ - 0x01, - 0x00, /* bDeviceClass : See interface */ - 0x00, /* bDeviceSubClass : See interface*/ - 0x00, /* bDeviceProtocol : See interface */ - bMaxPacketSize, /* bMaxPacketSize0 0x40 = 64 */ - VEND_ID0, /* idVendor (0110) */ - VEND_ID1, - - PROD_ID0, /* idProduct (0x1001 or 1002) */ - PROD_ID1, - - 0x00, /* bcdDevice*/ - 0x02, - 0x01, /* iManufacturer : index of string Manufacturer */ - 0x02, /* iProduct : index of string descriptor of product*/ - 0x03, /* iSerialNumber : index of string serial number*/ - 0x01 /*bNumConfigurations */ - }; - -ONE_DESCRIPTOR usbDeviceDescriptorDFU = - { - u8_usbDeviceDescriptorDFU, - 0x12 - }; - -u8 u8_usbFunctionalDescriptor[9] = - { - /******************** DFU Functional Descriptor********************/ - 0x09, /*blength = 7 Bytes*/ - 0x21, /* DFU Functional Descriptor*/ - 0x01, /*bmAttribute, can only download for now */ - 0xFF, /*DetachTimeOut= 255 ms*/ - 0xFF, - (wTransferSize & 0x00FF), - (wTransferSize & 0xFF00) >> 8, /* TransferSize = 1024 Byte*/ - 0x1A, /* bcdDFUVersion*/ - 0x01 - }; - -ONE_DESCRIPTOR usbFunctionalDescriptor = - { - u8_usbFunctionalDescriptor, - 0x09 - }; - - -u8 u8_usbConfigDescriptorDFU[36] = - { - 0x09, /* bLength: Configuation Descriptor size */ - 0x02, /* bDescriptorType: Configuration */ - 0x24, /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - 0x00, /* iConfiguration: */ - 0x80, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ - /* 09 */ - - /************ Descriptor of DFU interface 0 Alternate setting 0 *********/ - 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType: */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x00, /* bNumEndpoints*/ - 0xFE, /* bInterfaceClass: DFU */ - 0x01, /* bInterfaceSubClass */ - - 0x02, /* nInterfaceProtocol, switched to 0x02 while in dfu_mode */ - - 0x04, /* iInterface: */ - - /************ Descriptor of DFU interface 0 Alternate setting 1 *********/ - 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType: */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x01, /* bAlternateSetting: Alternate setting */ - 0x00, /* bNumEndpoints*/ - 0xFE, /* bInterfaceClass: DFU */ - 0x01, /* bInterfaceSubClass */ - - 0x02, /* nInterfaceProtocol, switched to 0x02 while in dfu_mode */ - - 0x05, /* iInterface: */ - - /******************** DFU Functional Descriptor********************/ - 0x09, /*blength = 7 Bytes*/ - 0x21, /* DFU Functional Descriptor*/ - 0x01, /*bmAttribute, can only download for now */ - 0xFF, /*DetachTimeOut= 255 ms*/ - 0xFF, - (wTransferSize & 0x00FF), - (wTransferSize & 0xFF00) >> 8, /* TransferSize = 1024 Byte*/ - 0x01, /* bcdDFUVersion*/ - 0x00 - /***********************************************************/ - /*36*/ - }; - -ONE_DESCRIPTOR usbConfigDescriptorDFU = - { - u8_usbConfigDescriptorDFU, - 0x24 - }; - -u8 u8_usbStringLangId[0x04] = - { - 0x04, - 0x03, - 0x09, - 0x04 /* LangID = 0x0409: U.S. English */ - }; - -u8 u8_usbStringVendor[0x12] = - { - 0x12, - 0x03, - 'L',0,'e',0,'a',0,'f',0,'L',0,'a',0,'b',0,'s',0 - }; - -u8 u8_usbStringProduct[0x14] = - { - 0x14, - 0x03, - 'M',0,'a',0,'p',0,'l',0,'e',0,' ',0,'0',0,'0',0,'3',0 - }; - -u8 u8_usbStringSerial[0x10] = - { - 0x10, - 0x03, - 'L',0,'L',0,'M',0,' ',0,'0',0,'0',0,'3',0 - }; - -u8 u8_usbStringAlt0[0x36] = - { - 0x36, - 0x03, - 'D',0,'F',0,'U',0,' ',0,'P',0,'r',0,'o',0,'g',0,'r',0, - 'a',0,'m',0,' ',0,'R',0,'A',0,'M',0,' ',0,'0',0,'x',0, - '2',0,'0',0,'0',0,'0',0,'0',0,'C',0,'0',0,'0',0 - }; - -u8 u8_usbStringAlt1[0x3A] = - { - 0x3A, - 0x03, - 'D',0,'F',0,'U',0,' ',0,'P',0,'r',0,'o',0,'g',0,'r',0, - 'a',0,'m',0,' ',0,'F',0,'L',0,'A',0,'S',0,'H',0,' ',0, -#ifdef BOARD_aeroquad32mini - '0',0,'x',0,'0',0,'8',0,'0',0,'0',0,'5',0,'0',0,'0',0, // ala42 -#else - '0',0,'x',0,'0',0,'8',0,'0',0,'1',0,'0',0,'0',0,'0',0, // ala42 -#endif - '0',0 - }; - -u8 u8_usbStringInterface = NULL; - -ONE_DESCRIPTOR usbStringDescriptor[STR_DESC_LEN] = - { - { (u8*)u8_usbStringLangId, 0x04 }, - { (u8*)u8_usbStringVendor, 0x12 }, - { (u8*)u8_usbStringProduct, 0x20 }, - { (u8*)u8_usbStringSerial, 0x10 }, - { (u8*)u8_usbStringAlt0, 0x36 }, - { (u8*)u8_usbStringAlt1, 0x3A } - }; - +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + + +/** + * @file usb_descriptor.c + * + * @brief aka application descriptor; big static struct and callbacks for sending + * the descriptor. + * + */ + + +#include "usb_descriptor.h" + +u8 u8_usbDeviceDescriptorDFU[18] = + { + 0x12, /* bLength */ + 0x01, /* bDescriptorType */ + 0x00, /* bcdUSB, version 1.00 */ + 0x01, + 0x00, /* bDeviceClass : See interface */ + 0x00, /* bDeviceSubClass : See interface*/ + 0x00, /* bDeviceProtocol : See interface */ + bMaxPacketSize, /* bMaxPacketSize0 0x40 = 64 */ + VEND_ID0, /* idVendor (0110) */ + VEND_ID1, + + PROD_ID0, /* idProduct (0x1001 or 1002) */ + PROD_ID1, + + 0x00, /* bcdDevice*/ + 0x02, + 0x01, /* iManufacturer : index of string Manufacturer */ + 0x02, /* iProduct : index of string descriptor of product*/ + 0x03, /* iSerialNumber : index of string serial number*/ + 0x01 /*bNumConfigurations */ + }; + +ONE_DESCRIPTOR usbDeviceDescriptorDFU = + { + u8_usbDeviceDescriptorDFU, + 0x12 + }; + +u8 u8_usbFunctionalDescriptor[9] = + { + /******************** DFU Functional Descriptor********************/ + 0x09, /*blength = 7 Bytes*/ + 0x21, /* DFU Functional Descriptor*/ + 0x01, /*bmAttribute, can only download for now */ + 0xFF, /*DetachTimeOut= 255 ms*/ + 0xFF, + (wTransferSize & 0x00FF), + (wTransferSize & 0xFF00) >> 8, /* TransferSize = 1024 Byte*/ + 0x1A, /* bcdDFUVersion*/ + 0x01 + }; + +ONE_DESCRIPTOR usbFunctionalDescriptor = + { + u8_usbFunctionalDescriptor, + 0x09 + }; + + +u8 u8_usbConfigDescriptorDFU[36] = + { + 0x09, /* bLength: Configuation Descriptor size */ + 0x02, /* bDescriptorType: Configuration */ + 0x24, /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + 0x00, /* iConfiguration: */ + 0x80, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ + /* 09 */ + + /************ Descriptor of DFU interface 0 Alternate setting 0 *********/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x00, /* bNumEndpoints*/ + 0xFE, /* bInterfaceClass: DFU */ + 0x01, /* bInterfaceSubClass */ + + 0x02, /* nInterfaceProtocol, switched to 0x02 while in dfu_mode */ + + 0x04, /* iInterface: */ + + /************ Descriptor of DFU interface 0 Alternate setting 1 *********/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x01, /* bAlternateSetting: Alternate setting */ + 0x00, /* bNumEndpoints*/ + 0xFE, /* bInterfaceClass: DFU */ + 0x01, /* bInterfaceSubClass */ + + 0x02, /* nInterfaceProtocol, switched to 0x02 while in dfu_mode */ + + 0x05, /* iInterface: */ + + /******************** DFU Functional Descriptor********************/ + 0x09, /*blength = 7 Bytes*/ + 0x21, /* DFU Functional Descriptor*/ + 0x01, /*bmAttribute, can only download for now */ + 0xFF, /*DetachTimeOut= 255 ms*/ + 0xFF, + (wTransferSize & 0x00FF), + (wTransferSize & 0xFF00) >> 8, /* TransferSize = 1024 Byte*/ + 0x01, /* bcdDFUVersion*/ + 0x00 + /***********************************************************/ + /*36*/ + }; + +ONE_DESCRIPTOR usbConfigDescriptorDFU = + { + u8_usbConfigDescriptorDFU, + 0x24 + }; + +u8 u8_usbStringLangId[0x04] = + { + 0x04, + 0x03, + 0x09, + 0x04 /* LangID = 0x0409: U.S. English */ + }; + +u8 u8_usbStringVendor[0x12] = + { + 0x12, + 0x03, + 'L',0,'e',0,'a',0,'f',0,'L',0,'a',0,'b',0,'s',0 + }; + +u8 u8_usbStringProduct[0x14] = + { + 0x14, + 0x03, + 'M',0,'a',0,'p',0,'l',0,'e',0,' ',0,'0',0,'0',0,'3',0 + }; + +u8 u8_usbStringSerial[0x10] = + { + 0x10, + 0x03, + 'L',0,'L',0,'M',0,' ',0,'0',0,'0',0,'3',0 + }; + +u8 u8_usbStringAlt0[0x36] = + { + 0x36, + 0x03, + 'D',0,'F',0,'U',0,' ',0,'P',0,'r',0,'o',0,'g',0,'r',0, + 'a',0,'m',0,' ',0,'R',0,'A',0,'M',0,' ',0,'0',0,'x',0, + '2',0,'0',0,'0',0,'0',0,'0',0,'C',0,'0',0,'0',0 + }; + +u8 u8_usbStringAlt1[0x3A] = + { + 0x3A, + 0x03, + 'D',0,'F',0,'U',0,' ',0,'P',0,'r',0,'o',0,'g',0,'r',0, + 'a',0,'m',0,' ',0,'F',0,'L',0,'A',0,'S',0,'H',0,' ',0, +#ifdef BOARD_aeroquad32mini + '0',0,'x',0,'0',0,'8',0,'0',0,'0',0,'5',0,'0',0,'0',0, // ala42 +#else + '0',0,'x',0,'0',0,'8',0,'0',0,'1',0,'0',0,'0',0,'0',0, // ala42 +#endif + '0',0 + }; + +u8 u8_usbStringInterface = NULL; + +ONE_DESCRIPTOR usbStringDescriptor[STR_DESC_LEN] = + { + { (u8*)u8_usbStringLangId, 0x04 }, + { (u8*)u8_usbStringVendor, 0x12 }, + { (u8*)u8_usbStringProduct, 0x20 }, + { (u8*)u8_usbStringSerial, 0x10 }, + { (u8*)u8_usbStringAlt0, 0x36 }, + { (u8*)u8_usbStringAlt1, 0x3A } + }; + diff --git a/Libmaple/maple-bootloader/usb_descriptor.h b/Libmaple/maple-bootloader/usb_descriptor.h index 5bfe63c3..963f480a 100644 --- a/Libmaple/maple-bootloader/usb_descriptor.h +++ b/Libmaple/maple-bootloader/usb_descriptor.h @@ -1,40 +1,40 @@ -/* ***************************************************************************** - * The MIT License - * - * Copyright (c) 2010 LeafLabs LLC. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ****************************************************************************/ - -#ifndef __MAPLE_USB_DESC_H -#define __MAPLE_USB_DESC_H - -#include "common.h" -#include "usb_lib.h" -#include "usb.h" - -#define NUM_ALT_SETTINGS 2 -#define STR_DESC_LEN 6 - -extern ONE_DESCRIPTOR usbDeviceDescriptorDFU; -extern ONE_DESCRIPTOR usbConfigDescriptorDFU; -extern ONE_DESCRIPTOR usbStringDescriptor[6]; -extern ONE_DESCRIPTOR usbFunctionalDescriptor; - -#endif +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +#ifndef __MAPLE_USB_DESC_H +#define __MAPLE_USB_DESC_H + +#include "common.h" +#include "usb_lib.h" +#include "usb.h" + +#define NUM_ALT_SETTINGS 2 +#define STR_DESC_LEN 6 + +extern ONE_DESCRIPTOR usbDeviceDescriptorDFU; +extern ONE_DESCRIPTOR usbConfigDescriptorDFU; +extern ONE_DESCRIPTOR usbStringDescriptor[6]; +extern ONE_DESCRIPTOR usbFunctionalDescriptor; + +#endif diff --git a/Libmaple/maple-bootloader/usb_lib/usb_conf.h b/Libmaple/maple-bootloader/usb_lib/usb_conf.h index e9b7f147..e17fc7aa 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_conf.h +++ b/Libmaple/maple-bootloader/usb_lib/usb_conf.h @@ -1,86 +1,86 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_conf.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Device Firmware Upgrade (DFU) configuration file -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CONF_H -#define __USB_CONF_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -/* External variables --------------------------------------------------------*/ -/*-------------------------------------------------------------*/ -/* EP_NUM */ -/* defines how many endpoints are used by the device */ -/*-------------------------------------------------------------*/ -#define EP_NUM (1) - -/*-------------------------------------------------------------*/ -/* -------------- Buffer Description Table -----------------*/ -/*-------------------------------------------------------------*/ -/* buffer table base address */ -/* buffer table base address */ -#define BTABLE_ADDRESS (0x00) - -/* EP0 */ -/* rx/tx buffer base address */ -#define ENDP0_RXADDR (0x10) -#define ENDP0_TXADDR (0x50) - - -/*-------------------------------------------------------------*/ -/* ------------------- ISTR events -------------------------*/ -/*-------------------------------------------------------------*/ -/* IMR_MSK */ -/* mask defining which events has to be handled */ -/* by the device application software */ -#define IMR_MSK (CNTR_CTRM | \ - CNTR_WKUPM | \ - CNTR_SUSPM | \ - CNTR_ERRM | \ - CNTR_SOFM | \ - CNTR_ESOFM | \ - CNTR_RESETM \ - ) - -/* CTR service routines */ -/* associated to defined endpoints */ -#define EP1_IN_Callback NOP_Process -#define EP2_IN_Callback NOP_Process -#define EP3_IN_Callback NOP_Process -#define EP4_IN_Callback NOP_Process -#define EP5_IN_Callback NOP_Process -#define EP6_IN_Callback NOP_Process -#define EP7_IN_Callback NOP_Process - - -#define EP1_OUT_Callback NOP_Process -#define EP2_OUT_Callback NOP_Process -#define EP3_OUT_Callback NOP_Process -#define EP4_OUT_Callback NOP_Process -#define EP5_OUT_Callback NOP_Process -#define EP6_OUT_Callback NOP_Process -#define EP7_OUT_Callback NOP_Process - - -#endif /*__USB_CONF_H*/ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ - - - - +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_conf.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Device Firmware Upgrade (DFU) configuration file +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CONF_H +#define __USB_CONF_H + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* External variables --------------------------------------------------------*/ +/*-------------------------------------------------------------*/ +/* EP_NUM */ +/* defines how many endpoints are used by the device */ +/*-------------------------------------------------------------*/ +#define EP_NUM (1) + +/*-------------------------------------------------------------*/ +/* -------------- Buffer Description Table -----------------*/ +/*-------------------------------------------------------------*/ +/* buffer table base address */ +/* buffer table base address */ +#define BTABLE_ADDRESS (0x00) + +/* EP0 */ +/* rx/tx buffer base address */ +#define ENDP0_RXADDR (0x10) +#define ENDP0_TXADDR (0x50) + + +/*-------------------------------------------------------------*/ +/* ------------------- ISTR events -------------------------*/ +/*-------------------------------------------------------------*/ +/* IMR_MSK */ +/* mask defining which events has to be handled */ +/* by the device application software */ +#define IMR_MSK (CNTR_CTRM | \ + CNTR_WKUPM | \ + CNTR_SUSPM | \ + CNTR_ERRM | \ + CNTR_SOFM | \ + CNTR_ESOFM | \ + CNTR_RESETM \ + ) + +/* CTR service routines */ +/* associated to defined endpoints */ +#define EP1_IN_Callback NOP_Process +#define EP2_IN_Callback NOP_Process +#define EP3_IN_Callback NOP_Process +#define EP4_IN_Callback NOP_Process +#define EP5_IN_Callback NOP_Process +#define EP6_IN_Callback NOP_Process +#define EP7_IN_Callback NOP_Process + + +#define EP1_OUT_Callback NOP_Process +#define EP2_OUT_Callback NOP_Process +#define EP3_OUT_Callback NOP_Process +#define EP4_OUT_Callback NOP_Process +#define EP5_OUT_Callback NOP_Process +#define EP6_OUT_Callback NOP_Process +#define EP7_OUT_Callback NOP_Process + + +#endif /*__USB_CONF_H*/ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ + + + + diff --git a/Libmaple/maple-bootloader/usb_lib/usb_core.c b/Libmaple/maple-bootloader/usb_lib/usb_core.c index f6371651..d406839c 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_core.c +++ b/Libmaple/maple-bootloader/usb_lib/usb_core.c @@ -1,1016 +1,1016 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_core.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Standard protocol processing (USB v2.0) -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define ValBit(VAR,Place) (VAR & (1 << Place)) -#define SetBit(VAR,Place) (VAR |= (1 << Place)) -#define ClrBit(VAR,Place) (VAR &= ((1 << Place) ^ 255)) - -#define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \ - vSetEPTxStatus(EP_TX_VALID); \ - } - -#define vSetEPRxStatus(st) (SaveRState = st) -#define vSetEPTxStatus(st) (SaveTState = st) - -#define USB_StatusIn() Send0LengthData() -#define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID) - -#define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */ -#define StatusInfo1 StatusInfo.bw.bb0 - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -u16_u8 StatusInfo; -bool Data_Mul_MaxPacketSize = FALSE; -/* Private function prototypes -----------------------------------------------*/ -static void DataStageOut(void); -static void DataStageIn(void); -static void NoData_Setup0(void); -static void Data_Setup0(void); -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : Standard_GetConfiguration. -* Description : Return the current configuration variable address. -* Input : Length - How many bytes are needed. -* Output : None. -* Return : Return 1 , if the request is invalid when "Length" is 0. -* Return "Buffer" if the "Length" is not 0. -*******************************************************************************/ -u8 *Standard_GetConfiguration(u16 Length) -{ - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = - sizeof(pInformation->Current_Configuration); - return 0; - } - pUser_Standard_Requests->User_GetConfiguration(); - return (u8 *)&pInformation->Current_Configuration; -} - -/******************************************************************************* -* Function Name : Standard_SetConfiguration. -* Description : This routine is called to set the configuration value -* Then each class should configure device themself. -* Input : None. -* Output : None. -* Return : Return USB_SUCCESS, if the request is performed. -* Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetConfiguration(void) -{ - - if ((pInformation->USBwValue0 <= - Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0) - && (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/ - { - pInformation->Current_Configuration = pInformation->USBwValue0; - pUser_Standard_Requests->User_SetConfiguration(); - return USB_SUCCESS; - } - else - { - return USB_UNSUPPORT; - } -} - -/******************************************************************************* -* Function Name : Standard_GetInterface. -* Description : Return the Alternate Setting of the current interface. -* Input : Length - How many bytes are needed. -* Output : None. -* Return : Return 0, if the request is invalid when "Length" is 0. -* Return "Buffer" if the "Length" is not 0. -*******************************************************************************/ -u8 *Standard_GetInterface(u16 Length) -{ - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = - sizeof(pInformation->Current_AlternateSetting); - return 0; - } - pUser_Standard_Requests->User_GetInterface(); - return (u8 *)&pInformation->Current_AlternateSetting; -} - -/******************************************************************************* -* Function Name : Standard_SetInterface. -* Description : This routine is called to set the interface. -* Then each class should configure the interface them self. -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetInterface(void) -{ - RESULT Re; - /*Test if the specified Interface and Alternate Setting are supported by - the application Firmware*/ - Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0); - - if (pInformation->Current_Configuration != 0) - { - if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0) - || (pInformation->USBwValue1 != 0)) - { - return USB_UNSUPPORT; - } - else if (Re == USB_SUCCESS) - { - pUser_Standard_Requests->User_SetInterface(); - pInformation->Current_Interface = pInformation->USBwIndex0; - pInformation->Current_AlternateSetting = pInformation->USBwValue0; - return USB_SUCCESS; - } - - } - - return USB_UNSUPPORT; -} - -/******************************************************************************* -* Function Name : Standard_GetStatus. -* Description : Copy the device request data to "StatusInfo buffer". -* Input : - Length - How many bytes are needed. -* Output : None. -* Return : Return 0, if the request is at end of data block, -* or is invalid when "Length" is 0. -*******************************************************************************/ -u8 *Standard_GetStatus(u16 Length) -{ - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = 2; - return 0; - } - - StatusInfo.w = 0; - /* Reset Status Information */ - - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - /*Get Device Status */ - u8 Feature = pInformation->Current_Feature; - - /* Remote Wakeup enabled */ - if (ValBit(Feature, 5)) - { - SetBit(StatusInfo0, 1); - } - - /* Bus-powered */ - if (ValBit(Feature, 6)) - { - ClrBit(StatusInfo0, 0); - } - else /* Self-powered */ - { - SetBit(StatusInfo0, 0); - } - } - /*Interface Status*/ - else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - { - return (u8 *)&StatusInfo; - } - /*Get EndPoint Status*/ - else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - { - u8 Related_Endpoint; - u8 wIndex0 = pInformation->USBwIndex0; - - Related_Endpoint = (wIndex0 & 0x0f); - if (ValBit(wIndex0, 7)) - { - /* IN endpoint */ - if (_GetTxStallStatus(Related_Endpoint)) - { - SetBit(StatusInfo0, 0); /* IN Endpoint stalled */ - } - } - else - { - /* OUT endpoint */ - if (_GetRxStallStatus(Related_Endpoint)) - { - SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */ - } - } - - } - else - { - return NULL; - } - pUser_Standard_Requests->User_GetStatus(); - return (u8 *)&StatusInfo; -} - -/******************************************************************************* -* Function Name : Standard_ClearFeature. -* Description : Clear or disable a specific feature. -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_ClearFeature(void) -{ - u32 Type_Rec = Type_Recipient; - u32 Status; - - - if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - {/*Device Clear Feature*/ - ClrBit(pInformation->Current_Feature, 5); - return USB_SUCCESS; - } - else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - {/*EndPoint Clear Feature*/ - DEVICE* pDev; - u32 Related_Endpoint; - u32 wIndex0; - u32 rEP; - - if ((pInformation->USBwValue != ENDPOINT_STALL) - || (pInformation->USBwIndex1 != 0)) - { - return USB_UNSUPPORT; - } - - pDev = &Device_Table; - wIndex0 = pInformation->USBwIndex0; - rEP = wIndex0 & ~0x80; - Related_Endpoint = ENDP0 + rEP; - - if (ValBit(pInformation->USBwIndex0, 7)) - { - /*Get Status of endpoint & stall the request if the related_ENdpoint - is Disabled*/ - Status = _GetEPTxStatus(Related_Endpoint); - } - else - { - Status = _GetEPRxStatus(Related_Endpoint); - } - - if ((rEP >= pDev->Total_Endpoint) || (Status == 0) - || (pInformation->Current_Configuration == 0)) - { - return USB_UNSUPPORT; - } - - - if (wIndex0 & 0x80) - { - /* IN endpoint */ - if (_GetTxStallStatus(Related_Endpoint )) - { - ClearDTOG_TX(Related_Endpoint); - SetEPTxStatus(Related_Endpoint, EP_TX_VALID); - } - } - else - { - /* OUT endpoint */ - if (_GetRxStallStatus(Related_Endpoint)) - { - if (Related_Endpoint == ENDP0) - { - /* After clear the STALL, enable the default endpoint receiver */ - SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize); - _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); - } - else - { - ClearDTOG_RX(Related_Endpoint); - _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); - } - } - } - pUser_Standard_Requests->User_ClearFeature(); - return USB_SUCCESS; - } - - return USB_UNSUPPORT; -} - -/******************************************************************************* -* Function Name : Standard_SetEndPointFeature -* Description : Set or enable a specific feature of EndPoint -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetEndPointFeature(void) -{ - u32 wIndex0; - u32 Related_Endpoint; - u32 rEP; - u32 Status; - - wIndex0 = pInformation->USBwIndex0; - rEP = wIndex0 & ~0x80; - Related_Endpoint = ENDP0 + rEP; - - if (ValBit(pInformation->USBwIndex0, 7)) - { - /* get Status of endpoint & stall the request if the related_ENdpoint - is Disabled*/ - Status = _GetEPTxStatus(Related_Endpoint); - } - else - { - Status = _GetEPRxStatus(Related_Endpoint); - } - - if (Related_Endpoint >= Device_Table.Total_Endpoint - || pInformation->USBwValue != 0 || Status == 0 - || pInformation->Current_Configuration == 0) - { - return USB_UNSUPPORT; - } - else - { - if (wIndex0 & 0x80) - { - /* IN endpoint */ - _SetEPTxStatus(Related_Endpoint, EP_TX_STALL); - } - - else - { - /* OUT endpoint */ - _SetEPRxStatus(Related_Endpoint, EP_RX_STALL); - } - } - pUser_Standard_Requests->User_SetEndPointFeature(); - return USB_SUCCESS; -} - -/******************************************************************************* -* Function Name : Standard_SetDeviceFeature. -* Description : Set or enable a specific feature of Device. -* Input : None. -* Output : None. -* Return : - Return USB_SUCCESS, if the request is performed. -* - Return USB_UNSUPPORT, if the request is invalid. -*******************************************************************************/ -RESULT Standard_SetDeviceFeature(void) -{ - SetBit(pInformation->Current_Feature, 5); - pUser_Standard_Requests->User_SetDeviceFeature(); - return USB_SUCCESS; -} - -/******************************************************************************* -* Function Name : Standard_GetDescriptorData. -* Description : Standard_GetDescriptorData is used for descriptors transfer. -* : This routine is used for the descriptors resident in Flash -* or RAM -* pDesc can be in either Flash or RAM -* The purpose of this routine is to have a versatile way to -* response descriptors request. It allows user to generate -* certain descriptors with software or read descriptors from -* external storage part by part. -* Input : - Length - Length of the data in this transfer. -* - pDesc - A pointer points to descriptor struct. -* The structure gives the initial address of the descriptor and -* its original size. -* Output : None. -* Return : Address of a part of the descriptor pointed by the Usb_ -* wOffset The buffer pointed by this address contains at least -* Length bytes. -*******************************************************************************/ -u8 *Standard_GetDescriptorData(u16 Length, ONE_DESCRIPTOR *pDesc) -{ - u32 wOffset; - - wOffset = pInformation->Ctrl_Info.Usb_wOffset; - if (Length == 0) - { - pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset; - return 0; - } - - return pDesc->Descriptor + wOffset; -} - -/******************************************************************************* -* Function Name : DataStageOut. -* Description : Data stage of a Control Write Transfer. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void DataStageOut(void) -{ - ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; - u32 save_rLength; - - save_rLength = pEPinfo->Usb_rLength; - - if (pEPinfo->CopyData && save_rLength) - { - u8 *Buffer; - u32 Length; - - Length = pEPinfo->PacketSize; - if (Length > save_rLength) - { - Length = save_rLength; - } - - Buffer = (*pEPinfo->CopyData)(Length); - pEPinfo->Usb_rLength -= Length; - pEPinfo->Usb_rOffset += Length; - - PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); - } - - if (pEPinfo->Usb_rLength != 0) - { - vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */ - SetEPTxCount(ENDP0, 0); - vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */ - } - /* Set the next State*/ - if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) - { - pInformation->ControlState = OUT_DATA; - } - else - { - if (pEPinfo->Usb_rLength > 0) - { - pInformation->ControlState = LAST_OUT_DATA; - } - else if (pEPinfo->Usb_rLength == 0) - { - pInformation->ControlState = WAIT_STATUS_IN; - USB_StatusIn(); - } - } -} - -/******************************************************************************* -* Function Name : DataStageIn. -* Description : Data stage of a Control Read Transfer. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void DataStageIn(void) -{ - ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; - u32 save_wLength = pEPinfo->Usb_wLength; - u32 ControlState = pInformation->ControlState; - - u8 *DataBuffer; - u32 Length; - - if ((save_wLength == 0) && (ControlState == LAST_IN_DATA)) - { - if(Data_Mul_MaxPacketSize == TRUE) - { - /* No more data to send and empty packet */ - Send0LengthData(); - ControlState = LAST_IN_DATA; - Data_Mul_MaxPacketSize = FALSE; - } - else - { - /* No more data to send so STALL the TX Status*/ - ControlState = WAIT_STATUS_OUT; - vSetEPTxStatus(EP_TX_STALL); - } - - goto Expect_Status_Out; - } - - Length = pEPinfo->PacketSize; - ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA; - - if (Length > save_wLength) - { - Length = save_wLength; - } - - DataBuffer = (*pEPinfo->CopyData)(Length); - - UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length); - - SetEPTxCount(ENDP0, Length); - - pEPinfo->Usb_wLength -= Length; - pEPinfo->Usb_wOffset += Length; - vSetEPTxStatus(EP_TX_VALID); - - USB_StatusOut();/* Expect the host to abort the data IN stage */ - -Expect_Status_Out: - pInformation->ControlState = ControlState; -} - -/******************************************************************************* -* Function Name : NoData_Setup0. -* Description : Proceed the processing of setup request without data stage. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void NoData_Setup0(void) -{ - RESULT Result = USB_UNSUPPORT; - u32 RequestNo = pInformation->USBbRequest; - u32 ControlState; - - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - /* Device Request*/ - /* SET_CONFIGURATION*/ - if (RequestNo == SET_CONFIGURATION) - { - Result = Standard_SetConfiguration(); - } - - /*SET ADDRESS*/ - else if (RequestNo == SET_ADDRESS) - { - if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0) - || (pInformation->USBwIndex != 0) - || (pInformation->Current_Configuration != 0)) - /* Device Address should be 127 or less*/ - { - ControlState = STALLED; - goto exit_NoData_Setup0; - } - else - { - Result = USB_SUCCESS; - } - } - /*SET FEATURE for Device*/ - else if (RequestNo == SET_FEATURE) - { - if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP) - && (pInformation->USBwIndex == 0) - && (ValBit(pInformation->Current_Feature, 5))) - { - Result = Standard_SetDeviceFeature(); - } - else - { - Result = USB_UNSUPPORT; - } - } - /*Clear FEATURE for Device */ - else if (RequestNo == CLEAR_FEATURE) - { - if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP - && pInformation->USBwIndex == 0 - && ValBit(pInformation->Current_Feature, 5)) - { - Result = Standard_ClearFeature(); - } - else - { - Result = USB_UNSUPPORT; - } - } - - } - - /* Interface Request*/ - else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - { - /*SET INTERFACE*/ - if (RequestNo == SET_INTERFACE) - { - Result = Standard_SetInterface(); - } - } - - /* EndPoint Request*/ - else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - { - /*CLEAR FEATURE for EndPoint*/ - if (RequestNo == CLEAR_FEATURE) - { - Result = Standard_ClearFeature(); - } - /* SET FEATURE for EndPoint*/ - else if (RequestNo == SET_FEATURE) - { - Result = Standard_SetEndPointFeature(); - } - } - else - { - Result = USB_UNSUPPORT; - } - - - if (Result != USB_SUCCESS) - { - Result = (*pProperty->Class_NoData_Setup)(RequestNo); - if (Result == USB_NOT_READY) - { - ControlState = PAUSE; - goto exit_NoData_Setup0; - } - } - - if (Result != USB_SUCCESS) - { - ControlState = STALLED; - goto exit_NoData_Setup0; - } - - ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */ - - USB_StatusIn(); - -exit_NoData_Setup0: - pInformation->ControlState = ControlState; - return; -} - -/******************************************************************************* -* Function Name : Data_Setup0. -* Description : Proceed the processing of setup request with data stage. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void Data_Setup0(void) -{ - u8 *(*CopyRoutine)(u16); - RESULT Result; - u32 Request_No = pInformation->USBbRequest; - - u32 Related_Endpoint, Reserved; - u32 wOffset, Status; - - - - CopyRoutine = NULL; - wOffset = 0; - - if (Request_No == GET_DESCRIPTOR) - { - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - u8 wValue1 = pInformation->USBwValue1; - if (wValue1 == DEVICE_DESCRIPTOR) - { - CopyRoutine = pProperty->GetDeviceDescriptor; - } - else if (wValue1 == CONFIG_DESCRIPTOR) - { - CopyRoutine = pProperty->GetConfigDescriptor; - } - else if (wValue1 == STRING_DESCRIPTOR) - { - CopyRoutine = pProperty->GetStringDescriptor; - } else if (wValue1 == 0x21) /* added to support functional descriptors */ - { - CopyRoutine = pProperty->GetFunctionalDescriptor; - } /* End of GET_DESCRIPTOR */ - } - } - - /*GET STATUS*/ - else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0) - && (pInformation->USBwLength == 0x0002) - && (pInformation->USBwIndex1 == 0)) - { - /* GET STATUS for Device*/ - if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - && (pInformation->USBwIndex == 0)) - { - CopyRoutine = Standard_GetStatus; - } - - /* GET STATUS for Interface*/ - else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - { - if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS) - && (pInformation->Current_Configuration != 0)) - { - CopyRoutine = Standard_GetStatus; - } - } - - /* GET STATUS for EndPoint*/ - else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) - { - Related_Endpoint = (pInformation->USBwIndex0 & 0x0f); - Reserved = pInformation->USBwIndex0 & 0x70; - - if (ValBit(pInformation->USBwIndex0, 7)) - { - /*Get Status of endpoint & stall the request if the related_ENdpoint - is Disabled*/ - Status = _GetEPTxStatus(Related_Endpoint); - } - else - { - Status = _GetEPRxStatus(Related_Endpoint); - } - - if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0) - && (Status != 0)) - { - CopyRoutine = Standard_GetStatus; - } - } - - } - - /*GET CONFIGURATION*/ - else if (Request_No == GET_CONFIGURATION) - { - if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) - { - CopyRoutine = Standard_GetConfiguration; - } - } - /*GET INTERFACE*/ - else if (Request_No == GET_INTERFACE) - { - if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) - && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0) - && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001) - && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)) - { - CopyRoutine = Standard_GetInterface; - } - - } - - if (CopyRoutine) - { - pInformation->Ctrl_Info.Usb_wOffset = wOffset; - pInformation->Ctrl_Info.CopyData = CopyRoutine; - /* sb in the original the cast to word was directly */ - /* now the cast is made step by step */ - (*CopyRoutine)(0); - Result = USB_SUCCESS; - } - else - { - Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest); - if (Result == USB_NOT_READY) - { - pInformation->ControlState = PAUSE; - return; - } - } - - if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF) - { - /* Data is not ready, wait it */ - pInformation->ControlState = PAUSE; - return; - } - if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0)) - { - /* Unsupported request */ - pInformation->ControlState = STALLED; - return; - } - - - if (ValBit(pInformation->USBbmRequestType, 7)) - { - /* Device ==> Host */ - vu32 wLength = pInformation->USBwLength; - - /* Restrict the data length to be the one host asks */ - if (pInformation->Ctrl_Info.Usb_wLength > wLength) - { - pInformation->Ctrl_Info.Usb_wLength = wLength; - } - - else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength) - { - if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize) - { - Data_Mul_MaxPacketSize = FALSE; - } - else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0) - { - Data_Mul_MaxPacketSize = TRUE; - } - } - - pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize; - DataStageIn(); - } - else - { - pInformation->ControlState = OUT_DATA; - vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */ - } - - return; -} - -/******************************************************************************* -* Function Name : Setup0_Process -* Description : Get the device request data and dispatch to individual process. -* Input : None. -* Output : None. -* Return : Post0_Process. -*******************************************************************************/ -u8 Setup0_Process(void) -{ - - union - { - u8* b; - u16* w; - } pBuf; - - pBuf.b = PMAAddr + (u8 *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */ - - if (pInformation->ControlState != PAUSE) - { - pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */ - pInformation->USBbRequest = *pBuf.b++; /* bRequest */ - pBuf.w++; /* word not accessed because of 32 bits addressing */ - pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */ - pBuf.w++; /* word not accessed because of 32 bits addressing */ - pInformation->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */ - pBuf.w++; /* word not accessed because of 32 bits addressing */ - pInformation->USBwLength = *pBuf.w; /* wLength */ - } - - pInformation->ControlState = SETTING_UP; - if (pInformation->USBwLength == 0) - { - /* Setup with no data stage */ - NoData_Setup0(); - } - else - { - /* Setup with data stage */ - Data_Setup0(); - } - return Post0_Process(); -} - -/******************************************************************************* -* Function Name : In0_Process -* Description : Process the IN token on all default endpoint. -* Input : None. -* Output : None. -* Return : Post0_Process. -*******************************************************************************/ -u8 In0_Process(void) -{ - u32 ControlState = pInformation->ControlState; - - if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) - { - DataStageIn(); - /* ControlState may be changed outside the function */ - ControlState = pInformation->ControlState; - } - - else if (ControlState == WAIT_STATUS_IN) - { - if ((pInformation->USBbRequest == SET_ADDRESS) && - (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))) - { - SetDeviceAddress(pInformation->USBwValue0); - pUser_Standard_Requests->User_SetDeviceAddress(); - } - (*pProperty->Process_Status_IN)(); - ControlState = STALLED; - } - - else - { - ControlState = STALLED; - } - - pInformation->ControlState = ControlState; - - return Post0_Process(); -} - -/******************************************************************************* -* Function Name : Out0_Process -* Description : Process the OUT token on all default endpoint. -* Input : None. -* Output : None. -* Return : Post0_Process. -*******************************************************************************/ -u8 Out0_Process(void) -{ - u32 ControlState = pInformation->ControlState; - - if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA)) - { - DataStageOut(); - ControlState = pInformation->ControlState; /* may be changed outside the function */ - } - - else if (ControlState == WAIT_STATUS_OUT) - { - (*pProperty->Process_Status_OUT)(); - ControlState = STALLED; - } - - else if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) - { - /* host aborts the transfer before finish */ - ControlState = STALLED; - } - - /* Unexpect state, STALL the endpoint */ - else - { - ControlState = STALLED; - } - - pInformation->ControlState = ControlState; - - return Post0_Process(); -} - -/******************************************************************************* -* Function Name : Post0_Process -* Description : Stall the Endpoint 0 in case of error. -* Input : None. -* Output : None. -* Return : - 0 if the control State is in PAUSE -* - 1 if not. -*******************************************************************************/ -u8 Post0_Process(void) -{ - SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); - - if (pInformation->ControlState == STALLED) - { - vSetEPRxStatus(EP_RX_STALL); - vSetEPTxStatus(EP_TX_STALL); - } - - return (pInformation->ControlState == PAUSE); -} - -/******************************************************************************* -* Function Name : SetDeviceAddress. -* Description : Set the device and all the used Endpoints addresses. -* Input : - Val: device adress. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetDeviceAddress(u8 Val) -{ - u32 i; - u32 nEP = Device_Table.Total_Endpoint; - - /* set address in every used endpoint */ - for (i = 0; i < nEP; i++) - { - _SetEPAddress((u8)i, (u8)i); - } /* for */ - _SetDADDR(Val | DADDR_EF); /* set device address and enable function */ -} - -/******************************************************************************* -* Function Name : NOP_Process -* Description : No operation function. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void NOP_Process(void) -{ -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_core.c +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Standard protocol processing (USB v2.0) +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_lib.h" +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define ValBit(VAR,Place) (VAR & (1 << Place)) +#define SetBit(VAR,Place) (VAR |= (1 << Place)) +#define ClrBit(VAR,Place) (VAR &= ((1 << Place) ^ 255)) + +#define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \ + vSetEPTxStatus(EP_TX_VALID); \ + } + +#define vSetEPRxStatus(st) (SaveRState = st) +#define vSetEPTxStatus(st) (SaveTState = st) + +#define USB_StatusIn() Send0LengthData() +#define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID) + +#define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */ +#define StatusInfo1 StatusInfo.bw.bb0 + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +u16_u8 StatusInfo; +bool Data_Mul_MaxPacketSize = FALSE; +/* Private function prototypes -----------------------------------------------*/ +static void DataStageOut(void); +static void DataStageIn(void); +static void NoData_Setup0(void); +static void Data_Setup0(void); +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : Standard_GetConfiguration. +* Description : Return the current configuration variable address. +* Input : Length - How many bytes are needed. +* Output : None. +* Return : Return 1 , if the request is invalid when "Length" is 0. +* Return "Buffer" if the "Length" is not 0. +*******************************************************************************/ +u8 *Standard_GetConfiguration(u16 Length) +{ + if (Length == 0) + { + pInformation->Ctrl_Info.Usb_wLength = + sizeof(pInformation->Current_Configuration); + return 0; + } + pUser_Standard_Requests->User_GetConfiguration(); + return (u8 *)&pInformation->Current_Configuration; +} + +/******************************************************************************* +* Function Name : Standard_SetConfiguration. +* Description : This routine is called to set the configuration value +* Then each class should configure device themself. +* Input : None. +* Output : None. +* Return : Return USB_SUCCESS, if the request is performed. +* Return USB_UNSUPPORT, if the request is invalid. +*******************************************************************************/ +RESULT Standard_SetConfiguration(void) +{ + + if ((pInformation->USBwValue0 <= + Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0) + && (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/ + { + pInformation->Current_Configuration = pInformation->USBwValue0; + pUser_Standard_Requests->User_SetConfiguration(); + return USB_SUCCESS; + } + else + { + return USB_UNSUPPORT; + } +} + +/******************************************************************************* +* Function Name : Standard_GetInterface. +* Description : Return the Alternate Setting of the current interface. +* Input : Length - How many bytes are needed. +* Output : None. +* Return : Return 0, if the request is invalid when "Length" is 0. +* Return "Buffer" if the "Length" is not 0. +*******************************************************************************/ +u8 *Standard_GetInterface(u16 Length) +{ + if (Length == 0) + { + pInformation->Ctrl_Info.Usb_wLength = + sizeof(pInformation->Current_AlternateSetting); + return 0; + } + pUser_Standard_Requests->User_GetInterface(); + return (u8 *)&pInformation->Current_AlternateSetting; +} + +/******************************************************************************* +* Function Name : Standard_SetInterface. +* Description : This routine is called to set the interface. +* Then each class should configure the interface them self. +* Input : None. +* Output : None. +* Return : - Return USB_SUCCESS, if the request is performed. +* - Return USB_UNSUPPORT, if the request is invalid. +*******************************************************************************/ +RESULT Standard_SetInterface(void) +{ + RESULT Re; + /*Test if the specified Interface and Alternate Setting are supported by + the application Firmware*/ + Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0); + + if (pInformation->Current_Configuration != 0) + { + if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0) + || (pInformation->USBwValue1 != 0)) + { + return USB_UNSUPPORT; + } + else if (Re == USB_SUCCESS) + { + pUser_Standard_Requests->User_SetInterface(); + pInformation->Current_Interface = pInformation->USBwIndex0; + pInformation->Current_AlternateSetting = pInformation->USBwValue0; + return USB_SUCCESS; + } + + } + + return USB_UNSUPPORT; +} + +/******************************************************************************* +* Function Name : Standard_GetStatus. +* Description : Copy the device request data to "StatusInfo buffer". +* Input : - Length - How many bytes are needed. +* Output : None. +* Return : Return 0, if the request is at end of data block, +* or is invalid when "Length" is 0. +*******************************************************************************/ +u8 *Standard_GetStatus(u16 Length) +{ + if (Length == 0) + { + pInformation->Ctrl_Info.Usb_wLength = 2; + return 0; + } + + StatusInfo.w = 0; + /* Reset Status Information */ + + if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + { + /*Get Device Status */ + u8 Feature = pInformation->Current_Feature; + + /* Remote Wakeup enabled */ + if (ValBit(Feature, 5)) + { + SetBit(StatusInfo0, 1); + } + + /* Bus-powered */ + if (ValBit(Feature, 6)) + { + ClrBit(StatusInfo0, 0); + } + else /* Self-powered */ + { + SetBit(StatusInfo0, 0); + } + } + /*Interface Status*/ + else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) + { + return (u8 *)&StatusInfo; + } + /*Get EndPoint Status*/ + else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) + { + u8 Related_Endpoint; + u8 wIndex0 = pInformation->USBwIndex0; + + Related_Endpoint = (wIndex0 & 0x0f); + if (ValBit(wIndex0, 7)) + { + /* IN endpoint */ + if (_GetTxStallStatus(Related_Endpoint)) + { + SetBit(StatusInfo0, 0); /* IN Endpoint stalled */ + } + } + else + { + /* OUT endpoint */ + if (_GetRxStallStatus(Related_Endpoint)) + { + SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */ + } + } + + } + else + { + return NULL; + } + pUser_Standard_Requests->User_GetStatus(); + return (u8 *)&StatusInfo; +} + +/******************************************************************************* +* Function Name : Standard_ClearFeature. +* Description : Clear or disable a specific feature. +* Input : None. +* Output : None. +* Return : - Return USB_SUCCESS, if the request is performed. +* - Return USB_UNSUPPORT, if the request is invalid. +*******************************************************************************/ +RESULT Standard_ClearFeature(void) +{ + u32 Type_Rec = Type_Recipient; + u32 Status; + + + if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + {/*Device Clear Feature*/ + ClrBit(pInformation->Current_Feature, 5); + return USB_SUCCESS; + } + else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) + {/*EndPoint Clear Feature*/ + DEVICE* pDev; + u32 Related_Endpoint; + u32 wIndex0; + u32 rEP; + + if ((pInformation->USBwValue != ENDPOINT_STALL) + || (pInformation->USBwIndex1 != 0)) + { + return USB_UNSUPPORT; + } + + pDev = &Device_Table; + wIndex0 = pInformation->USBwIndex0; + rEP = wIndex0 & ~0x80; + Related_Endpoint = ENDP0 + rEP; + + if (ValBit(pInformation->USBwIndex0, 7)) + { + /*Get Status of endpoint & stall the request if the related_ENdpoint + is Disabled*/ + Status = _GetEPTxStatus(Related_Endpoint); + } + else + { + Status = _GetEPRxStatus(Related_Endpoint); + } + + if ((rEP >= pDev->Total_Endpoint) || (Status == 0) + || (pInformation->Current_Configuration == 0)) + { + return USB_UNSUPPORT; + } + + + if (wIndex0 & 0x80) + { + /* IN endpoint */ + if (_GetTxStallStatus(Related_Endpoint )) + { + ClearDTOG_TX(Related_Endpoint); + SetEPTxStatus(Related_Endpoint, EP_TX_VALID); + } + } + else + { + /* OUT endpoint */ + if (_GetRxStallStatus(Related_Endpoint)) + { + if (Related_Endpoint == ENDP0) + { + /* After clear the STALL, enable the default endpoint receiver */ + SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize); + _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); + } + else + { + ClearDTOG_RX(Related_Endpoint); + _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); + } + } + } + pUser_Standard_Requests->User_ClearFeature(); + return USB_SUCCESS; + } + + return USB_UNSUPPORT; +} + +/******************************************************************************* +* Function Name : Standard_SetEndPointFeature +* Description : Set or enable a specific feature of EndPoint +* Input : None. +* Output : None. +* Return : - Return USB_SUCCESS, if the request is performed. +* - Return USB_UNSUPPORT, if the request is invalid. +*******************************************************************************/ +RESULT Standard_SetEndPointFeature(void) +{ + u32 wIndex0; + u32 Related_Endpoint; + u32 rEP; + u32 Status; + + wIndex0 = pInformation->USBwIndex0; + rEP = wIndex0 & ~0x80; + Related_Endpoint = ENDP0 + rEP; + + if (ValBit(pInformation->USBwIndex0, 7)) + { + /* get Status of endpoint & stall the request if the related_ENdpoint + is Disabled*/ + Status = _GetEPTxStatus(Related_Endpoint); + } + else + { + Status = _GetEPRxStatus(Related_Endpoint); + } + + if (Related_Endpoint >= Device_Table.Total_Endpoint + || pInformation->USBwValue != 0 || Status == 0 + || pInformation->Current_Configuration == 0) + { + return USB_UNSUPPORT; + } + else + { + if (wIndex0 & 0x80) + { + /* IN endpoint */ + _SetEPTxStatus(Related_Endpoint, EP_TX_STALL); + } + + else + { + /* OUT endpoint */ + _SetEPRxStatus(Related_Endpoint, EP_RX_STALL); + } + } + pUser_Standard_Requests->User_SetEndPointFeature(); + return USB_SUCCESS; +} + +/******************************************************************************* +* Function Name : Standard_SetDeviceFeature. +* Description : Set or enable a specific feature of Device. +* Input : None. +* Output : None. +* Return : - Return USB_SUCCESS, if the request is performed. +* - Return USB_UNSUPPORT, if the request is invalid. +*******************************************************************************/ +RESULT Standard_SetDeviceFeature(void) +{ + SetBit(pInformation->Current_Feature, 5); + pUser_Standard_Requests->User_SetDeviceFeature(); + return USB_SUCCESS; +} + +/******************************************************************************* +* Function Name : Standard_GetDescriptorData. +* Description : Standard_GetDescriptorData is used for descriptors transfer. +* : This routine is used for the descriptors resident in Flash +* or RAM +* pDesc can be in either Flash or RAM +* The purpose of this routine is to have a versatile way to +* response descriptors request. It allows user to generate +* certain descriptors with software or read descriptors from +* external storage part by part. +* Input : - Length - Length of the data in this transfer. +* - pDesc - A pointer points to descriptor struct. +* The structure gives the initial address of the descriptor and +* its original size. +* Output : None. +* Return : Address of a part of the descriptor pointed by the Usb_ +* wOffset The buffer pointed by this address contains at least +* Length bytes. +*******************************************************************************/ +u8 *Standard_GetDescriptorData(u16 Length, ONE_DESCRIPTOR *pDesc) +{ + u32 wOffset; + + wOffset = pInformation->Ctrl_Info.Usb_wOffset; + if (Length == 0) + { + pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset; + return 0; + } + + return pDesc->Descriptor + wOffset; +} + +/******************************************************************************* +* Function Name : DataStageOut. +* Description : Data stage of a Control Write Transfer. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void DataStageOut(void) +{ + ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; + u32 save_rLength; + + save_rLength = pEPinfo->Usb_rLength; + + if (pEPinfo->CopyData && save_rLength) + { + u8 *Buffer; + u32 Length; + + Length = pEPinfo->PacketSize; + if (Length > save_rLength) + { + Length = save_rLength; + } + + Buffer = (*pEPinfo->CopyData)(Length); + pEPinfo->Usb_rLength -= Length; + pEPinfo->Usb_rOffset += Length; + + PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); + } + + if (pEPinfo->Usb_rLength != 0) + { + vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */ + SetEPTxCount(ENDP0, 0); + vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */ + } + /* Set the next State*/ + if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) + { + pInformation->ControlState = OUT_DATA; + } + else + { + if (pEPinfo->Usb_rLength > 0) + { + pInformation->ControlState = LAST_OUT_DATA; + } + else if (pEPinfo->Usb_rLength == 0) + { + pInformation->ControlState = WAIT_STATUS_IN; + USB_StatusIn(); + } + } +} + +/******************************************************************************* +* Function Name : DataStageIn. +* Description : Data stage of a Control Read Transfer. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void DataStageIn(void) +{ + ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; + u32 save_wLength = pEPinfo->Usb_wLength; + u32 ControlState = pInformation->ControlState; + + u8 *DataBuffer; + u32 Length; + + if ((save_wLength == 0) && (ControlState == LAST_IN_DATA)) + { + if(Data_Mul_MaxPacketSize == TRUE) + { + /* No more data to send and empty packet */ + Send0LengthData(); + ControlState = LAST_IN_DATA; + Data_Mul_MaxPacketSize = FALSE; + } + else + { + /* No more data to send so STALL the TX Status*/ + ControlState = WAIT_STATUS_OUT; + vSetEPTxStatus(EP_TX_STALL); + } + + goto Expect_Status_Out; + } + + Length = pEPinfo->PacketSize; + ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA; + + if (Length > save_wLength) + { + Length = save_wLength; + } + + DataBuffer = (*pEPinfo->CopyData)(Length); + + UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length); + + SetEPTxCount(ENDP0, Length); + + pEPinfo->Usb_wLength -= Length; + pEPinfo->Usb_wOffset += Length; + vSetEPTxStatus(EP_TX_VALID); + + USB_StatusOut();/* Expect the host to abort the data IN stage */ + +Expect_Status_Out: + pInformation->ControlState = ControlState; +} + +/******************************************************************************* +* Function Name : NoData_Setup0. +* Description : Proceed the processing of setup request without data stage. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void NoData_Setup0(void) +{ + RESULT Result = USB_UNSUPPORT; + u32 RequestNo = pInformation->USBbRequest; + u32 ControlState; + + if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + { + /* Device Request*/ + /* SET_CONFIGURATION*/ + if (RequestNo == SET_CONFIGURATION) + { + Result = Standard_SetConfiguration(); + } + + /*SET ADDRESS*/ + else if (RequestNo == SET_ADDRESS) + { + if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0) + || (pInformation->USBwIndex != 0) + || (pInformation->Current_Configuration != 0)) + /* Device Address should be 127 or less*/ + { + ControlState = STALLED; + goto exit_NoData_Setup0; + } + else + { + Result = USB_SUCCESS; + } + } + /*SET FEATURE for Device*/ + else if (RequestNo == SET_FEATURE) + { + if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP) + && (pInformation->USBwIndex == 0) + && (ValBit(pInformation->Current_Feature, 5))) + { + Result = Standard_SetDeviceFeature(); + } + else + { + Result = USB_UNSUPPORT; + } + } + /*Clear FEATURE for Device */ + else if (RequestNo == CLEAR_FEATURE) + { + if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP + && pInformation->USBwIndex == 0 + && ValBit(pInformation->Current_Feature, 5)) + { + Result = Standard_ClearFeature(); + } + else + { + Result = USB_UNSUPPORT; + } + } + + } + + /* Interface Request*/ + else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) + { + /*SET INTERFACE*/ + if (RequestNo == SET_INTERFACE) + { + Result = Standard_SetInterface(); + } + } + + /* EndPoint Request*/ + else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) + { + /*CLEAR FEATURE for EndPoint*/ + if (RequestNo == CLEAR_FEATURE) + { + Result = Standard_ClearFeature(); + } + /* SET FEATURE for EndPoint*/ + else if (RequestNo == SET_FEATURE) + { + Result = Standard_SetEndPointFeature(); + } + } + else + { + Result = USB_UNSUPPORT; + } + + + if (Result != USB_SUCCESS) + { + Result = (*pProperty->Class_NoData_Setup)(RequestNo); + if (Result == USB_NOT_READY) + { + ControlState = PAUSE; + goto exit_NoData_Setup0; + } + } + + if (Result != USB_SUCCESS) + { + ControlState = STALLED; + goto exit_NoData_Setup0; + } + + ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */ + + USB_StatusIn(); + +exit_NoData_Setup0: + pInformation->ControlState = ControlState; + return; +} + +/******************************************************************************* +* Function Name : Data_Setup0. +* Description : Proceed the processing of setup request with data stage. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void Data_Setup0(void) +{ + u8 *(*CopyRoutine)(u16); + RESULT Result; + u32 Request_No = pInformation->USBbRequest; + + u32 Related_Endpoint, Reserved; + u32 wOffset, Status; + + + + CopyRoutine = NULL; + wOffset = 0; + + if (Request_No == GET_DESCRIPTOR) + { + if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + { + u8 wValue1 = pInformation->USBwValue1; + if (wValue1 == DEVICE_DESCRIPTOR) + { + CopyRoutine = pProperty->GetDeviceDescriptor; + } + else if (wValue1 == CONFIG_DESCRIPTOR) + { + CopyRoutine = pProperty->GetConfigDescriptor; + } + else if (wValue1 == STRING_DESCRIPTOR) + { + CopyRoutine = pProperty->GetStringDescriptor; + } else if (wValue1 == 0x21) /* added to support functional descriptors */ + { + CopyRoutine = pProperty->GetFunctionalDescriptor; + } /* End of GET_DESCRIPTOR */ + } + } + + /*GET STATUS*/ + else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0) + && (pInformation->USBwLength == 0x0002) + && (pInformation->USBwIndex1 == 0)) + { + /* GET STATUS for Device*/ + if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + && (pInformation->USBwIndex == 0)) + { + CopyRoutine = Standard_GetStatus; + } + + /* GET STATUS for Interface*/ + else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) + { + if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS) + && (pInformation->Current_Configuration != 0)) + { + CopyRoutine = Standard_GetStatus; + } + } + + /* GET STATUS for EndPoint*/ + else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) + { + Related_Endpoint = (pInformation->USBwIndex0 & 0x0f); + Reserved = pInformation->USBwIndex0 & 0x70; + + if (ValBit(pInformation->USBwIndex0, 7)) + { + /*Get Status of endpoint & stall the request if the related_ENdpoint + is Disabled*/ + Status = _GetEPTxStatus(Related_Endpoint); + } + else + { + Status = _GetEPRxStatus(Related_Endpoint); + } + + if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0) + && (Status != 0)) + { + CopyRoutine = Standard_GetStatus; + } + } + + } + + /*GET CONFIGURATION*/ + else if (Request_No == GET_CONFIGURATION) + { + if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) + { + CopyRoutine = Standard_GetConfiguration; + } + } + /*GET INTERFACE*/ + else if (Request_No == GET_INTERFACE) + { + if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) + && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0) + && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001) + && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)) + { + CopyRoutine = Standard_GetInterface; + } + + } + + if (CopyRoutine) + { + pInformation->Ctrl_Info.Usb_wOffset = wOffset; + pInformation->Ctrl_Info.CopyData = CopyRoutine; + /* sb in the original the cast to word was directly */ + /* now the cast is made step by step */ + (*CopyRoutine)(0); + Result = USB_SUCCESS; + } + else + { + Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest); + if (Result == USB_NOT_READY) + { + pInformation->ControlState = PAUSE; + return; + } + } + + if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF) + { + /* Data is not ready, wait it */ + pInformation->ControlState = PAUSE; + return; + } + if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0)) + { + /* Unsupported request */ + pInformation->ControlState = STALLED; + return; + } + + + if (ValBit(pInformation->USBbmRequestType, 7)) + { + /* Device ==> Host */ + vu32 wLength = pInformation->USBwLength; + + /* Restrict the data length to be the one host asks */ + if (pInformation->Ctrl_Info.Usb_wLength > wLength) + { + pInformation->Ctrl_Info.Usb_wLength = wLength; + } + + else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength) + { + if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize) + { + Data_Mul_MaxPacketSize = FALSE; + } + else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0) + { + Data_Mul_MaxPacketSize = TRUE; + } + } + + pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize; + DataStageIn(); + } + else + { + pInformation->ControlState = OUT_DATA; + vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */ + } + + return; +} + +/******************************************************************************* +* Function Name : Setup0_Process +* Description : Get the device request data and dispatch to individual process. +* Input : None. +* Output : None. +* Return : Post0_Process. +*******************************************************************************/ +u8 Setup0_Process(void) +{ + + union + { + u8* b; + u16* w; + } pBuf; + + pBuf.b = PMAAddr + (u8 *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */ + + if (pInformation->ControlState != PAUSE) + { + pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */ + pInformation->USBbRequest = *pBuf.b++; /* bRequest */ + pBuf.w++; /* word not accessed because of 32 bits addressing */ + pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */ + pBuf.w++; /* word not accessed because of 32 bits addressing */ + pInformation->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */ + pBuf.w++; /* word not accessed because of 32 bits addressing */ + pInformation->USBwLength = *pBuf.w; /* wLength */ + } + + pInformation->ControlState = SETTING_UP; + if (pInformation->USBwLength == 0) + { + /* Setup with no data stage */ + NoData_Setup0(); + } + else + { + /* Setup with data stage */ + Data_Setup0(); + } + return Post0_Process(); +} + +/******************************************************************************* +* Function Name : In0_Process +* Description : Process the IN token on all default endpoint. +* Input : None. +* Output : None. +* Return : Post0_Process. +*******************************************************************************/ +u8 In0_Process(void) +{ + u32 ControlState = pInformation->ControlState; + + if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) + { + DataStageIn(); + /* ControlState may be changed outside the function */ + ControlState = pInformation->ControlState; + } + + else if (ControlState == WAIT_STATUS_IN) + { + if ((pInformation->USBbRequest == SET_ADDRESS) && + (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))) + { + SetDeviceAddress(pInformation->USBwValue0); + pUser_Standard_Requests->User_SetDeviceAddress(); + } + (*pProperty->Process_Status_IN)(); + ControlState = STALLED; + } + + else + { + ControlState = STALLED; + } + + pInformation->ControlState = ControlState; + + return Post0_Process(); +} + +/******************************************************************************* +* Function Name : Out0_Process +* Description : Process the OUT token on all default endpoint. +* Input : None. +* Output : None. +* Return : Post0_Process. +*******************************************************************************/ +u8 Out0_Process(void) +{ + u32 ControlState = pInformation->ControlState; + + if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA)) + { + DataStageOut(); + ControlState = pInformation->ControlState; /* may be changed outside the function */ + } + + else if (ControlState == WAIT_STATUS_OUT) + { + (*pProperty->Process_Status_OUT)(); + ControlState = STALLED; + } + + else if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) + { + /* host aborts the transfer before finish */ + ControlState = STALLED; + } + + /* Unexpect state, STALL the endpoint */ + else + { + ControlState = STALLED; + } + + pInformation->ControlState = ControlState; + + return Post0_Process(); +} + +/******************************************************************************* +* Function Name : Post0_Process +* Description : Stall the Endpoint 0 in case of error. +* Input : None. +* Output : None. +* Return : - 0 if the control State is in PAUSE +* - 1 if not. +*******************************************************************************/ +u8 Post0_Process(void) +{ + SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); + + if (pInformation->ControlState == STALLED) + { + vSetEPRxStatus(EP_RX_STALL); + vSetEPTxStatus(EP_TX_STALL); + } + + return (pInformation->ControlState == PAUSE); +} + +/******************************************************************************* +* Function Name : SetDeviceAddress. +* Description : Set the device and all the used Endpoints addresses. +* Input : - Val: device adress. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetDeviceAddress(u8 Val) +{ + u32 i; + u32 nEP = Device_Table.Total_Endpoint; + + /* set address in every used endpoint */ + for (i = 0; i < nEP; i++) + { + _SetEPAddress((u8)i, (u8)i); + } /* for */ + _SetDADDR(Val | DADDR_EF); /* set device address and enable function */ +} + +/******************************************************************************* +* Function Name : NOP_Process +* Description : No operation function. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void NOP_Process(void) +{ +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_core.h b/Libmaple/maple-bootloader/usb_lib/usb_core.h index 35c9a753..bd37b4f4 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_core.h +++ b/Libmaple/maple-bootloader/usb_lib/usb_core.h @@ -1,244 +1,244 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_core.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Standard protocol processing functions prototypes -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CORE_H -#define __USB_CORE_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -typedef enum _CONTROL_STATE -{ - WAIT_SETUP, /* 0 */ - SETTING_UP, /* 1 */ - IN_DATA, /* 2 */ - OUT_DATA, /* 3 */ - LAST_IN_DATA, /* 4 */ - LAST_OUT_DATA, /* 5 */ - WAIT_STATUS_IN, /* 7 */ - WAIT_STATUS_OUT, /* 8 */ - STALLED, /* 9 */ - PAUSE /* 10 */ -} CONTROL_STATE; /* The state machine states of a control pipe */ - -typedef struct OneDescriptor -{ - u8 *Descriptor; - u16 Descriptor_Size; -} -ONE_DESCRIPTOR, *PONE_DESCRIPTOR; -/* All the request process routines return a value of this type - If the return value is not SUCCESS or NOT_READY, - the software will STALL the correspond endpoint */ -typedef enum _RESULT -{ - USB_SUCCESS = 0, /* Process sucessfully */ - USB_ERROR, - USB_UNSUPPORT, - USB_NOT_READY /* The process has not been finished, endpoint will be - NAK to further rquest */ -} RESULT; - - -/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/ -typedef struct _ENDPOINT_INFO -{ - /* When send data out of the device, - CopyData() is used to get data buffer 'Length' bytes data - if Length is 0, - CopyData() returns the total length of the data - if the request is not supported, returns 0 - (NEW Feature ) - if CopyData() returns -1, the calling routine should not proceed - further and will resume the SETUP process by the class device - if Length is not 0, - CopyData() returns a pointer to indicate the data location - Usb_wLength is the data remain to be sent, - Usb_wOffset is the Offset of original data - When receive data from the host, - CopyData() is used to get user data buffer which is capable - of Length bytes data to copy data from the endpoint buffer. - if Length is 0, - CopyData() returns the available data length, - if Length is not 0, - CopyData() returns user buffer address - Usb_rLength is the data remain to be received, - Usb_rPointer is the Offset of data buffer - */ - u16 Usb_wLength; - u16 Usb_wOffset; - u16 PacketSize; - vu8 *(*CopyData)(u16 Length); -}ENDPOINT_INFO; - -/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/ - -typedef struct _DEVICE -{ - u8 Total_Endpoint; /* Number of endpoints that are used */ - u8 Total_Configuration;/* Number of configuration available */ -} -DEVICE; - -typedef union -{ - u16 w; - struct BW - { - u8 bb1; - u8 bb0; - } - bw; -} u16_u8; - -typedef struct _DEVICE_INFO -{ - u8 USBbmRequestType; /* bmRequestType */ - u8 USBbRequest; /* bRequest */ - u16_u8 USBwValues; /* wValue */ - u16_u8 USBwIndexs; /* wIndex */ - u16_u8 USBwLengths; /* wLength */ - - u8 ControlState; /* of type CONTROL_STATE */ - u8 Current_Feature; - u8 Current_Configuration; /* Selected configuration */ - u8 Current_Interface; /* Selected interface of current configuration */ - u8 Current_AlternateSetting;/* Selected Alternate Setting of current - interface*/ - - ENDPOINT_INFO Ctrl_Info; -}DEVICE_INFO; - -typedef struct _DEVICE_PROP -{ - void (*Init)(void); /* Initialize the device */ - void (*Reset)(void); /* Reset routine of this device */ - - /* Device dependent process after the status stage */ - void (*Process_Status_IN)(void); - void (*Process_Status_OUT)(void); - - /* Procedure of process on setup stage of a class specified request with data stage */ - /* All class specified requests with data stage are processed in Class_Data_Setup - Class_Data_Setup() - responses to check all special requests and fills ENDPOINT_INFO - according to the request - If IN tokens are expected, then wLength & wOffset will be filled - with the total transferring bytes and the starting position - If OUT tokens are expected, then rLength & rOffset will be filled - with the total expected bytes and the starting position in the buffer - - If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT - - CAUTION: - Since GET_CONFIGURATION & GET_INTERFACE are highly related to - the individual classes, they will be checked and processed here. - */ - RESULT (*Class_Data_Setup)(u8 RequestNo); - - /* Procedure of process on setup stage of a class specified request without data stage */ - /* All class specified requests without data stage are processed in Class_NoData_Setup - Class_NoData_Setup - responses to check all special requests and perform the request - - CAUTION: - Since SET_CONFIGURATION & SET_INTERFACE are highly related to - the individual classes, they will be checked and processed here. - */ - RESULT (*Class_NoData_Setup)(u8 RequestNo); - - /*Class_Get_Interface_Setting - This function is used by the file usb_core.c to test if the selected Interface - and Alternate Setting (u8 Interface, u8 AlternateSetting) are supported by - the application. - This function is writing by user. It should return "SUCCESS" if the Interface - and Alternate Setting are supported by the application or "UNSUPPORT" if they - are not supported. */ - - RESULT (*Class_Get_Interface_Setting)(u8 Interface, u8 AlternateSetting); - - u8* (*GetDeviceDescriptor)(u16 Length); - u8* (*GetConfigDescriptor)(u16 Length); - u8* (*GetStringDescriptor)(u16 Length); - u8* (*GetFunctionalDescriptor)(u16 Length); - - u8* RxEP_buffer; - u8 MaxPacketSize; - -}DEVICE_PROP; - -typedef struct _USER_STANDARD_REQUESTS -{ - void (*User_GetConfiguration)(void); /* Get Configuration */ - void (*User_SetConfiguration)(void); /* Set Configuration */ - void (*User_GetInterface)(void); /* Get Interface */ - void (*User_SetInterface)(void); /* Set Interface */ - void (*User_GetStatus)(void); /* Get Status */ - void (*User_ClearFeature)(void); /* Clear Feature */ - void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */ - void (*User_SetDeviceFeature)(void); /* Set Device Feature */ - void (*User_SetDeviceAddress)(void); /* Set Device Address */ -} -USER_STANDARD_REQUESTS; - -/* Exported constants --------------------------------------------------------*/ -#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) - -#define Usb_rLength Usb_wLength -#define Usb_rOffset Usb_wOffset - -#define USBwValue USBwValues.w -#define USBwValue0 USBwValues.bw.bb0 -#define USBwValue1 USBwValues.bw.bb1 -#define USBwIndex USBwIndexs.w -#define USBwIndex0 USBwIndexs.bw.bb0 -#define USBwIndex1 USBwIndexs.bw.bb1 -#define USBwLength USBwLengths.w -#define USBwLength0 USBwLengths.bw.bb0 -#define USBwLength1 USBwLengths.bw.bb1 - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -u8 Setup0_Process(void); -u8 Post0_Process(void); -u8 Out0_Process(void); -u8 In0_Process(void); - -RESULT Standard_SetEndPointFeature(void); -RESULT Standard_SetDeviceFeature(void); - -u8 *Standard_GetConfiguration(u16 Length); -RESULT Standard_SetConfiguration(void); -u8 *Standard_GetInterface(u16 Length); -RESULT Standard_SetInterface(void); -u8 *Standard_GetDescriptorData(u16 Length, PONE_DESCRIPTOR pDesc); - -u8 *Standard_GetStatus(u16 Length); -RESULT Standard_ClearFeature(void); -void SetDeviceAddress(u8); -void NOP_Process(void); - -extern DEVICE_PROP Device_Property; -extern USER_STANDARD_REQUESTS User_Standard_Requests; -extern DEVICE Device_Table; -extern volatile DEVICE_INFO Device_Info; - -/* cells saving status during interrupt servicing */ -extern u16 SaveRState; -extern u16 SaveTState; - -#endif /* __USB_CORE_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_core.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Standard protocol processing functions prototypes +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CORE_H +#define __USB_CORE_H + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +typedef enum _CONTROL_STATE +{ + WAIT_SETUP, /* 0 */ + SETTING_UP, /* 1 */ + IN_DATA, /* 2 */ + OUT_DATA, /* 3 */ + LAST_IN_DATA, /* 4 */ + LAST_OUT_DATA, /* 5 */ + WAIT_STATUS_IN, /* 7 */ + WAIT_STATUS_OUT, /* 8 */ + STALLED, /* 9 */ + PAUSE /* 10 */ +} CONTROL_STATE; /* The state machine states of a control pipe */ + +typedef struct OneDescriptor +{ + u8 *Descriptor; + u16 Descriptor_Size; +} +ONE_DESCRIPTOR, *PONE_DESCRIPTOR; +/* All the request process routines return a value of this type + If the return value is not SUCCESS or NOT_READY, + the software will STALL the correspond endpoint */ +typedef enum _RESULT +{ + USB_SUCCESS = 0, /* Process sucessfully */ + USB_ERROR, + USB_UNSUPPORT, + USB_NOT_READY /* The process has not been finished, endpoint will be + NAK to further rquest */ +} RESULT; + + +/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _ENDPOINT_INFO +{ + /* When send data out of the device, + CopyData() is used to get data buffer 'Length' bytes data + if Length is 0, + CopyData() returns the total length of the data + if the request is not supported, returns 0 + (NEW Feature ) + if CopyData() returns -1, the calling routine should not proceed + further and will resume the SETUP process by the class device + if Length is not 0, + CopyData() returns a pointer to indicate the data location + Usb_wLength is the data remain to be sent, + Usb_wOffset is the Offset of original data + When receive data from the host, + CopyData() is used to get user data buffer which is capable + of Length bytes data to copy data from the endpoint buffer. + if Length is 0, + CopyData() returns the available data length, + if Length is not 0, + CopyData() returns user buffer address + Usb_rLength is the data remain to be received, + Usb_rPointer is the Offset of data buffer + */ + u16 Usb_wLength; + u16 Usb_wOffset; + u16 PacketSize; + vu8 *(*CopyData)(u16 Length); +}ENDPOINT_INFO; + +/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/ + +typedef struct _DEVICE +{ + u8 Total_Endpoint; /* Number of endpoints that are used */ + u8 Total_Configuration;/* Number of configuration available */ +} +DEVICE; + +typedef union +{ + u16 w; + struct BW + { + u8 bb1; + u8 bb0; + } + bw; +} u16_u8; + +typedef struct _DEVICE_INFO +{ + u8 USBbmRequestType; /* bmRequestType */ + u8 USBbRequest; /* bRequest */ + u16_u8 USBwValues; /* wValue */ + u16_u8 USBwIndexs; /* wIndex */ + u16_u8 USBwLengths; /* wLength */ + + u8 ControlState; /* of type CONTROL_STATE */ + u8 Current_Feature; + u8 Current_Configuration; /* Selected configuration */ + u8 Current_Interface; /* Selected interface of current configuration */ + u8 Current_AlternateSetting;/* Selected Alternate Setting of current + interface*/ + + ENDPOINT_INFO Ctrl_Info; +}DEVICE_INFO; + +typedef struct _DEVICE_PROP +{ + void (*Init)(void); /* Initialize the device */ + void (*Reset)(void); /* Reset routine of this device */ + + /* Device dependent process after the status stage */ + void (*Process_Status_IN)(void); + void (*Process_Status_OUT)(void); + + /* Procedure of process on setup stage of a class specified request with data stage */ + /* All class specified requests with data stage are processed in Class_Data_Setup + Class_Data_Setup() + responses to check all special requests and fills ENDPOINT_INFO + according to the request + If IN tokens are expected, then wLength & wOffset will be filled + with the total transferring bytes and the starting position + If OUT tokens are expected, then rLength & rOffset will be filled + with the total expected bytes and the starting position in the buffer + + If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT + + CAUTION: + Since GET_CONFIGURATION & GET_INTERFACE are highly related to + the individual classes, they will be checked and processed here. + */ + RESULT (*Class_Data_Setup)(u8 RequestNo); + + /* Procedure of process on setup stage of a class specified request without data stage */ + /* All class specified requests without data stage are processed in Class_NoData_Setup + Class_NoData_Setup + responses to check all special requests and perform the request + + CAUTION: + Since SET_CONFIGURATION & SET_INTERFACE are highly related to + the individual classes, they will be checked and processed here. + */ + RESULT (*Class_NoData_Setup)(u8 RequestNo); + + /*Class_Get_Interface_Setting + This function is used by the file usb_core.c to test if the selected Interface + and Alternate Setting (u8 Interface, u8 AlternateSetting) are supported by + the application. + This function is writing by user. It should return "SUCCESS" if the Interface + and Alternate Setting are supported by the application or "UNSUPPORT" if they + are not supported. */ + + RESULT (*Class_Get_Interface_Setting)(u8 Interface, u8 AlternateSetting); + + u8* (*GetDeviceDescriptor)(u16 Length); + u8* (*GetConfigDescriptor)(u16 Length); + u8* (*GetStringDescriptor)(u16 Length); + u8* (*GetFunctionalDescriptor)(u16 Length); + + u8* RxEP_buffer; + u8 MaxPacketSize; + +}DEVICE_PROP; + +typedef struct _USER_STANDARD_REQUESTS +{ + void (*User_GetConfiguration)(void); /* Get Configuration */ + void (*User_SetConfiguration)(void); /* Set Configuration */ + void (*User_GetInterface)(void); /* Get Interface */ + void (*User_SetInterface)(void); /* Set Interface */ + void (*User_GetStatus)(void); /* Get Status */ + void (*User_ClearFeature)(void); /* Clear Feature */ + void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */ + void (*User_SetDeviceFeature)(void); /* Set Device Feature */ + void (*User_SetDeviceAddress)(void); /* Set Device Address */ +} +USER_STANDARD_REQUESTS; + +/* Exported constants --------------------------------------------------------*/ +#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) + +#define Usb_rLength Usb_wLength +#define Usb_rOffset Usb_wOffset + +#define USBwValue USBwValues.w +#define USBwValue0 USBwValues.bw.bb0 +#define USBwValue1 USBwValues.bw.bb1 +#define USBwIndex USBwIndexs.w +#define USBwIndex0 USBwIndexs.bw.bb0 +#define USBwIndex1 USBwIndexs.bw.bb1 +#define USBwLength USBwLengths.w +#define USBwLength0 USBwLengths.bw.bb0 +#define USBwLength1 USBwLengths.bw.bb1 + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +u8 Setup0_Process(void); +u8 Post0_Process(void); +u8 Out0_Process(void); +u8 In0_Process(void); + +RESULT Standard_SetEndPointFeature(void); +RESULT Standard_SetDeviceFeature(void); + +u8 *Standard_GetConfiguration(u16 Length); +RESULT Standard_SetConfiguration(void); +u8 *Standard_GetInterface(u16 Length); +RESULT Standard_SetInterface(void); +u8 *Standard_GetDescriptorData(u16 Length, PONE_DESCRIPTOR pDesc); + +u8 *Standard_GetStatus(u16 Length); +RESULT Standard_ClearFeature(void); +void SetDeviceAddress(u8); +void NOP_Process(void); + +extern DEVICE_PROP Device_Property; +extern USER_STANDARD_REQUESTS User_Standard_Requests; +extern DEVICE Device_Table; +extern volatile DEVICE_INFO Device_Info; + +/* cells saving status during interrupt servicing */ +extern u16 SaveRState; +extern u16 SaveTState; + +#endif /* __USB_CORE_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_def.h b/Libmaple/maple-bootloader/usb_lib/usb_def.h index 4261d463..cfc551c9 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_def.h +++ b/Libmaple/maple-bootloader/usb_lib/usb_def.h @@ -1,80 +1,80 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_def.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Definitions related to USB Core -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_DEF_H -#define __USB_DEF_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -typedef enum _RECIPIENT_TYPE -{ - DEVICE_RECIPIENT, /* Recipient device */ - INTERFACE_RECIPIENT, /* Recipient interface */ - ENDPOINT_RECIPIENT, /* Recipient endpoint */ - OTHER_RECIPIENT -} RECIPIENT_TYPE; - - -typedef enum _STANDARD_REQUESTS -{ - GET_STATUS = 0, - CLEAR_FEATURE, - RESERVED1, - SET_FEATURE, - RESERVED2, - SET_ADDRESS, - GET_DESCRIPTOR, - SET_DESCRIPTOR, - GET_CONFIGURATION, - SET_CONFIGURATION, - GET_INTERFACE, - SET_INTERFACE, - TOTAL_sREQUEST, /* Total number of Standard request */ - SYNCH_FRAME = 12 -} STANDARD_REQUESTS; - -/* Definition of "USBwValue" */ -typedef enum _DESCRIPTOR_TYPE -{ - DEVICE_DESCRIPTOR = 1, - CONFIG_DESCRIPTOR, - STRING_DESCRIPTOR, - INTERFACE_DESCRIPTOR, - ENDPOINT_DESCRIPTOR -} DESCRIPTOR_TYPE; - -/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */ -typedef enum _FEATURE_SELECTOR -{ - ENDPOINT_STALL, - DEVICE_REMOTE_WAKEUP -} FEATURE_SELECTOR; - -/* Exported constants --------------------------------------------------------*/ -/* Definition of "USBbmRequestType" */ -#define REQUEST_TYPE 0x60 /* Mask to get request type */ -#define STANDARD_REQUEST 0x00 /* Standard request */ -#define CLASS_REQUEST 0x20 /* Class request */ -#define VENDOR_REQUEST 0x40 /* Vendor request */ - -#define RECIPIENT 0x1F /* Mask to get recipient */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#endif /* __USB_DEF_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_def.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Definitions related to USB Core +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_DEF_H +#define __USB_DEF_H + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +typedef enum _RECIPIENT_TYPE +{ + DEVICE_RECIPIENT, /* Recipient device */ + INTERFACE_RECIPIENT, /* Recipient interface */ + ENDPOINT_RECIPIENT, /* Recipient endpoint */ + OTHER_RECIPIENT +} RECIPIENT_TYPE; + + +typedef enum _STANDARD_REQUESTS +{ + GET_STATUS = 0, + CLEAR_FEATURE, + RESERVED1, + SET_FEATURE, + RESERVED2, + SET_ADDRESS, + GET_DESCRIPTOR, + SET_DESCRIPTOR, + GET_CONFIGURATION, + SET_CONFIGURATION, + GET_INTERFACE, + SET_INTERFACE, + TOTAL_sREQUEST, /* Total number of Standard request */ + SYNCH_FRAME = 12 +} STANDARD_REQUESTS; + +/* Definition of "USBwValue" */ +typedef enum _DESCRIPTOR_TYPE +{ + DEVICE_DESCRIPTOR = 1, + CONFIG_DESCRIPTOR, + STRING_DESCRIPTOR, + INTERFACE_DESCRIPTOR, + ENDPOINT_DESCRIPTOR +} DESCRIPTOR_TYPE; + +/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */ +typedef enum _FEATURE_SELECTOR +{ + ENDPOINT_STALL, + DEVICE_REMOTE_WAKEUP +} FEATURE_SELECTOR; + +/* Exported constants --------------------------------------------------------*/ +/* Definition of "USBbmRequestType" */ +#define REQUEST_TYPE 0x60 /* Mask to get request type */ +#define STANDARD_REQUEST 0x00 /* Standard request */ +#define CLASS_REQUEST 0x20 /* Class request */ +#define VENDOR_REQUEST 0x40 /* Vendor request */ + +#define RECIPIENT 0x1F /* Mask to get recipient */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* __USB_DEF_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_init.c b/Libmaple/maple-bootloader/usb_lib/usb_init.c index 832ebabc..3280b5fb 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_init.c +++ b/Libmaple/maple-bootloader/usb_lib/usb_init.c @@ -1,64 +1,64 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_init.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Initialization routines & global variables -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* The number of current endpoint, it will be used to specify an endpoint */ -volatile u8 EPindex; -/* The number of current device, it is an index to the Device_Table */ -/* u8 Device_no; */ -/* Points to the DEVICE_INFO structure of current device */ -/* The purpose of this register is to speed up the execution */ -volatile DEVICE_INFO *pInformation; -/* Points to the DEVICE_PROP structure of current device */ -/* The purpose of this register is to speed up the execution */ -volatile DEVICE_PROP *pProperty; -/* Temporary save the state of Rx & Tx status. */ -/* Whenever the Rx or Tx state is changed, its value is saved */ -/* in this variable first and will be set to the EPRB or EPRA */ -/* at the end of interrupt process */ -volatile u16 SaveState ; -volatile u16 wInterrupt_Mask; -volatile DEVICE_INFO Device_Info; -volatile USER_STANDARD_REQUESTS *pUser_Standard_Requests; - -/* Extern variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : USB_Init -* Description : USB system initialization -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void USB_Init(void) -{ - pInformation = &Device_Info; - pInformation->ControlState = 2; - pProperty = &Device_Property; - pUser_Standard_Requests = &User_Standard_Requests; - /* Initialize devices one by one */ - - pProperty->Init(); -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_init.c +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Initialization routines & global variables +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_lib.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* The number of current endpoint, it will be used to specify an endpoint */ +volatile u8 EPindex; +/* The number of current device, it is an index to the Device_Table */ +/* u8 Device_no; */ +/* Points to the DEVICE_INFO structure of current device */ +/* The purpose of this register is to speed up the execution */ +volatile DEVICE_INFO *pInformation; +/* Points to the DEVICE_PROP structure of current device */ +/* The purpose of this register is to speed up the execution */ +volatile DEVICE_PROP *pProperty; +/* Temporary save the state of Rx & Tx status. */ +/* Whenever the Rx or Tx state is changed, its value is saved */ +/* in this variable first and will be set to the EPRB or EPRA */ +/* at the end of interrupt process */ +volatile u16 SaveState ; +volatile u16 wInterrupt_Mask; +volatile DEVICE_INFO Device_Info; +volatile USER_STANDARD_REQUESTS *pUser_Standard_Requests; + +/* Extern variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : USB_Init +* Description : USB system initialization +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void USB_Init(void) +{ + pInformation = &Device_Info; + pInformation->ControlState = 2; + pProperty = &Device_Property; + pUser_Standard_Requests = &User_Standard_Requests; + /* Initialize devices one by one */ + + pProperty->Init(); +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_init.h b/Libmaple/maple-bootloader/usb_lib/usb_init.h index 3efd0c8a..b78c8fdf 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_init.h +++ b/Libmaple/maple-bootloader/usb_lib/usb_init.h @@ -1,49 +1,49 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_init.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Initialization routines & global variables -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_INIT_H -#define __USB_INIT_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -void USB_Init(void); - -/* External variables --------------------------------------------------------*/ -/* The number of current endpoint, it will be used to specify an endpoint */ -extern volatile u8 EPindex; -/* The number of current device, it is an index to the Device_Table */ -/*extern u8 Device_no; */ -/* Points to the DEVICE_INFO structure of current device */ -/* The purpose of this register is to speed up the execution */ -extern volatile DEVICE_INFO* pInformation; -/* Points to the DEVICE_PROP structure of current device */ -/* The purpose of this register is to speed up the execution */ -extern volatile DEVICE_PROP* pProperty; -/* Temporary save the state of Rx & Tx status. */ -/* Whenever the Rx or Tx state is changed, its value is saved */ -/* in this variable first and will be set to the EPRB or EPRA */ -/* at the end of interrupt process */ -extern volatile USER_STANDARD_REQUESTS *pUser_Standard_Requests; - -extern volatile u16 SaveState ; -extern volatile u16 wInterrupt_Mask; - -#endif /* __USB_INIT_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_init.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Initialization routines & global variables +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_INIT_H +#define __USB_INIT_H + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +void USB_Init(void); + +/* External variables --------------------------------------------------------*/ +/* The number of current endpoint, it will be used to specify an endpoint */ +extern volatile u8 EPindex; +/* The number of current device, it is an index to the Device_Table */ +/*extern u8 Device_no; */ +/* Points to the DEVICE_INFO structure of current device */ +/* The purpose of this register is to speed up the execution */ +extern volatile DEVICE_INFO* pInformation; +/* Points to the DEVICE_PROP structure of current device */ +/* The purpose of this register is to speed up the execution */ +extern volatile DEVICE_PROP* pProperty; +/* Temporary save the state of Rx & Tx status. */ +/* Whenever the Rx or Tx state is changed, its value is saved */ +/* in this variable first and will be set to the EPRB or EPRA */ +/* at the end of interrupt process */ +extern volatile USER_STANDARD_REQUESTS *pUser_Standard_Requests; + +extern volatile u16 SaveState ; +extern volatile u16 wInterrupt_Mask; + +#endif /* __USB_INIT_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_int.c b/Libmaple/maple-bootloader/usb_lib/usb_int.c index f1d82be7..61a989bf 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_int.c +++ b/Libmaple/maple-bootloader/usb_lib/usb_int.c @@ -1,192 +1,192 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_int.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Endpoint CTR (Low and High) interrupt's service routines -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -u16 SaveRState; -u16 SaveTState; - -/* Extern variables ----------------------------------------------------------*/ -extern void (*pEpInt_IN[7])(void); /* Handles IN interrupts */ -extern void (*pEpInt_OUT[7])(void); /* Handles OUT interrupts */ - -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : CTR_LP. -* Description : Low priority Endpoint Correct Transfer interrupt's service -* routine. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void CTR_LP(void) -{ - u32 wEPVal = 0; - /* stay in loop while pending ints */ - while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) - { - _SetISTR((u16)CLR_CTR); /* clear CTR flag */ - /* extract highest priority endpoint number */ - EPindex = (u8)(wIstr & ISTR_EP_ID); - if (EPindex == 0) - { - /* Decode and service control endpoint interrupt */ - /* calling related service routine */ - /* (Setup0_Process, In0_Process, Out0_Process) */ - - /* save RX & TX status */ - /* and set both to NAK */ - SaveRState = _GetEPRxStatus(ENDP0); - SaveTState = _GetEPTxStatus(ENDP0); - _SetEPRxStatus(ENDP0, EP_RX_NAK); - _SetEPTxStatus(ENDP0, EP_TX_NAK); - - - /* DIR bit = origin of the interrupt */ - - if ((wIstr & ISTR_DIR) == 0) - { - /* DIR = 0 */ - - /* DIR = 0 => IN int */ - /* DIR = 0 implies that (EP_CTR_TX = 1) always */ - - - _ClearEP_CTR_TX(ENDP0); - In0_Process(); - - /* before terminate set Tx & Rx status */ - _SetEPRxStatus(ENDP0, SaveRState); - _SetEPTxStatus(ENDP0, SaveTState); - return; - } - else - { - /* DIR = 1 */ - - /* DIR = 1 & CTR_RX => SETUP or OUT int */ - /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ - - wEPVal = _GetENDPOINT(ENDP0); - if ((wEPVal & EP_CTR_TX) != 0) - { - _ClearEP_CTR_TX(ENDP0); - In0_Process(); - /* before terminate set Tx & Rx status */ - _SetEPRxStatus(ENDP0, SaveRState); - _SetEPTxStatus(ENDP0, SaveTState); - return; - } - else if ((wEPVal &EP_SETUP) != 0) - { - _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */ - Setup0_Process(); - /* before terminate set Tx & Rx status */ - _SetEPRxStatus(ENDP0, SaveRState); - _SetEPTxStatus(ENDP0, SaveTState); - return; - } - - else if ((wEPVal & EP_CTR_RX) != 0) - { - _ClearEP_CTR_RX(ENDP0); - Out0_Process(); - /* before terminate set Tx & Rx status */ - _SetEPRxStatus(ENDP0, SaveRState); - _SetEPTxStatus(ENDP0, SaveTState); - return; - } - } - }/* if(EPindex == 0) */ - else - { - /* Decode and service non control endpoints interrupt */ - - /* process related endpoint register */ - wEPVal = _GetENDPOINT(EPindex); - if ((wEPVal & EP_CTR_RX) != 0) - { - /* clear int flag */ - _ClearEP_CTR_RX(EPindex); - - /* call OUT service function */ - (*pEpInt_OUT[EPindex-1])(); - - } /* if((wEPVal & EP_CTR_RX) */ - - if ((wEPVal & EP_CTR_TX) != 0) - { - /* clear int flag */ - _ClearEP_CTR_TX(EPindex); - - /* call IN service function */ - (*pEpInt_IN[EPindex-1])(); - } /* if((wEPVal & EP_CTR_TX) != 0) */ - - }/* if(EPindex == 0) else */ - - }/* while(...) */ -} - -/******************************************************************************* -* Function Name : CTR_HP. -* Description : High Priority Endpoint Correct Transfer interrupt's service -* routine. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -void CTR_HP(void) -{ - u32 wEPVal = 0; - - while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) - { - _SetISTR((u16)CLR_CTR); /* clear CTR flag */ - /* extract highest priority endpoint number */ - EPindex = (u8)(wIstr & ISTR_EP_ID); - /* process related endpoint register */ - wEPVal = _GetENDPOINT(EPindex); - if ((wEPVal & EP_CTR_RX) != 0) - { - /* clear int flag */ - _ClearEP_CTR_RX(EPindex); - - /* call OUT service function */ - (*pEpInt_OUT[EPindex-1])(); - - } /* if((wEPVal & EP_CTR_RX) */ - else if ((wEPVal & EP_CTR_TX) != 0) - { - /* clear int flag */ - _ClearEP_CTR_TX(EPindex); - - /* call IN service function */ - (*pEpInt_IN[EPindex-1])(); - - - } /* if((wEPVal & EP_CTR_TX) != 0) */ - - }/* while(...) */ -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_int.c +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Endpoint CTR (Low and High) interrupt's service routines +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_lib.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +u16 SaveRState; +u16 SaveTState; + +/* Extern variables ----------------------------------------------------------*/ +extern void (*pEpInt_IN[7])(void); /* Handles IN interrupts */ +extern void (*pEpInt_OUT[7])(void); /* Handles OUT interrupts */ + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : CTR_LP. +* Description : Low priority Endpoint Correct Transfer interrupt's service +* routine. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void CTR_LP(void) +{ + u32 wEPVal = 0; + /* stay in loop while pending ints */ + while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) + { + _SetISTR((u16)CLR_CTR); /* clear CTR flag */ + /* extract highest priority endpoint number */ + EPindex = (u8)(wIstr & ISTR_EP_ID); + if (EPindex == 0) + { + /* Decode and service control endpoint interrupt */ + /* calling related service routine */ + /* (Setup0_Process, In0_Process, Out0_Process) */ + + /* save RX & TX status */ + /* and set both to NAK */ + SaveRState = _GetEPRxStatus(ENDP0); + SaveTState = _GetEPTxStatus(ENDP0); + _SetEPRxStatus(ENDP0, EP_RX_NAK); + _SetEPTxStatus(ENDP0, EP_TX_NAK); + + + /* DIR bit = origin of the interrupt */ + + if ((wIstr & ISTR_DIR) == 0) + { + /* DIR = 0 */ + + /* DIR = 0 => IN int */ + /* DIR = 0 implies that (EP_CTR_TX = 1) always */ + + + _ClearEP_CTR_TX(ENDP0); + In0_Process(); + + /* before terminate set Tx & Rx status */ + _SetEPRxStatus(ENDP0, SaveRState); + _SetEPTxStatus(ENDP0, SaveTState); + return; + } + else + { + /* DIR = 1 */ + + /* DIR = 1 & CTR_RX => SETUP or OUT int */ + /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ + + wEPVal = _GetENDPOINT(ENDP0); + if ((wEPVal & EP_CTR_TX) != 0) + { + _ClearEP_CTR_TX(ENDP0); + In0_Process(); + /* before terminate set Tx & Rx status */ + _SetEPRxStatus(ENDP0, SaveRState); + _SetEPTxStatus(ENDP0, SaveTState); + return; + } + else if ((wEPVal &EP_SETUP) != 0) + { + _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */ + Setup0_Process(); + /* before terminate set Tx & Rx status */ + _SetEPRxStatus(ENDP0, SaveRState); + _SetEPTxStatus(ENDP0, SaveTState); + return; + } + + else if ((wEPVal & EP_CTR_RX) != 0) + { + _ClearEP_CTR_RX(ENDP0); + Out0_Process(); + /* before terminate set Tx & Rx status */ + _SetEPRxStatus(ENDP0, SaveRState); + _SetEPTxStatus(ENDP0, SaveTState); + return; + } + } + }/* if(EPindex == 0) */ + else + { + /* Decode and service non control endpoints interrupt */ + + /* process related endpoint register */ + wEPVal = _GetENDPOINT(EPindex); + if ((wEPVal & EP_CTR_RX) != 0) + { + /* clear int flag */ + _ClearEP_CTR_RX(EPindex); + + /* call OUT service function */ + (*pEpInt_OUT[EPindex-1])(); + + } /* if((wEPVal & EP_CTR_RX) */ + + if ((wEPVal & EP_CTR_TX) != 0) + { + /* clear int flag */ + _ClearEP_CTR_TX(EPindex); + + /* call IN service function */ + (*pEpInt_IN[EPindex-1])(); + } /* if((wEPVal & EP_CTR_TX) != 0) */ + + }/* if(EPindex == 0) else */ + + }/* while(...) */ +} + +/******************************************************************************* +* Function Name : CTR_HP. +* Description : High Priority Endpoint Correct Transfer interrupt's service +* routine. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +void CTR_HP(void) +{ + u32 wEPVal = 0; + + while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) + { + _SetISTR((u16)CLR_CTR); /* clear CTR flag */ + /* extract highest priority endpoint number */ + EPindex = (u8)(wIstr & ISTR_EP_ID); + /* process related endpoint register */ + wEPVal = _GetENDPOINT(EPindex); + if ((wEPVal & EP_CTR_RX) != 0) + { + /* clear int flag */ + _ClearEP_CTR_RX(EPindex); + + /* call OUT service function */ + (*pEpInt_OUT[EPindex-1])(); + + } /* if((wEPVal & EP_CTR_RX) */ + else if ((wEPVal & EP_CTR_TX) != 0) + { + /* clear int flag */ + _ClearEP_CTR_TX(EPindex); + + /* call IN service function */ + (*pEpInt_IN[EPindex-1])(); + + + } /* if((wEPVal & EP_CTR_TX) != 0) */ + + }/* while(...) */ +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_int.h b/Libmaple/maple-bootloader/usb_lib/usb_int.h index 1eb18a76..ddc8b332 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_int.h +++ b/Libmaple/maple-bootloader/usb_lib/usb_int.h @@ -1,33 +1,33 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_int.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Endpoint CTR (Low and High) interrupt's service routines -* prototypes -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_INT_H -#define __USB_INT_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -void CTR_LP(void); -void CTR_HP(void); - -/* External variables --------------------------------------------------------*/ - -#endif /* __USB_INT_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_int.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Endpoint CTR (Low and High) interrupt's service routines +* prototypes +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_INT_H +#define __USB_INT_H + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +void CTR_LP(void); +void CTR_HP(void); + +/* External variables --------------------------------------------------------*/ + +#endif /* __USB_INT_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_lib.h b/Libmaple/maple-bootloader/usb_lib/usb_lib.h index 5d14b5af..4437b8dd 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_lib.h +++ b/Libmaple/maple-bootloader/usb_lib/usb_lib.h @@ -1,37 +1,37 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_lib.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : USB library include files -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_LIB_H -#define __USB_LIB_H - -/* Includes ------------------------------------------------------------------*/ -#include "usb_type.h" -#include "usb_regs.h" -#include "usb_def.h" -#include "usb_core.h" -#include "usb_init.h" -#include "usb_mem.h" -#include "usb_int.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -/* External variables --------------------------------------------------------*/ - -#endif /* __USB_LIB_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_lib.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : USB library include files +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_LIB_H +#define __USB_LIB_H + +/* Includes ------------------------------------------------------------------*/ +#include "usb_type.h" +#include "usb_regs.h" +#include "usb_def.h" +#include "usb_core.h" +#include "usb_init.h" +#include "usb_mem.h" +#include "usb_int.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* External variables --------------------------------------------------------*/ + +#endif /* __USB_LIB_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_mem.c b/Libmaple/maple-bootloader/usb_lib/usb_mem.c index ee698c5b..b72778c6 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_mem.c +++ b/Libmaple/maple-bootloader/usb_lib/usb_mem.c @@ -1,73 +1,73 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_mem.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Utility functions for memory transfers to/from PMA -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Extern variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ -/******************************************************************************* -* Function Name : UserToPMABufferCopy -* Description : Copy a buffer from user memory area to packet memory area (PMA) -* Input : - pbUsrBuf: pointer to user memory area. -* - wPMABufAddr: address into PMA. -* - wNBytes: no. of bytes to be copied. -* Output : None. -* Return : None . -*******************************************************************************/ -void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) -{ - u32 n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */ - u32 i, temp1, temp2; - u16 *pdwVal; - pdwVal = (u16 *)(wPMABufAddr * 2 + PMAAddr); - for (i = n; i != 0; i--) - { - temp1 = (u16) * pbUsrBuf; - pbUsrBuf++; - temp2 = temp1 | (u16) * pbUsrBuf << 8; - *pdwVal++ = temp2; - pdwVal++; - pbUsrBuf++; - } -} -/******************************************************************************* -* Function Name : PMAToUserBufferCopy -* Description : Copy a buffer from user memory area to packet memory area (PMA) -* Input : - pbUsrBuf = pointer to user memory area. -* - wPMABufAddr = address into PMA. -* - wNBytes = no. of bytes to be copied. -* Output : None. -* Return : None. -*******************************************************************************/ -void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) -{ - u32 n = (wNBytes + 1) >> 1;/* /2*/ - u32 i; - u32 *pdwVal; - pdwVal = (u32 *)(wPMABufAddr * 2 + PMAAddr); - for (i = n; i != 0; i--) - { - *(u16*)pbUsrBuf++ = *pdwVal++; - pbUsrBuf++; - } -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_mem.c +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Utility functions for memory transfers to/from PMA +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_lib.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Extern variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/******************************************************************************* +* Function Name : UserToPMABufferCopy +* Description : Copy a buffer from user memory area to packet memory area (PMA) +* Input : - pbUsrBuf: pointer to user memory area. +* - wPMABufAddr: address into PMA. +* - wNBytes: no. of bytes to be copied. +* Output : None. +* Return : None . +*******************************************************************************/ +void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) +{ + u32 n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */ + u32 i, temp1, temp2; + u16 *pdwVal; + pdwVal = (u16 *)(wPMABufAddr * 2 + PMAAddr); + for (i = n; i != 0; i--) + { + temp1 = (u16) * pbUsrBuf; + pbUsrBuf++; + temp2 = temp1 | (u16) * pbUsrBuf << 8; + *pdwVal++ = temp2; + pdwVal++; + pbUsrBuf++; + } +} +/******************************************************************************* +* Function Name : PMAToUserBufferCopy +* Description : Copy a buffer from user memory area to packet memory area (PMA) +* Input : - pbUsrBuf = pointer to user memory area. +* - wPMABufAddr = address into PMA. +* - wNBytes = no. of bytes to be copied. +* Output : None. +* Return : None. +*******************************************************************************/ +void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) +{ + u32 n = (wNBytes + 1) >> 1;/* /2*/ + u32 i; + u32 *pdwVal; + pdwVal = (u32 *)(wPMABufAddr * 2 + PMAAddr); + for (i = n; i != 0; i--) + { + *(u16*)pbUsrBuf++ = *pdwVal++; + pbUsrBuf++; + } +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_mem.h b/Libmaple/maple-bootloader/usb_lib/usb_mem.h index d4cc4a61..f726b49e 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_mem.h +++ b/Libmaple/maple-bootloader/usb_lib/usb_mem.h @@ -1,32 +1,32 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_mem.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Utility prototypes functions for memory/PMA transfers -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_MEM_H -#define __USB_MEM_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); -void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); - -/* External variables --------------------------------------------------------*/ - -#endif /*__USB_MEM_H*/ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_mem.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Utility prototypes functions for memory/PMA transfers +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_MEM_H +#define __USB_MEM_H + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); +void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); + +/* External variables --------------------------------------------------------*/ + +#endif /*__USB_MEM_H*/ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_regs.c b/Libmaple/maple-bootloader/usb_lib/usb_regs.c index c28ef5a7..c7e0276f 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_regs.c +++ b/Libmaple/maple-bootloader/usb_lib/usb_regs.c @@ -1,748 +1,748 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_regs.c -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Interface functions to USB cell registers -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_lib.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Extern variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : SetCNTR. -* Description : Set the CNTR register value. -* Input : wRegValue: new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetCNTR(u16 wRegValue) -{ - _SetCNTR(wRegValue); -} - -/******************************************************************************* -* Function Name : GetCNTR. -* Description : returns the CNTR register value. -* Input : None. -* Output : None. -* Return : CNTR register Value. -*******************************************************************************/ -u16 GetCNTR(void) -{ - return(_GetCNTR()); -} - -/******************************************************************************* -* Function Name : SetISTR. -* Description : Set the ISTR register value. -* Input : wRegValue: new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetISTR(u16 wRegValue) -{ - _SetISTR(wRegValue); -} - -/******************************************************************************* -* Function Name : GetISTR -* Description : Returns the ISTR register value. -* Input : None. -* Output : None. -* Return : ISTR register Value -*******************************************************************************/ -u16 GetISTR(void) -{ - return(_GetISTR()); -} - -/******************************************************************************* -* Function Name : GetFNR -* Description : Returns the FNR register value. -* Input : None. -* Output : None. -* Return : FNR register Value -*******************************************************************************/ -u16 GetFNR(void) -{ - return(_GetFNR()); -} - -/******************************************************************************* -* Function Name : SetDADDR -* Description : Set the DADDR register value. -* Input : wRegValue: new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetDADDR(u16 wRegValue) -{ - _SetDADDR(wRegValue); -} - -/******************************************************************************* -* Function Name : GetDADDR -* Description : Returns the DADDR register value. -* Input : None. -* Output : None. -* Return : DADDR register Value -*******************************************************************************/ -u16 GetDADDR(void) -{ - return(_GetDADDR()); -} - -/******************************************************************************* -* Function Name : SetBTABLE -* Description : Set the BTABLE. -* Input : wRegValue: New register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetBTABLE(u16 wRegValue) -{ - _SetBTABLE(wRegValue); -} - -/******************************************************************************* -* Function Name : GetBTABLE. -* Description : Returns the BTABLE register value. -* Input : None. -* Output : None. -* Return : BTABLE address. -*******************************************************************************/ -u16 GetBTABLE(void) -{ - return(_GetBTABLE()); -} - -/******************************************************************************* -* Function Name : SetENDPOINT -* Description : Setthe Endpoint register value. -* Input : bEpNum: Endpoint Number. -* wRegValue. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetENDPOINT(u8 bEpNum, u16 wRegValue) -{ - _SetENDPOINT(bEpNum, wRegValue); -} - -/******************************************************************************* -* Function Name : GetENDPOINT -* Description : Return the Endpoint register value. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint register value. -*******************************************************************************/ -u16 GetENDPOINT(u8 bEpNum) -{ - return(_GetENDPOINT(bEpNum)); -} - -/******************************************************************************* -* Function Name : SetEPType -* Description : sets the type in the endpoint register. -* Input : bEpNum: Endpoint Number. -* wType: type definition. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPType(u8 bEpNum, u16 wType) -{ - _SetEPType(bEpNum, wType); -} - -/******************************************************************************* -* Function Name : GetEPType -* Description : Returns the endpoint type. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Type -*******************************************************************************/ -u16 GetEPType(u8 bEpNum) -{ - return(_GetEPType(bEpNum)); -} - -/******************************************************************************* -* Function Name : SetEPTxStatus -* Description : Set the status of Tx endpoint. -* Input : bEpNum: Endpoint Number. -* wState: new state. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxStatus(u8 bEpNum, u16 wState) -{ - _SetEPTxStatus(bEpNum, wState); -} - -/******************************************************************************* -* Function Name : SetEPRxStatus -* Description : Set the status of Rx endpoint. -* Input : bEpNum: Endpoint Number. -* wState: new state. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxStatus(u8 bEpNum, u16 wState) -{ - _SetEPRxStatus(bEpNum, wState); -} - -/******************************************************************************* -* Function Name : SetDouBleBuffEPStall -* Description : sets the status for Double Buffer Endpoint to STALL -* Input : bEpNum: Endpoint Number. -* bDir: Endpoint direction. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetDouBleBuffEPStall(u8 bEpNum, u8 bDir) -{ - u16 Endpoint_DTOG_Status; - Endpoint_DTOG_Status = GetENDPOINT(bEpNum); - if (bDir == EP_DBUF_OUT) - { /* OUT double buffered endpoint */ - _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1); - } - else if (bDir == EP_DBUF_IN) - { /* IN double buffered endpoint */ - _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1); - } -} - -/******************************************************************************* -* Function Name : GetEPTxStatus -* Description : Returns the endpoint Tx status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint TX Status -*******************************************************************************/ -u16 GetEPTxStatus(u8 bEpNum) -{ - return(_GetEPTxStatus(bEpNum)); -} - -/******************************************************************************* -* Function Name : GetEPRxStatus -* Description : Returns the endpoint Rx status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint RX Status -*******************************************************************************/ -u16 GetEPRxStatus(u8 bEpNum) -{ - return(_GetEPRxStatus(bEpNum)); -} - -/******************************************************************************* -* Function Name : SetEPTxValid -* Description : Valid the endpoint Tx Status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxValid(u8 bEpNum) -{ - _SetEPTxStatus(bEpNum, EP_TX_VALID); -} - -/******************************************************************************* -* Function Name : SetEPRxValid -* Description : Valid the endpoint Rx Status. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxValid(u8 bEpNum) -{ - _SetEPRxStatus(bEpNum, EP_RX_VALID); -} - -/******************************************************************************* -* Function Name : SetEP_KIND -* Description : Clear the EP_KIND bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEP_KIND(u8 bEpNum) -{ - _SetEP_KIND(bEpNum); -} - -/******************************************************************************* -* Function Name : ClearEP_KIND -* Description : set the EP_KIND bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEP_KIND(u8 bEpNum) -{ - _ClearEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : Clear_Status_Out -* Description : Clear the Status Out of the related Endpoint -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void Clear_Status_Out(u8 bEpNum) -{ - _ClearEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : Set_Status_Out -* Description : Set the Status Out of the related Endpoint -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void Set_Status_Out(u8 bEpNum) -{ - _SetEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : SetEPDoubleBuff -* Description : Enable the double buffer feature for the endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDoubleBuff(u8 bEpNum) -{ - _SetEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : ClearEPDoubleBuff -* Description : Disable the double buffer feature for the endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEPDoubleBuff(u8 bEpNum) -{ - _ClearEP_KIND(bEpNum); -} -/******************************************************************************* -* Function Name : GetTxStallStatus -* Description : Returns the Stall status of the Tx endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Tx Stall status. -*******************************************************************************/ -u16 GetTxStallStatus(u8 bEpNum) -{ - return(_GetTxStallStatus(bEpNum)); -} -/******************************************************************************* -* Function Name : GetRxStallStatus -* Description : Returns the Stall status of the Rx endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx Stall status. -*******************************************************************************/ -u16 GetRxStallStatus(u8 bEpNum) -{ - return(_GetRxStallStatus(bEpNum)); -} -/******************************************************************************* -* Function Name : ClearEP_CTR_RX -* Description : Clear the CTR_RX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEP_CTR_RX(u8 bEpNum) -{ - _ClearEP_CTR_RX(bEpNum); -} -/******************************************************************************* -* Function Name : ClearEP_CTR_TX -* Description : Clear the CTR_TX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearEP_CTR_TX(u8 bEpNum) -{ - _ClearEP_CTR_TX(bEpNum); -} -/******************************************************************************* -* Function Name : ToggleDTOG_RX -* Description : Toggle the DTOG_RX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ToggleDTOG_RX(u8 bEpNum) -{ - _ToggleDTOG_RX(bEpNum); -} -/******************************************************************************* -* Function Name : ToggleDTOG_TX -* Description : Toggle the DTOG_TX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ToggleDTOG_TX(u8 bEpNum) -{ - _ToggleDTOG_TX(bEpNum); -} -/******************************************************************************* -* Function Name : ClearDTOG_RX. -* Description : Clear the DTOG_RX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearDTOG_RX(u8 bEpNum) -{ - _ClearDTOG_RX(bEpNum); -} -/******************************************************************************* -* Function Name : ClearDTOG_TX. -* Description : Clear the DTOG_TX bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -void ClearDTOG_TX(u8 bEpNum) -{ - _ClearDTOG_TX(bEpNum); -} -/******************************************************************************* -* Function Name : SetEPAddress -* Description : Set the endpoint address. -* Input : bEpNum: Endpoint Number. -* bAddr: New endpoint address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPAddress(u8 bEpNum, u8 bAddr) -{ - _SetEPAddress(bEpNum, bAddr); -} -/******************************************************************************* -* Function Name : GetEPAddress -* Description : Get the endpoint address. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint address. -*******************************************************************************/ -u8 GetEPAddress(u8 bEpNum) -{ - return(_GetEPAddress(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPTxAddr -* Description : Set the endpoint Tx buffer address. -* Input : bEpNum: Endpoint Number. -* wAddr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxAddr(u8 bEpNum, u16 wAddr) -{ - _SetEPTxAddr(bEpNum, wAddr); -} -/******************************************************************************* -* Function Name : SetEPRxAddr -* Description : Set the endpoint Rx buffer address. -* Input : bEpNum: Endpoint Number. -* wAddr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxAddr(u8 bEpNum, u16 wAddr) -{ - _SetEPRxAddr(bEpNum, wAddr); -} -/******************************************************************************* -* Function Name : GetEPTxAddr -* Description : Returns the endpoint Tx buffer address. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx buffer address. -*******************************************************************************/ -u16 GetEPTxAddr(u8 bEpNum) -{ - return(_GetEPTxAddr(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPRxAddr. -* Description : Returns the endpoint Rx buffer address. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx buffer address. -*******************************************************************************/ -u16 GetEPRxAddr(u8 bEpNum) -{ - return(_GetEPRxAddr(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPTxCount. -* Description : Set the Tx count. -* Input : bEpNum: Endpoint Number. -* wCount: new count value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPTxCount(u8 bEpNum, u16 wCount) -{ - _SetEPTxCount(bEpNum, wCount); -} -/******************************************************************************* -* Function Name : SetEPCountRxReg. -* Description : Set the Count Rx Register value. -* Input : *pdwReg: point to the register. -* wCount: the new register value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPCountRxReg(u32 *pdwReg, u16 wCount) -{ - _SetEPCountRxReg(dwReg, wCount); -} -/******************************************************************************* -* Function Name : SetEPRxCount -* Description : Set the Rx count. -* Input : bEpNum: Endpoint Number. -* wCount: the new count value. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPRxCount(u8 bEpNum, u16 wCount) -{ - _SetEPRxCount(bEpNum, wCount); -} -/******************************************************************************* -* Function Name : GetEPTxCount -* Description : Get the Tx count. -* Input : bEpNum: Endpoint Number. -* Output : None -* Return : Tx count value. -*******************************************************************************/ -u16 GetEPTxCount(u8 bEpNum) -{ - return(_GetEPTxCount(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPRxCount -* Description : Get the Rx count. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Rx count value. -*******************************************************************************/ -u16 GetEPRxCount(u8 bEpNum) -{ - return(_GetEPRxCount(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPDblBuffAddr -* Description : Set the addresses of the buffer 0 and 1. -* Input : bEpNum: Endpoint Number. -* wBuf0Addr: new address of buffer 0. -* wBuf1Addr: new address of buffer 1. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuffAddr(u8 bEpNum, u16 wBuf0Addr, u16 wBuf1Addr) -{ - _SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr); -} -/******************************************************************************* -* Function Name : SetEPDblBuf0Addr -* Description : Set the Buffer 1 address. -* Input : bEpNum: Endpoint Number -* wBuf0Addr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf0Addr(u8 bEpNum, u16 wBuf0Addr) -{ - _SetEPDblBuf0Addr(bEpNum, wBuf0Addr); -} -/******************************************************************************* -* Function Name : SetEPDblBuf1Addr -* Description : Set the Buffer 1 address. -* Input : bEpNum: Endpoint Number -* wBuf1Addr: new address. -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf1Addr(u8 bEpNum, u16 wBuf1Addr) -{ - _SetEPDblBuf1Addr(bEpNum, wBuf1Addr); -} -/******************************************************************************* -* Function Name : GetEPDblBuf0Addr -* Description : Returns the address of the Buffer 0. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -u16 GetEPDblBuf0Addr(u8 bEpNum) -{ - return(_GetEPDblBuf0Addr(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPDblBuf1Addr -* Description : Returns the address of the Buffer 1. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Address of the Buffer 1. -*******************************************************************************/ -u16 GetEPDblBuf1Addr(u8 bEpNum) -{ - return(_GetEPDblBuf1Addr(bEpNum)); -} -/******************************************************************************* -* Function Name : SetEPDblBuffCount -* Description : Set the number of bytes for a double Buffer -* endpoint. -* Input : bEpNum,bDir, wCount -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuffCount(u8 bEpNum, u8 bDir, u16 wCount) -{ - _SetEPDblBuffCount(bEpNum, bDir, wCount); -} -/******************************************************************************* -* Function Name : SetEPDblBuf0Count -* Description : Set the number of bytes in the buffer 0 of a double Buffer -* endpoint. -* Input : bEpNum, bDir, wCount -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf0Count(u8 bEpNum, u8 bDir, u16 wCount) -{ - _SetEPDblBuf0Count(bEpNum, bDir, wCount); -} -/******************************************************************************* -* Function Name : SetEPDblBuf1Count -* Description : Set the number of bytes in the buffer 0 of a double Buffer -* endpoint. -* Input : bEpNum, bDir, wCount -* Output : None. -* Return : None. -*******************************************************************************/ -void SetEPDblBuf1Count(u8 bEpNum, u8 bDir, u16 wCount) -{ - _SetEPDblBuf1Count(bEpNum, bDir, wCount); -} -/******************************************************************************* -* Function Name : GetEPDblBuf0Count -* Description : Returns the number of byte received in the buffer 0 of a double -* Buffer endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Buffer 0 count -*******************************************************************************/ -u16 GetEPDblBuf0Count(u8 bEpNum) -{ - return(_GetEPDblBuf0Count(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPDblBuf1Count -* Description : Returns the number of data received in the buffer 1 of a double -* Buffer endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Buffer 1 count. -*******************************************************************************/ -u16 GetEPDblBuf1Count(u8 bEpNum) -{ - return(_GetEPDblBuf1Count(bEpNum)); -} -/******************************************************************************* -* Function Name : GetEPDblBufDir -* Description : gets direction of the double buffered endpoint -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : EP_DBUF_OUT, EP_DBUF_IN, -* EP_DBUF_ERR if the endpoint counter not yet programmed. -*******************************************************************************/ -EP_DBUF_DIR GetEPDblBufDir(u8 bEpNum) -{ - if ((u16)(*_pEPRxCount(bEpNum) & 0xFC00) != 0) - return(EP_DBUF_OUT); - else if (((u16)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0) - return(EP_DBUF_IN); - else - return(EP_DBUF_ERR); -} -/******************************************************************************* -* Function Name : FreeUserBuffer -* Description : free buffer used from the application realizing it to the line - toggles bit SW_BUF in the double buffered endpoint register -* Input : bEpNum, bDir -* Output : None. -* Return : None. -*******************************************************************************/ -void FreeUserBuffer(u8 bEpNum, u8 bDir) -{ - if (bDir == EP_DBUF_OUT) - { /* OUT double buffered endpoint */ - _ToggleDTOG_TX(bEpNum); - } - else if (bDir == EP_DBUF_IN) - { /* IN double buffered endpoint */ - _ToggleDTOG_RX(bEpNum); - } -} - -/******************************************************************************* -* Function Name : ToWord -* Description : merge two byte in a word. -* Input : bh: byte high, bl: bytes low. -* Output : None. -* Return : resulted word. -*******************************************************************************/ -u16 ToWord(u8 bh, u8 bl) -{ - u16 wRet; - wRet = (u16)bl | ((u16)bh << 8); - return(wRet); -} -/******************************************************************************* -* Function Name : ByteSwap -* Description : Swap two byte in a word. -* Input : wSwW: word to Swap. -* Output : None. -* Return : resulted word. -*******************************************************************************/ -u16 ByteSwap(u16 wSwW) -{ - u8 bTemp; - u16 wRet; - bTemp = (u8)(wSwW & 0xff); - wRet = (wSwW >> 8) | ((u16)bTemp << 8); - return(wRet); -} - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_regs.c +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Interface functions to USB cell registers +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "usb_lib.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Extern variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : SetCNTR. +* Description : Set the CNTR register value. +* Input : wRegValue: new register value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetCNTR(u16 wRegValue) +{ + _SetCNTR(wRegValue); +} + +/******************************************************************************* +* Function Name : GetCNTR. +* Description : returns the CNTR register value. +* Input : None. +* Output : None. +* Return : CNTR register Value. +*******************************************************************************/ +u16 GetCNTR(void) +{ + return(_GetCNTR()); +} + +/******************************************************************************* +* Function Name : SetISTR. +* Description : Set the ISTR register value. +* Input : wRegValue: new register value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetISTR(u16 wRegValue) +{ + _SetISTR(wRegValue); +} + +/******************************************************************************* +* Function Name : GetISTR +* Description : Returns the ISTR register value. +* Input : None. +* Output : None. +* Return : ISTR register Value +*******************************************************************************/ +u16 GetISTR(void) +{ + return(_GetISTR()); +} + +/******************************************************************************* +* Function Name : GetFNR +* Description : Returns the FNR register value. +* Input : None. +* Output : None. +* Return : FNR register Value +*******************************************************************************/ +u16 GetFNR(void) +{ + return(_GetFNR()); +} + +/******************************************************************************* +* Function Name : SetDADDR +* Description : Set the DADDR register value. +* Input : wRegValue: new register value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetDADDR(u16 wRegValue) +{ + _SetDADDR(wRegValue); +} + +/******************************************************************************* +* Function Name : GetDADDR +* Description : Returns the DADDR register value. +* Input : None. +* Output : None. +* Return : DADDR register Value +*******************************************************************************/ +u16 GetDADDR(void) +{ + return(_GetDADDR()); +} + +/******************************************************************************* +* Function Name : SetBTABLE +* Description : Set the BTABLE. +* Input : wRegValue: New register value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetBTABLE(u16 wRegValue) +{ + _SetBTABLE(wRegValue); +} + +/******************************************************************************* +* Function Name : GetBTABLE. +* Description : Returns the BTABLE register value. +* Input : None. +* Output : None. +* Return : BTABLE address. +*******************************************************************************/ +u16 GetBTABLE(void) +{ + return(_GetBTABLE()); +} + +/******************************************************************************* +* Function Name : SetENDPOINT +* Description : Setthe Endpoint register value. +* Input : bEpNum: Endpoint Number. +* wRegValue. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetENDPOINT(u8 bEpNum, u16 wRegValue) +{ + _SetENDPOINT(bEpNum, wRegValue); +} + +/******************************************************************************* +* Function Name : GetENDPOINT +* Description : Return the Endpoint register value. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint register value. +*******************************************************************************/ +u16 GetENDPOINT(u8 bEpNum) +{ + return(_GetENDPOINT(bEpNum)); +} + +/******************************************************************************* +* Function Name : SetEPType +* Description : sets the type in the endpoint register. +* Input : bEpNum: Endpoint Number. +* wType: type definition. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPType(u8 bEpNum, u16 wType) +{ + _SetEPType(bEpNum, wType); +} + +/******************************************************************************* +* Function Name : GetEPType +* Description : Returns the endpoint type. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint Type +*******************************************************************************/ +u16 GetEPType(u8 bEpNum) +{ + return(_GetEPType(bEpNum)); +} + +/******************************************************************************* +* Function Name : SetEPTxStatus +* Description : Set the status of Tx endpoint. +* Input : bEpNum: Endpoint Number. +* wState: new state. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPTxStatus(u8 bEpNum, u16 wState) +{ + _SetEPTxStatus(bEpNum, wState); +} + +/******************************************************************************* +* Function Name : SetEPRxStatus +* Description : Set the status of Rx endpoint. +* Input : bEpNum: Endpoint Number. +* wState: new state. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPRxStatus(u8 bEpNum, u16 wState) +{ + _SetEPRxStatus(bEpNum, wState); +} + +/******************************************************************************* +* Function Name : SetDouBleBuffEPStall +* Description : sets the status for Double Buffer Endpoint to STALL +* Input : bEpNum: Endpoint Number. +* bDir: Endpoint direction. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetDouBleBuffEPStall(u8 bEpNum, u8 bDir) +{ + u16 Endpoint_DTOG_Status; + Endpoint_DTOG_Status = GetENDPOINT(bEpNum); + if (bDir == EP_DBUF_OUT) + { /* OUT double buffered endpoint */ + _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1); + } + else if (bDir == EP_DBUF_IN) + { /* IN double buffered endpoint */ + _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1); + } +} + +/******************************************************************************* +* Function Name : GetEPTxStatus +* Description : Returns the endpoint Tx status. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint TX Status +*******************************************************************************/ +u16 GetEPTxStatus(u8 bEpNum) +{ + return(_GetEPTxStatus(bEpNum)); +} + +/******************************************************************************* +* Function Name : GetEPRxStatus +* Description : Returns the endpoint Rx status. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint RX Status +*******************************************************************************/ +u16 GetEPRxStatus(u8 bEpNum) +{ + return(_GetEPRxStatus(bEpNum)); +} + +/******************************************************************************* +* Function Name : SetEPTxValid +* Description : Valid the endpoint Tx Status. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPTxValid(u8 bEpNum) +{ + _SetEPTxStatus(bEpNum, EP_TX_VALID); +} + +/******************************************************************************* +* Function Name : SetEPRxValid +* Description : Valid the endpoint Rx Status. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPRxValid(u8 bEpNum) +{ + _SetEPRxStatus(bEpNum, EP_RX_VALID); +} + +/******************************************************************************* +* Function Name : SetEP_KIND +* Description : Clear the EP_KIND bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEP_KIND(u8 bEpNum) +{ + _SetEP_KIND(bEpNum); +} + +/******************************************************************************* +* Function Name : ClearEP_KIND +* Description : set the EP_KIND bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearEP_KIND(u8 bEpNum) +{ + _ClearEP_KIND(bEpNum); +} +/******************************************************************************* +* Function Name : Clear_Status_Out +* Description : Clear the Status Out of the related Endpoint +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void Clear_Status_Out(u8 bEpNum) +{ + _ClearEP_KIND(bEpNum); +} +/******************************************************************************* +* Function Name : Set_Status_Out +* Description : Set the Status Out of the related Endpoint +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void Set_Status_Out(u8 bEpNum) +{ + _SetEP_KIND(bEpNum); +} +/******************************************************************************* +* Function Name : SetEPDoubleBuff +* Description : Enable the double buffer feature for the endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDoubleBuff(u8 bEpNum) +{ + _SetEP_KIND(bEpNum); +} +/******************************************************************************* +* Function Name : ClearEPDoubleBuff +* Description : Disable the double buffer feature for the endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearEPDoubleBuff(u8 bEpNum) +{ + _ClearEP_KIND(bEpNum); +} +/******************************************************************************* +* Function Name : GetTxStallStatus +* Description : Returns the Stall status of the Tx endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Tx Stall status. +*******************************************************************************/ +u16 GetTxStallStatus(u8 bEpNum) +{ + return(_GetTxStallStatus(bEpNum)); +} +/******************************************************************************* +* Function Name : GetRxStallStatus +* Description : Returns the Stall status of the Rx endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Rx Stall status. +*******************************************************************************/ +u16 GetRxStallStatus(u8 bEpNum) +{ + return(_GetRxStallStatus(bEpNum)); +} +/******************************************************************************* +* Function Name : ClearEP_CTR_RX +* Description : Clear the CTR_RX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearEP_CTR_RX(u8 bEpNum) +{ + _ClearEP_CTR_RX(bEpNum); +} +/******************************************************************************* +* Function Name : ClearEP_CTR_TX +* Description : Clear the CTR_TX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearEP_CTR_TX(u8 bEpNum) +{ + _ClearEP_CTR_TX(bEpNum); +} +/******************************************************************************* +* Function Name : ToggleDTOG_RX +* Description : Toggle the DTOG_RX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ToggleDTOG_RX(u8 bEpNum) +{ + _ToggleDTOG_RX(bEpNum); +} +/******************************************************************************* +* Function Name : ToggleDTOG_TX +* Description : Toggle the DTOG_TX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ToggleDTOG_TX(u8 bEpNum) +{ + _ToggleDTOG_TX(bEpNum); +} +/******************************************************************************* +* Function Name : ClearDTOG_RX. +* Description : Clear the DTOG_RX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearDTOG_RX(u8 bEpNum) +{ + _ClearDTOG_RX(bEpNum); +} +/******************************************************************************* +* Function Name : ClearDTOG_TX. +* Description : Clear the DTOG_TX bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +void ClearDTOG_TX(u8 bEpNum) +{ + _ClearDTOG_TX(bEpNum); +} +/******************************************************************************* +* Function Name : SetEPAddress +* Description : Set the endpoint address. +* Input : bEpNum: Endpoint Number. +* bAddr: New endpoint address. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPAddress(u8 bEpNum, u8 bAddr) +{ + _SetEPAddress(bEpNum, bAddr); +} +/******************************************************************************* +* Function Name : GetEPAddress +* Description : Get the endpoint address. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint address. +*******************************************************************************/ +u8 GetEPAddress(u8 bEpNum) +{ + return(_GetEPAddress(bEpNum)); +} +/******************************************************************************* +* Function Name : SetEPTxAddr +* Description : Set the endpoint Tx buffer address. +* Input : bEpNum: Endpoint Number. +* wAddr: new address. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPTxAddr(u8 bEpNum, u16 wAddr) +{ + _SetEPTxAddr(bEpNum, wAddr); +} +/******************************************************************************* +* Function Name : SetEPRxAddr +* Description : Set the endpoint Rx buffer address. +* Input : bEpNum: Endpoint Number. +* wAddr: new address. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPRxAddr(u8 bEpNum, u16 wAddr) +{ + _SetEPRxAddr(bEpNum, wAddr); +} +/******************************************************************************* +* Function Name : GetEPTxAddr +* Description : Returns the endpoint Tx buffer address. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Rx buffer address. +*******************************************************************************/ +u16 GetEPTxAddr(u8 bEpNum) +{ + return(_GetEPTxAddr(bEpNum)); +} +/******************************************************************************* +* Function Name : GetEPRxAddr. +* Description : Returns the endpoint Rx buffer address. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Rx buffer address. +*******************************************************************************/ +u16 GetEPRxAddr(u8 bEpNum) +{ + return(_GetEPRxAddr(bEpNum)); +} +/******************************************************************************* +* Function Name : SetEPTxCount. +* Description : Set the Tx count. +* Input : bEpNum: Endpoint Number. +* wCount: new count value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPTxCount(u8 bEpNum, u16 wCount) +{ + _SetEPTxCount(bEpNum, wCount); +} +/******************************************************************************* +* Function Name : SetEPCountRxReg. +* Description : Set the Count Rx Register value. +* Input : *pdwReg: point to the register. +* wCount: the new register value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPCountRxReg(u32 *pdwReg, u16 wCount) +{ + _SetEPCountRxReg(dwReg, wCount); +} +/******************************************************************************* +* Function Name : SetEPRxCount +* Description : Set the Rx count. +* Input : bEpNum: Endpoint Number. +* wCount: the new count value. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPRxCount(u8 bEpNum, u16 wCount) +{ + _SetEPRxCount(bEpNum, wCount); +} +/******************************************************************************* +* Function Name : GetEPTxCount +* Description : Get the Tx count. +* Input : bEpNum: Endpoint Number. +* Output : None +* Return : Tx count value. +*******************************************************************************/ +u16 GetEPTxCount(u8 bEpNum) +{ + return(_GetEPTxCount(bEpNum)); +} +/******************************************************************************* +* Function Name : GetEPRxCount +* Description : Get the Rx count. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Rx count value. +*******************************************************************************/ +u16 GetEPRxCount(u8 bEpNum) +{ + return(_GetEPRxCount(bEpNum)); +} +/******************************************************************************* +* Function Name : SetEPDblBuffAddr +* Description : Set the addresses of the buffer 0 and 1. +* Input : bEpNum: Endpoint Number. +* wBuf0Addr: new address of buffer 0. +* wBuf1Addr: new address of buffer 1. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuffAddr(u8 bEpNum, u16 wBuf0Addr, u16 wBuf1Addr) +{ + _SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr); +} +/******************************************************************************* +* Function Name : SetEPDblBuf0Addr +* Description : Set the Buffer 1 address. +* Input : bEpNum: Endpoint Number +* wBuf0Addr: new address. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuf0Addr(u8 bEpNum, u16 wBuf0Addr) +{ + _SetEPDblBuf0Addr(bEpNum, wBuf0Addr); +} +/******************************************************************************* +* Function Name : SetEPDblBuf1Addr +* Description : Set the Buffer 1 address. +* Input : bEpNum: Endpoint Number +* wBuf1Addr: new address. +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuf1Addr(u8 bEpNum, u16 wBuf1Addr) +{ + _SetEPDblBuf1Addr(bEpNum, wBuf1Addr); +} +/******************************************************************************* +* Function Name : GetEPDblBuf0Addr +* Description : Returns the address of the Buffer 0. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +u16 GetEPDblBuf0Addr(u8 bEpNum) +{ + return(_GetEPDblBuf0Addr(bEpNum)); +} +/******************************************************************************* +* Function Name : GetEPDblBuf1Addr +* Description : Returns the address of the Buffer 1. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Address of the Buffer 1. +*******************************************************************************/ +u16 GetEPDblBuf1Addr(u8 bEpNum) +{ + return(_GetEPDblBuf1Addr(bEpNum)); +} +/******************************************************************************* +* Function Name : SetEPDblBuffCount +* Description : Set the number of bytes for a double Buffer +* endpoint. +* Input : bEpNum,bDir, wCount +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuffCount(u8 bEpNum, u8 bDir, u16 wCount) +{ + _SetEPDblBuffCount(bEpNum, bDir, wCount); +} +/******************************************************************************* +* Function Name : SetEPDblBuf0Count +* Description : Set the number of bytes in the buffer 0 of a double Buffer +* endpoint. +* Input : bEpNum, bDir, wCount +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuf0Count(u8 bEpNum, u8 bDir, u16 wCount) +{ + _SetEPDblBuf0Count(bEpNum, bDir, wCount); +} +/******************************************************************************* +* Function Name : SetEPDblBuf1Count +* Description : Set the number of bytes in the buffer 0 of a double Buffer +* endpoint. +* Input : bEpNum, bDir, wCount +* Output : None. +* Return : None. +*******************************************************************************/ +void SetEPDblBuf1Count(u8 bEpNum, u8 bDir, u16 wCount) +{ + _SetEPDblBuf1Count(bEpNum, bDir, wCount); +} +/******************************************************************************* +* Function Name : GetEPDblBuf0Count +* Description : Returns the number of byte received in the buffer 0 of a double +* Buffer endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint Buffer 0 count +*******************************************************************************/ +u16 GetEPDblBuf0Count(u8 bEpNum) +{ + return(_GetEPDblBuf0Count(bEpNum)); +} +/******************************************************************************* +* Function Name : GetEPDblBuf1Count +* Description : Returns the number of data received in the buffer 1 of a double +* Buffer endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint Buffer 1 count. +*******************************************************************************/ +u16 GetEPDblBuf1Count(u8 bEpNum) +{ + return(_GetEPDblBuf1Count(bEpNum)); +} +/******************************************************************************* +* Function Name : GetEPDblBufDir +* Description : gets direction of the double buffered endpoint +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : EP_DBUF_OUT, EP_DBUF_IN, +* EP_DBUF_ERR if the endpoint counter not yet programmed. +*******************************************************************************/ +EP_DBUF_DIR GetEPDblBufDir(u8 bEpNum) +{ + if ((u16)(*_pEPRxCount(bEpNum) & 0xFC00) != 0) + return(EP_DBUF_OUT); + else if (((u16)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0) + return(EP_DBUF_IN); + else + return(EP_DBUF_ERR); +} +/******************************************************************************* +* Function Name : FreeUserBuffer +* Description : free buffer used from the application realizing it to the line + toggles bit SW_BUF in the double buffered endpoint register +* Input : bEpNum, bDir +* Output : None. +* Return : None. +*******************************************************************************/ +void FreeUserBuffer(u8 bEpNum, u8 bDir) +{ + if (bDir == EP_DBUF_OUT) + { /* OUT double buffered endpoint */ + _ToggleDTOG_TX(bEpNum); + } + else if (bDir == EP_DBUF_IN) + { /* IN double buffered endpoint */ + _ToggleDTOG_RX(bEpNum); + } +} + +/******************************************************************************* +* Function Name : ToWord +* Description : merge two byte in a word. +* Input : bh: byte high, bl: bytes low. +* Output : None. +* Return : resulted word. +*******************************************************************************/ +u16 ToWord(u8 bh, u8 bl) +{ + u16 wRet; + wRet = (u16)bl | ((u16)bh << 8); + return(wRet); +} +/******************************************************************************* +* Function Name : ByteSwap +* Description : Swap two byte in a word. +* Input : wSwW: word to Swap. +* Output : None. +* Return : resulted word. +*******************************************************************************/ +u16 ByteSwap(u16 wSwW) +{ + u8 bTemp; + u16 wRet; + bTemp = (u8)(wSwW & 0xff); + wRet = (wSwW >> 8) | ((u16)bTemp << 8); + return(wRet); +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_regs.h b/Libmaple/maple-bootloader/usb_lib/usb_regs.h index 8f32e44d..e07a9a68 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_regs.h +++ b/Libmaple/maple-bootloader/usb_lib/usb_regs.h @@ -1,619 +1,619 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_regs.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Interface prototype functions to USB cell registers -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_REGS_H -#define __USB_REGS_H - -/* Includes ------------------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -typedef enum _EP_DBUF_DIR -{ - /* double buffered endpoint direction */ - EP_DBUF_ERR, - EP_DBUF_OUT, - EP_DBUF_IN -}EP_DBUF_DIR; - -/* endpoint buffer number */ -enum EP_BUF_NUM -{ - EP_NOBUF, - EP_BUF0, - EP_BUF1 -}; - -/* Exported constants --------------------------------------------------------*/ -#define RegBase (0x40005C00L) /* USB_IP Peripheral Registers base address */ -#define PMAAddr (0x40006000L) /* USB_IP Packet Memory Area base address */ - -/******************************************************************************/ -/* General registers */ -/******************************************************************************/ - -/* Control register */ -#define CNTR ((volatile unsigned *)(RegBase + 0x40)) -/* Interrupt status register */ -#define ISTR ((volatile unsigned *)(RegBase + 0x44)) -/* Frame number register */ -#define FNR ((volatile unsigned *)(RegBase + 0x48)) -/* Device address register */ -#define DADDR ((volatile unsigned *)(RegBase + 0x4C)) -/* Buffer Table address register */ -#define BTABLE ((volatile unsigned *)(RegBase + 0x50)) -/******************************************************************************/ -/* Endpoint registers */ -/******************************************************************************/ -#define EP0REG ((volatile unsigned *)(RegBase)) /* endpoint 0 register address */ - -/* endpoints enumeration */ -#define ENDP0 ((u8)0) -#define ENDP1 ((u8)1) -#define ENDP2 ((u8)2) -#define ENDP3 ((u8)3) -#define ENDP4 ((u8)4) -#define ENDP5 ((u8)5) -#define ENDP6 ((u8)6) -#define ENDP7 ((u8)7) -/******************************************************************************/ -/* ISTR interrupt events */ -/******************************************************************************/ -#define ISTR_CTR (0x8000) /* Correct TRansfer (clear-only bit) */ -#define ISTR_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */ -#define ISTR_ERR (0x2000) /* ERRor (clear-only bit) */ -#define ISTR_WKUP (0x1000) /* WaKe UP (clear-only bit) */ -#define ISTR_SUSP (0x0800) /* SUSPend (clear-only bit) */ -#define ISTR_RESET (0x0400) /* RESET (clear-only bit) */ -#define ISTR_SOF (0x0200) /* Start Of Frame (clear-only bit) */ -#define ISTR_ESOF (0x0100) /* Expected Start Of Frame (clear-only bit) */ - - -#define ISTR_DIR (0x0010) /* DIRection of transaction (read-only bit) */ -#define ISTR_EP_ID (0x000F) /* EndPoint IDentifier (read-only bit) */ - -#define CLR_CTR (~ISTR_CTR) /* clear Correct TRansfer bit */ -#define CLR_DOVR (~ISTR_DOVR) /* clear DMA OVeR/underrun bit*/ -#define CLR_ERR (~ISTR_ERR) /* clear ERRor bit */ -#define CLR_WKUP (~ISTR_WKUP) /* clear WaKe UP bit */ -#define CLR_SUSP (~ISTR_SUSP) /* clear SUSPend bit */ -#define CLR_RESET (~ISTR_RESET) /* clear RESET bit */ -#define CLR_SOF (~ISTR_SOF) /* clear Start Of Frame bit */ -#define CLR_ESOF (~ISTR_ESOF) /* clear Expected Start Of Frame bit */ - -/******************************************************************************/ -/* CNTR control register bits definitions */ -/******************************************************************************/ -#define CNTR_CTRM (0x8000) /* Correct TRansfer Mask */ -#define CNTR_DOVRM (0x4000) /* DMA OVeR/underrun Mask */ -#define CNTR_ERRM (0x2000) /* ERRor Mask */ -#define CNTR_WKUPM (0x1000) /* WaKe UP Mask */ -#define CNTR_SUSPM (0x0800) /* SUSPend Mask */ -#define CNTR_RESETM (0x0400) /* RESET Mask */ -#define CNTR_SOFM (0x0200) /* Start Of Frame Mask */ -#define CNTR_ESOFM (0x0100) /* Expected Start Of Frame Mask */ - - -#define CNTR_RESUME (0x0010) /* RESUME request */ -#define CNTR_FSUSP (0x0008) /* Force SUSPend */ -#define CNTR_LPMODE (0x0004) /* Low-power MODE */ -#define CNTR_PDWN (0x0002) /* Power DoWN */ -#define CNTR_FRES (0x0001) /* Force USB RESet */ - -/******************************************************************************/ -/* FNR Frame Number Register bit definitions */ -/******************************************************************************/ -#define FNR_RXDP (0x8000) /* status of D+ data line */ -#define FNR_RXDM (0x4000) /* status of D- data line */ -#define FNR_LCK (0x2000) /* LoCKed */ -#define FNR_LSOF (0x1800) /* Lost SOF */ -#define FNR_FN (0x07FF) /* Frame Number */ -/******************************************************************************/ -/* DADDR Device ADDRess bit definitions */ -/******************************************************************************/ -#define DADDR_EF (0x80) -#define DADDR_ADD (0x7F) -/******************************************************************************/ -/* Endpoint register */ -/******************************************************************************/ -/* bit positions */ -#define EP_CTR_RX (0x8000) /* EndPoint Correct TRansfer RX */ -#define EP_DTOG_RX (0x4000) /* EndPoint Data TOGGLE RX */ -#define EPRX_STAT (0x3000) /* EndPoint RX STATus bit field */ -#define EP_SETUP (0x0800) /* EndPoint SETUP */ -#define EP_T_FIELD (0x0600) /* EndPoint TYPE */ -#define EP_KIND (0x0100) /* EndPoint KIND */ -#define EP_CTR_TX (0x0080) /* EndPoint Correct TRansfer TX */ -#define EP_DTOG_TX (0x0040) /* EndPoint Data TOGGLE TX */ -#define EPTX_STAT (0x0030) /* EndPoint TX STATus bit field */ -#define EPADDR_FIELD (0x000F) /* EndPoint ADDRess FIELD */ - -/* EndPoint REGister MASK (no toggle fields) */ -#define EPREG_MASK (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD) - -/* EP_TYPE[1:0] EndPoint TYPE */ -#define EP_TYPE_MASK (0x0600) /* EndPoint TYPE Mask */ -#define EP_BULK (0x0000) /* EndPoint BULK */ -#define EP_CONTROL (0x0200) /* EndPoint CONTROL */ -#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */ -#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */ -#define EP_T_MASK (~EP_T_FIELD & EPREG_MASK) - - -/* EP_KIND EndPoint KIND */ -#define EPKIND_MASK (~EP_KIND & EPREG_MASK) - -/* STAT_TX[1:0] STATus for TX transfer */ -#define EP_TX_DIS (0x0000) /* EndPoint TX DISabled */ -#define EP_TX_STALL (0x0010) /* EndPoint TX STALLed */ -#define EP_TX_NAK (0x0020) /* EndPoint TX NAKed */ -#define EP_TX_VALID (0x0030) /* EndPoint TX VALID */ -#define EPTX_DTOG1 (0x0010) /* EndPoint TX Data TOGgle bit1 */ -#define EPTX_DTOG2 (0x0020) /* EndPoint TX Data TOGgle bit2 */ -#define EPTX_DTOGMASK (EPTX_STAT|EPREG_MASK) - -/* STAT_RX[1:0] STATus for RX transfer */ -#define EP_RX_DIS (0x0000) /* EndPoint RX DISabled */ -#define EP_RX_STALL (0x1000) /* EndPoint RX STALLed */ -#define EP_RX_NAK (0x2000) /* EndPoint RX NAKed */ -#define EP_RX_VALID (0x3000) /* EndPoint RX VALID */ -#define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */ -#define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */ -#define EPRX_DTOGMASK (EPRX_STAT|EPREG_MASK) -/* Exported macro ------------------------------------------------------------*/ -/* SetCNTR */ -#define _SetCNTR(wRegValue) (*CNTR = (u16)wRegValue) - -/* SetISTR */ -#define _SetISTR(wRegValue) (*ISTR = (u16)wRegValue) - -/* SetDADDR */ -#define _SetDADDR(wRegValue) (*DADDR = (u16)wRegValue) - -/* SetBTABLE */ -#define _SetBTABLE(wRegValue)(*BTABLE = (u16)(wRegValue & 0xFFF8)) - -/* GetCNTR */ -#define _GetCNTR() ((u16) *CNTR) - -/* GetISTR */ -#define _GetISTR() ((u16) *ISTR) - -/* GetFNR */ -#define _GetFNR() ((u16) *FNR) - -/* GetDADDR */ -#define _GetDADDR() ((u16) *DADDR) - -/* GetBTABLE */ -#define _GetBTABLE() ((u16) *BTABLE) - -/* SetENDPOINT */ -#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \ - (u16)wRegValue) - -/* GetENDPOINT */ -#define _GetENDPOINT(bEpNum) ((u16)(*(EP0REG + bEpNum))) - -/******************************************************************************* -* Macro Name : SetEPType -* Description : sets the type in the endpoint register(bits EP_TYPE[1:0]) -* Input : bEpNum: Endpoint Number. -* wType -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\ - ((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType))) - -/******************************************************************************* -* Macro Name : GetEPType -* Description : gets the type in the endpoint register(bits EP_TYPE[1:0]) -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : Endpoint Type -*******************************************************************************/ -#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD) - -/******************************************************************************* -* Macro Name : SetEPTxStatus -* Description : sets the status for tx transfer (bits STAT_TX[1:0]). -* Input : bEpNum: Endpoint Number. -* wState: new state -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxStatus(bEpNum,wState) {\ - register u16 _wRegVal; \ - _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\ - /* toggle first bit ? */ \ - if((EPTX_DTOG1 & wState)!= 0) \ - _wRegVal ^= EPTX_DTOG1; \ - /* toggle second bit ? */ \ - if((EPTX_DTOG2 & wState)!= 0) \ - _wRegVal ^= EPTX_DTOG2; \ - _SetENDPOINT(bEpNum, _wRegVal); \ - } /* _SetEPTxStatus */ - -/******************************************************************************* -* Macro Name : SetEPRxStatus -* Description : sets the status for rx transfer (bits STAT_TX[1:0]) -* Input : bEpNum: Endpoint Number. -* wState: new state. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPRxStatus(bEpNum,wState) {\ - register u16 _wRegVal; \ - \ - _wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\ - /* toggle first bit ? */ \ - if((EPRX_DTOG1 & wState)!= 0) \ - _wRegVal ^= EPRX_DTOG1; \ - /* toggle second bit ? */ \ - if((EPRX_DTOG2 & wState)!= 0) \ - _wRegVal ^= EPRX_DTOG2; \ - _SetENDPOINT(bEpNum, _wRegVal); \ - } /* _SetEPRxStatus */ -/******************************************************************************* -* Macro Name : GetEPTxStatus / GetEPRxStatus -* Description : gets the status for tx/rx transfer (bits STAT_TX[1:0] -* /STAT_RX[1:0]) -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : status . -*******************************************************************************/ -#define _GetEPTxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPTX_STAT) - -#define _GetEPRxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPRX_STAT) - -/******************************************************************************* -* Macro Name : SetEPTxValid / SetEPRxValid -* Description : sets directly the VALID tx/rx-status into the enpoint register -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxValid(bEpNum) (_SetEPTxStatus(bEpNum, EP_TX_VALID)) - -#define _SetEPRxValid(bEpNum) (_SetEPRxStatus(bEpNum, EP_RX_VALID)) - -/******************************************************************************* -* Macro Name : GetTxStallStatus / GetRxStallStatus. -* Description : checks stall condition in an endpoint. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : TRUE = endpoint in stall condition. -*******************************************************************************/ -#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \ - == EP_TX_STALL) -#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \ - == EP_RX_STALL) - -/******************************************************************************* -* Macro Name : SetEP_KIND / ClearEP_KIND. -* Description : set & clear EP_KIND bit. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \ - (_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK)) -#define _ClearEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \ - (_GetENDPOINT(bEpNum) & EPKIND_MASK))) - -/******************************************************************************* -* Macro Name : Set_Status_Out / Clear_Status_Out. -* Description : Sets/clears directly STATUS_OUT bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _Set_Status_Out(bEpNum) _SetEP_KIND(bEpNum) -#define _Clear_Status_Out(bEpNum) _ClearEP_KIND(bEpNum) - -/******************************************************************************* -* Macro Name : SetEPDoubleBuff / ClearEPDoubleBuff. -* Description : Sets/clears directly EP_KIND bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDoubleBuff(bEpNum) _SetEP_KIND(bEpNum) -#define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum) - -/******************************************************************************* -* Macro Name : ClearEP_CTR_RX / ClearEP_CTR_TX. -* Description : Clears bit CTR_RX / CTR_TX in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _ClearEP_CTR_RX(bEpNum) (_SetENDPOINT(bEpNum,\ - _GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK)) -#define _ClearEP_CTR_TX(bEpNum) (_SetENDPOINT(bEpNum,\ - _GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK)) - -/******************************************************************************* -* Macro Name : ToggleDTOG_RX / ToggleDTOG_TX . -* Description : Toggles DTOG_RX / DTOG_TX bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _ToggleDTOG_RX(bEpNum) (_SetENDPOINT(bEpNum, \ - EP_DTOG_RX | _GetENDPOINT(bEpNum) & EPREG_MASK)) -#define _ToggleDTOG_TX(bEpNum) (_SetENDPOINT(bEpNum, \ - EP_DTOG_TX | _GetENDPOINT(bEpNum) & EPREG_MASK)) - -/******************************************************************************* -* Macro Name : ClearDTOG_RX / ClearDTOG_TX. -* Description : Clears DTOG_RX / DTOG_TX bit in the endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _ClearDTOG_RX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\ - _ToggleDTOG_RX(bEpNum) -#define _ClearDTOG_TX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\ - _ToggleDTOG_TX(bEpNum) -/******************************************************************************* -* Macro Name : SetEPAddress. -* Description : Sets address in an endpoint register. -* Input : bEpNum: Endpoint Number. -* bAddr: Address. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\ - _GetENDPOINT(bEpNum) & EPREG_MASK | bAddr) - -/******************************************************************************* -* Macro Name : GetEPAddress. -* Description : Gets address in an endpoint register. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _GetEPAddress(bEpNum) ((u8)(_GetENDPOINT(bEpNum) & EPADDR_FIELD)) - -#define _pEPTxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8 )*2 + PMAAddr)) -#define _pEPTxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr)) -#define _pEPRxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr)) -#define _pEPRxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr)) - -/******************************************************************************* -* Macro Name : SetEPTxAddr / SetEPRxAddr. -* Description : sets address of the tx/rx buffer. -* Input : bEpNum: Endpoint Number. -* wAddr: address to be set (must be word aligned). -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1)) -#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1)) - -/******************************************************************************* -* Macro Name : GetEPTxAddr / GetEPRxAddr. -* Description : Gets address of the tx/rx buffer. -* Input : bEpNum: Endpoint Number. -* Output : None. -* Return : address of the buffer. -*******************************************************************************/ -#define _GetEPTxAddr(bEpNum) ((u16)*_pEPTxAddr(bEpNum)) -#define _GetEPRxAddr(bEpNum) ((u16)*_pEPRxAddr(bEpNum)) - -/******************************************************************************* -* Macro Name : SetEPCountRxReg. -* Description : Sets counter of rx buffer with no. of blocks. -* Input : pdwReg: pointer to counter. -* wCount: Counter. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _BlocksOf32(dwReg,wCount,wNBlocks) {\ - wNBlocks = wCount >> 5;\ - if((wCount & 0x1f) == 0)\ - wNBlocks--;\ - *pdwReg = (u32)((wNBlocks << 10) | 0x8000);\ - }/* _BlocksOf32 */ - -#define _BlocksOf2(dwReg,wCount,wNBlocks) {\ - wNBlocks = wCount >> 1;\ - if((wCount & 0x1) != 0)\ - wNBlocks++;\ - *pdwReg = (u32)(wNBlocks << 10);\ - }/* _BlocksOf2 */ - -#define _SetEPCountRxReg(dwReg,wCount) {\ - u16 wNBlocks;\ - if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\ - else {_BlocksOf2(dwReg,wCount,wNBlocks);}\ - }/* _SetEPCountRxReg */ - - - -#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\ - u32 *pdwReg = _pEPTxCount(bEpNum); \ - _SetEPCountRxReg(pdwReg, wCount);\ - } -/******************************************************************************* -* Macro Name : SetEPTxCount / SetEPRxCount. -* Description : sets counter for the tx/rx buffer. -* Input : bEpNum: endpoint number. -* wCount: Counter value. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount) -#define _SetEPRxCount(bEpNum,wCount) {\ - u32 *pdwReg = _pEPRxCount(bEpNum); \ - _SetEPCountRxReg(pdwReg, wCount);\ - } -/******************************************************************************* -* Macro Name : GetEPTxCount / GetEPRxCount. -* Description : gets counter of the tx buffer. -* Input : bEpNum: endpoint number. -* Output : None. -* Return : Counter value. -*******************************************************************************/ -#define _GetEPTxCount(bEpNum)((u16)(*_pEPTxCount(bEpNum)) & 0x3ff) -#define _GetEPRxCount(bEpNum)((u16)(*_pEPRxCount(bEpNum)) & 0x3ff) - -/******************************************************************************* -* Macro Name : SetEPDblBuf0Addr / SetEPDblBuf1Addr. -* Description : Sets buffer 0/1 address in a double buffer endpoint. -* Input : bEpNum: endpoint number. -* : wBuf0Addr: buffer 0 address. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);} -#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);} - -/******************************************************************************* -* Macro Name : SetEPDblBuffAddr. -* Description : Sets addresses in a double buffer endpoint. -* Input : bEpNum: endpoint number. -* : wBuf0Addr: buffer 0 address. -* : wBuf1Addr = buffer 1 address. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \ - _SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\ - _SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\ - } /* _SetEPDblBuffAddr */ - -/******************************************************************************* -* Macro Name : GetEPDblBuf0Addr / GetEPDblBuf1Addr. -* Description : Gets buffer 0/1 address of a double buffer endpoint. -* Input : bEpNum: endpoint number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum)) -#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum)) - -/******************************************************************************* -* Macro Name : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count. -* Description : Gets buffer 0/1 address of a double buffer endpoint. -* Input : bEpNum: endpoint number. -* : bDir: endpoint dir EP_DBUF_OUT = OUT -* EP_DBUF_IN = IN -* : wCount: Counter value -* Output : None. -* Return : None. -*******************************************************************************/ -#define _SetEPDblBuf0Count(bEpNum, bDir, wCount) { \ - if(bDir == EP_DBUF_OUT)\ - /* OUT endpoint */ \ - {_SetEPRxDblBuf0Count(bEpNum,wCount);} \ - else if(bDir == EP_DBUF_IN)\ - /* IN endpoint */ \ - *_pEPTxCount(bEpNum) = (u32)wCount; \ - } /* SetEPDblBuf0Count*/ - -#define _SetEPDblBuf1Count(bEpNum, bDir, wCount) { \ - if(bDir == EP_DBUF_OUT)\ - /* OUT endpoint */ \ - {_SetEPRxCount(bEpNum,wCount);}\ - else if(bDir == EP_DBUF_IN)\ - /* IN endpoint */\ - *_pEPRxCount(bEpNum) = (u32)wCount; \ - } /* SetEPDblBuf1Count */ - -#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\ - _SetEPDblBuf0Count(bEpNum, bDir, wCount); \ - _SetEPDblBuf1Count(bEpNum, bDir, wCount); \ - } /* _SetEPDblBuffCount */ - -/******************************************************************************* -* Macro Name : GetEPDblBuf0Count / GetEPDblBuf1Count. -* Description : Gets buffer 0/1 rx/tx counter for double buffering. -* Input : bEpNum: endpoint number. -* Output : None. -* Return : None. -*******************************************************************************/ -#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum)) -#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum)) - - -/* External variables --------------------------------------------------------*/ -extern volatile u16 wIstr; /* ISTR register last read value */ - -/* Exported functions ------------------------------------------------------- */ -void SetCNTR(u16 /*wRegValue*/); -void SetISTR(u16 /*wRegValue*/); -void SetDADDR(u16 /*wRegValue*/); -void SetBTABLE(u16 /*wRegValue*/); -u16 GetCNTR(void); -u16 GetISTR(void); -u16 GetFNR(void); -u16 GetDADDR(void); -u16 GetBTABLE(void); -void SetENDPOINT(u8 /*bEpNum*/, u16 /*wRegValue*/); -u16 GetENDPOINT(u8 /*bEpNum*/); -void SetEPType(u8 /*bEpNum*/, u16 /*wType*/); -u16 GetEPType(u8 /*bEpNum*/); -void SetEPTxStatus(u8 /*bEpNum*/, u16 /*wState*/); -void SetEPRxStatus(u8 /*bEpNum*/, u16 /*wState*/); -void SetDouBleBuffEPStall(u8 /*bEpNum*/, u8 bDir); -u16 GetEPTxStatus(u8 /*bEpNum*/); -u16 GetEPRxStatus(u8 /*bEpNum*/); -void SetEPTxValid(u8 /*bEpNum*/); -void SetEPRxValid(u8 /*bEpNum*/); -u16 GetTxStallStatus(u8 /*bEpNum*/); -u16 GetRxStallStatus(u8 /*bEpNum*/); -void SetEP_KIND(u8 /*bEpNum*/); -void ClearEP_KIND(u8 /*bEpNum*/); -void Set_Status_Out(u8 /*bEpNum*/); -void Clear_Status_Out(u8 /*bEpNum*/); -void SetEPDoubleBuff(u8 /*bEpNum*/); -void ClearEPDoubleBuff(u8 /*bEpNum*/); -void ClearEP_CTR_RX(u8 /*bEpNum*/); -void ClearEP_CTR_TX(u8 /*bEpNum*/); -void ToggleDTOG_RX(u8 /*bEpNum*/); -void ToggleDTOG_TX(u8 /*bEpNum*/); -void ClearDTOG_RX(u8 /*bEpNum*/); -void ClearDTOG_TX(u8 /*bEpNum*/); -void SetEPAddress(u8 /*bEpNum*/, u8 /*bAddr*/); -u8 GetEPAddress(u8 /*bEpNum*/); -void SetEPTxAddr(u8 /*bEpNum*/, u16 /*wAddr*/); -void SetEPRxAddr(u8 /*bEpNum*/, u16 /*wAddr*/); -u16 GetEPTxAddr(u8 /*bEpNum*/); -u16 GetEPRxAddr(u8 /*bEpNum*/); -void SetEPCountRxReg(u32 * /*pdwReg*/, u16 /*wCount*/); -void SetEPTxCount(u8 /*bEpNum*/, u16 /*wCount*/); -void SetEPRxCount(u8 /*bEpNum*/, u16 /*wCount*/); -u16 GetEPTxCount(u8 /*bEpNum*/); -u16 GetEPRxCount(u8 /*bEpNum*/); -void SetEPDblBuf0Addr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/); -void SetEPDblBuf1Addr(u8 /*bEpNum*/, u16 /*wBuf1Addr*/); -void SetEPDblBuffAddr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/, u16 /*wBuf1Addr*/); -u16 GetEPDblBuf0Addr(u8 /*bEpNum*/); -u16 GetEPDblBuf1Addr(u8 /*bEpNum*/); -void SetEPDblBuffCount(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); -void SetEPDblBuf0Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); -void SetEPDblBuf1Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); -u16 GetEPDblBuf0Count(u8 /*bEpNum*/); -u16 GetEPDblBuf1Count(u8 /*bEpNum*/); -EP_DBUF_DIR GetEPDblBufDir(u8 /*bEpNum*/); -void FreeUserBuffer(u8 bEpNum/*bEpNum*/, u8 bDir); -u16 ToWord(u8, u8); -u16 ByteSwap(u16); - -#endif /* __USB_REGS_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_regs.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Interface prototype functions to USB cell registers +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_REGS_H +#define __USB_REGS_H + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +typedef enum _EP_DBUF_DIR +{ + /* double buffered endpoint direction */ + EP_DBUF_ERR, + EP_DBUF_OUT, + EP_DBUF_IN +}EP_DBUF_DIR; + +/* endpoint buffer number */ +enum EP_BUF_NUM +{ + EP_NOBUF, + EP_BUF0, + EP_BUF1 +}; + +/* Exported constants --------------------------------------------------------*/ +#define RegBase (0x40005C00L) /* USB_IP Peripheral Registers base address */ +#define PMAAddr (0x40006000L) /* USB_IP Packet Memory Area base address */ + +/******************************************************************************/ +/* General registers */ +/******************************************************************************/ + +/* Control register */ +#define CNTR ((volatile unsigned *)(RegBase + 0x40)) +/* Interrupt status register */ +#define ISTR ((volatile unsigned *)(RegBase + 0x44)) +/* Frame number register */ +#define FNR ((volatile unsigned *)(RegBase + 0x48)) +/* Device address register */ +#define DADDR ((volatile unsigned *)(RegBase + 0x4C)) +/* Buffer Table address register */ +#define BTABLE ((volatile unsigned *)(RegBase + 0x50)) +/******************************************************************************/ +/* Endpoint registers */ +/******************************************************************************/ +#define EP0REG ((volatile unsigned *)(RegBase)) /* endpoint 0 register address */ + +/* endpoints enumeration */ +#define ENDP0 ((u8)0) +#define ENDP1 ((u8)1) +#define ENDP2 ((u8)2) +#define ENDP3 ((u8)3) +#define ENDP4 ((u8)4) +#define ENDP5 ((u8)5) +#define ENDP6 ((u8)6) +#define ENDP7 ((u8)7) +/******************************************************************************/ +/* ISTR interrupt events */ +/******************************************************************************/ +#define ISTR_CTR (0x8000) /* Correct TRansfer (clear-only bit) */ +#define ISTR_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */ +#define ISTR_ERR (0x2000) /* ERRor (clear-only bit) */ +#define ISTR_WKUP (0x1000) /* WaKe UP (clear-only bit) */ +#define ISTR_SUSP (0x0800) /* SUSPend (clear-only bit) */ +#define ISTR_RESET (0x0400) /* RESET (clear-only bit) */ +#define ISTR_SOF (0x0200) /* Start Of Frame (clear-only bit) */ +#define ISTR_ESOF (0x0100) /* Expected Start Of Frame (clear-only bit) */ + + +#define ISTR_DIR (0x0010) /* DIRection of transaction (read-only bit) */ +#define ISTR_EP_ID (0x000F) /* EndPoint IDentifier (read-only bit) */ + +#define CLR_CTR (~ISTR_CTR) /* clear Correct TRansfer bit */ +#define CLR_DOVR (~ISTR_DOVR) /* clear DMA OVeR/underrun bit*/ +#define CLR_ERR (~ISTR_ERR) /* clear ERRor bit */ +#define CLR_WKUP (~ISTR_WKUP) /* clear WaKe UP bit */ +#define CLR_SUSP (~ISTR_SUSP) /* clear SUSPend bit */ +#define CLR_RESET (~ISTR_RESET) /* clear RESET bit */ +#define CLR_SOF (~ISTR_SOF) /* clear Start Of Frame bit */ +#define CLR_ESOF (~ISTR_ESOF) /* clear Expected Start Of Frame bit */ + +/******************************************************************************/ +/* CNTR control register bits definitions */ +/******************************************************************************/ +#define CNTR_CTRM (0x8000) /* Correct TRansfer Mask */ +#define CNTR_DOVRM (0x4000) /* DMA OVeR/underrun Mask */ +#define CNTR_ERRM (0x2000) /* ERRor Mask */ +#define CNTR_WKUPM (0x1000) /* WaKe UP Mask */ +#define CNTR_SUSPM (0x0800) /* SUSPend Mask */ +#define CNTR_RESETM (0x0400) /* RESET Mask */ +#define CNTR_SOFM (0x0200) /* Start Of Frame Mask */ +#define CNTR_ESOFM (0x0100) /* Expected Start Of Frame Mask */ + + +#define CNTR_RESUME (0x0010) /* RESUME request */ +#define CNTR_FSUSP (0x0008) /* Force SUSPend */ +#define CNTR_LPMODE (0x0004) /* Low-power MODE */ +#define CNTR_PDWN (0x0002) /* Power DoWN */ +#define CNTR_FRES (0x0001) /* Force USB RESet */ + +/******************************************************************************/ +/* FNR Frame Number Register bit definitions */ +/******************************************************************************/ +#define FNR_RXDP (0x8000) /* status of D+ data line */ +#define FNR_RXDM (0x4000) /* status of D- data line */ +#define FNR_LCK (0x2000) /* LoCKed */ +#define FNR_LSOF (0x1800) /* Lost SOF */ +#define FNR_FN (0x07FF) /* Frame Number */ +/******************************************************************************/ +/* DADDR Device ADDRess bit definitions */ +/******************************************************************************/ +#define DADDR_EF (0x80) +#define DADDR_ADD (0x7F) +/******************************************************************************/ +/* Endpoint register */ +/******************************************************************************/ +/* bit positions */ +#define EP_CTR_RX (0x8000) /* EndPoint Correct TRansfer RX */ +#define EP_DTOG_RX (0x4000) /* EndPoint Data TOGGLE RX */ +#define EPRX_STAT (0x3000) /* EndPoint RX STATus bit field */ +#define EP_SETUP (0x0800) /* EndPoint SETUP */ +#define EP_T_FIELD (0x0600) /* EndPoint TYPE */ +#define EP_KIND (0x0100) /* EndPoint KIND */ +#define EP_CTR_TX (0x0080) /* EndPoint Correct TRansfer TX */ +#define EP_DTOG_TX (0x0040) /* EndPoint Data TOGGLE TX */ +#define EPTX_STAT (0x0030) /* EndPoint TX STATus bit field */ +#define EPADDR_FIELD (0x000F) /* EndPoint ADDRess FIELD */ + +/* EndPoint REGister MASK (no toggle fields) */ +#define EPREG_MASK (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD) + +/* EP_TYPE[1:0] EndPoint TYPE */ +#define EP_TYPE_MASK (0x0600) /* EndPoint TYPE Mask */ +#define EP_BULK (0x0000) /* EndPoint BULK */ +#define EP_CONTROL (0x0200) /* EndPoint CONTROL */ +#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */ +#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */ +#define EP_T_MASK (~EP_T_FIELD & EPREG_MASK) + + +/* EP_KIND EndPoint KIND */ +#define EPKIND_MASK (~EP_KIND & EPREG_MASK) + +/* STAT_TX[1:0] STATus for TX transfer */ +#define EP_TX_DIS (0x0000) /* EndPoint TX DISabled */ +#define EP_TX_STALL (0x0010) /* EndPoint TX STALLed */ +#define EP_TX_NAK (0x0020) /* EndPoint TX NAKed */ +#define EP_TX_VALID (0x0030) /* EndPoint TX VALID */ +#define EPTX_DTOG1 (0x0010) /* EndPoint TX Data TOGgle bit1 */ +#define EPTX_DTOG2 (0x0020) /* EndPoint TX Data TOGgle bit2 */ +#define EPTX_DTOGMASK (EPTX_STAT|EPREG_MASK) + +/* STAT_RX[1:0] STATus for RX transfer */ +#define EP_RX_DIS (0x0000) /* EndPoint RX DISabled */ +#define EP_RX_STALL (0x1000) /* EndPoint RX STALLed */ +#define EP_RX_NAK (0x2000) /* EndPoint RX NAKed */ +#define EP_RX_VALID (0x3000) /* EndPoint RX VALID */ +#define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */ +#define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */ +#define EPRX_DTOGMASK (EPRX_STAT|EPREG_MASK) +/* Exported macro ------------------------------------------------------------*/ +/* SetCNTR */ +#define _SetCNTR(wRegValue) (*CNTR = (u16)wRegValue) + +/* SetISTR */ +#define _SetISTR(wRegValue) (*ISTR = (u16)wRegValue) + +/* SetDADDR */ +#define _SetDADDR(wRegValue) (*DADDR = (u16)wRegValue) + +/* SetBTABLE */ +#define _SetBTABLE(wRegValue)(*BTABLE = (u16)(wRegValue & 0xFFF8)) + +/* GetCNTR */ +#define _GetCNTR() ((u16) *CNTR) + +/* GetISTR */ +#define _GetISTR() ((u16) *ISTR) + +/* GetFNR */ +#define _GetFNR() ((u16) *FNR) + +/* GetDADDR */ +#define _GetDADDR() ((u16) *DADDR) + +/* GetBTABLE */ +#define _GetBTABLE() ((u16) *BTABLE) + +/* SetENDPOINT */ +#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \ + (u16)wRegValue) + +/* GetENDPOINT */ +#define _GetENDPOINT(bEpNum) ((u16)(*(EP0REG + bEpNum))) + +/******************************************************************************* +* Macro Name : SetEPType +* Description : sets the type in the endpoint register(bits EP_TYPE[1:0]) +* Input : bEpNum: Endpoint Number. +* wType +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\ + ((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType))) + +/******************************************************************************* +* Macro Name : GetEPType +* Description : gets the type in the endpoint register(bits EP_TYPE[1:0]) +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : Endpoint Type +*******************************************************************************/ +#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD) + +/******************************************************************************* +* Macro Name : SetEPTxStatus +* Description : sets the status for tx transfer (bits STAT_TX[1:0]). +* Input : bEpNum: Endpoint Number. +* wState: new state +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPTxStatus(bEpNum,wState) {\ + register u16 _wRegVal; \ + _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\ + /* toggle first bit ? */ \ + if((EPTX_DTOG1 & wState)!= 0) \ + _wRegVal ^= EPTX_DTOG1; \ + /* toggle second bit ? */ \ + if((EPTX_DTOG2 & wState)!= 0) \ + _wRegVal ^= EPTX_DTOG2; \ + _SetENDPOINT(bEpNum, _wRegVal); \ + } /* _SetEPTxStatus */ + +/******************************************************************************* +* Macro Name : SetEPRxStatus +* Description : sets the status for rx transfer (bits STAT_TX[1:0]) +* Input : bEpNum: Endpoint Number. +* wState: new state. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPRxStatus(bEpNum,wState) {\ + register u16 _wRegVal; \ + \ + _wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\ + /* toggle first bit ? */ \ + if((EPRX_DTOG1 & wState)!= 0) \ + _wRegVal ^= EPRX_DTOG1; \ + /* toggle second bit ? */ \ + if((EPRX_DTOG2 & wState)!= 0) \ + _wRegVal ^= EPRX_DTOG2; \ + _SetENDPOINT(bEpNum, _wRegVal); \ + } /* _SetEPRxStatus */ +/******************************************************************************* +* Macro Name : GetEPTxStatus / GetEPRxStatus +* Description : gets the status for tx/rx transfer (bits STAT_TX[1:0] +* /STAT_RX[1:0]) +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : status . +*******************************************************************************/ +#define _GetEPTxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPTX_STAT) + +#define _GetEPRxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPRX_STAT) + +/******************************************************************************* +* Macro Name : SetEPTxValid / SetEPRxValid +* Description : sets directly the VALID tx/rx-status into the enpoint register +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPTxValid(bEpNum) (_SetEPTxStatus(bEpNum, EP_TX_VALID)) + +#define _SetEPRxValid(bEpNum) (_SetEPRxStatus(bEpNum, EP_RX_VALID)) + +/******************************************************************************* +* Macro Name : GetTxStallStatus / GetRxStallStatus. +* Description : checks stall condition in an endpoint. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : TRUE = endpoint in stall condition. +*******************************************************************************/ +#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \ + == EP_TX_STALL) +#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \ + == EP_RX_STALL) + +/******************************************************************************* +* Macro Name : SetEP_KIND / ClearEP_KIND. +* Description : set & clear EP_KIND bit. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \ + (_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK)) +#define _ClearEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \ + (_GetENDPOINT(bEpNum) & EPKIND_MASK))) + +/******************************************************************************* +* Macro Name : Set_Status_Out / Clear_Status_Out. +* Description : Sets/clears directly STATUS_OUT bit in the endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _Set_Status_Out(bEpNum) _SetEP_KIND(bEpNum) +#define _Clear_Status_Out(bEpNum) _ClearEP_KIND(bEpNum) + +/******************************************************************************* +* Macro Name : SetEPDoubleBuff / ClearEPDoubleBuff. +* Description : Sets/clears directly EP_KIND bit in the endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPDoubleBuff(bEpNum) _SetEP_KIND(bEpNum) +#define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum) + +/******************************************************************************* +* Macro Name : ClearEP_CTR_RX / ClearEP_CTR_TX. +* Description : Clears bit CTR_RX / CTR_TX in the endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _ClearEP_CTR_RX(bEpNum) (_SetENDPOINT(bEpNum,\ + _GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK)) +#define _ClearEP_CTR_TX(bEpNum) (_SetENDPOINT(bEpNum,\ + _GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK)) + +/******************************************************************************* +* Macro Name : ToggleDTOG_RX / ToggleDTOG_TX . +* Description : Toggles DTOG_RX / DTOG_TX bit in the endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _ToggleDTOG_RX(bEpNum) (_SetENDPOINT(bEpNum, \ + EP_DTOG_RX | _GetENDPOINT(bEpNum) & EPREG_MASK)) +#define _ToggleDTOG_TX(bEpNum) (_SetENDPOINT(bEpNum, \ + EP_DTOG_TX | _GetENDPOINT(bEpNum) & EPREG_MASK)) + +/******************************************************************************* +* Macro Name : ClearDTOG_RX / ClearDTOG_TX. +* Description : Clears DTOG_RX / DTOG_TX bit in the endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _ClearDTOG_RX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\ + _ToggleDTOG_RX(bEpNum) +#define _ClearDTOG_TX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\ + _ToggleDTOG_TX(bEpNum) +/******************************************************************************* +* Macro Name : SetEPAddress. +* Description : Sets address in an endpoint register. +* Input : bEpNum: Endpoint Number. +* bAddr: Address. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\ + _GetENDPOINT(bEpNum) & EPREG_MASK | bAddr) + +/******************************************************************************* +* Macro Name : GetEPAddress. +* Description : Gets address in an endpoint register. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _GetEPAddress(bEpNum) ((u8)(_GetENDPOINT(bEpNum) & EPADDR_FIELD)) + +#define _pEPTxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8 )*2 + PMAAddr)) +#define _pEPTxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr)) +#define _pEPRxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr)) +#define _pEPRxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr)) + +/******************************************************************************* +* Macro Name : SetEPTxAddr / SetEPRxAddr. +* Description : sets address of the tx/rx buffer. +* Input : bEpNum: Endpoint Number. +* wAddr: address to be set (must be word aligned). +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1)) +#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1)) + +/******************************************************************************* +* Macro Name : GetEPTxAddr / GetEPRxAddr. +* Description : Gets address of the tx/rx buffer. +* Input : bEpNum: Endpoint Number. +* Output : None. +* Return : address of the buffer. +*******************************************************************************/ +#define _GetEPTxAddr(bEpNum) ((u16)*_pEPTxAddr(bEpNum)) +#define _GetEPRxAddr(bEpNum) ((u16)*_pEPRxAddr(bEpNum)) + +/******************************************************************************* +* Macro Name : SetEPCountRxReg. +* Description : Sets counter of rx buffer with no. of blocks. +* Input : pdwReg: pointer to counter. +* wCount: Counter. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _BlocksOf32(dwReg,wCount,wNBlocks) {\ + wNBlocks = wCount >> 5;\ + if((wCount & 0x1f) == 0)\ + wNBlocks--;\ + *pdwReg = (u32)((wNBlocks << 10) | 0x8000);\ + }/* _BlocksOf32 */ + +#define _BlocksOf2(dwReg,wCount,wNBlocks) {\ + wNBlocks = wCount >> 1;\ + if((wCount & 0x1) != 0)\ + wNBlocks++;\ + *pdwReg = (u32)(wNBlocks << 10);\ + }/* _BlocksOf2 */ + +#define _SetEPCountRxReg(dwReg,wCount) {\ + u16 wNBlocks;\ + if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\ + else {_BlocksOf2(dwReg,wCount,wNBlocks);}\ + }/* _SetEPCountRxReg */ + + + +#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\ + u32 *pdwReg = _pEPTxCount(bEpNum); \ + _SetEPCountRxReg(pdwReg, wCount);\ + } +/******************************************************************************* +* Macro Name : SetEPTxCount / SetEPRxCount. +* Description : sets counter for the tx/rx buffer. +* Input : bEpNum: endpoint number. +* wCount: Counter value. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount) +#define _SetEPRxCount(bEpNum,wCount) {\ + u32 *pdwReg = _pEPRxCount(bEpNum); \ + _SetEPCountRxReg(pdwReg, wCount);\ + } +/******************************************************************************* +* Macro Name : GetEPTxCount / GetEPRxCount. +* Description : gets counter of the tx buffer. +* Input : bEpNum: endpoint number. +* Output : None. +* Return : Counter value. +*******************************************************************************/ +#define _GetEPTxCount(bEpNum)((u16)(*_pEPTxCount(bEpNum)) & 0x3ff) +#define _GetEPRxCount(bEpNum)((u16)(*_pEPRxCount(bEpNum)) & 0x3ff) + +/******************************************************************************* +* Macro Name : SetEPDblBuf0Addr / SetEPDblBuf1Addr. +* Description : Sets buffer 0/1 address in a double buffer endpoint. +* Input : bEpNum: endpoint number. +* : wBuf0Addr: buffer 0 address. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);} +#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);} + +/******************************************************************************* +* Macro Name : SetEPDblBuffAddr. +* Description : Sets addresses in a double buffer endpoint. +* Input : bEpNum: endpoint number. +* : wBuf0Addr: buffer 0 address. +* : wBuf1Addr = buffer 1 address. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \ + _SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\ + _SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\ + } /* _SetEPDblBuffAddr */ + +/******************************************************************************* +* Macro Name : GetEPDblBuf0Addr / GetEPDblBuf1Addr. +* Description : Gets buffer 0/1 address of a double buffer endpoint. +* Input : bEpNum: endpoint number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum)) +#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum)) + +/******************************************************************************* +* Macro Name : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count. +* Description : Gets buffer 0/1 address of a double buffer endpoint. +* Input : bEpNum: endpoint number. +* : bDir: endpoint dir EP_DBUF_OUT = OUT +* EP_DBUF_IN = IN +* : wCount: Counter value +* Output : None. +* Return : None. +*******************************************************************************/ +#define _SetEPDblBuf0Count(bEpNum, bDir, wCount) { \ + if(bDir == EP_DBUF_OUT)\ + /* OUT endpoint */ \ + {_SetEPRxDblBuf0Count(bEpNum,wCount);} \ + else if(bDir == EP_DBUF_IN)\ + /* IN endpoint */ \ + *_pEPTxCount(bEpNum) = (u32)wCount; \ + } /* SetEPDblBuf0Count*/ + +#define _SetEPDblBuf1Count(bEpNum, bDir, wCount) { \ + if(bDir == EP_DBUF_OUT)\ + /* OUT endpoint */ \ + {_SetEPRxCount(bEpNum,wCount);}\ + else if(bDir == EP_DBUF_IN)\ + /* IN endpoint */\ + *_pEPRxCount(bEpNum) = (u32)wCount; \ + } /* SetEPDblBuf1Count */ + +#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\ + _SetEPDblBuf0Count(bEpNum, bDir, wCount); \ + _SetEPDblBuf1Count(bEpNum, bDir, wCount); \ + } /* _SetEPDblBuffCount */ + +/******************************************************************************* +* Macro Name : GetEPDblBuf0Count / GetEPDblBuf1Count. +* Description : Gets buffer 0/1 rx/tx counter for double buffering. +* Input : bEpNum: endpoint number. +* Output : None. +* Return : None. +*******************************************************************************/ +#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum)) +#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum)) + + +/* External variables --------------------------------------------------------*/ +extern volatile u16 wIstr; /* ISTR register last read value */ + +/* Exported functions ------------------------------------------------------- */ +void SetCNTR(u16 /*wRegValue*/); +void SetISTR(u16 /*wRegValue*/); +void SetDADDR(u16 /*wRegValue*/); +void SetBTABLE(u16 /*wRegValue*/); +u16 GetCNTR(void); +u16 GetISTR(void); +u16 GetFNR(void); +u16 GetDADDR(void); +u16 GetBTABLE(void); +void SetENDPOINT(u8 /*bEpNum*/, u16 /*wRegValue*/); +u16 GetENDPOINT(u8 /*bEpNum*/); +void SetEPType(u8 /*bEpNum*/, u16 /*wType*/); +u16 GetEPType(u8 /*bEpNum*/); +void SetEPTxStatus(u8 /*bEpNum*/, u16 /*wState*/); +void SetEPRxStatus(u8 /*bEpNum*/, u16 /*wState*/); +void SetDouBleBuffEPStall(u8 /*bEpNum*/, u8 bDir); +u16 GetEPTxStatus(u8 /*bEpNum*/); +u16 GetEPRxStatus(u8 /*bEpNum*/); +void SetEPTxValid(u8 /*bEpNum*/); +void SetEPRxValid(u8 /*bEpNum*/); +u16 GetTxStallStatus(u8 /*bEpNum*/); +u16 GetRxStallStatus(u8 /*bEpNum*/); +void SetEP_KIND(u8 /*bEpNum*/); +void ClearEP_KIND(u8 /*bEpNum*/); +void Set_Status_Out(u8 /*bEpNum*/); +void Clear_Status_Out(u8 /*bEpNum*/); +void SetEPDoubleBuff(u8 /*bEpNum*/); +void ClearEPDoubleBuff(u8 /*bEpNum*/); +void ClearEP_CTR_RX(u8 /*bEpNum*/); +void ClearEP_CTR_TX(u8 /*bEpNum*/); +void ToggleDTOG_RX(u8 /*bEpNum*/); +void ToggleDTOG_TX(u8 /*bEpNum*/); +void ClearDTOG_RX(u8 /*bEpNum*/); +void ClearDTOG_TX(u8 /*bEpNum*/); +void SetEPAddress(u8 /*bEpNum*/, u8 /*bAddr*/); +u8 GetEPAddress(u8 /*bEpNum*/); +void SetEPTxAddr(u8 /*bEpNum*/, u16 /*wAddr*/); +void SetEPRxAddr(u8 /*bEpNum*/, u16 /*wAddr*/); +u16 GetEPTxAddr(u8 /*bEpNum*/); +u16 GetEPRxAddr(u8 /*bEpNum*/); +void SetEPCountRxReg(u32 * /*pdwReg*/, u16 /*wCount*/); +void SetEPTxCount(u8 /*bEpNum*/, u16 /*wCount*/); +void SetEPRxCount(u8 /*bEpNum*/, u16 /*wCount*/); +u16 GetEPTxCount(u8 /*bEpNum*/); +u16 GetEPRxCount(u8 /*bEpNum*/); +void SetEPDblBuf0Addr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/); +void SetEPDblBuf1Addr(u8 /*bEpNum*/, u16 /*wBuf1Addr*/); +void SetEPDblBuffAddr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/, u16 /*wBuf1Addr*/); +u16 GetEPDblBuf0Addr(u8 /*bEpNum*/); +u16 GetEPDblBuf1Addr(u8 /*bEpNum*/); +void SetEPDblBuffCount(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); +void SetEPDblBuf0Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); +void SetEPDblBuf1Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/); +u16 GetEPDblBuf0Count(u8 /*bEpNum*/); +u16 GetEPDblBuf1Count(u8 /*bEpNum*/); +EP_DBUF_DIR GetEPDblBufDir(u8 /*bEpNum*/); +void FreeUserBuffer(u8 bEpNum/*bEpNum*/, u8 bDir); +u16 ToWord(u8, u8); +u16 ByteSwap(u16); + +#endif /* __USB_REGS_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libmaple/maple-bootloader/usb_lib/usb_type.h b/Libmaple/maple-bootloader/usb_lib/usb_type.h index 9e428b93..a40be619 100644 --- a/Libmaple/maple-bootloader/usb_lib/usb_type.h +++ b/Libmaple/maple-bootloader/usb_lib/usb_type.h @@ -1,72 +1,72 @@ -/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** -* File Name : usb_type.h -* Author : MCD Application Team -* Version : V2.2.1 -* Date : 09/22/2008 -* Description : Type definitions used by the USB Library -******************************************************************************** -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. -* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, -* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE -* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING -* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -*******************************************************************************/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_TYPE_H -#define __USB_TYPE_H - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -#ifndef NULL -#define NULL ((void *)0) -#endif - -#ifndef __STM32F10x_TYPE_H - -typedef signed long s32; -typedef signed short s16; -typedef signed char s8; - -typedef volatile signed long vs32; -typedef volatile signed short vs16; -typedef volatile signed char vs8; - -typedef unsigned long u32; -typedef unsigned short u16; -typedef unsigned char u8; - -typedef unsigned long const uc32; /* Read Only */ -typedef unsigned short const uc16; /* Read Only */ -typedef unsigned char const uc8; /* Read Only */ - -typedef volatile unsigned long vu32; -typedef volatile unsigned short vu16; -typedef volatile unsigned char vu8; - -typedef volatile unsigned long const vuc32; /* Read Only */ -typedef volatile unsigned short const vuc16; /* Read Only */ -typedef volatile unsigned char const vuc8; /* Read Only */ - - -typedef enum -{ - FALSE = 0, TRUE = !FALSE -} -bool; - -typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus; - -typedef enum { DISABLE = 0, ENABLE = !DISABLE} FunctionalState; - -typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus; -#endif - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -/* External variables --------------------------------------------------------*/ - -#endif /* __USB_TYPE_H */ - -/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : usb_type.h +* Author : MCD Application Team +* Version : V2.2.1 +* Date : 09/22/2008 +* Description : Type definitions used by the USB Library +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_TYPE_H +#define __USB_TYPE_H + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __STM32F10x_TYPE_H + +typedef signed long s32; +typedef signed short s16; +typedef signed char s8; + +typedef volatile signed long vs32; +typedef volatile signed short vs16; +typedef volatile signed char vs8; + +typedef unsigned long u32; +typedef unsigned short u16; +typedef unsigned char u8; + +typedef unsigned long const uc32; /* Read Only */ +typedef unsigned short const uc16; /* Read Only */ +typedef unsigned char const uc8; /* Read Only */ + +typedef volatile unsigned long vu32; +typedef volatile unsigned short vu16; +typedef volatile unsigned char vu8; + +typedef volatile unsigned long const vuc32; /* Read Only */ +typedef volatile unsigned short const vuc16; /* Read Only */ +typedef volatile unsigned char const vuc8; /* Read Only */ + + +typedef enum +{ + FALSE = 0, TRUE = !FALSE +} +bool; + +typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus; + +typedef enum { DISABLE = 0, ENABLE = !DISABLE} FunctionalState; + +typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus; +#endif + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* External variables --------------------------------------------------------*/ + +#endif /* __USB_TYPE_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/Libraries/AQ_Accelerometer/Accelerometer_MPU6000.h b/Libraries/AQ_Accelerometer/Accelerometer_MPU6000.h index 1809f2d7..81baea32 100644 --- a/Libraries/AQ_Accelerometer/Accelerometer_MPU6000.h +++ b/Libraries/AQ_Accelerometer/Accelerometer_MPU6000.h @@ -1,77 +1,77 @@ -/* - AeroQuad v3.0 - May 2011 - www.AeroQuad.com - Copyright (c) 2011 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . -*/ - -#ifndef _AEROQUAD_ACCELEROMETER_MPU6000_COMMON_H_ -#define _AEROQUAD_ACCELEROMETER_MPU6000_COMMON_H_ - -#include -#include - -void initializeAccel() { - initializeMPU6000Sensors(); -} - - -void measureAccel() { - readMPU6000Accel(); - - meterPerSecSec[XAXIS] = MPU6000.data.accel.x * accelScaleFactor[XAXIS] + runTimeAccelBias[XAXIS]; - meterPerSecSec[YAXIS] = MPU6000.data.accel.y * accelScaleFactor[YAXIS] + runTimeAccelBias[YAXIS]; - meterPerSecSec[ZAXIS] = MPU6000.data.accel.z * accelScaleFactor[ZAXIS] + runTimeAccelBias[ZAXIS]; -} - -void measureAccelSum() { - readMPU6000Accel(); - accelSample[XAXIS] += MPU6000.data.accel.x; - accelSample[YAXIS] += MPU6000.data.accel.y; - accelSample[ZAXIS] += MPU6000.data.accel.z; - - accelSampleCount++; -} - -void evaluateMetersPerSec() { - for (byte axis = XAXIS; axis <= ZAXIS; axis++) { - meterPerSecSec[axis] = (accelSample[axis] / accelSampleCount) * accelScaleFactor[axis] + runTimeAccelBias[axis]; - accelSample[axis] = 0; - } - accelSampleCount = 0; -} - -void computeAccelBias() { - for (int samples = 0; samples < SAMPLECOUNT; samples++) { - readMPU6000Sensors(); - measureAccelSum(); - delayMicroseconds(2500); - } - - for (byte axis = 0; axis < 3; axis++) { - meterPerSecSec[axis] = (float(accelSample[axis])/SAMPLECOUNT) * accelScaleFactor[axis]; - accelSample[axis] = 0; - } - accelSampleCount = 0; - - runTimeAccelBias[XAXIS] = -meterPerSecSec[XAXIS]; - runTimeAccelBias[YAXIS] = -meterPerSecSec[YAXIS]; - runTimeAccelBias[ZAXIS] = -9.8065 - meterPerSecSec[ZAXIS]; - - accelOneG = abs(meterPerSecSec[ZAXIS] + runTimeAccelBias[ZAXIS]); -} - -#endif +/* + AeroQuad v3.0 - May 2011 + www.AeroQuad.com + Copyright (c) 2011 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . +*/ + +#ifndef _AEROQUAD_ACCELEROMETER_MPU6000_COMMON_H_ +#define _AEROQUAD_ACCELEROMETER_MPU6000_COMMON_H_ + +#include +#include + +void initializeAccel() { + initializeMPU6000Sensors(); +} + + +void measureAccel() { + readMPU6000Accel(); + + meterPerSecSec[XAXIS] = MPU6000.data.accel.x * accelScaleFactor[XAXIS] + runTimeAccelBias[XAXIS]; + meterPerSecSec[YAXIS] = MPU6000.data.accel.y * accelScaleFactor[YAXIS] + runTimeAccelBias[YAXIS]; + meterPerSecSec[ZAXIS] = MPU6000.data.accel.z * accelScaleFactor[ZAXIS] + runTimeAccelBias[ZAXIS]; +} + +void measureAccelSum() { + readMPU6000Accel(); + accelSample[XAXIS] += MPU6000.data.accel.x; + accelSample[YAXIS] += MPU6000.data.accel.y; + accelSample[ZAXIS] += MPU6000.data.accel.z; + + accelSampleCount++; +} + +void evaluateMetersPerSec() { + for (byte axis = XAXIS; axis <= ZAXIS; axis++) { + meterPerSecSec[axis] = (accelSample[axis] / accelSampleCount) * accelScaleFactor[axis] + runTimeAccelBias[axis]; + accelSample[axis] = 0; + } + accelSampleCount = 0; +} + +void computeAccelBias() { + for (int samples = 0; samples < SAMPLECOUNT; samples++) { + readMPU6000Sensors(); + measureAccelSum(); + delayMicroseconds(2500); + } + + for (byte axis = 0; axis < 3; axis++) { + meterPerSecSec[axis] = (float(accelSample[axis])/SAMPLECOUNT) * accelScaleFactor[axis]; + accelSample[axis] = 0; + } + accelSampleCount = 0; + + runTimeAccelBias[XAXIS] = -meterPerSecSec[XAXIS]; + runTimeAccelBias[YAXIS] = -meterPerSecSec[YAXIS]; + runTimeAccelBias[ZAXIS] = -9.8065 - meterPerSecSec[ZAXIS]; + + accelOneG = abs(meterPerSecSec[ZAXIS] + runTimeAccelBias[ZAXIS]); +} + +#endif diff --git a/Libraries/AQ_BarometricSensor/Examples/Test_BMP085/Test_BMP085.ino b/Libraries/AQ_BarometricSensor/Examples/Test_BMP085/Test_BMP085.ino index 393d0dce..b9ba69e8 100644 --- a/Libraries/AQ_BarometricSensor/Examples/Test_BMP085/Test_BMP085.ino +++ b/Libraries/AQ_BarometricSensor/Examples/Test_BMP085/Test_BMP085.ino @@ -49,4 +49,4 @@ void loop() { Serial.println(); } } - + diff --git a/Libraries/AQ_CameraStabilizer/CameraStabilizer_TXControl.h b/Libraries/AQ_CameraStabilizer/CameraStabilizer_TXControl.h index 8211064e..78ba4bc1 100644 --- a/Libraries/AQ_CameraStabilizer/CameraStabilizer_TXControl.h +++ b/Libraries/AQ_CameraStabilizer/CameraStabilizer_TXControl.h @@ -1,81 +1,81 @@ -/* - AeroQuad v3.0.1 - February 2012 - www.AeroQuad.com - Copyright (c) 2012 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . - */ - -#ifndef _AEROQUAD_CAMERA_STABILIZER_TXCONTROL_H_ -#define _AEROQUAD_CAMERA_STABILIZER_TXCONTROL_H_ - -#if defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined (AeroQuadSTM32) - -#include "CameraStabilizer.h" - -int servoCenterPitchDiff = 0; -int servoCenterPitchDesired = 0; -int servoTXChannels = 0; -int servoActualCenter = 0; - -void processCameraTXControl() -{ - if (servoTXChannels == 1) - { - if (receiverCommand[AUX3] == 1500) // channel is centered -> move back to center - { - servoCenterPitchDiff = (servoActualCenter - servoCenterPitch) / 25; - if ((servoCenterPitchDiff > 0) && (servoCenterPitchDiff < 1)) - { - servoCenterPitchDiff = 1; - } - servoCenterPitch += servoCenterPitchDiff; - } - else - { - servoCenterPitchDesired = map(receiverCommand[AUX3],1000,2000,servoMaxPitch,servoMinPitch); - if (servoCenterPitch != servoCenterPitchDesired) - { - servoCenterPitchDiff = (servoCenterPitchDesired - servoCenterPitch) / 25; - if ((servoCenterPitchDiff > 0) && (servoCenterPitchDiff < 1)) - { - servoCenterPitchDiff = 1; - } - servoCenterPitch += servoCenterPitchDiff; - } - } - } - else if (servoTXChannels == 2) - { - if (receiverCommand[AUX4] == 1500) // override back to center - { - servoCenterPitchDiff = (servoActualCenter - servoCenterPitch) / 25; - if ((servoCenterPitchDiff > 0) && (servoCenterPitchDiff < 1)) - { - servoCenterPitchDiff = 1; - } - servoCenterPitch += servoCenterPitchDiff; - } - else // move up or down at a nice rate - { - if (receiverCommand[AUX3] != 1500) // map to up or down movement - { - servoCenterPitch += (1500 - receiverCommand[AUX3]) / 50; - } - } - } -} -#endif -#endif +/* + AeroQuad v3.0.1 - February 2012 + www.AeroQuad.com + Copyright (c) 2012 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . + */ + +#ifndef _AEROQUAD_CAMERA_STABILIZER_TXCONTROL_H_ +#define _AEROQUAD_CAMERA_STABILIZER_TXCONTROL_H_ + +#if defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined (AeroQuadSTM32) + +#include "CameraStabilizer.h" + +int servoCenterPitchDiff = 0; +int servoCenterPitchDesired = 0; +int servoTXChannels = 0; +int servoActualCenter = 0; + +void processCameraTXControl() +{ + if (servoTXChannels == 1) + { + if (receiverCommand[AUX3] == 1500) // channel is centered -> move back to center + { + servoCenterPitchDiff = (servoActualCenter - servoCenterPitch) / 25; + if ((servoCenterPitchDiff > 0) && (servoCenterPitchDiff < 1)) + { + servoCenterPitchDiff = 1; + } + servoCenterPitch += servoCenterPitchDiff; + } + else + { + servoCenterPitchDesired = map(receiverCommand[AUX3],1000,2000,servoMaxPitch,servoMinPitch); + if (servoCenterPitch != servoCenterPitchDesired) + { + servoCenterPitchDiff = (servoCenterPitchDesired - servoCenterPitch) / 25; + if ((servoCenterPitchDiff > 0) && (servoCenterPitchDiff < 1)) + { + servoCenterPitchDiff = 1; + } + servoCenterPitch += servoCenterPitchDiff; + } + } + } + else if (servoTXChannels == 2) + { + if (receiverCommand[AUX4] == 1500) // override back to center + { + servoCenterPitchDiff = (servoActualCenter - servoCenterPitch) / 25; + if ((servoCenterPitchDiff > 0) && (servoCenterPitchDiff < 1)) + { + servoCenterPitchDiff = 1; + } + servoCenterPitch += servoCenterPitchDiff; + } + else // move up or down at a nice rate + { + if (receiverCommand[AUX3] != 1500) // map to up or down movement + { + servoCenterPitch += (1500 - receiverCommand[AUX3]) / 50; + } + } + } +} +#endif +#endif diff --git a/Libraries/AQ_Defines/GlobalDefined.h b/Libraries/AQ_Defines/GlobalDefined.h index df2651a8..c0687f76 100644 --- a/Libraries/AQ_Defines/GlobalDefined.h +++ b/Libraries/AQ_Defines/GlobalDefined.h @@ -1,43 +1,43 @@ -/* - AeroQuad v3.0.1 - February 2012 - www.AeroQuad.com - Copyright (c) 2012 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . -*/ - -#ifndef _AEROQUAD_GLOBAL_DEFINES_H_ -#define _AEROQUAD_GLOBAL_DEFINES_H_ - - -// More AQ relative than generic... have to be think again -// Basic axis definitions -#define XAXIS 0 -#define YAXIS 1 -#define ZAXIS 2 -#define THROTTLE 3 -#define MODE 4 -#define AUX1 5 -#define AUX2 6 -#define AUX3 7 -#define AUX4 8 -#define AUX5 9 - -#define ON 1 -#define OFF 0 - -#define ALTPANIC 2 - +/* + AeroQuad v3.0.1 - February 2012 + www.AeroQuad.com + Copyright (c) 2012 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . +*/ + +#ifndef _AEROQUAD_GLOBAL_DEFINES_H_ +#define _AEROQUAD_GLOBAL_DEFINES_H_ + + +// More AQ relative than generic... have to be think again +// Basic axis definitions +#define XAXIS 0 +#define YAXIS 1 +#define ZAXIS 2 +#define THROTTLE 3 +#define MODE 4 +#define AUX1 5 +#define AUX2 6 +#define AUX3 7 +#define AUX4 8 +#define AUX5 9 + +#define ON 1 +#define OFF 0 + +#define ALTPANIC 2 + #endif \ No newline at end of file diff --git a/Libraries/AQ_FlightControlProcessor/FlightControlHexPlus.h b/Libraries/AQ_FlightControlProcessor/FlightControlHexPlus.h index 619ec48e..325e2e03 100644 --- a/Libraries/AQ_FlightControlProcessor/FlightControlHexPlus.h +++ b/Libraries/AQ_FlightControlProcessor/FlightControlHexPlus.h @@ -1,62 +1,62 @@ -/* - AeroQuad v3.0.1 - February 2012 - www.AeroQuad.com - Copyright (c) 2012 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . -*/ - -#ifndef _AQ_PROCESS_FLIGHT_CONTROL_HEX_PLUS_MODE_H_ -#define _AQ_PROCESS_FLIGHT_CONTROL_HEX_PLUS_MODE_H_ - -#include "FlightControlVariable.h" - -/* - - CCW - - CW 0....Front....0 CW - ......***...... - ......***...... - ......***...... - CCW 0....Back.....0 CCW - - CW -*/ - - -#define FRONT MOTOR1 -#define FRONT_RIGHT MOTOR2 -#define REAR_RIGHT MOTOR3 -#define REAR MOTOR4 -#define REAR_LEFT MOTOR5 -#define FRONT_LEFT MOTOR6 -#define LASTMOTOR (MOTOR6+1) - -int motorMaxCommand[6] = {0,0,0,0,0,0}; -int motorMinCommand[6] = {0,0,0,0,0,0}; -int motorConfiguratorCommand[6] = {0,0,0,0,0,0}; - -void applyMotorCommand() { - motorCommand[FRONT_LEFT] = throttle + motorAxisCommandRoll/2 - motorAxisCommandPitch/2 + (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[REAR_RIGHT] = throttle - motorAxisCommandRoll/2 + motorAxisCommandPitch/2 - (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[FRONT_RIGHT] = throttle - motorAxisCommandRoll/2 - motorAxisCommandPitch/2 + (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[REAR_LEFT] = throttle + motorAxisCommandRoll/2 + motorAxisCommandPitch/2 - (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[FRONT] = throttle - motorAxisCommandPitch - (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[REAR] = throttle + motorAxisCommandPitch + (YAW_DIRECTION * motorAxisCommandYaw); -} - -#endif // #define _AQ_PROCESS_FLIGHT_CONTROL_HEX_PLUS_MODE_H_ - +/* + AeroQuad v3.0.1 - February 2012 + www.AeroQuad.com + Copyright (c) 2012 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . +*/ + +#ifndef _AQ_PROCESS_FLIGHT_CONTROL_HEX_PLUS_MODE_H_ +#define _AQ_PROCESS_FLIGHT_CONTROL_HEX_PLUS_MODE_H_ + +#include "FlightControlVariable.h" + +/* + + CCW + + CW 0....Front....0 CW + ......***...... + ......***...... + ......***...... + CCW 0....Back.....0 CCW + + CW +*/ + + +#define FRONT MOTOR1 +#define FRONT_RIGHT MOTOR2 +#define REAR_RIGHT MOTOR3 +#define REAR MOTOR4 +#define REAR_LEFT MOTOR5 +#define FRONT_LEFT MOTOR6 +#define LASTMOTOR (MOTOR6+1) + +int motorMaxCommand[6] = {0,0,0,0,0,0}; +int motorMinCommand[6] = {0,0,0,0,0,0}; +int motorConfiguratorCommand[6] = {0,0,0,0,0,0}; + +void applyMotorCommand() { + motorCommand[FRONT_LEFT] = throttle + motorAxisCommandRoll/2 - motorAxisCommandPitch/2 + (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[REAR_RIGHT] = throttle - motorAxisCommandRoll/2 + motorAxisCommandPitch/2 - (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[FRONT_RIGHT] = throttle - motorAxisCommandRoll/2 - motorAxisCommandPitch/2 + (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[REAR_LEFT] = throttle + motorAxisCommandRoll/2 + motorAxisCommandPitch/2 - (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[FRONT] = throttle - motorAxisCommandPitch - (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[REAR] = throttle + motorAxisCommandPitch + (YAW_DIRECTION * motorAxisCommandYaw); +} + +#endif // #define _AQ_PROCESS_FLIGHT_CONTROL_HEX_PLUS_MODE_H_ + diff --git a/Libraries/AQ_FlightControlProcessor/FlightControlHexX.h b/Libraries/AQ_FlightControlProcessor/FlightControlHexX.h index e84a711a..d16c0dae 100644 --- a/Libraries/AQ_FlightControlProcessor/FlightControlHexX.h +++ b/Libraries/AQ_FlightControlProcessor/FlightControlHexX.h @@ -1,59 +1,59 @@ -/* - AeroQuad v3.0.1 - February 2012 - www.AeroQuad.com - Copyright (c) 2012 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . -*/ - -#ifndef _AQ_PROCESS_FLIGHT_CONTROL_HEX_X_MODE_H_ -#define _AQ_PROCESS_FLIGHT_CONTROL_HEX_X_MODE_H_ - -/* - CW CCW - - 0....Front....0 - ......***...... - CCW ......***...... CW - ......***...... - 0....Back.....0 - - CW CCW -*/ - -#include "FlightControlVariable.h" - -#define FRONT_LEFT MOTOR1 -#define FRONT_RIGHT MOTOR2 -#define RIGHT MOTOR3 -#define REAR_RIGHT MOTOR4 -#define REAR_LEFT MOTOR5 -#define LEFT MOTOR6 -#define LASTMOTOR (MOTOR6+1) - -int motorMaxCommand[6] = {0,0,0,0,0,0}; -int motorMinCommand[6] = {0,0,0,0,0,0}; -int motorConfiguratorCommand[6] = {0,0,0,0,0,0}; - -void applyMotorCommand() { - motorCommand[FRONT_LEFT] = throttle + motorAxisCommandRoll/2 - motorAxisCommandPitch/2 - (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[REAR_RIGHT] = throttle - motorAxisCommandRoll/2 + motorAxisCommandPitch/2 + (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[FRONT_RIGHT] = throttle - motorAxisCommandRoll/2 - motorAxisCommandPitch/2 + (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[REAR_LEFT] = throttle + motorAxisCommandRoll/2 + motorAxisCommandPitch/2 - (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[RIGHT] = throttle - motorAxisCommandRoll - (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[LEFT] = throttle + motorAxisCommandRoll + (YAW_DIRECTION * motorAxisCommandYaw); -} - -#endif // #define _AQ_PROCESS_FLIGHT_CONTROL_HEX_X_MODE_H_ +/* + AeroQuad v3.0.1 - February 2012 + www.AeroQuad.com + Copyright (c) 2012 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . +*/ + +#ifndef _AQ_PROCESS_FLIGHT_CONTROL_HEX_X_MODE_H_ +#define _AQ_PROCESS_FLIGHT_CONTROL_HEX_X_MODE_H_ + +/* + CW CCW + + 0....Front....0 + ......***...... + CCW ......***...... CW + ......***...... + 0....Back.....0 + + CW CCW +*/ + +#include "FlightControlVariable.h" + +#define FRONT_LEFT MOTOR1 +#define FRONT_RIGHT MOTOR2 +#define RIGHT MOTOR3 +#define REAR_RIGHT MOTOR4 +#define REAR_LEFT MOTOR5 +#define LEFT MOTOR6 +#define LASTMOTOR (MOTOR6+1) + +int motorMaxCommand[6] = {0,0,0,0,0,0}; +int motorMinCommand[6] = {0,0,0,0,0,0}; +int motorConfiguratorCommand[6] = {0,0,0,0,0,0}; + +void applyMotorCommand() { + motorCommand[FRONT_LEFT] = throttle + motorAxisCommandRoll/2 - motorAxisCommandPitch/2 - (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[REAR_RIGHT] = throttle - motorAxisCommandRoll/2 + motorAxisCommandPitch/2 + (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[FRONT_RIGHT] = throttle - motorAxisCommandRoll/2 - motorAxisCommandPitch/2 + (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[REAR_LEFT] = throttle + motorAxisCommandRoll/2 + motorAxisCommandPitch/2 - (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[RIGHT] = throttle - motorAxisCommandRoll - (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[LEFT] = throttle + motorAxisCommandRoll + (YAW_DIRECTION * motorAxisCommandYaw); +} + +#endif // #define _AQ_PROCESS_FLIGHT_CONTROL_HEX_X_MODE_H_ diff --git a/Libraries/AQ_FlightControlProcessor/FlightControlQuadX.h b/Libraries/AQ_FlightControlProcessor/FlightControlQuadX.h index 14ae5daa..2003f686 100644 --- a/Libraries/AQ_FlightControlProcessor/FlightControlQuadX.h +++ b/Libraries/AQ_FlightControlProcessor/FlightControlQuadX.h @@ -1,59 +1,59 @@ -/* - AeroQuad v3.0.1 - February 2012 - www.AeroQuad.com - Copyright (c) 2012 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . -*/ - -#ifndef _AQ_PROCESS_FLIGHT_CONTROL_X_MODE_H_ -#define _AQ_PROCESS_FLIGHT_CONTROL_X_MODE_H_ - -/* - CW 0....Front....0 CCW - ......***...... - ......***...... - ......***...... - CCW 0....Back.....0 CW -*/ - -#include "FlightControlVariable.h" - -#ifdef OLD_MOTOR_NUMBERING - #define FRONT_LEFT MOTOR1 - #define REAR_RIGHT MOTOR2 - #define FRONT_RIGHT MOTOR3 - #define REAR_LEFT MOTOR4 -#else - #define FRONT_LEFT MOTOR1 - #define FRONT_RIGHT MOTOR2 - #define REAR_RIGHT MOTOR3 - #define REAR_LEFT MOTOR4 -#endif -#define LASTMOTOR (MOTOR4+1) - -int motorMaxCommand[4] = {0,0,0,0}; -int motorMinCommand[4] = {0,0,0,0}; -int motorConfiguratorCommand[4] = {0,0,0,0}; - -void applyMotorCommand() { - motorCommand[FRONT_LEFT] = throttle - motorAxisCommandPitch + motorAxisCommandRoll - (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[FRONT_RIGHT] = throttle - motorAxisCommandPitch - motorAxisCommandRoll + (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[REAR_LEFT] = throttle + motorAxisCommandPitch + motorAxisCommandRoll + (YAW_DIRECTION * motorAxisCommandYaw); - motorCommand[REAR_RIGHT] = throttle + motorAxisCommandPitch - motorAxisCommandRoll - (YAW_DIRECTION * motorAxisCommandYaw); -} - -#endif // #define _AQ_PROCESS_FLIGHT_CONTROL_X_MODE_H_ - +/* + AeroQuad v3.0.1 - February 2012 + www.AeroQuad.com + Copyright (c) 2012 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . +*/ + +#ifndef _AQ_PROCESS_FLIGHT_CONTROL_X_MODE_H_ +#define _AQ_PROCESS_FLIGHT_CONTROL_X_MODE_H_ + +/* + CW 0....Front....0 CCW + ......***...... + ......***...... + ......***...... + CCW 0....Back.....0 CW +*/ + +#include "FlightControlVariable.h" + +#ifdef OLD_MOTOR_NUMBERING + #define FRONT_LEFT MOTOR1 + #define REAR_RIGHT MOTOR2 + #define FRONT_RIGHT MOTOR3 + #define REAR_LEFT MOTOR4 +#else + #define FRONT_LEFT MOTOR1 + #define FRONT_RIGHT MOTOR2 + #define REAR_RIGHT MOTOR3 + #define REAR_LEFT MOTOR4 +#endif +#define LASTMOTOR (MOTOR4+1) + +int motorMaxCommand[4] = {0,0,0,0}; +int motorMinCommand[4] = {0,0,0,0}; +int motorConfiguratorCommand[4] = {0,0,0,0}; + +void applyMotorCommand() { + motorCommand[FRONT_LEFT] = throttle - motorAxisCommandPitch + motorAxisCommandRoll - (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[FRONT_RIGHT] = throttle - motorAxisCommandPitch - motorAxisCommandRoll + (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[REAR_LEFT] = throttle + motorAxisCommandPitch + motorAxisCommandRoll + (YAW_DIRECTION * motorAxisCommandYaw); + motorCommand[REAR_RIGHT] = throttle + motorAxisCommandPitch - motorAxisCommandRoll - (YAW_DIRECTION * motorAxisCommandYaw); +} + +#endif // #define _AQ_PROCESS_FLIGHT_CONTROL_X_MODE_H_ + diff --git a/Libraries/AQ_Gyroscope/Gyroscope_MPU6000.h b/Libraries/AQ_Gyroscope/Gyroscope_MPU6000.h index 90cfca95..86bb352a 100644 --- a/Libraries/AQ_Gyroscope/Gyroscope_MPU6000.h +++ b/Libraries/AQ_Gyroscope/Gyroscope_MPU6000.h @@ -1,119 +1,119 @@ -/* - AeroQuad v3.0 - May 2011 - www.AeroQuad.com - Copyright (c) 2011 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . -*/ - -#ifndef _AEROQUAD_GYROSCOPE_MPU6000_COMMON_H_ -#define _AEROQUAD_GYROSCOPE_MPU6000_COMMON_H_ - -int gyroRaw[3] = {0,0,0}; - -#include -#include - -#define GYRO_CALIBRATION_TRESHOLD 25 - -void initializeGyro() { - float range = 2*1000.0; - gyroScaleFactor = radians(range/65536.0); - - initializeMPU6000Sensors(); -} - -void gyroUpdateHeading() -{ - long int currentTime = micros(); - if (gyroRate[ZAXIS] > (float)radians(1.0) || gyroRate[ZAXIS] < (float)radians(-1.0)) { - gyroHeading += gyroRate[ZAXIS] * ((currentTime - gyroLastMesuredTime) / 1000000.0); - } - gyroLastMesuredTime = currentTime; -} - -void measureGyro() { - readMPU6000Gyro(); - - int gyroADC[3]; - gyroADC[XAXIS] = (gyroRaw[XAXIS]=MPU6000.data.gyro.x) - gyroZero[XAXIS]; - gyroADC[YAXIS] = gyroZero[YAXIS] - (gyroRaw[YAXIS]=MPU6000.data.gyro.y); - gyroADC[ZAXIS] = gyroZero[ZAXIS] - (gyroRaw[ZAXIS]=MPU6000.data.gyro.z); - - for (byte axis = 0; axis <= ZAXIS; axis++) { - gyroRate[axis] = gyroADC[axis] * gyroScaleFactor; - } - - gyroUpdateHeading(); -} - -void measureGyroSum() { - readMPU6000Gyro(); - gyroSample[XAXIS] += (gyroRaw[XAXIS]=MPU6000.data.gyro.x); - gyroSample[YAXIS] += (gyroRaw[YAXIS]=MPU6000.data.gyro.y); - gyroSample[ZAXIS] += (gyroRaw[ZAXIS]=MPU6000.data.gyro.z); - - gyroSampleCount++; -} - -void evaluateGyroRate() { - int gyroADC[3]; - gyroADC[XAXIS] = (gyroSample[XAXIS] / gyroSampleCount) - gyroZero[XAXIS]; - gyroADC[YAXIS] = gyroZero[YAXIS] - (gyroSample[YAXIS] / gyroSampleCount); - gyroADC[ZAXIS] = gyroZero[ZAXIS] - (gyroSample[ZAXIS] / gyroSampleCount); - - gyroSample[XAXIS] = 0; - gyroSample[YAXIS] = 0; - gyroSample[ZAXIS] = 0; - gyroSampleCount = 0; - - for (byte axis = 0; axis <= ZAXIS; axis++) { - gyroRate[axis] = gyroADC[axis] * gyroScaleFactor; - } - - gyroUpdateHeading(); -} - - -boolean calibrateGyro() { - - int findZero[FINDZERO]; - int diff = 0; - for (byte axis = 0; axis < 3; axis++) { - for (int i=0; i. +*/ + +#ifndef _AEROQUAD_GYROSCOPE_MPU6000_COMMON_H_ +#define _AEROQUAD_GYROSCOPE_MPU6000_COMMON_H_ + +int gyroRaw[3] = {0,0,0}; + +#include +#include + +#define GYRO_CALIBRATION_TRESHOLD 25 + +void initializeGyro() { + float range = 2*1000.0; + gyroScaleFactor = radians(range/65536.0); + + initializeMPU6000Sensors(); +} + +void gyroUpdateHeading() +{ + long int currentTime = micros(); + if (gyroRate[ZAXIS] > (float)radians(1.0) || gyroRate[ZAXIS] < (float)radians(-1.0)) { + gyroHeading += gyroRate[ZAXIS] * ((currentTime - gyroLastMesuredTime) / 1000000.0); + } + gyroLastMesuredTime = currentTime; +} + +void measureGyro() { + readMPU6000Gyro(); + + int gyroADC[3]; + gyroADC[XAXIS] = (gyroRaw[XAXIS]=MPU6000.data.gyro.x) - gyroZero[XAXIS]; + gyroADC[YAXIS] = gyroZero[YAXIS] - (gyroRaw[YAXIS]=MPU6000.data.gyro.y); + gyroADC[ZAXIS] = gyroZero[ZAXIS] - (gyroRaw[ZAXIS]=MPU6000.data.gyro.z); + + for (byte axis = 0; axis <= ZAXIS; axis++) { + gyroRate[axis] = gyroADC[axis] * gyroScaleFactor; + } + + gyroUpdateHeading(); +} + +void measureGyroSum() { + readMPU6000Gyro(); + gyroSample[XAXIS] += (gyroRaw[XAXIS]=MPU6000.data.gyro.x); + gyroSample[YAXIS] += (gyroRaw[YAXIS]=MPU6000.data.gyro.y); + gyroSample[ZAXIS] += (gyroRaw[ZAXIS]=MPU6000.data.gyro.z); + + gyroSampleCount++; +} + +void evaluateGyroRate() { + int gyroADC[3]; + gyroADC[XAXIS] = (gyroSample[XAXIS] / gyroSampleCount) - gyroZero[XAXIS]; + gyroADC[YAXIS] = gyroZero[YAXIS] - (gyroSample[YAXIS] / gyroSampleCount); + gyroADC[ZAXIS] = gyroZero[ZAXIS] - (gyroSample[ZAXIS] / gyroSampleCount); + + gyroSample[XAXIS] = 0; + gyroSample[YAXIS] = 0; + gyroSample[ZAXIS] = 0; + gyroSampleCount = 0; + + for (byte axis = 0; axis <= ZAXIS; axis++) { + gyroRate[axis] = gyroADC[axis] * gyroScaleFactor; + } + + gyroUpdateHeading(); +} + + +boolean calibrateGyro() { + + int findZero[FINDZERO]; + int diff = 0; + for (byte axis = 0; axis < 3; axis++) { + for (int i=0; i. - */ - -#ifndef _AQ_OSD_MAX7456_CONFIG_H_ -#define _AQ_OSD_MAX7456_CONFIG_H_ - -// You can configure positioning of various display elements below. -// '#defines' for elements which will not be displayed, can be ignored. -// -// The MAX7456 overlays characters in a grid 30 characters wide, 16/13 high -// (PAL/NTSC respectively). The row/column defines below correspond to -// positions in the grid of characters, with the origin at the top left. -// 0-origin indexing is used - ie row 0, col 0 is the highest, leftmost -// character on the screen while row 15, col 29 is the bottom right (for PAL). -// -// Generally avoid using the extreme border rows/columns as they are not -// always visible. -// -// Display elements start at the position you give and print to the right. -// They will wrap around to the next row if there are too few columns remaining -// on the row you specify. - -//Battery info - 5-16 characters long -#define VOLTAGE_ROW 1 -#define VOLTAGE_COL 1 - -//Compass reading - 5 characters long -#define COMPASS_ROW 0 -#define COMPASS_COL 13 - -//Altitude reading - up to 8 characters long (32768 max) -#define ALTITUDE_ROW 0 -#define ALTITUDE_COL 1 - -//Flight timer - 6 characters long -#define TIMER_ROW 0 -#define TIMER_COL 23 - -//Callsign -#if defined CALLSIGN - const char *callsign = CALLSIGN; - #define CALLSIGN_ROW 2 - #define CALLSIGN_COL (29-strlen(callsign)) -#endif - -// RSSI monitor -#define RSSI_ROW 2 -#define RSSI_COL 24 -#define SIGNAL_QUALITY_ROW 2 -#define SIGNAL_QUALITY_COL 1 - -// GPS info -#define GPS_ROW MAX_screen_rows-1 -#define GPS_COL 1 - -// GPS home arrow -- under the reticle -#define GPS_HA_ROW (MAX_screen_rows/2+2) -#define GPS_HA_COL 14 - -// Notify -#define NOTIFY_ROW MAX_screen_rows-2 -#define NOTIFY_COL 1 // don't change this, it needs a full line - -// Artificial horizon mode (default is attitude indicator) -#define ARTIFICIAL_HORIZON - -/********************** End of user configuration section ********************************/ - -#endif // #define _AQ_OSD_MAX7456_CONFIG_H_ +/* + AeroQuad v3.0 - Nov 2011 + www.AeroQuad.com + Copyright (c) 2011 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . + */ + +#ifndef _AQ_OSD_MAX7456_CONFIG_H_ +#define _AQ_OSD_MAX7456_CONFIG_H_ + +// You can configure positioning of various display elements below. +// '#defines' for elements which will not be displayed, can be ignored. +// +// The MAX7456 overlays characters in a grid 30 characters wide, 16/13 high +// (PAL/NTSC respectively). The row/column defines below correspond to +// positions in the grid of characters, with the origin at the top left. +// 0-origin indexing is used - ie row 0, col 0 is the highest, leftmost +// character on the screen while row 15, col 29 is the bottom right (for PAL). +// +// Generally avoid using the extreme border rows/columns as they are not +// always visible. +// +// Display elements start at the position you give and print to the right. +// They will wrap around to the next row if there are too few columns remaining +// on the row you specify. + +//Battery info - 5-16 characters long +#define VOLTAGE_ROW 1 +#define VOLTAGE_COL 1 + +//Compass reading - 5 characters long +#define COMPASS_ROW 0 +#define COMPASS_COL 13 + +//Altitude reading - up to 8 characters long (32768 max) +#define ALTITUDE_ROW 0 +#define ALTITUDE_COL 1 + +//Flight timer - 6 characters long +#define TIMER_ROW 0 +#define TIMER_COL 23 + +//Callsign +#if defined CALLSIGN + const char *callsign = CALLSIGN; + #define CALLSIGN_ROW 2 + #define CALLSIGN_COL (29-strlen(callsign)) +#endif + +// RSSI monitor +#define RSSI_ROW 2 +#define RSSI_COL 24 +#define SIGNAL_QUALITY_ROW 2 +#define SIGNAL_QUALITY_COL 1 + +// GPS info +#define GPS_ROW MAX_screen_rows-1 +#define GPS_COL 1 + +// GPS home arrow -- under the reticle +#define GPS_HA_ROW (MAX_screen_rows/2+2) +#define GPS_HA_COL 14 + +// Notify +#define NOTIFY_ROW MAX_screen_rows-2 +#define NOTIFY_COL 1 // don't change this, it needs a full line + +// Artificial horizon mode (default is attitude indicator) +#define ARTIFICIAL_HORIZON + +/********************** End of user configuration section ********************************/ + +#endif // #define _AQ_OSD_MAX7456_CONFIG_H_ diff --git a/Libraries/AQ_OSD/MAX7456_RSSI.h b/Libraries/AQ_OSD/MAX7456_RSSI.h index 5aeea54e..f57887bf 100644 --- a/Libraries/AQ_OSD/MAX7456_RSSI.h +++ b/Libraries/AQ_OSD/MAX7456_RSSI.h @@ -1,65 +1,65 @@ -/* - AeroQuad v3.0 - Nov 2011 - www.AeroQuad.com - Copyright (c) 2011 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . - */ - -#ifndef _AQ_OSD_MAX7456_RSSI_H_ -#define _AQ_OSD_MAX7456_RSSI_H_ - -////////////////////////////////////////////////////////////////////////////// -/////////////////////////// RSSI Display ///////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -// Show RSSI information (analog input value optionally mapped to percents.) -#if defined (UseEzUHFRSSIReader) - #include -#elif defined (UseSBUSRSSIReader) - #include -#else - #include -#endif - -short lastRSSI = 4321; //forces update at first run -#if defined (UseEzUHFRSSIReader) - short lastQuality = 4321; //forces update at first run -#endif - -void displayRSSI() { - - if (rssiRawValue != lastRSSI) { - lastRSSI = rssiRawValue; - char buf[6]; - #ifdef RSSI_RAWVAL - snprintf(buf, 6, "\372%4u", rssiRawValue); - writeChars(buf, 5, 0, RSSI_ROW, RSSI_COL); - #else - snprintf(buf, 6, "\372%3u%%", rssiRawValue); - writeChars(buf, 5, (RSSI_WARN>rssiRawValue)?1:0, RSSI_ROW, RSSI_COL); - #endif - } - #if defined (UseEzUHFRSSIReader) - if (lastQuality != signalQualityRawValue) { - char buf[6]; - snprintf(buf, 6, "\372%4u", signalQualityRawValue); - writeChars(buf, 5, 0, SIGNAL_QUALITY_ROW, SIGNAL_QUALITY_COL); - signalQualityRawValue = lastQuality; - } - #endif - -} - -#endif // #define _AQ_OSD_MAX7456_RSSI_H_ +/* + AeroQuad v3.0 - Nov 2011 + www.AeroQuad.com + Copyright (c) 2011 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . + */ + +#ifndef _AQ_OSD_MAX7456_RSSI_H_ +#define _AQ_OSD_MAX7456_RSSI_H_ + +////////////////////////////////////////////////////////////////////////////// +/////////////////////////// RSSI Display ///////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +// Show RSSI information (analog input value optionally mapped to percents.) +#if defined (UseEzUHFRSSIReader) + #include +#elif defined (UseSBUSRSSIReader) + #include +#else + #include +#endif + +short lastRSSI = 4321; //forces update at first run +#if defined (UseEzUHFRSSIReader) + short lastQuality = 4321; //forces update at first run +#endif + +void displayRSSI() { + + if (rssiRawValue != lastRSSI) { + lastRSSI = rssiRawValue; + char buf[6]; + #ifdef RSSI_RAWVAL + snprintf(buf, 6, "\372%4u", rssiRawValue); + writeChars(buf, 5, 0, RSSI_ROW, RSSI_COL); + #else + snprintf(buf, 6, "\372%3u%%", rssiRawValue); + writeChars(buf, 5, (RSSI_WARN>rssiRawValue)?1:0, RSSI_ROW, RSSI_COL); + #endif + } + #if defined (UseEzUHFRSSIReader) + if (lastQuality != signalQualityRawValue) { + char buf[6]; + snprintf(buf, 6, "\372%4u", signalQualityRawValue); + writeChars(buf, 5, 0, SIGNAL_QUALITY_ROW, SIGNAL_QUALITY_COL); + signalQualityRawValue = lastQuality; + } + #endif + +} + +#endif // #define _AQ_OSD_MAX7456_RSSI_H_ diff --git a/Libraries/AQ_Platform_APM/APM_ADC_Optimized.h b/Libraries/AQ_Platform_APM/APM_ADC_Optimized.h index 1494e0a0..33758dfb 100644 --- a/Libraries/AQ_Platform_APM/APM_ADC_Optimized.h +++ b/Libraries/AQ_Platform_APM/APM_ADC_Optimized.h @@ -1,248 +1,248 @@ -/* - AeroQuad v2.2 - Feburary 2011 - www.AeroQuad.com - Copyright (c) 2011 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . -*/ - -#ifndef _APM_ADC_OPTIMIZED_H_ -#define _APM_ADC_OPTIMIZED_H_ - -#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) - - -#include -#include - -//#define SPI_MEASURE -#define ADC_SPI_LASTCHANNEL 6 - -#define bit_set(p,m) ((p) |= (1<cmd; - for (uint8_t ch = 0; ch < ADC_SPI_LASTCHANNEL; ch++) { - ADCValue.highByte = ADC_SPI_WaitReadByte(); // read high byte - ADC_SPI_WaitSendByte(cmd); // select next ADC input - - // after sending a byte, we have 8 SPI clock cycles time, - // which is 3us at 375ns cycle time - p++; - cmd = (p+1)->cmd; - p->numberOfSamples++; - if(p->numberOfSamples == 0) { // during start up the counter could overrun - p->numberOfSamples = 1; // this does not happen during normal operation - p->value = 0; // so dropping the old values is fine here - } - - ADCValue.lowByte = ADC_SPI_WaitReadByte(); // read low byte - if(ch != ADC_SPI_LASTCHANNEL-1) { - ADC_SPI_WaitSendByte(0); - } - - // after sending a byte, we have 8 SPI clock cycles time - // which is 3us at 375ns cycle time - p->value += ADCValue.val; - } - - DisableADCChipSelect(); - //bit_clear(PORTL,6); // To test performance - -#ifdef SPI_MEASURE - unsigned long t1 = micros(); - - if(adcloop++ == 0) - { - Serial.println(t1-t0); - } -#endif - - //TCNT2 = SPI_CLOCK_RATE_2_COUNTER_START_VALUE(411); - TCNT2 = SPI_CLOCK_RATE_2_COUNTER_START_VALUE(1000); -} - -ISR (TIMER2_OVF_vect) { - ReadADCs(); -} - - - -void zero_ArduCopter_ADC(void) { - cli(); - for (byte i=0; i < sizeof(ADCData)/sizeof(ADCData[0]); i++) { - ADCData[i].value = 0; - ADCData[i].numberOfSamples = 0; - } - sei(); -} - -void initializeADC(void) { - zero_ArduCopter_ADC(); - for (byte i=0; i < sizeof(ADCData)/sizeof(ADCData[0]); i++) { - ADCData[i].cmd = adc_cmd[i+1]; - } - ADCData[ADC_SPI_LASTCHANNEL-1].cmd = 0; - - - pinMode(ADC_CHIP_SELECT,OUTPUT); - DisableADCChipSelect(); - - // Setup Serial Port2 in SPI mode - UBRR2 = 0; - DDRH |= (1<numberOfSamples > 0) - result = p->value/(p->numberOfSamples*8); - else - result = 0; - - p->value = 0; // Initialize for next reading - p->numberOfSamples = 0; - sei(); - - return(result); -} - -#endif // #if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) - -#endif //#define _APM_ADC_OPTIMIZED_H_ +/* + AeroQuad v2.2 - Feburary 2011 + www.AeroQuad.com + Copyright (c) 2011 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . +*/ + +#ifndef _APM_ADC_OPTIMIZED_H_ +#define _APM_ADC_OPTIMIZED_H_ + +#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) + + +#include +#include + +//#define SPI_MEASURE +#define ADC_SPI_LASTCHANNEL 6 + +#define bit_set(p,m) ((p) |= (1<cmd; + for (uint8_t ch = 0; ch < ADC_SPI_LASTCHANNEL; ch++) { + ADCValue.highByte = ADC_SPI_WaitReadByte(); // read high byte + ADC_SPI_WaitSendByte(cmd); // select next ADC input + + // after sending a byte, we have 8 SPI clock cycles time, + // which is 3us at 375ns cycle time + p++; + cmd = (p+1)->cmd; + p->numberOfSamples++; + if(p->numberOfSamples == 0) { // during start up the counter could overrun + p->numberOfSamples = 1; // this does not happen during normal operation + p->value = 0; // so dropping the old values is fine here + } + + ADCValue.lowByte = ADC_SPI_WaitReadByte(); // read low byte + if(ch != ADC_SPI_LASTCHANNEL-1) { + ADC_SPI_WaitSendByte(0); + } + + // after sending a byte, we have 8 SPI clock cycles time + // which is 3us at 375ns cycle time + p->value += ADCValue.val; + } + + DisableADCChipSelect(); + //bit_clear(PORTL,6); // To test performance + +#ifdef SPI_MEASURE + unsigned long t1 = micros(); + + if(adcloop++ == 0) + { + Serial.println(t1-t0); + } +#endif + + //TCNT2 = SPI_CLOCK_RATE_2_COUNTER_START_VALUE(411); + TCNT2 = SPI_CLOCK_RATE_2_COUNTER_START_VALUE(1000); +} + +ISR (TIMER2_OVF_vect) { + ReadADCs(); +} + + + +void zero_ArduCopter_ADC(void) { + cli(); + for (byte i=0; i < sizeof(ADCData)/sizeof(ADCData[0]); i++) { + ADCData[i].value = 0; + ADCData[i].numberOfSamples = 0; + } + sei(); +} + +void initializeADC(void) { + zero_ArduCopter_ADC(); + for (byte i=0; i < sizeof(ADCData)/sizeof(ADCData[0]); i++) { + ADCData[i].cmd = adc_cmd[i+1]; + } + ADCData[ADC_SPI_LASTCHANNEL-1].cmd = 0; + + + pinMode(ADC_CHIP_SELECT,OUTPUT); + DisableADCChipSelect(); + + // Setup Serial Port2 in SPI mode + UBRR2 = 0; + DDRH |= (1<numberOfSamples > 0) + result = p->value/(p->numberOfSamples*8); + else + result = 0; + + p->value = 0; // Initialize for next reading + p->numberOfSamples = 0; + sei(); + + return(result); +} + +#endif // #if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) + +#endif //#define _APM_ADC_OPTIMIZED_H_ diff --git a/Libraries/AQ_RSSI/AnalogRSSIReader.h b/Libraries/AQ_RSSI/AnalogRSSIReader.h index 9401c3a0..a78ec45c 100644 --- a/Libraries/AQ_RSSI/AnalogRSSIReader.h +++ b/Libraries/AQ_RSSI/AnalogRSSIReader.h @@ -1,53 +1,53 @@ -/* - AeroQuad v3.0 - Nov 2011 - www.AeroQuad.com - Copyright (c) 2011 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . - */ - -#ifndef _AQ_ANALOG_RSSI_READER_H_ -#define _AQ_ANALOG_RSSI_READER_H_ - - -#define RSSI_PIN A6 // analog pin to read -//#define RSSI_RAWVAL // show raw A/D value instead of percents (for tuning) -#define RSSI_100P 800 // A/D value for 100% -#define RSSI_0P 80 // A/D value for 0% -#define RSSI_WARN 20 // show alarm at % - - -////////////////////////////////////////////////////////////////////////////// -/////////////////////////// RSSI Display ///////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -// Show RSSI information (analog input value optionally mapped to percents.) - -short rssiRawValue = 0; //forces update at first run - -void readRSSI() { - - rssiRawValue = analogRead(RSSI_PIN); - #ifndef RSSI_RAWVAL - rssiRawValue = ((long)rssiRawValue - RSSI_0P) * 100 / (RSSI_100P - RSSI_0P); - if (rssiRawValue < 0) { - rssiRawValue = 0; - } - if (rssiRawValue > 100) { - rssiRawValue = 100; - } - #endif -} - -#endif // #define _AQ_OSD_MAX7456_RSSI_H_ +/* + AeroQuad v3.0 - Nov 2011 + www.AeroQuad.com + Copyright (c) 2011 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . + */ + +#ifndef _AQ_ANALOG_RSSI_READER_H_ +#define _AQ_ANALOG_RSSI_READER_H_ + + +#define RSSI_PIN A6 // analog pin to read +//#define RSSI_RAWVAL // show raw A/D value instead of percents (for tuning) +#define RSSI_100P 800 // A/D value for 100% +#define RSSI_0P 80 // A/D value for 0% +#define RSSI_WARN 20 // show alarm at % + + +////////////////////////////////////////////////////////////////////////////// +/////////////////////////// RSSI Display ///////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +// Show RSSI information (analog input value optionally mapped to percents.) + +short rssiRawValue = 0; //forces update at first run + +void readRSSI() { + + rssiRawValue = analogRead(RSSI_PIN); + #ifndef RSSI_RAWVAL + rssiRawValue = ((long)rssiRawValue - RSSI_0P) * 100 / (RSSI_100P - RSSI_0P); + if (rssiRawValue < 0) { + rssiRawValue = 0; + } + if (rssiRawValue > 100) { + rssiRawValue = 100; + } + #endif +} + +#endif // #define _AQ_OSD_MAX7456_RSSI_H_ diff --git a/Libraries/AQ_RSSI/EzUHFRSSIReader.h b/Libraries/AQ_RSSI/EzUHFRSSIReader.h index f75a05e7..e82bf7e8 100644 --- a/Libraries/AQ_RSSI/EzUHFRSSIReader.h +++ b/Libraries/AQ_RSSI/EzUHFRSSIReader.h @@ -1,50 +1,50 @@ -/* - AeroQuad v3.0 - Nov 2011 - www.AeroQuad.com - Copyright (c) 2011 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . - */ - -#ifndef _AQ_EzUHF_RSSI_READER_H_ -#define _AQ_EzUHF_RSSI_READER_H_ - -#include - -#define RSSI_RAWVAL // show raw A/D value instead of percents (for tuning) -#define RSSI_MAX_RAW_VALUE 1001 -#define RSSI_MIN_RAW_VALUE 2000 -#define SIGNAL_QUALITY_MAX_RAW_VALUE 2001 -#define SIGNAL_QUALITY_MIN_RAW_VALUE 1614 - -#define RSSI_WARN 20 // show alarm at % - -////////////////////////////////////////////////////////////////////////////// -/////////////////////////// RSSI Display ///////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -// Show RSSI information (analog input value optionally mapped to percents.) - -short rssiRawValue = 0; //forces update at first run -short signalQualityRawValue = 0; - -void readRSSI() { - - rssiRawValue = map(receiverCommand[AUX2],RSSI_MIN_RAW_VALUE,RSSI_MAX_RAW_VALUE,0,100); - rssiRawValue = constrain(rssiRawValue,0,100); - signalQualityRawValue = map(receiverCommand[AUX3],SIGNAL_QUALITY_MIN_RAW_VALUE,SIGNAL_QUALITY_MAX_RAW_VALUE,0,100); - signalQualityRawValue = constrain(signalQualityRawValue,0,100); -} - -#endif // #define _AQ_OSD_MAX7456_RSSI_H_ +/* + AeroQuad v3.0 - Nov 2011 + www.AeroQuad.com + Copyright (c) 2011 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . + */ + +#ifndef _AQ_EzUHF_RSSI_READER_H_ +#define _AQ_EzUHF_RSSI_READER_H_ + +#include + +#define RSSI_RAWVAL // show raw A/D value instead of percents (for tuning) +#define RSSI_MAX_RAW_VALUE 1001 +#define RSSI_MIN_RAW_VALUE 2000 +#define SIGNAL_QUALITY_MAX_RAW_VALUE 2001 +#define SIGNAL_QUALITY_MIN_RAW_VALUE 1614 + +#define RSSI_WARN 20 // show alarm at % + +////////////////////////////////////////////////////////////////////////////// +/////////////////////////// RSSI Display ///////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +// Show RSSI information (analog input value optionally mapped to percents.) + +short rssiRawValue = 0; //forces update at first run +short signalQualityRawValue = 0; + +void readRSSI() { + + rssiRawValue = map(receiverCommand[AUX2],RSSI_MIN_RAW_VALUE,RSSI_MAX_RAW_VALUE,0,100); + rssiRawValue = constrain(rssiRawValue,0,100); + signalQualityRawValue = map(receiverCommand[AUX3],SIGNAL_QUALITY_MIN_RAW_VALUE,SIGNAL_QUALITY_MAX_RAW_VALUE,0,100); + signalQualityRawValue = constrain(signalQualityRawValue,0,100); +} + +#endif // #define _AQ_OSD_MAX7456_RSSI_H_ diff --git a/Libraries/AQ_RSSI/SBUSRSSIReader.h b/Libraries/AQ_RSSI/SBUSRSSIReader.h index c501a34c..7a14b470 100644 --- a/Libraries/AQ_RSSI/SBUSRSSIReader.h +++ b/Libraries/AQ_RSSI/SBUSRSSIReader.h @@ -1,56 +1,56 @@ -/* - AeroQuad v3.0.1 - February 2012 - www.AeroQuad.com - Copyright (c) 2012 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . - */ - -#ifndef _SBUSRSSIReader_h -#define _SBUSRSSIReader_h - -#if defined ReceiverSBUS - -#define RSSI_WARN 50 // show alarm at % - -long sbusFrameCountLast = 0; -short rssiRawValue = 0; // forces update at first run -float rssiTemp = 0; - - -void readRSSI() { - // need to detect what rate sBUS is running at - 7ms (~143Hz) or 14ms (~71Hz) - // if 143Hz, difference between current and last frame count will be 2 or 3 - // if difference is 1, data rate is 71Hz - if (sbusRate == 0) { - if (sbusFrameCountLast != 0) { - if ((sbusFrameCount > 1) && (sbusFrameCount < 4)) { - sbusRate = 143; - } else if (sbusFrameCount <= 1) { - sbusRate = 71; - } - } else { - sbusFrameCountLast = sbusFrameCount; - sbusFrameCount = 0; - } - } - rssiTemp = (1 - ((float)sbusFailSafeCount / sbusRate)) * 100; - rssiRawValue = rssiTemp; -} - - - -#endif -#endif +/* + AeroQuad v3.0.1 - February 2012 + www.AeroQuad.com + Copyright (c) 2012 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . + */ + +#ifndef _SBUSRSSIReader_h +#define _SBUSRSSIReader_h + +#if defined ReceiverSBUS + +#define RSSI_WARN 50 // show alarm at % + +long sbusFrameCountLast = 0; +short rssiRawValue = 0; // forces update at first run +float rssiTemp = 0; + + +void readRSSI() { + // need to detect what rate sBUS is running at - 7ms (~143Hz) or 14ms (~71Hz) + // if 143Hz, difference between current and last frame count will be 2 or 3 + // if difference is 1, data rate is 71Hz + if (sbusRate == 0) { + if (sbusFrameCountLast != 0) { + if ((sbusFrameCount > 1) && (sbusFrameCount < 4)) { + sbusRate = 143; + } else if (sbusFrameCount <= 1) { + sbusRate = 71; + } + } else { + sbusFrameCountLast = sbusFrameCount; + sbusFrameCount = 0; + } + } + rssiTemp = (1 - ((float)sbusFailSafeCount / sbusRate)) * 100; + rssiRawValue = rssiTemp; +} + + + +#endif +#endif diff --git a/Libraries/AQ_Receiver/Receiver.h b/Libraries/AQ_Receiver/Receiver.h index 06bf57f2..5b80f9e7 100644 --- a/Libraries/AQ_Receiver/Receiver.h +++ b/Libraries/AQ_Receiver/Receiver.h @@ -1,119 +1,119 @@ -/* - AeroQuad v3.0.1 - February 2012 - www.AeroQuad.com - Copyright (c) 2012 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . -*/ - -#ifndef _AEROQUAD_RECEIVER_H_ -#define _AEROQUAD_RECEIVER_H_ - -#include "Arduino.h" - -#define PWM2RAD 0.002 // Based upon 5RAD for full stick movement, you take this times the RAD to get the PWM conversion factor - -// Receiver variables -#define TIMEOUT 25000 -#define MINCOMMAND 1000 -#define MIDCOMMAND 1500 -#define MAXCOMMAND 2000 -#define MINDELTA 200 -#define MINCHECK (MINCOMMAND + 100) -#define MAXCHECK (MAXCOMMAND - 100) -#define MINTHROTTLE (MINCOMMAND + 100) -#define LEVELOFF 100 -#define MAX_NB_CHANNEL 10 - -int lastReceiverChannel = 0; - -float receiverXmitFactor = 0.0; -int receiverData[MAX_NB_CHANNEL] = {0,0,0,0,0,0,0,0,0,0}; -int receiverZero[3] = {0,0,0}; -int receiverCommand[MAX_NB_CHANNEL] = {0,0,0,0,0,0,0,0,0,0}; -int receiverCommandSmooth[MAX_NB_CHANNEL] = {0,0,0,0,0,0,0,0,0,0,}; -float receiverSlope[MAX_NB_CHANNEL] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; -float receiverOffset[MAX_NB_CHANNEL] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; -float receiverSmoothFactor[MAX_NB_CHANNEL] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; -int channelCal; - -void initializeReceiverParam(int nbChannel = 6) { - - lastReceiverChannel = nbChannel; - - receiverCommand[XAXIS] = 1500; - receiverCommand[YAXIS] = 1500; - receiverCommand[ZAXIS] = 1500; - receiverCommand[THROTTLE] = 1000; - receiverCommand[MODE] = 1000; - receiverCommand[AUX1] = 1000; - receiverCommand[AUX2] = 1000; - receiverCommand[AUX3] = 1000; - receiverCommand[AUX4] = 1000; - receiverCommand[AUX5] = 1000; - - for (byte channel = XAXIS; channel < lastReceiverChannel; channel++) { - receiverCommandSmooth[channel] = 1.0; - } - for (byte channel = XAXIS; channel < THROTTLE; channel++) { - receiverZero[channel] = 1500; - } - - for (byte channel = XAXIS; channel < lastReceiverChannel; channel++) { - receiverSlope[channel] = 1; - } - for (byte channel = XAXIS; channel < lastReceiverChannel; channel++) { - receiverOffset[channel] = 1; - } - for (byte channel = XAXIS; channel < lastReceiverChannel; channel++) { - receiverSmoothFactor[channel] = 1; - } -} - -int getRawChannelValue(byte channel); -void readReceiver(); - -void readReceiver() -{ - for(byte channel = XAXIS; channel < lastReceiverChannel; channel++) { - - // Apply receiver calibration adjustment - receiverData[channel] = (receiverSlope[channel] * getRawChannelValue(channel)) + receiverOffset[channel]; - // Smooth the flight control receiver inputs - receiverCommandSmooth[channel] = filterSmooth(receiverData[channel], receiverCommandSmooth[channel], receiverSmoothFactor[channel]); - } - - // Reduce receiver commands using receiverXmitFactor and center around 1500 - for (byte channel = XAXIS; channel < THROTTLE; channel++) { - receiverCommand[channel] = ((receiverCommandSmooth[channel] - receiverZero[channel]) * receiverXmitFactor) + receiverZero[channel]; - } - // No xmitFactor reduction applied for throttle, mode and AUX - for (byte channel = THROTTLE; channel < lastReceiverChannel; channel++) { - receiverCommand[channel] = receiverCommandSmooth[channel]; - } -} - - -void setChannelValue(byte channel,int value); - -// return the smoothed & scaled number of radians/sec in stick movement - zero centered -const float getReceiverSIData(byte channel) { - return ((receiverCommand[channel] - receiverZero[channel]) * (2.5 * PWM2RAD)); // +/- 2.5RPS 50% of full rate -} - -#endif - - - +/* + AeroQuad v3.0.1 - February 2012 + www.AeroQuad.com + Copyright (c) 2012 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . +*/ + +#ifndef _AEROQUAD_RECEIVER_H_ +#define _AEROQUAD_RECEIVER_H_ + +#include "Arduino.h" + +#define PWM2RAD 0.002 // Based upon 5RAD for full stick movement, you take this times the RAD to get the PWM conversion factor + +// Receiver variables +#define TIMEOUT 25000 +#define MINCOMMAND 1000 +#define MIDCOMMAND 1500 +#define MAXCOMMAND 2000 +#define MINDELTA 200 +#define MINCHECK (MINCOMMAND + 100) +#define MAXCHECK (MAXCOMMAND - 100) +#define MINTHROTTLE (MINCOMMAND + 100) +#define LEVELOFF 100 +#define MAX_NB_CHANNEL 10 + +int lastReceiverChannel = 0; + +float receiverXmitFactor = 0.0; +int receiverData[MAX_NB_CHANNEL] = {0,0,0,0,0,0,0,0,0,0}; +int receiverZero[3] = {0,0,0}; +int receiverCommand[MAX_NB_CHANNEL] = {0,0,0,0,0,0,0,0,0,0}; +int receiverCommandSmooth[MAX_NB_CHANNEL] = {0,0,0,0,0,0,0,0,0,0,}; +float receiverSlope[MAX_NB_CHANNEL] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; +float receiverOffset[MAX_NB_CHANNEL] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; +float receiverSmoothFactor[MAX_NB_CHANNEL] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; +int channelCal; + +void initializeReceiverParam(int nbChannel = 6) { + + lastReceiverChannel = nbChannel; + + receiverCommand[XAXIS] = 1500; + receiverCommand[YAXIS] = 1500; + receiverCommand[ZAXIS] = 1500; + receiverCommand[THROTTLE] = 1000; + receiverCommand[MODE] = 1000; + receiverCommand[AUX1] = 1000; + receiverCommand[AUX2] = 1000; + receiverCommand[AUX3] = 1000; + receiverCommand[AUX4] = 1000; + receiverCommand[AUX5] = 1000; + + for (byte channel = XAXIS; channel < lastReceiverChannel; channel++) { + receiverCommandSmooth[channel] = 1.0; + } + for (byte channel = XAXIS; channel < THROTTLE; channel++) { + receiverZero[channel] = 1500; + } + + for (byte channel = XAXIS; channel < lastReceiverChannel; channel++) { + receiverSlope[channel] = 1; + } + for (byte channel = XAXIS; channel < lastReceiverChannel; channel++) { + receiverOffset[channel] = 1; + } + for (byte channel = XAXIS; channel < lastReceiverChannel; channel++) { + receiverSmoothFactor[channel] = 1; + } +} + +int getRawChannelValue(byte channel); +void readReceiver(); + +void readReceiver() +{ + for(byte channel = XAXIS; channel < lastReceiverChannel; channel++) { + + // Apply receiver calibration adjustment + receiverData[channel] = (receiverSlope[channel] * getRawChannelValue(channel)) + receiverOffset[channel]; + // Smooth the flight control receiver inputs + receiverCommandSmooth[channel] = filterSmooth(receiverData[channel], receiverCommandSmooth[channel], receiverSmoothFactor[channel]); + } + + // Reduce receiver commands using receiverXmitFactor and center around 1500 + for (byte channel = XAXIS; channel < THROTTLE; channel++) { + receiverCommand[channel] = ((receiverCommandSmooth[channel] - receiverZero[channel]) * receiverXmitFactor) + receiverZero[channel]; + } + // No xmitFactor reduction applied for throttle, mode and AUX + for (byte channel = THROTTLE; channel < lastReceiverChannel; channel++) { + receiverCommand[channel] = receiverCommandSmooth[channel]; + } +} + + +void setChannelValue(byte channel,int value); + +// return the smoothed & scaled number of radians/sec in stick movement - zero centered +const float getReceiverSIData(byte channel) { + return ((receiverCommand[channel] - receiverZero[channel]) * (2.5 * PWM2RAD)); // +/- 2.5RPS 50% of full rate +} + +#endif + + + diff --git a/Libraries/AQ_Receiver/Receiver_PPM.h b/Libraries/AQ_Receiver/Receiver_PPM.h index a9235565..b0b88aff 100644 --- a/Libraries/AQ_Receiver/Receiver_PPM.h +++ b/Libraries/AQ_Receiver/Receiver_PPM.h @@ -1,80 +1,80 @@ -/* - AeroQuad v3.0.1 - February 2012 - www.AeroQuad.com - Copyright (c) 2012 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . -*/ - -#ifndef _AEROQUAD_RECEIVER_PPM_H_ -#define _AEROQUAD_RECEIVER_PPM_H_ - -#if defined (__AVR_ATmega328P__) || defined(__AVR_ATmegaUNO__) - #define PPM_PIN_INTERRUPT() attachInterrupt(0, rxInt, RISING) //PIN 0 -#else - #define PPM_PIN_INTERRUPT() attachInterrupt(4, rxInt, RISING) //PIN 19, also used for Spektrum satellite option -#endif - -#include "Arduino.h" -#include "Receiver.h" - -#include "pins_arduino.h" -#include -#include "GlobalDefined.h" - -#include "Receiver_PPM_common.h" - -static uint8_t rcChannel[PPM_CHANNELS] = {SERIAL_SUM_PPM}; -volatile uint16_t rcValue[PPM_CHANNELS] = {1500,1500,1500,1500,1500,1500,1500,1500,1500,1500}; // interval [1000;2000] - -static void rxInt() { - uint16_t now,diff; - static uint16_t last = 0; - static uint8_t chan = PPM_CHANNELS; - - now = micros(); - diff = now - last; - last = now; - if(diff>3000) { - chan = 0; - } - else if( 800 < diff && diff < 2200 && chan < PPM_CHANNELS ) { - rcValue[chan] = diff; - chan++; - } - else { - chan = PPM_CHANNELS; - } -} - -void initializeReceiver(int nbChannel) { - - initializeReceiverParam(nbChannel); - PPM_PIN_INTERRUPT(); -} - -int getRawChannelValue(byte channel) { - uint8_t oldSREG; - oldSREG = SREG; - cli(); // Let's disable interrupts - - int rawChannelValue = rcValue[rcChannel[channel]]; - SREG = oldSREG; - - return rawChannelValue; -} - - -#endif +/* + AeroQuad v3.0.1 - February 2012 + www.AeroQuad.com + Copyright (c) 2012 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . +*/ + +#ifndef _AEROQUAD_RECEIVER_PPM_H_ +#define _AEROQUAD_RECEIVER_PPM_H_ + +#if defined (__AVR_ATmega328P__) || defined(__AVR_ATmegaUNO__) + #define PPM_PIN_INTERRUPT() attachInterrupt(0, rxInt, RISING) //PIN 0 +#else + #define PPM_PIN_INTERRUPT() attachInterrupt(4, rxInt, RISING) //PIN 19, also used for Spektrum satellite option +#endif + +#include "Arduino.h" +#include "Receiver.h" + +#include "pins_arduino.h" +#include +#include "GlobalDefined.h" + +#include "Receiver_PPM_common.h" + +static uint8_t rcChannel[PPM_CHANNELS] = {SERIAL_SUM_PPM}; +volatile uint16_t rcValue[PPM_CHANNELS] = {1500,1500,1500,1500,1500,1500,1500,1500,1500,1500}; // interval [1000;2000] + +static void rxInt() { + uint16_t now,diff; + static uint16_t last = 0; + static uint8_t chan = PPM_CHANNELS; + + now = micros(); + diff = now - last; + last = now; + if(diff>3000) { + chan = 0; + } + else if( 800 < diff && diff < 2200 && chan < PPM_CHANNELS ) { + rcValue[chan] = diff; + chan++; + } + else { + chan = PPM_CHANNELS; + } +} + +void initializeReceiver(int nbChannel) { + + initializeReceiverParam(nbChannel); + PPM_PIN_INTERRUPT(); +} + +int getRawChannelValue(byte channel) { + uint8_t oldSREG; + oldSREG = SREG; + cli(); // Let's disable interrupts + + int rawChannelValue = rcValue[rcChannel[channel]]; + SREG = oldSREG; + + return rawChannelValue; +} + + +#endif diff --git a/Libraries/AQ_Receiver/Receiver_PPM_common.h b/Libraries/AQ_Receiver/Receiver_PPM_common.h index afcf06aa..e65393d7 100644 --- a/Libraries/AQ_Receiver/Receiver_PPM_common.h +++ b/Libraries/AQ_Receiver/Receiver_PPM_common.h @@ -1,37 +1,37 @@ -/* - AeroQuad v3.0.1 - February 2012 - www.AeroQuad.com - Copyright (c) 2012 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . -*/ - -#ifndef _AEROQUAD_RECEIVER_PPM_COMMON_H_ -#define _AEROQUAD_RECEIVER_PPM_COMMON_H_ - -#define PPM_CHANNELS 10 - -#define SERIAL_SUM_PPM_1 1,2,3,0,4,5,6,7,8,9 // PITCH,YAW,THR,ROLL... For Graupner/Spektrum -#define SERIAL_SUM_PPM_2 0,1,3,2,4,5,6,7,8,9 // ROLL,PITCH,THR,YAW... For Robe/Hitec/Futaba/Turnigy9xFrsky -#define SERIAL_SUM_PPM_3 1,0,3,2,4,5,6,7,8,9 // PITCH,ROLL,THR,YAW... For some Hitec/Sanwa/Others - -#if defined (SKETCH_SERIAL_SUM_PPM) - #define SERIAL_SUM_PPM SKETCH_SERIAL_SUM_PPM -#else - #define SERIAL_SUM_PPM SERIAL_SUM_PPM_1 -#endif - -#endif - +/* + AeroQuad v3.0.1 - February 2012 + www.AeroQuad.com + Copyright (c) 2012 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . +*/ + +#ifndef _AEROQUAD_RECEIVER_PPM_COMMON_H_ +#define _AEROQUAD_RECEIVER_PPM_COMMON_H_ + +#define PPM_CHANNELS 10 + +#define SERIAL_SUM_PPM_1 1,2,3,0,4,5,6,7,8,9 // PITCH,YAW,THR,ROLL... For Graupner/Spektrum +#define SERIAL_SUM_PPM_2 0,1,3,2,4,5,6,7,8,9 // ROLL,PITCH,THR,YAW... For Robe/Hitec/Futaba/Turnigy9xFrsky +#define SERIAL_SUM_PPM_3 1,0,3,2,4,5,6,7,8,9 // PITCH,ROLL,THR,YAW... For some Hitec/Sanwa/Others + +#if defined (SKETCH_SERIAL_SUM_PPM) + #define SERIAL_SUM_PPM SKETCH_SERIAL_SUM_PPM +#else + #define SERIAL_SUM_PPM SERIAL_SUM_PPM_1 +#endif + +#endif + diff --git a/Libraries/AQ_Receiver/Receiver_SBUS.h b/Libraries/AQ_Receiver/Receiver_SBUS.h index f67fa86d..2a9a2c1f 100644 --- a/Libraries/AQ_Receiver/Receiver_SBUS.h +++ b/Libraries/AQ_Receiver/Receiver_SBUS.h @@ -1,116 +1,116 @@ -/* - AeroQuad v3.0.1 - February 2012 - www.AeroQuad.com - Copyright (c) 2012 Ted Carancho. All rights reserved. - An Open Source Arduino based multicopter. - - This program is free software: you can 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 . - */ - -#ifndef _AEROQUAD_RECEIVER_SBUS_H_ -#define _AEROQUAD_RECEIVER_SBUS_H_ - -#if defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined (AeroQuadSTM32) - -#if !defined (AeroQuadSTM32) - #include "Arduino.h" - #include "pins_arduino.h" - #include - #include "GlobalDefined.h" -#endif -#include "Receiver.h" - -#define SBUS_SYNCBYTE 0x0F // some sites say 0xF0 - -#define SERIAL_SBUS Serial3 - -// 16 analog, 2 digital channels -static unsigned int rcChannel[18] = {XAXIS,YAXIS,THROTTLE,ZAXIS,MODE,AUX1,AUX2,AUX3,AUX4,AUX5,10,11,12,13,14,15,16,17}; -static unsigned int sbusIndex = 0; -#if defined (UseSBUSRSSIReader) - static unsigned short sbusFailSafeCount = 0; - static unsigned long sbusFrameCount = 0; - static unsigned short sbusRate = 0; -#endif - -void initializeReceiver(int nbChannel = 10) { - initializeReceiverParam(nbChannel); - #if defined (AeroQuadSTM32) - pinMode(BOARD_SPI2_NSS_PIN, OUTPUT); - digitalWrite(BOARD_SPI2_NSS_PIN,HIGH); // GPIO PB12 /Libmaple/libmaple/wirish/boards/aeroquad32.h line 69 - #endif - SERIAL_SBUS.begin(100000); -} - -void readSBUS() { - - static byte sbus[25] = {0}; - while(SERIAL_SBUS.available()) { - - int val = SERIAL_SBUS.read(); - if(sbusIndex == 0 && val != SBUS_SYNCBYTE) { - continue; - } - - sbus[sbusIndex] = val; - sbusIndex++; - if (sbusIndex == 25) { - - sbusIndex = 0; - // check stop bit before updating buffers - if (sbus[24] == 0x0) { - - rcChannel[XAXIS] = ((sbus[1] | sbus[2]<<8) & 0x07FF); // pitch - rcChannel[YAXIS] = ((sbus[2]>>3 | sbus[3]<<5) & 0x07FF); // roll - rcChannel[THROTTLE] = ((sbus[3]>>6 | sbus[4]<<2 | sbus[5]<<10) & 0x07FF); // throttle - rcChannel[ZAXIS] = ((sbus[5]>>1 | sbus[6]<<7) & 0x07FF); // yaw - rcChannel[MODE] = ((sbus[6]>>4 | sbus[7]<<4) & 0x07FF); - rcChannel[AUX1] = ((sbus[7]>>7 | sbus[8]<<1 | sbus[9]<<9) & 0x07FF); - rcChannel[AUX2] = ((sbus[9]>>2 | sbus[10]<<6) & 0x07FF); - rcChannel[AUX3] = ((sbus[10]>>5 | sbus[11]<<3) & 0x07FF); - rcChannel[AUX4] = ((sbus[12] | sbus[13]<<8) & 0x07FF); - rcChannel[AUX5] = ((sbus[13]>>3 | sbus[14]<<5) & 0x07FF); - //rcChannel[AUX6] = ((sbus[14]>>6 | sbus[15]<<2|sbus[16]<<10) & 0x07FF); - //rcChannel[AUX7] = ((sbus[16]>>1 | sbus[17]<<7) & 0x07FF); - - - #ifdef UseSBUSRSSIReader - if (sbusRate == 0) { - sbusFrameCount++; - } - if (((sbus[23] >> 3) & 0x0001)) { - if ((sbusRate > 0) && (sbusFailSafeCount < sbusRate)) { - sbusFailSafeCount++; - } - } else if (sbusFailSafeCount > 0) { - sbusFailSafeCount--; - } - #endif - } - } - } -} - -int getRawChannelValue(byte channel) { - if (channel == XAXIS) { - readSBUS(); - } - return rcChannel[channel]; -} - -void setChannelValue(byte channel, int value) { -} - -#endif +/* + AeroQuad v3.0.1 - February 2012 + www.AeroQuad.com + Copyright (c) 2012 Ted Carancho. All rights reserved. + An Open Source Arduino based multicopter. + + This program is free software: you can 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 . + */ + +#ifndef _AEROQUAD_RECEIVER_SBUS_H_ +#define _AEROQUAD_RECEIVER_SBUS_H_ + +#if defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined (AeroQuadSTM32) + +#if !defined (AeroQuadSTM32) + #include "Arduino.h" + #include "pins_arduino.h" + #include + #include "GlobalDefined.h" +#endif +#include "Receiver.h" + +#define SBUS_SYNCBYTE 0x0F // some sites say 0xF0 + +#define SERIAL_SBUS Serial3 + +// 16 analog, 2 digital channels +static unsigned int rcChannel[18] = {XAXIS,YAXIS,THROTTLE,ZAXIS,MODE,AUX1,AUX2,AUX3,AUX4,AUX5,10,11,12,13,14,15,16,17}; +static unsigned int sbusIndex = 0; +#if defined (UseSBUSRSSIReader) + static unsigned short sbusFailSafeCount = 0; + static unsigned long sbusFrameCount = 0; + static unsigned short sbusRate = 0; +#endif + +void initializeReceiver(int nbChannel = 10) { + initializeReceiverParam(nbChannel); + #if defined (AeroQuadSTM32) + pinMode(BOARD_SPI2_NSS_PIN, OUTPUT); + digitalWrite(BOARD_SPI2_NSS_PIN,HIGH); // GPIO PB12 /Libmaple/libmaple/wirish/boards/aeroquad32.h line 69 + #endif + SERIAL_SBUS.begin(100000); +} + +void readSBUS() { + + static byte sbus[25] = {0}; + while(SERIAL_SBUS.available()) { + + int val = SERIAL_SBUS.read(); + if(sbusIndex == 0 && val != SBUS_SYNCBYTE) { + continue; + } + + sbus[sbusIndex] = val; + sbusIndex++; + if (sbusIndex == 25) { + + sbusIndex = 0; + // check stop bit before updating buffers + if (sbus[24] == 0x0) { + + rcChannel[XAXIS] = ((sbus[1] | sbus[2]<<8) & 0x07FF); // pitch + rcChannel[YAXIS] = ((sbus[2]>>3 | sbus[3]<<5) & 0x07FF); // roll + rcChannel[THROTTLE] = ((sbus[3]>>6 | sbus[4]<<2 | sbus[5]<<10) & 0x07FF); // throttle + rcChannel[ZAXIS] = ((sbus[5]>>1 | sbus[6]<<7) & 0x07FF); // yaw + rcChannel[MODE] = ((sbus[6]>>4 | sbus[7]<<4) & 0x07FF); + rcChannel[AUX1] = ((sbus[7]>>7 | sbus[8]<<1 | sbus[9]<<9) & 0x07FF); + rcChannel[AUX2] = ((sbus[9]>>2 | sbus[10]<<6) & 0x07FF); + rcChannel[AUX3] = ((sbus[10]>>5 | sbus[11]<<3) & 0x07FF); + rcChannel[AUX4] = ((sbus[12] | sbus[13]<<8) & 0x07FF); + rcChannel[AUX5] = ((sbus[13]>>3 | sbus[14]<<5) & 0x07FF); + //rcChannel[AUX6] = ((sbus[14]>>6 | sbus[15]<<2|sbus[16]<<10) & 0x07FF); + //rcChannel[AUX7] = ((sbus[16]>>1 | sbus[17]<<7) & 0x07FF); + + + #ifdef UseSBUSRSSIReader + if (sbusRate == 0) { + sbusFrameCount++; + } + if (((sbus[23] >> 3) & 0x0001)) { + if ((sbusRate > 0) && (sbusFailSafeCount < sbusRate)) { + sbusFailSafeCount++; + } + } else if (sbusFailSafeCount > 0) { + sbusFailSafeCount--; + } + #endif + } + } + } +} + +int getRawChannelValue(byte channel) { + if (channel == XAXIS) { + readSBUS(); + } + return rcChannel[channel]; +} + +void setChannelValue(byte channel, int value) { +} + +#endif #endif \ No newline at end of file diff --git a/Libraries/AQ_Receiver/Receiver_STM32.h b/Libraries/AQ_Receiver/Receiver_STM32.h index 2ef735ca..8292948f 100644 --- a/Libraries/AQ_Receiver/Receiver_STM32.h +++ b/Libraries/AQ_Receiver/Receiver_STM32.h @@ -1,207 +1,207 @@ -/* - Copyright (c) 2011 ala42. All rights reserved. - - STM32 receiver class by ala42 using time input capture - for use with AeroQuad software and Maple library - V 1.0 Oct 15 2011 - V 1.1 Jan 22 2012 class free version for AeroQuad 3.0 compatibility - - Define the pin numbers used for the receiver in receiverPin[] - - Timer and timer channels are accessed using the Maple PIN_MAP array. - Make sure libmaple and this receiver class are compiled using the - same structure alignment mode. When in doubt, change the stm32_pin_info - declaration in wirish_types.h to align the size to a multiple of 4 byte - by adding a filler byte at the end of the structure declaration. -*/ - -#ifndef _AEROQUAD_RECEIVER_STM32_H_ -#define _AEROQUAD_RECEIVER_STM32_H_ - -#if defined(AeroQuadSTM32) - -#include "Receiver.h" -#include "wirish.h" - -//#define STM32_TIMER_DEBUG // enable debug messages - -/////////////////////////////////////////////////////////////////////////////// -// configuration part starts here -// definition of pins used for PWM receiver input - - -/* - ROLL 0 3 - PITCH 1 1 - YAW 2 0 - THROTTLE 3 2 - MODE 4 4 - AUX 5 6 - AUX2 6 5 - AUX3 7 7 -*/ -static byte ReceiverChannelMap[] = {0, 1, 2, 3, 4, 5, 6, 7}; // default mapping - - -/////////////////////////////////////////////////////////////////////////////// -// implementation part starts here. -// forward declaration, array is defined at the end of this file -extern voidFuncPtr PWM_in_handler[]; - -typedef struct { - timer_dev *TimerDev; - timer_gen_reg_map *TimerRegs; - __io uint32 *Timer_ccr; - int Low; - int High; - uint16 HighTime; - uint16 RiseTime; - uint16 LastChange; - int Channel; - int TimerChannel; - int PolarityMask; - int Valid; - int Debug; -} tFrqData; - -#define FRQInputs 8 -volatile tFrqData FrqData[FRQInputs]; - -void FrqInit(int aChannel, int aDefault, volatile tFrqData *f, timer_dev *aTimer, int aTimerChannel) { - - aTimerChannel--; // transform timer channel numbering from 1-4 to 0-3 - - f->Channel = aChannel; - f->Valid = false; - - f->TimerDev = aTimer; - timer_gen_reg_map *timer = aTimer->regs.gen; - f->TimerRegs = timer; - - f->Timer_ccr = &timer->CCR1 + aTimerChannel; - f->Debug = false; - f->HighTime = aDefault; - f->TimerChannel = aTimerChannel; - - int TimerEnable = (1 << (4*aTimerChannel)); - f->PolarityMask = TimerEnable << 1; - - uint32 clock_speed = rcc_dev_timer_clk_speed(f->TimerDev->clk_id); - timer->PSC = (clock_speed/1000000)-1; - timer->ARR = 0xffff; - timer->CR1 = 0; - timer->DIER &= ~(1); - - timer->CCER &= ~TimerEnable; // Disable timer - timer->CCER &= ~(f->PolarityMask); - - volatile uint32 *mr; - if(aTimerChannel < 2) { - mr = &(timer->CCMR1); - } - else { - mr = &(timer->CCMR2); - } - *mr &= ~(0xFF << (8*(aTimerChannel&1))); // prescaler 1 - *mr |= 0x61 << (8*(aTimerChannel&1)); // 0x61 -> 6=filter, 1=inputs 1,2,3,4 - - timer->CCER |= TimerEnable; // Enable - timer->CR1 = 1; -} - - -void InitFrqMeasurement() { - - for(int rcLine = 0; rcLine < (int)(sizeof(receiverPin) / sizeof(receiverPin[0])); rcLine++) { - int pin = receiverPin[rcLine]; - timer_dev *timer_num = PIN_MAP[pin].timer_device; - if(timer_num != NULL) { - gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_AF_INPUT_PD); - FrqInit(rcLine, 1500, &FrqData[rcLine], timer_num, PIN_MAP[pin].timer_channel); - timer_attach_interrupt(timer_num, PIN_MAP[pin].timer_channel, PWM_in_handler[rcLine]); - } - } -} - - -void PWMInvertPolarity(volatile tFrqData *f) { - f->TimerRegs->CCER ^= f->PolarityMask; // invert polarity -} - -void FrqChange(volatile tFrqData *f) { - - timer_gen_reg_map *timer = f->TimerRegs; - uint16_t c = *(f->Timer_ccr); - bool rising = (timer->CCER & f->PolarityMask) == 0; - - if(f->Valid) { - if(rising) { - f->RiseTime = c; - } - else { - uint16_t highTime = c - f->RiseTime; - if(highTime > 900 && highTime < 2100) { - f->HighTime = highTime; - } - else { - f->Valid = false; - } - } - } - else if(rising) { - // rising edge, store start time - f->RiseTime = c; - f->Valid = true; - } - - PWMInvertPolarity(f); -} - -// hide the class details from the interrupt handler -void IrqChangeValue(int chan) { - FrqChange(&FrqData[chan]); -} - - -/////////////////////////////////////////////////////////////////////////////// -// definition of interrupt handler functions, one for each channel -void PWM_in_0() { IrqChangeValue(0); } -void PWM_in_1() { IrqChangeValue(1); } -void PWM_in_2() { IrqChangeValue(2); } -void PWM_in_3() { IrqChangeValue(3); } -void PWM_in_4() { IrqChangeValue(4); } -void PWM_in_5() { IrqChangeValue(5); } -void PWM_in_6() { IrqChangeValue(6); } -void PWM_in_7() { IrqChangeValue(7); } - -voidFuncPtr PWM_in_handler[] = { PWM_in_0, PWM_in_1, PWM_in_2, PWM_in_3, PWM_in_4, PWM_in_5, PWM_in_6, PWM_in_7 }; - - -/////////////////////////////////////////////////////////////////////////////// -// interface part starts here - -void initializeReceiver(int nbChannel = 8) { - - initializeReceiverParam(nbChannel); - InitFrqMeasurement(); -} - - -int getRawChannelValue(const byte channel) { - int chan = ReceiverChannelMap[channel]; - if(chan < (int)sizeof(receiverPin)) { - volatile tFrqData *f = &FrqData[chan]; - uint16_t PulsLength = f->HighTime; - return PulsLength; - } else { - return 1500; - } -} - - -void setChannelValue(byte channel,int value) { -} - -#endif - -#endif +/* + Copyright (c) 2011 ala42. All rights reserved. + + STM32 receiver class by ala42 using time input capture + for use with AeroQuad software and Maple library + V 1.0 Oct 15 2011 + V 1.1 Jan 22 2012 class free version for AeroQuad 3.0 compatibility + + Define the pin numbers used for the receiver in receiverPin[] + + Timer and timer channels are accessed using the Maple PIN_MAP array. + Make sure libmaple and this receiver class are compiled using the + same structure alignment mode. When in doubt, change the stm32_pin_info + declaration in wirish_types.h to align the size to a multiple of 4 byte + by adding a filler byte at the end of the structure declaration. +*/ + +#ifndef _AEROQUAD_RECEIVER_STM32_H_ +#define _AEROQUAD_RECEIVER_STM32_H_ + +#if defined(AeroQuadSTM32) + +#include "Receiver.h" +#include "wirish.h" + +//#define STM32_TIMER_DEBUG // enable debug messages + +/////////////////////////////////////////////////////////////////////////////// +// configuration part starts here +// definition of pins used for PWM receiver input + + +/* + ROLL 0 3 + PITCH 1 1 + YAW 2 0 + THROTTLE 3 2 + MODE 4 4 + AUX 5 6 + AUX2 6 5 + AUX3 7 7 +*/ +static byte ReceiverChannelMap[] = {0, 1, 2, 3, 4, 5, 6, 7}; // default mapping + + +/////////////////////////////////////////////////////////////////////////////// +// implementation part starts here. +// forward declaration, array is defined at the end of this file +extern voidFuncPtr PWM_in_handler[]; + +typedef struct { + timer_dev *TimerDev; + timer_gen_reg_map *TimerRegs; + __io uint32 *Timer_ccr; + int Low; + int High; + uint16 HighTime; + uint16 RiseTime; + uint16 LastChange; + int Channel; + int TimerChannel; + int PolarityMask; + int Valid; + int Debug; +} tFrqData; + +#define FRQInputs 8 +volatile tFrqData FrqData[FRQInputs]; + +void FrqInit(int aChannel, int aDefault, volatile tFrqData *f, timer_dev *aTimer, int aTimerChannel) { + + aTimerChannel--; // transform timer channel numbering from 1-4 to 0-3 + + f->Channel = aChannel; + f->Valid = false; + + f->TimerDev = aTimer; + timer_gen_reg_map *timer = aTimer->regs.gen; + f->TimerRegs = timer; + + f->Timer_ccr = &timer->CCR1 + aTimerChannel; + f->Debug = false; + f->HighTime = aDefault; + f->TimerChannel = aTimerChannel; + + int TimerEnable = (1 << (4*aTimerChannel)); + f->PolarityMask = TimerEnable << 1; + + uint32 clock_speed = rcc_dev_timer_clk_speed(f->TimerDev->clk_id); + timer->PSC = (clock_speed/1000000)-1; + timer->ARR = 0xffff; + timer->CR1 = 0; + timer->DIER &= ~(1); + + timer->CCER &= ~TimerEnable; // Disable timer + timer->CCER &= ~(f->PolarityMask); + + volatile uint32 *mr; + if(aTimerChannel < 2) { + mr = &(timer->CCMR1); + } + else { + mr = &(timer->CCMR2); + } + *mr &= ~(0xFF << (8*(aTimerChannel&1))); // prescaler 1 + *mr |= 0x61 << (8*(aTimerChannel&1)); // 0x61 -> 6=filter, 1=inputs 1,2,3,4 + + timer->CCER |= TimerEnable; // Enable + timer->CR1 = 1; +} + + +void InitFrqMeasurement() { + + for(int rcLine = 0; rcLine < (int)(sizeof(receiverPin) / sizeof(receiverPin[0])); rcLine++) { + int pin = receiverPin[rcLine]; + timer_dev *timer_num = PIN_MAP[pin].timer_device; + if(timer_num != NULL) { + gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_AF_INPUT_PD); + FrqInit(rcLine, 1500, &FrqData[rcLine], timer_num, PIN_MAP[pin].timer_channel); + timer_attach_interrupt(timer_num, PIN_MAP[pin].timer_channel, PWM_in_handler[rcLine]); + } + } +} + + +void PWMInvertPolarity(volatile tFrqData *f) { + f->TimerRegs->CCER ^= f->PolarityMask; // invert polarity +} + +void FrqChange(volatile tFrqData *f) { + + timer_gen_reg_map *timer = f->TimerRegs; + uint16_t c = *(f->Timer_ccr); + bool rising = (timer->CCER & f->PolarityMask) == 0; + + if(f->Valid) { + if(rising) { + f->RiseTime = c; + } + else { + uint16_t highTime = c - f->RiseTime; + if(highTime > 900 && highTime < 2100) { + f->HighTime = highTime; + } + else { + f->Valid = false; + } + } + } + else if(rising) { + // rising edge, store start time + f->RiseTime = c; + f->Valid = true; + } + + PWMInvertPolarity(f); +} + +// hide the class details from the interrupt handler +void IrqChangeValue(int chan) { + FrqChange(&FrqData[chan]); +} + + +/////////////////////////////////////////////////////////////////////////////// +// definition of interrupt handler functions, one for each channel +void PWM_in_0() { IrqChangeValue(0); } +void PWM_in_1() { IrqChangeValue(1); } +void PWM_in_2() { IrqChangeValue(2); } +void PWM_in_3() { IrqChangeValue(3); } +void PWM_in_4() { IrqChangeValue(4); } +void PWM_in_5() { IrqChangeValue(5); } +void PWM_in_6() { IrqChangeValue(6); } +void PWM_in_7() { IrqChangeValue(7); } + +voidFuncPtr PWM_in_handler[] = { PWM_in_0, PWM_in_1, PWM_in_2, PWM_in_3, PWM_in_4, PWM_in_5, PWM_in_6, PWM_in_7 }; + + +/////////////////////////////////////////////////////////////////////////////// +// interface part starts here + +void initializeReceiver(int nbChannel = 8) { + + initializeReceiverParam(nbChannel); + InitFrqMeasurement(); +} + + +int getRawChannelValue(const byte channel) { + int chan = ReceiverChannelMap[channel]; + if(chan < (int)sizeof(receiverPin)) { + volatile tFrqData *f = &FrqData[chan]; + uint16_t PulsLength = f->HighTime; + return PulsLength; + } else { + return 1500; + } +} + + +void setChannelValue(byte channel,int value) { +} + +#endif + +#endif diff --git a/Libraries/AQ_Receiver/Receiver_STM32PPM.h b/Libraries/AQ_Receiver/Receiver_STM32PPM.h index 9429035d..cb5f0363 100644 --- a/Libraries/AQ_Receiver/Receiver_STM32PPM.h +++ b/Libraries/AQ_Receiver/Receiver_STM32PPM.h @@ -1,140 +1,140 @@ -/* - Copyright (c) 2012 kha. All rights reserved. - - STM32 PPM receiver by kha based on - STM32 receiver class by ala42 using time input capture - for use with AeroQuad software and Maple library - V 1.0 Jun 14 2012 - - Define the pin numbers used for the receiver in receiverPinPPM - - Timer and timer channels are accessed using the Maple PIN_MAP array. - Make sure libmaple and this receiver class are compiled using the - same structure alignment mode. When in doubt, change the stm32_pin_info - declaration in wirish_types.h to align the size to a multiple of 4 byte - by adding a filler byte at the end of the structure declaration. -*/ - -#ifndef _AEROQUAD_RECEIVER_STM32PPM_H_ -#define _AEROQUAD_RECEIVER_STM32PPM_H_ - -#if defined(AeroQuadSTM32) - -#include "Receiver.h" -#include "wirish.h" -#include "Receiver_PPM_common.h" - -static byte ReceiverChannelMap[PPM_CHANNELS] = {SERIAL_SUM_PPM}; - -uint16 rawChannelValue[PPM_CHANNELS] = {1500,1500,1500,1500,1500,1500,1500,1500,1500,1500}; -byte currentChannel; - - -/////////////////////////////////////////////////////////////////////////////// -// implementation part starts here. - -typedef struct { - timer_dev *TimerDev; - timer_gen_reg_map *TimerRegs; - __io uint32 *Timer_ccr; - uint16 RiseTime; - int TimerChannel; - int PolarityMask; -} tFrqData; - -volatile tFrqData FrqData; - -void FrqInit(int aDefault, timer_dev *aTimer, int aTimerChannel) -{ - aTimerChannel--; // transform timer channel numbering from 1-4 to 0-3 - - FrqData.TimerDev = aTimer; - timer_gen_reg_map *timer = aTimer->regs.gen; - FrqData.TimerRegs = timer; - - FrqData.Timer_ccr = &timer->CCR1 + aTimerChannel; - FrqData.TimerChannel = aTimerChannel; - - int TimerEnable = (1 << (4*aTimerChannel)); - FrqData.PolarityMask = TimerEnable << 1; - - uint32 clock_speed = rcc_dev_timer_clk_speed(FrqData.TimerDev->clk_id); - timer->PSC = (clock_speed/1000000)-1; - timer->ARR = 0xffff; - timer->CR1 = 0; - timer->DIER &= ~(1); - - timer->CCER &= ~TimerEnable; // Disable timer - timer->CCER &= ~(FrqData.PolarityMask); - - volatile uint32 *mr; - if(aTimerChannel < 2) { - mr = &(timer->CCMR1); - } - else { - mr = &(timer->CCMR2); - } - *mr &= ~(0xFF << (8*(aTimerChannel&1))); // prescaler 1 - *mr |= 0x61 << (8*(aTimerChannel&1)); // 0x61 -> 6=filter, 1=inputs 1,2,3,4 - - timer->CCER |= TimerEnable; // Enable - timer->CR1 = 1; - -} - -void FrqChange() -{ - uint16_t c = *(FrqData.Timer_ccr); - uint16_t diffTime = c - FrqData.RiseTime; - if ((diffTime > 900) && (diffTime < 2100)) { - if (currentChannel < PPM_CHANNELS) { - rawChannelValue[currentChannel] = diffTime; - currentChannel++; - } - } - else if (diffTime > 2500) { - currentChannel = 0; - } - else { - // glitch; stop and wait next round - currentChannel = PPM_CHANNELS; - } - FrqData.RiseTime = c; -} - -void InitFrqMeasurement() -{ - int pin = receiverPinPPM; - timer_dev *timer_num = PIN_MAP[pin].timer_device; - - currentChannel=8; - if(timer_num != NULL) { - gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_AF_INPUT_PD); - FrqInit(1500, timer_num, PIN_MAP[pin].timer_channel); - timer_attach_interrupt(timer_num, PIN_MAP[pin].timer_channel, FrqChange); - } - -} - - - -/////////////////////////////////////////////////////////////////////////////// -// interface part starts here - -void initializeReceiver(int nbChannel = 8) { - initializeReceiverParam(nbChannel); - InitFrqMeasurement(); -} - - -int getRawChannelValue(const byte channel) { - return rawChannelValue[ReceiverChannelMap[channel]]; -} - - -void setChannelValue(byte channel,int value) { -} - -#endif - -#endif +/* + Copyright (c) 2012 kha. All rights reserved. + + STM32 PPM receiver by kha based on + STM32 receiver class by ala42 using time input capture + for use with AeroQuad software and Maple library + V 1.0 Jun 14 2012 + + Define the pin numbers used for the receiver in receiverPinPPM + + Timer and timer channels are accessed using the Maple PIN_MAP array. + Make sure libmaple and this receiver class are compiled using the + same structure alignment mode. When in doubt, change the stm32_pin_info + declaration in wirish_types.h to align the size to a multiple of 4 byte + by adding a filler byte at the end of the structure declaration. +*/ + +#ifndef _AEROQUAD_RECEIVER_STM32PPM_H_ +#define _AEROQUAD_RECEIVER_STM32PPM_H_ + +#if defined(AeroQuadSTM32) + +#include "Receiver.h" +#include "wirish.h" +#include "Receiver_PPM_common.h" + +static byte ReceiverChannelMap[PPM_CHANNELS] = {SERIAL_SUM_PPM}; + +uint16 rawChannelValue[PPM_CHANNELS] = {1500,1500,1500,1500,1500,1500,1500,1500,1500,1500}; +byte currentChannel; + + +/////////////////////////////////////////////////////////////////////////////// +// implementation part starts here. + +typedef struct { + timer_dev *TimerDev; + timer_gen_reg_map *TimerRegs; + __io uint32 *Timer_ccr; + uint16 RiseTime; + int TimerChannel; + int PolarityMask; +} tFrqData; + +volatile tFrqData FrqData; + +void FrqInit(int aDefault, timer_dev *aTimer, int aTimerChannel) +{ + aTimerChannel--; // transform timer channel numbering from 1-4 to 0-3 + + FrqData.TimerDev = aTimer; + timer_gen_reg_map *timer = aTimer->regs.gen; + FrqData.TimerRegs = timer; + + FrqData.Timer_ccr = &timer->CCR1 + aTimerChannel; + FrqData.TimerChannel = aTimerChannel; + + int TimerEnable = (1 << (4*aTimerChannel)); + FrqData.PolarityMask = TimerEnable << 1; + + uint32 clock_speed = rcc_dev_timer_clk_speed(FrqData.TimerDev->clk_id); + timer->PSC = (clock_speed/1000000)-1; + timer->ARR = 0xffff; + timer->CR1 = 0; + timer->DIER &= ~(1); + + timer->CCER &= ~TimerEnable; // Disable timer + timer->CCER &= ~(FrqData.PolarityMask); + + volatile uint32 *mr; + if(aTimerChannel < 2) { + mr = &(timer->CCMR1); + } + else { + mr = &(timer->CCMR2); + } + *mr &= ~(0xFF << (8*(aTimerChannel&1))); // prescaler 1 + *mr |= 0x61 << (8*(aTimerChannel&1)); // 0x61 -> 6=filter, 1=inputs 1,2,3,4 + + timer->CCER |= TimerEnable; // Enable + timer->CR1 = 1; + +} + +void FrqChange() +{ + uint16_t c = *(FrqData.Timer_ccr); + uint16_t diffTime = c - FrqData.RiseTime; + if ((diffTime > 900) && (diffTime < 2100)) { + if (currentChannel < PPM_CHANNELS) { + rawChannelValue[currentChannel] = diffTime; + currentChannel++; + } + } + else if (diffTime > 2500) { + currentChannel = 0; + } + else { + // glitch; stop and wait next round + currentChannel = PPM_CHANNELS; + } + FrqData.RiseTime = c; +} + +void InitFrqMeasurement() +{ + int pin = receiverPinPPM; + timer_dev *timer_num = PIN_MAP[pin].timer_device; + + currentChannel=8; + if(timer_num != NULL) { + gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_AF_INPUT_PD); + FrqInit(1500, timer_num, PIN_MAP[pin].timer_channel); + timer_attach_interrupt(timer_num, PIN_MAP[pin].timer_channel, FrqChange); + } + +} + + + +/////////////////////////////////////////////////////////////////////////////// +// interface part starts here + +void initializeReceiver(int nbChannel = 8) { + initializeReceiverParam(nbChannel); + InitFrqMeasurement(); +} + + +int getRawChannelValue(const byte channel) { + return rawChannelValue[ReceiverChannelMap[channel]]; +} + + +void setChannelValue(byte channel,int value) { +} + +#endif + +#endif diff --git a/Libraries/AQ_SPI/HardwareSPIExt.h b/Libraries/AQ_SPI/HardwareSPIExt.h index 6a80ae9c..64bdca85 100644 --- a/Libraries/AQ_SPI/HardwareSPIExt.h +++ b/Libraries/AQ_SPI/HardwareSPIExt.h @@ -1,80 +1,80 @@ -#ifndef _AEROQUAD_SPI_HARDWARESPIEXT_H_ -#define _AEROQUAD_SPI_HARDWARESPIEXT_H_ - -#if defined(AeroQuadSTM32) - -// helper class to extend the maple HardwareSPI class -// used by the MPU6000 library - -#include - -#define SPI_READ_FLAG 0x80 -#define SPI_MULTI_FLAG 0x40 -#define SetPin digitalWrite - -class HardwareSPIExt : public HardwareSPI { -public: - HardwareSPIExt(uint32 spiPortNumber) : HardwareSPI(spiPortNumber) { - SetCS(nssPin()); - fSpiMultiFlag = 0; - } - - void SetCS(int aCS) - { - fCS = aCS; - } - - void SetMultiFlag() { - fSpiMultiFlag = SPI_MULTI_FLAG; - } - - void begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode) - { - SetPin(fCS, 1); - pinMode(fCS, OUTPUT); - - HardwareSPI::begin(frequency, bitOrder, mode); - } - - void Read(int addr, unsigned char *data, int dataLen) - { - SetPin(fCS, 0); - transfer(addr | SPI_READ_FLAG | fSpiMultiFlag); - while(dataLen-- > 0) { - *data++ = transfer(0); - } - SetPin(fCS, 1); - } - - unsigned char Read(int addr) - { - unsigned char data; - Read(addr, &data, 1); - - return data; - } - - void Write(int addr, unsigned char *data, int dataLen) - { - SetPin(fCS, 0); - transfer(addr | fSpiMultiFlag); - while(dataLen-- > 0) { - transfer(*data++); - } - SetPin(fCS, 1); - } - - void Write(int addr, unsigned char data) - { - Write(addr, &data, 1); - } - - -private: - int fCS; - unsigned char fSpiMultiFlag; -}; - -#endif - -#endif +#ifndef _AEROQUAD_SPI_HARDWARESPIEXT_H_ +#define _AEROQUAD_SPI_HARDWARESPIEXT_H_ + +#if defined(AeroQuadSTM32) + +// helper class to extend the maple HardwareSPI class +// used by the MPU6000 library + +#include + +#define SPI_READ_FLAG 0x80 +#define SPI_MULTI_FLAG 0x40 +#define SetPin digitalWrite + +class HardwareSPIExt : public HardwareSPI { +public: + HardwareSPIExt(uint32 spiPortNumber) : HardwareSPI(spiPortNumber) { + SetCS(nssPin()); + fSpiMultiFlag = 0; + } + + void SetCS(int aCS) + { + fCS = aCS; + } + + void SetMultiFlag() { + fSpiMultiFlag = SPI_MULTI_FLAG; + } + + void begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode) + { + SetPin(fCS, 1); + pinMode(fCS, OUTPUT); + + HardwareSPI::begin(frequency, bitOrder, mode); + } + + void Read(int addr, unsigned char *data, int dataLen) + { + SetPin(fCS, 0); + transfer(addr | SPI_READ_FLAG | fSpiMultiFlag); + while(dataLen-- > 0) { + *data++ = transfer(0); + } + SetPin(fCS, 1); + } + + unsigned char Read(int addr) + { + unsigned char data; + Read(addr, &data, 1); + + return data; + } + + void Write(int addr, unsigned char *data, int dataLen) + { + SetPin(fCS, 0); + transfer(addr | fSpiMultiFlag); + while(dataLen-- > 0) { + transfer(*data++); + } + SetPin(fCS, 1); + } + + void Write(int addr, unsigned char data) + { + Write(addr, &data, 1); + } + + +private: + int fCS; + unsigned char fSpiMultiFlag; +}; + +#endif + +#endif diff --git a/Libraries/AQ_SoftModem/AQ_SoftModem.h b/Libraries/AQ_SoftModem/AQ_SoftModem.h index 6757784b..ccc7700d 100644 --- a/Libraries/AQ_SoftModem/AQ_SoftModem.h +++ b/Libraries/AQ_SoftModem/AQ_SoftModem.h @@ -1,135 +1,135 @@ -/* - STM32 SoftModem for AQ32 by kha - - Copyright (c) 2012 AeroQuad developers. All rights reserved. - - This program is free software: you can 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 . - - Uses - - DAC channel 1 to pin PA4 - - Timers 6 and 7 - - DMA1 Stream 5 - -*/ - -#ifndef _AEROQUAD_SOFTMODEM_H_ -#define _AEROQUAD_SOFTMODEM_H_ - -#if !defined(AeroQuadSTM32) - #error SoftModem is only supported on STM32 -#endif - -#include -#include -#include - - -#ifdef SOFTMODEM_FSKv2 - // TCMS105 clocked at 8Mhz - #define ARR_MARK 1118 // 2345 Hz - #define ARR_SPACE 692 // 3789 Hz -#else - // Standard 1300/2100 - #define ARR_MARK 2016 // 1300 Hz - #define ARR_SPACE 1249 // 2100 Hz -#endif - -#ifndef SOFTMODEM_BAUDRATE - #define BAUDRATE 1200 -#endif - - -#define SOFTMODEM_PIN Port2Pin('A',4) - -unsigned char softmodemDMABuffer[32] = { // sine wave 32 samples - 128,153,177,199,219,234,246,253,255,253,246,234,219,199,177,153, - 128,103, 79, 57, 37, 22, 10, 2, 0, 2, 10, 22, 37, 57, 79,103}; - -volatile byte softmodemCurrentBit=0; // 1 - startbit, 2-9 databits, 10 stop, 11 stop2 -volatile byte softmodemCurrentByte='A'; - -void softmodemInterrupt() { - TIMER7_BASE->SR&=~1; // gludge... may get double int if this is not done - if (softmodemCurrentBit) { - if (softmodemCurrentBit == 1) { - TIMER6_BASE->ARR = ARR_SPACE; // START bit - } - else if (softmodemCurrentBit == 10) { - TIMER6_BASE->ARR = ARR_MARK; - } - else if (softmodemCurrentBit > 10) { - softmodemCurrentBit = 0; - return; // do not increase counter - } - else { - if (softmodemCurrentByte & (1 << (softmodemCurrentBit - 2))) { - TIMER6_BASE->ARR = ARR_MARK; - } else { - TIMER6_BASE->ARR = ARR_SPACE; - } - } - softmodemCurrentBit++; - } -} - -void softmodemInit() -{ - dac_init(DAC,0); // do not enable yet - pinMode(SOFTMODEM_PIN, INPUT_ANALOG); - - dma_init(DMA1); - dma_setup_transfer(DMA1, DMA_STREAM5, &DAC->regs->DHR8R1, softmodemDMABuffer, softmodemDMABuffer, - DMA_CR_CH7|DMA_CR_CT1|DMA_CR_DBM|DMA_CR_PL_VERY_HIGH|DMA_CR_MINC|DMA_CR_CIRC|DMA_CR_DIR_M2P, - 0); - // 0x0e0f0540,1); - - dma_set_num_transfers(DMA1,DMA_STREAM5,32); - - DAC->regs->DHR8R1 = 0x7f; - DAC->regs->CR &= 0xffff0000; // clear bits for ch1 - DAC->regs->CR |= DAC_CR_DMAEN1; // enable DMA - DAC->regs->CR |= DAC_CR_TEN1; // enable trigger (timer6 TRGO) - dac_enable_channel(DAC,DAC_CH1); - - dma_enable(DMA1,DMA_STREAM5); - - timer_init(TIMER6); - TIMER6_BASE->ARR = ARR_MARK; - TIMER6_BASE->PSC = 0; - TIMER6_BASE->CR2 = TIMER_CR2_MMS_UPDATE; - TIMER6_BASE->CR1 = TIMER_CR1_ARPE | TIMER_CR1_URS | TIMER_CR1_CEN; - - timer_init(TIMER7); - timer_attach_interrupt(TIMER7,TIMER_UPDATE_INTERRUPT,softmodemInterrupt); - nvic_irq_set_priority(NVIC_TIMER7,1); - - TIMER7_BASE->ARR = 1288800/BAUDRATE; - TIMER7_BASE->PSC = 63; - TIMER7_BASE->CR2 = TIMER_CR2_MMS_ENABLE; - TIMER7_BASE->CR1 = TIMER_CR1_URS | TIMER_CR1_CEN; -} - - -byte softmodemFreeToSend() { - return (softmodemCurrentBit==0); -} - -void softmodemSendByte(unsigned char data) { - if (!softmodemCurrentBit) { - softmodemCurrentByte = data; - softmodemCurrentBit=1; - } -} - -#endif +/* + STM32 SoftModem for AQ32 by kha + + Copyright (c) 2012 AeroQuad developers. All rights reserved. + + This program is free software: you can 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 . + + Uses + - DAC channel 1 to pin PA4 + - Timers 6 and 7 + - DMA1 Stream 5 + +*/ + +#ifndef _AEROQUAD_SOFTMODEM_H_ +#define _AEROQUAD_SOFTMODEM_H_ + +#if !defined(AeroQuadSTM32) + #error SoftModem is only supported on STM32 +#endif + +#include +#include +#include + + +#ifdef SOFTMODEM_FSKv2 + // TCMS105 clocked at 8Mhz + #define ARR_MARK 1118 // 2345 Hz + #define ARR_SPACE 692 // 3789 Hz +#else + // Standard 1300/2100 + #define ARR_MARK 2016 // 1300 Hz + #define ARR_SPACE 1249 // 2100 Hz +#endif + +#ifndef SOFTMODEM_BAUDRATE + #define BAUDRATE 1200 +#endif + + +#define SOFTMODEM_PIN Port2Pin('A',4) + +unsigned char softmodemDMABuffer[32] = { // sine wave 32 samples + 128,153,177,199,219,234,246,253,255,253,246,234,219,199,177,153, + 128,103, 79, 57, 37, 22, 10, 2, 0, 2, 10, 22, 37, 57, 79,103}; + +volatile byte softmodemCurrentBit=0; // 1 - startbit, 2-9 databits, 10 stop, 11 stop2 +volatile byte softmodemCurrentByte='A'; + +void softmodemInterrupt() { + TIMER7_BASE->SR&=~1; // gludge... may get double int if this is not done + if (softmodemCurrentBit) { + if (softmodemCurrentBit == 1) { + TIMER6_BASE->ARR = ARR_SPACE; // START bit + } + else if (softmodemCurrentBit == 10) { + TIMER6_BASE->ARR = ARR_MARK; + } + else if (softmodemCurrentBit > 10) { + softmodemCurrentBit = 0; + return; // do not increase counter + } + else { + if (softmodemCurrentByte & (1 << (softmodemCurrentBit - 2))) { + TIMER6_BASE->ARR = ARR_MARK; + } else { + TIMER6_BASE->ARR = ARR_SPACE; + } + } + softmodemCurrentBit++; + } +} + +void softmodemInit() +{ + dac_init(DAC,0); // do not enable yet + pinMode(SOFTMODEM_PIN, INPUT_ANALOG); + + dma_init(DMA1); + dma_setup_transfer(DMA1, DMA_STREAM5, &DAC->regs->DHR8R1, softmodemDMABuffer, softmodemDMABuffer, + DMA_CR_CH7|DMA_CR_CT1|DMA_CR_DBM|DMA_CR_PL_VERY_HIGH|DMA_CR_MINC|DMA_CR_CIRC|DMA_CR_DIR_M2P, + 0); + // 0x0e0f0540,1); + + dma_set_num_transfers(DMA1,DMA_STREAM5,32); + + DAC->regs->DHR8R1 = 0x7f; + DAC->regs->CR &= 0xffff0000; // clear bits for ch1 + DAC->regs->CR |= DAC_CR_DMAEN1; // enable DMA + DAC->regs->CR |= DAC_CR_TEN1; // enable trigger (timer6 TRGO) + dac_enable_channel(DAC,DAC_CH1); + + dma_enable(DMA1,DMA_STREAM5); + + timer_init(TIMER6); + TIMER6_BASE->ARR = ARR_MARK; + TIMER6_BASE->PSC = 0; + TIMER6_BASE->CR2 = TIMER_CR2_MMS_UPDATE; + TIMER6_BASE->CR1 = TIMER_CR1_ARPE | TIMER_CR1_URS | TIMER_CR1_CEN; + + timer_init(TIMER7); + timer_attach_interrupt(TIMER7,TIMER_UPDATE_INTERRUPT,softmodemInterrupt); + nvic_irq_set_priority(NVIC_TIMER7,1); + + TIMER7_BASE->ARR = 1288800/BAUDRATE; + TIMER7_BASE->PSC = 63; + TIMER7_BASE->CR2 = TIMER_CR2_MMS_ENABLE; + TIMER7_BASE->CR1 = TIMER_CR1_URS | TIMER_CR1_CEN; +} + + +byte softmodemFreeToSend() { + return (softmodemCurrentBit==0); +} + +void softmodemSendByte(unsigned char data) { + if (!softmodemCurrentBit) { + softmodemCurrentByte = data; + softmodemCurrentBit=1; + } +} + +#endif